Compare commits

..

28 Commits

Author SHA1 Message Date
Colin Cross
635ff5fdac Merge "Add more of the bionic architecture logic" into master-soong 2015-07-10 01:03:44 +00:00
Colin Cross
a56904273c Merge "Add version_script to bionic Blueprints" into master-soong 2015-07-10 01:00:49 +00:00
Colin Cross
f93bddbbd8 Merge "Add translation directives to libc Android.bp" into master-soong 2015-07-10 01:00:41 +00:00
Colin Cross
2803a15d4c Add more of the bionic architecture logic
Change-Id: I8aecabdc7219ad9e9affab1a3e67164352858bf9
2015-07-09 17:42:58 -07:00
Colin Cross
70f11bd69b Add version_script to bionic Blueprints
Change-Id: Ieddd80fa599c21414608e1d1c20ebaa2507a66ef
2015-07-09 17:35:15 -07:00
Colin Cross
8f7a4a3cb5 Add translation directives to libc Android.bp
Add translation directives for the crt*.o files instead of trying
to handle them in the translator.

Change-Id: I44a491f1823f483d9c40368da35d4e0cf16030f2
2015-07-09 17:35:07 -07:00
Dan Willemsen
649a2ea0e2 Merge "Switch libm from thumb to arm" into master-soong 2015-07-09 05:31:41 +00:00
Dan Willemsen
c371306714 Switch libm from thumb to arm
To match the Android.mk file

Change-Id: I02cb5f4b140c03bc8630879f005e027426a5dd99
2015-07-08 19:12:09 -07:00
Dan Willemsen
87e33892fc Merge "Use exclude_srcs instead of "-file"" into master-soong 2015-07-06 19:52:39 +00:00
Dan Willemsen
7454daa97f Use exclude_srcs instead of "-file"
Change-Id: Ie07c5901233d429102f9b6afcef12ea8c4bdda2c
2015-07-01 14:00:21 -07:00
Colin Cross
dab6ead2aa Rename Blueprints to Android.bp
Rename module definition files to Android.bp to avoid conflicts
with another project called Blueprint.

Change-Id: I69cfe9649fe35735dade6416d15b171a5bb2e283
2015-05-20 13:11:07 -07:00
Colin Cross
7d0b7b4ba2 Merge "Remove nonexistant include path" into master-soong 2015-05-12 19:31:16 +00:00
Colin Cross
98f4e07237 Remove nonexistant include path
upstream-freebsd/lib/libc/include doesn't exist, remove it from the
include path.

Change-Id: I0492784db5dc45e4a9a937956d095a147a08e835
2015-05-12 11:35:48 -07:00
Colin Cross
b624072cbd Merge "Export libbenchmark include dir" into master-soong 2015-05-08 00:06:32 +00:00
Colin Cross
0ecd342743 Export libbenchmark include dir
Export the libbenchmark include directory so the build system
doesn't have manually add it for cc_benchmark modules.

Change-Id: I918a2fa5fb3104f4c2d86930ed2b9c5e00820ec6
2015-05-07 15:51:37 -07:00
Colin Cross
faa14d4de8 Merge "Fix Blueprints for building on Darwin" into master-soong 2015-05-07 21:31:49 +00:00
Colin Cross
abc97e2e71 Fix Blueprints for building on Darwin
Change-Id: I252e1b8a9ace397609f056f69aff83331b92aab7
2015-05-05 16:52:38 -07:00
Colin Cross
6549fe249c Update Blueprints files for AOSP changes
Change-Id: I915fc1e00b6e6eb1d6c08233893517b1d56c74fa
2015-04-29 11:34:24 -07:00
Colin Cross
c15e8fdb8d Merge remote-tracking branch 'aosp/master' into aosp 2015-04-29 11:29:05 -07:00
Colin Cross
90d6279802 Merge "Add Blueprints files for remaining bionic modules" into master-soong 2015-03-28 01:15:36 +00:00
Colin Cross
22d8776587 Add Blueprints files for remaining bionic modules
Change-Id: Ic9440fddb44ca1f17aad5b249535d7b96dd8d690
2015-03-27 11:14:39 -07:00
Colin Cross
51b8912253 Merge "Merge remote-tracking branch 'aosp/master' into HEAD" into master-soong 2015-03-17 19:31:44 +00:00
Colin Cross
270f2ea800 Merge remote-tracking branch 'aosp/master' into HEAD
Change-Id: Ia313444a62bcdeb676185b56ce730d0f997c8226
2015-03-17 12:30:41 -07:00
Colin Cross
7357ad0875 Merge "Update bionic Blueprints to match latest AOSP master" into master-soong 2015-03-17 00:44:29 +00:00
Colin Cross
959bc099a3 Merge remote-tracking branch 'aosp/master' into HEAD 2015-03-16 16:54:58 -07:00
Colin Cross
68a3b658b1 Update bionic Blueprints to match latest AOSP master
Change-Id: I90410ec60acfc3dcbdbcd0be6f283a90f4395643
2015-03-16 16:31:26 -07:00
Colin Cross
062d498e28 Merge "Initial bionic Blueprints files" into master-soong 2015-03-14 06:41:45 +00:00
Colin Cross
d2b8741e1b Initial bionic Blueprints files
Change-Id: Iafe8e84e0dc62e7d7c830e2c272ec92abdf6a801
2015-03-10 14:11:55 -07:00
87 changed files with 3891 additions and 1182 deletions

1
Android.bp Normal file
View File

@@ -0,0 +1 @@
subdirs = ["*"]

123
benchmarks/Android.bp Normal file
View File

@@ -0,0 +1,123 @@
//
// Copyright (C) 2013 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.
//
// -----------------------------------------------------------------------------
// Benchmarks library, usable by projects outside this directory.
// -----------------------------------------------------------------------------
benchmark_cflags = [
"-O2",
"-fno-builtin",
"-Wall",
"-Wextra",
"-Werror",
"-Wunused",
]
benchmark_cppflags = ["-std=gnu++11"]
benchmarklib_src_files = [
"Benchmark.cpp",
"utils.cpp",
"main.cpp",
]
cc_library_static {
name: "libbenchmark",
host_supported: true,
cflags: benchmark_cflags,
cppflags: benchmark_cppflags,
srcs: benchmarklib_src_files,
static_libs: ["libbase"],
export_include_dirs: ["."],
target: {
darwin: {
// Only supported on linux systems.
disabled: true,
},
},
}
// -----------------------------------------------------------------------------
// Benchmarks.
// -----------------------------------------------------------------------------
benchmark_src_files = [
"math_benchmark.cpp",
"property_benchmark.cpp",
"pthread_benchmark.cpp",
"semaphore_benchmark.cpp",
"stdio_benchmark.cpp",
"string_benchmark.cpp",
"time_benchmark.cpp",
"unistd_benchmark.cpp",
]
// Build benchmarks for the device (with bionic's .so). Run with:
// adb shell bionic-benchmarks32
// adb shell bionic-benchmarks64
cc_binary {
name: "bionic-benchmarks",
multilib: {
lib32: {
suffix: "32",
},
lib64: {
suffix: "64",
},
},
compile_multilib: "both",
cflags: benchmark_cflags,
cppflags: benchmark_cppflags,
srcs: benchmark_src_files,
static_libs: [
"libbenchmark",
"libbase",
],
}
// We don't build a static benchmark executable because it's not usually
// useful. If you're trying to run the current benchmarks on an older
// release, it's (so far at least) always because you want to measure the
// performance of the old release's libc, and a static benchmark isn't
// going to let you do that.
// Build benchmarks for the host (against glibc!). Run with:
cc_binary_host {
name: "bionic-benchmarks-glibc",
multilib: {
lib32: {
stem: "bionic-benchmarks-glibc32",
},
lib64: {
stem: "bionic-benchmarks-glibc64",
},
},
compile_multilib: "both",
cflags: benchmark_cflags,
cppflags: benchmark_cppflags,
ldflags: ["-lrt"],
srcs: benchmark_src_files,
static_libs: [
"libbenchmark",
"libbase",
],
target: {
darwin: {
// Only supported on linux systems.
disabled: true,
},
},
}

View File

@@ -16,7 +16,6 @@
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <benchmark/Benchmark.h>
@@ -74,7 +73,7 @@ static void FopenFgetsFclose(int iters, bool no_locking) {
for (int i = 0; i < iters; ++i) {
FILE* fp = fopen("/proc/version", "re");
if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
if (fgets(buf, sizeof(buf), fp) == nullptr) abort();
fgets(buf, sizeof(buf), fp);
fclose(fp);
}
}

View File

@@ -14,8 +14,6 @@
* limitations under the License.
*/
#include "utils.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
@@ -23,7 +21,7 @@
#include <string>
#include <base/stringprintf.h>
#include "utils.h"
int Round(int n) {
int base = 1;
@@ -74,7 +72,10 @@ std::string PrettyInt(long value, size_t base) {
break;
}
}
return android::base::StringPrintf("%s%" PRId64 "%s",
negative_number ? "-" : "",
count / kAmountPerUnit[i], kUnitStrings[i]);
char* s = NULL;
asprintf(&s, "%s%" PRId64 "%s", (negative_number ? "-" : ""),
count / kAmountPerUnit[i], kUnitStrings[i]);
std::string result(s);
free(s);
return result;
}

2261
libc/Android.bp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -131,7 +131,6 @@ libc_bionic_ndk_src_files := \
bionic/ffs.cpp \
bionic/flockfile.cpp \
bionic/fpclassify.cpp \
bionic/ftruncate.cpp \
bionic/futimens.cpp \
bionic/getcwd.cpp \
bionic/gethostname.cpp \
@@ -942,6 +941,10 @@ LOCAL_SRC_FILES := $(libc_bionic_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
@@ -969,6 +972,10 @@ LOCAL_SRC_FILES := $(libc_bionic_ndk_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
@@ -1017,6 +1024,10 @@ LOCAL_SRC_FILES := $(libc_pthread_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes)
@@ -1368,11 +1379,11 @@ LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/version_script.txt
# We'd really like to do this for all architectures, but since this wasn't done
# before, these symbols must continue to be exported on LP32 for binary
# compatibility.
LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
# TODO: disabled for http://b/20065774.
#LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
# TODO: This is to work around b/19059885. Remove after root cause is fixed
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_dynamic_src_files))
@@ -1502,8 +1513,7 @@ LOCAL_CFLAGS := $(libc_common_cflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags)
# TODO: This is to work around b/19059885. Remove after root cause is fixed
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
LOCAL_MODULE:= libstdc++

View File

@@ -307,6 +307,34 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2008-2010 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.
-------------------------------------------------------------------
Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -426,6 +454,22 @@ Android adaptation and tweak by Jim Huang <jserv@0xlab.org>.
-------------------------------------------------------------------
Copyright (C) 2011 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.
-------------------------------------------------------------------
Copyright (C) 2011 The Android Open Source Project
All rights reserved.
@@ -644,50 +688,6 @@ SUCH DAMAGE.
-------------------------------------------------------------------
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.
-------------------------------------------------------------------
Copyright (C) 2015 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.
-------------------------------------------------------------------
Copyright (c) 1980, 1983, 1988, 1993
The Regents of the University of California. All rights reserved.
@@ -2550,6 +2550,33 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 1995, 1996 Carnegie-Mellon University.
All rights reserved.
Author: Chris G. Demetriou
Permission to use, copy, modify and distribute this software and
its documentation is hereby granted, provided that both the copyright
notice and this permission notice appear in all copies of the
software, derivative works or modified versions, and any portions
thereof, and that both notices appear in supporting documentation.
CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
Carnegie Mellon requests users of this software to return to
Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
School of Computer Science
Carnegie Mellon University
Pittsburgh PA 15213-3890
any improvements or extensions that they make and grant Carnegie the
rights to redistribute these changes.
-------------------------------------------------------------------
Copyright (c) 1996 by Internet Software Consortium.
Permission to use, copy, modify, and distribute this software for any
@@ -3768,22 +3795,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-------------------------------------------------------------------
Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
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) 2007-2008 Michael G Schwern
This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
@@ -4722,6 +4733,31 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright 2000 David E. O'Brien, John D. Polstra.
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.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-------------------------------------------------------------------
Copyright 2008 Android Open Source Project (source port randomization)
Copyright (c) 1985, 1989, 1993
The Regents of the University of California. All rights reserved.

View File

@@ -151,6 +151,7 @@ int utimensat(int, const char*, const struct timespec times[2], int) all
off_t lseek(int, off_t, int) arm,mips,x86
int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86
off_t lseek|lseek64(int, off_t, int) arm64,mips64,x86_64
int ftruncate(int, off_t) arm,mips,x86
int ftruncate64(int, off64_t) arm,mips,x86
int ftruncate|ftruncate64(int, off_t) arm64,mips64,x86_64
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) arm,mips,x86
@@ -222,7 +223,7 @@ int __rt_sigpending:rt_sigpending(sigset_t*, size_t) all
int __rt_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t) all
int __rt_sigsuspend:rt_sigsuspend(const sigset_t*, size_t) all
int __rt_sigtimedwait:rt_sigtimedwait(const sigset_t*, struct siginfo_t*, struct timespec_t*, size_t) all
int ___rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all
int __rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all
int __signalfd4:signalfd4(int, const sigset_t*, size_t, int) all
# sockets

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (C) 2008-2010 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -35,7 +35,6 @@
*/
.fpu neon
.syntax unified
ENTRY(__memset_chk)
cmp r2, r3
@@ -101,9 +100,9 @@ ENTRY(memset)
1: bge 2f
vst1.32 {d0[0]}, [r0]!
2: movs ip, r2, lsl #31
strbmi r1, [r0], #1
strbcs r1, [r0], #1
strbcs r1, [r0], #1
strmib r1, [r0], #1
strcsb r1, [r0], #1
strcsb r1, [r0], #1
ldmfd sp!, {r0}
bx lr
END(memset)
@@ -132,11 +131,11 @@ ENTRY_PRIVATE(__memset_large_copy)
orr r1, r1, r1, lsr #16
movs r12, r3, lsl #31
strbcs r1, [r0], #1 /* can't use strh (alignment unknown) */
strbcs r1, [r0], #1
strbmi r1, [r0], #1
strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
strcsb r1, [r0], #1
strmib r1, [r0], #1
subs r2, r2, r3
popls {r0, r4-r7, lr} /* return */
ldmlsfd sp!, {r0, r4-r7, lr} /* return */
bxls lr
/* align the destination to a cache-line */
@@ -156,9 +155,9 @@ ENTRY_PRIVATE(__memset_large_copy)
/* conditionally writes 0 to 7 words (length in r3) */
movs r3, r3, lsl #28
stmcs r0!, {r1, lr}
stmcs r0!, {r1, lr}
stmmi r0!, {r1, lr}
stmcsia r0!, {r1, lr}
stmcsia r0!, {r1, lr}
stmmiia r0!, {r1, lr}
movs r3, r3, lsl #2
strcs r1, [r0], #4
@@ -173,13 +172,13 @@ ENTRY_PRIVATE(__memset_large_copy)
/* conditionally stores 0 to 31 bytes */
movs r2, r2, lsl #28
stmcs r0!, {r1,r3,r12,lr}
stmmi r0!, {r1, lr}
stmcsia r0!, {r1,r3,r12,lr}
stmmiia r0!, {r1, lr}
movs r2, r2, lsl #2
strcs r1, [r0], #4
strhmi r1, [r0], #2
strmih r1, [r0], #2
movs r2, r2, lsl #2
strbcs r1, [r0]
strcsb r1, [r0]
ldmfd sp!, {r0, r4-r7, lr}
bx lr
END(__memset_large_copy)

View File

@@ -40,8 +40,6 @@
* Optimized memcmp() for Cortex-A9.
*/
.syntax unified
ENTRY(memcmp)
pld [r0, #(CACHE_LINE_SIZE * 0)]
pld [r0, #(CACHE_LINE_SIZE * 1)]
@@ -163,25 +161,25 @@ ENTRY(memcmp)
eors r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
eorseq r0, r0, lr
eoreqs r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
eorseq r0, r0, ip
eoreqs r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
eorseq r0, r0, lr
eoreqs r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
eorseq r0, r0, ip
eoreqs r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
eorseq r0, r0, lr
eoreqs r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
eorseq r0, r0, ip
eoreqs r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
eorseq r0, r0, lr
eoreqs r0, r0, lr
bne 2f
subs r2, r2, #32
bhs 0b
@@ -265,17 +263,17 @@ ENTRY(memcmp)
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
eorseq r0, r0, ip
eoreqs r0, r0, ip
moveq ip, lr, lsr #16
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
eorseq r0, r0, ip
eoreqs r0, r0, ip
moveq ip, lr, lsr #16
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
eorseq r0, r0, ip
eoreqs r0, r0, ip
bne 7f
subs r2, r2, #16
bhs 6b
@@ -319,7 +317,7 @@ ENTRY(memcmp)
ldreq r7, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, r7, lsl r6
eorseq r0, r0, ip
eoreqs r0, r0, ip
bne 7f
subs r2, r2, #8
bhs 6b

View File

@@ -37,8 +37,6 @@
* so we have to preserve R0.
*/
.syntax unified
ENTRY(__memcpy_chk)
cmp r2, r3
bhi __memcpy_chk_fail
@@ -83,12 +81,12 @@ ENTRY(memcpy)
*/
movs r12, r3, lsl #31
sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
ldrbmi r3, [r1], #1
ldrbcs r4, [r1], #1
ldrbcs r12,[r1], #1
strbmi r3, [r0], #1
strbcs r4, [r0], #1
strbcs r12,[r0], #1
ldrmib r3, [r1], #1
ldrcsb r4, [r1], #1
ldrcsb r12,[r1], #1
strmib r3, [r0], #1
strcsb r4, [r0], #1
strcsb r12,[r0], #1
.Lsrc_aligned:
@@ -111,10 +109,10 @@ ENTRY(memcpy)
/* conditionally copies 0 to 7 words (length in r3) */
movs r12, r3, lsl #28
ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
ldmmi r1!, {r8, r9} /* 8 bytes */
stmcs r0!, {r4, r5, r6, r7}
stmmi r0!, {r8, r9}
ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */
ldmmiia r1!, {r8, r9} /* 8 bytes */
stmcsia r0!, {r4, r5, r6, r7}
stmmiia r0!, {r8, r9}
tst r3, #0x4
ldrne r10,[r1], #4 /* 4 bytes */
strne r10,[r0], #4
@@ -179,18 +177,18 @@ ENTRY(memcpy)
/* conditionnaly copies 0 to 31 bytes */
movs r12, r2, lsl #28
ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
ldmmi r1!, {r8, r9} /* 8 bytes */
stmcs r0!, {r4, r5, r6, r7}
stmmi r0!, {r8, r9}
ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */
ldmmiia r1!, {r8, r9} /* 8 bytes */
stmcsia r0!, {r4, r5, r6, r7}
stmmiia r0!, {r8, r9}
movs r12, r2, lsl #30
ldrcs r3, [r1], #4 /* 4 bytes */
ldrhmi r4, [r1], #2 /* 2 bytes */
ldrmih r4, [r1], #2 /* 2 bytes */
strcs r3, [r0], #4
strhmi r4, [r0], #2
strmih r4, [r0], #2
tst r2, #0x1
ldrbne r3, [r1] /* last byte */
strbne r3, [r0]
ldrneb r3, [r1] /* last byte */
strneb r3, [r0]
/* we're done! restore everything and return */
1: ldmfd sp!, {r5-r11}
@@ -230,11 +228,11 @@ ENTRY(memcpy)
* becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
*/
movs r5, r5, lsl #31
strbmi r3, [r0], #1
strmib r3, [r0], #1
movmi r3, r3, lsr #8
strbcs r3, [r0], #1
strcsb r3, [r0], #1
movcs r3, r3, lsr #8
strbcs r3, [r0], #1
strcsb r3, [r0], #1
movcs r3, r3, lsr #8
cmp r2, #4
@@ -365,23 +363,23 @@ ENTRY(memcpy)
.Lpartial_word_tail:
/* we have a partial word in the input buffer */
movs r5, lr, lsl #(31-3)
strbmi r3, [r0], #1
strmib r3, [r0], #1
movmi r3, r3, lsr #8
strbcs r3, [r0], #1
strcsb r3, [r0], #1
movcs r3, r3, lsr #8
strbcs r3, [r0], #1
strcsb r3, [r0], #1
/* Refill spilled registers from the stack. Don't update sp. */
ldmfd sp, {r5-r11}
.Lcopy_last_3_and_return:
movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
ldrbmi r2, [r1], #1
ldrbcs r3, [r1], #1
ldrbcs r12,[r1]
strbmi r2, [r0], #1
strbcs r3, [r0], #1
strbcs r12,[r0]
ldrmib r2, [r1], #1
ldrcsb r3, [r1], #1
ldrcsb r12,[r1]
strmib r2, [r0], #1
strcsb r3, [r0], #1
strcsb r12,[r0]
/* we're done! restore sp and spilled registers and return */
add sp, sp, #28

View File

@@ -35,8 +35,6 @@
* memset() returns its first argument.
*/
.syntax unified
ENTRY(__memset_chk)
cmp r2, r3
bls done
@@ -78,11 +76,11 @@ ENTRY(memset)
orr r1, r1, r1, lsr #16
movs r12, r3, lsl #31
strbcs r1, [r0], #1 /* can't use strh (alignment unknown) */
strbcs r1, [r0], #1
strbmi r1, [r0], #1
strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
strcsb r1, [r0], #1
strmib r1, [r0], #1
subs r2, r2, r3
popls {r0, r4-r7, lr} /* return */
ldmlsfd sp!, {r0, r4-r7, lr} /* return */
bxls lr
/* align the destination to a cache-line */
@@ -102,9 +100,9 @@ ENTRY(memset)
/* conditionally writes 0 to 7 words (length in r3) */
movs r3, r3, lsl #28
stmcs r0!, {r1, lr}
stmcs r0!, {r1, lr}
stmmi r0!, {r1, lr}
stmcsia r0!, {r1, lr}
stmcsia r0!, {r1, lr}
stmmiia r0!, {r1, lr}
movs r3, r3, lsl #2
strcs r1, [r0], #4
@@ -119,13 +117,13 @@ ENTRY(memset)
/* conditionally stores 0 to 31 bytes */
movs r2, r2, lsl #28
stmcs r0!, {r1,r3,r12,lr}
stmmi r0!, {r1, lr}
stmcsia r0!, {r1,r3,r12,lr}
stmmiia r0!, {r1, lr}
movs r2, r2, lsl #2
strcs r1, [r0], #4
strhmi r1, [r0], #2
strmih r1, [r0], #2
movs r2, r2, lsl #2
strbcs r1, [r0]
strcsb r1, [r0]
ldmfd sp!, {r0, r4-r7, lr}
bx lr
END(memset)

View File

@@ -32,8 +32,6 @@
#include <machine/cpu-features.h>
#include <private/bionic_asm.h>
.syntax unified
ENTRY(strcpy)
pld [r1, #0]
eor r2, r0, r1
@@ -110,15 +108,15 @@ ENTRY(strcpy)
#ifdef __ARMEB__
tst r2, #0xff00
iteet ne
strhne r2, [ip], #2
strneh r2, [ip], #2
lsreq r2, r2, #8
strbeq r2, [ip]
streqb r2, [ip]
tstne r2, #0xff
#else
tst r2, #0xff
itet ne
strhne r2, [ip], #2
strbeq r2, [ip]
strneh r2, [ip], #2
streqb r2, [ip]
tstne r2, #0xff00
#endif
bne 5b

View File

@@ -37,7 +37,6 @@
*/
.fpu neon
.syntax unified
ENTRY(__memset_chk)
cmp r2, r3
@@ -99,9 +98,9 @@ ENTRY(memset)
1: bge 2f
vst1.32 {d0[0]}, [r0]!
2: movs ip, r2, lsl #31
strbmi r1, [r0], #1
strbcs r1, [r0], #1
strbcs r1, [r0], #1
strmib r1, [r0], #1
strcsb r1, [r0], #1
strcsb r1, [r0], #1
ldmfd sp!, {r0}
bx lr
END(memset)

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___rt_sigqueueinfo)
ENTRY(__rt_sigqueueinfo)
mov ip, r7
ldr r7, =__NR_rt_sigqueueinfo
swi #0
@@ -11,5 +11,4 @@ ENTRY(___rt_sigqueueinfo)
bxls lr
neg r0, r0
b __set_errno_internal
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo
END(__rt_sigqueueinfo)

View File

@@ -0,0 +1,14 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(ftruncate)
mov ip, r7
ldr r7, =__NR_ftruncate
swi #0
mov r7, ip
cmn r0, #(MAX_ERRNO + 1)
bxls lr
neg r0, r0
b __set_errno_internal
END(ftruncate)

View File

@@ -40,6 +40,8 @@ libc_bionic_src_files_arm64 += \
arch-arm64/bionic/syscall.S \
arch-arm64/bionic/vfork.S \
# Work around for http://b/20065774.
libc_bionic_src_files_arm64 += arch-arm64/bionic/libgcc_compat.c
libc_crt_target_cflags_arm64 := \
-I$(LOCAL_PATH)/arch-arm64/include

View File

@@ -0,0 +1,15 @@
/* STOPSHIP: remove this once the flounder blobs have been rebuilt (http://b/20065774). */
#if !defined(__clang__)
extern void __clear_cache(char*, char*);
extern char _Unwind_Backtrace;
extern char _Unwind_GetIP;
void* __bionic_libgcc_compat_symbols[] = {
&__clear_cache,
&_Unwind_Backtrace,
&_Unwind_GetIP,
};
#endif

View File

@@ -101,7 +101,7 @@ ENTRY(memchr)
and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
addp vend.16b, vhas_chr1.16b, vhas_chr2.16b /* 256->128 */
addp vend.16b, vend.16b, vend.16b /* 128->64 */
mov synd, vend.d[0]
mov synd, vend.2d[0]
/* Clear the soff*2 lower bits */
lsl tmp, soff, #1
lsr synd, synd, tmp
@@ -121,7 +121,7 @@ ENTRY(memchr)
/* Use a fast check for the termination condition */
orr vend.16b, vhas_chr1.16b, vhas_chr2.16b
addp vend.2d, vend.2d, vend.2d
mov synd, vend.d[0]
mov synd, vend.2d[0]
/* We're not out of data, loop if we haven't found the character */
cbz synd, .Lloop
@@ -131,7 +131,7 @@ ENTRY(memchr)
and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
addp vend.16b, vhas_chr1.16b, vhas_chr2.16b /* 256->128 */
addp vend.16b, vend.16b, vend.16b /* 128->64 */
mov synd, vend.d[0]
mov synd, vend.2d[0]
/* Only do the clear for the last possible block */
b.hi .Ltail

View File

@@ -109,7 +109,7 @@ ENTRY(strchr)
addp vend1.16b, vend1.16b, vend2.16b // 128->64
lsr tmp1, tmp3, tmp1
mov tmp3, vend1.d[0]
mov tmp3, vend1.2d[0]
bic tmp1, tmp3, tmp1 // Mask padding bits.
cbnz tmp1, .Ltail
@@ -124,7 +124,7 @@ ENTRY(strchr)
orr vend2.16b, vhas_nul2.16b, vhas_chr2.16b
orr vend1.16b, vend1.16b, vend2.16b
addp vend1.2d, vend1.2d, vend1.2d
mov tmp1, vend1.d[0]
mov tmp1, vend1.2d[0]
cbz tmp1, .Lloop
/* Termination condition found. Now need to establish exactly why
@@ -138,7 +138,7 @@ ENTRY(strchr)
addp vend1.16b, vend1.16b, vend2.16b // 256->128
addp vend1.16b, vend1.16b, vend2.16b // 128->64
mov tmp1, vend1.d[0]
mov tmp1, vend1.2d[0]
.Ltail:
/* Count the trailing zeros, by bit reversing... */
rbit tmp1, tmp1

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___rt_sigqueueinfo)
ENTRY(__rt_sigqueueinfo)
mov x8, __NR_rt_sigqueueinfo
svc #0
@@ -11,5 +11,5 @@ ENTRY(___rt_sigqueueinfo)
b.hi __set_errno_internal
ret
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo

View File

@@ -28,9 +28,9 @@
#ifdef __LP64__
# define ASM_PTR_SIZE(x) .quad x
# define ASM_ALIGN_TO_PTR_SIZE .balign 8
# define ASM_ALIGN(x)
#else
# define ASM_PTR_SIZE(x) .long x
# define ASM_ALIGN_TO_PTR_SIZE .balign 4
# define ASM_ALIGN(x) .align x
#endif

View File

@@ -29,15 +29,12 @@
#include "asm_multiarch.h"
.section .preinit_array, "aw"
ASM_ALIGN_TO_PTR_SIZE
ASM_PTR_SIZE(0)
.section .init_array, "aw"
ASM_ALIGN_TO_PTR_SIZE
ASM_PTR_SIZE(0)
.section .fini_array, "aw"
ASM_ALIGN_TO_PTR_SIZE
ASM_PTR_SIZE(0)
#if defined(__linux__) && defined(__ELF__)
@@ -45,9 +42,7 @@
#endif
#if defined(__i386__) || defined(__x86_64__)
.section .eh_frame,"a",@progbits
#if defined(__i386__)
.balign 4
#endif
ASM_ALIGN(4)
.type __FRAME_END__, @object
.size __FRAME_END__, 4
__FRAME_END__:

View File

@@ -26,14 +26,22 @@
* SUCH DAMAGE.
*/
#include "asm_multiarch.h"
#ifndef __arm__
.section .init_array, "aw"
ASM_PTR_SIZE(0)
.section .fini_array, "aw"
ASM_PTR_SIZE(0)
#endif
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
#if defined(__i386__) || defined(__x86_64__)
.section .eh_frame,"a",@progbits
#if defined(__i386__)
.balign 4
#endif
ASM_ALIGN(4)
.type __FRAME_END__, @object
.size __FRAME_END__, 4
__FRAME_END__:

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* Copyright (C) 2014-2015 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___rt_sigqueueinfo)
ENTRY(__rt_sigqueueinfo)
.set noreorder
.cpload t9
li v0, __NR_rt_sigqueueinfo
@@ -16,5 +16,4 @@ ENTRY(___rt_sigqueueinfo)
j t9
nop
.set reorder
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo
END(__rt_sigqueueinfo)

View File

@@ -0,0 +1,19 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(ftruncate)
.set noreorder
.cpload t9
li v0, __NR_ftruncate
syscall
bnez a3, 1f
move a0, v0
j ra
nop
1:
la t9,__set_errno_internal
j t9
nop
.set reorder
END(ftruncate)

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___rt_sigqueueinfo)
ENTRY(__rt_sigqueueinfo)
.set push
.set noreorder
li v0, __NR_rt_sigqueueinfo
@@ -22,5 +22,5 @@ ENTRY(___rt_sigqueueinfo)
j t9
move ra, t0
.set pop
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___rt_sigqueueinfo)
ENTRY(__rt_sigqueueinfo)
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_rel_offset ebx, 0
@@ -28,5 +28,4 @@ ENTRY(___rt_sigqueueinfo)
popl %ecx
popl %ebx
ret
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo
END(__rt_sigqueueinfo)

View File

@@ -0,0 +1,26 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(ftruncate)
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_rel_offset ebx, 0
pushl %ecx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset ecx, 0
mov 12(%esp), %ebx
mov 16(%esp), %ecx
movl $__NR_ftruncate, %eax
int $0x80
cmpl $-MAX_ERRNO, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno_internal
addl $4, %esp
1:
popl %ecx
popl %ebx
ret
END(ftruncate)

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___rt_sigqueueinfo)
ENTRY(__rt_sigqueueinfo)
movl $__NR_rt_sigqueueinfo, %eax
syscall
cmpq $-MAX_ERRNO, %rax
@@ -12,5 +12,5 @@ ENTRY(___rt_sigqueueinfo)
call __set_errno_internal
1:
ret
END(___rt_sigqueueinfo)
.hidden ___rt_sigqueueinfo
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo

View File

@@ -1,28 +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 <errno.h>
#include <sys/cdefs.h>
#include <unistd.h>
#if !defined(__USE_FILE_OFFSET64) && !defined(__LP64__)
// The kernel's implementation of ftruncate uses an unsigned long for the length
// parameter, so it will not catch negative values. On the other hand
// ftruncate64 does check for this, so just forward the call.
int ftruncate(int filedes, off_t length) {
return ftruncate64(filedes, length);
}
#endif

View File

@@ -31,7 +31,7 @@
#include <sys/types.h>
#include <unistd.h>
extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
extern "C" int __rt_sigqueueinfo(pid_t, int, siginfo_t*);
int sigqueue(pid_t pid, int signo, const sigval value) {
siginfo_t info;
@@ -42,5 +42,5 @@ int sigqueue(pid_t pid, int signo, const sigval value) {
info.si_uid = getuid();
info.si_value = value;
return ___rt_sigqueueinfo(pid, signo, &info);
return __rt_sigqueueinfo(pid, signo, &info);
}

View File

@@ -34,11 +34,6 @@
#include <machine/elf_machdep.h>
#define ELF32_R_INFO(sym, type) ((((Elf32_Word)sym) << 8) | ((type) & 0xff))
#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)sym) << 32) | ((type) & 0xffffffff))
typedef __s64 Elf32_Sxword;
typedef struct {
__u32 a_type;
union {
@@ -192,11 +187,6 @@ typedef struct {
#define STT_LOPROC 13
#define STT_HIPROC 15
#define STV_DEFAULT 0
#define STV_INTERNAL 1
#define STV_HIDDEN 2
#define STV_PROTECTED 3
/* The kernel uses NT_PRFPREG but glibc also offers NT_FPREGSET */
#define NT_FPREGSET NT_PRFPREG

View File

@@ -81,6 +81,7 @@ struct prop_msg
#define PROP_PATH_RAMDISK_DEFAULT "/default.prop"
#define PROP_PATH_SYSTEM_BUILD "/system/build.prop"
#define PROP_PATH_VENDOR_BUILD "/vendor/build.prop"
#define PROP_PATH_BOOTIMAGE_BUILD "/build.prop"
#define PROP_PATH_LOCAL_OVERRIDE "/data/local.prop"
#define PROP_PATH_FACTORY "/factory/factory.prop"
@@ -103,19 +104,13 @@ int __system_property_area_init();
** objects will have seen __system_property_serial values change.
** But also aids the converse, as changes in the global serial can
** also be used to predict if a failed __system_property_find
** could in-turn now find a new object; thus preventing the
** could in-turn now find an new object; thus preventing the
** cycles of effort to poll __system_property_find.
**
** Typically called at beginning of a cache cycle to signal if _any_ possible
** changes have occurred since last. If there is, one may check each individual
** Called at the beginning of a cache cycle to signal _any_ possible
** changes have occurred since last. If there is, check each individual
** __system_property_serial to confirm dirty, or __system_property_find
** to check if the property now exists. If a call to __system_property_add
** or __system_property_update has completed between two calls to
** __system_property_area_serial then the second call will return a larger
** value than the first call. Beware of race conditions as changes to the
** properties are not atomic, the main value of this call is to determine
** whether the expensive __system_property_find is worth retrying to see if
** a property now exists.
** to check if the property now exists.
**
** Returns the serial number on success, -1 on error.
*/

View File

@@ -34,11 +34,6 @@
__BEGIN_DECLS
#if defined(__GNUC__) && __GNUC__ >= 5 && !defined(__cplusplus)
typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t;
#endif
#define __STD_UTF_16__ 1
#define __STD_UTF_32__ 1

59
libc/private/ScopedFd.h Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2009 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.
*/
#ifndef SCOPED_FD_H
#define SCOPED_FD_H
#include <unistd.h>
#include "bionic_macros.h"
// A smart pointer that closes the given fd on going out of scope.
// Use this when the fd is incidental to the purpose of your function,
// but needs to be cleaned up on exit.
class ScopedFd {
public:
explicit ScopedFd(int fd) : fd(fd) {
}
~ScopedFd() {
reset();
}
int get() const {
return fd;
}
int release() __attribute__((warn_unused_result)) {
int localFd = fd;
fd = -1;
return localFd;
}
void reset(int new_fd = -1) {
if (fd != -1) {
TEMP_FAILURE_RETRY(close(fd));
}
fd = new_fd;
}
private:
int fd;
// Disallow copy and assignment.
DISALLOW_COPY_AND_ASSIGN(ScopedFd);
};
#endif // SCOPED_FD_H

View File

@@ -86,5 +86,5 @@ __sseek(void *cookie, fpos_t offset, int whence)
int
__sclose(void *cookie)
{
return close(((FILE *)cookie)->_file);
return TEMP_FAILURE_RETRY(close(((FILE *)cookie)->_file));
}

View File

@@ -13,21 +13,9 @@ arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain)
sys.stderr.write('Checking symbols for arch "%s"...\n' % arch)
def GetSymbols(library, functions_or_variables):
global api
global arch
api = '9'
if library == 'libm' and arch == 'arm':
api = '3'
# There were no 64-bit ABIs before API level 21.
if '64' in arch:
api = '21'
# What GCC calls aarch64, Android calls arm64.
if arch == 'aarch64':
arch = 'arm64'
path = '%s/development/ndk/platforms/android-%s/arch-%s/symbols/%s.so.%s.txt' % (os.environ['ANDROID_BUILD_TOP'], api, arch, library, functions_or_variables)
symbols = set()
for line in open(path, 'r'):
@@ -38,11 +26,7 @@ def GetSymbols(library, functions_or_variables):
def CheckSymbols(library, functions_or_variables):
expected_symbols = GetSymbols(library, functions_or_variables)
lib_dir = 'lib'
if '64' in arch:
lib_dir = 'lib64'
so_file = '%s/system/%s/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], lib_dir, library)
so_file = '%s/system/lib/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], library)
# Example readelf output:
# 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf
@@ -54,7 +38,7 @@ def CheckSymbols(library, functions_or_variables):
r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
actual_symbols = set()
for line in subprocess.check_output(['readelf', '-W', '--dyn-syms', so_file]).split('\n'):
for line in subprocess.check_output(['readelf', '--dyn-syms', so_file]).split('\n'):
m = r.match(line)
if m:
if m.group(1) == 'FUNC' and functions_or_variables == 'functions':
@@ -70,12 +54,6 @@ def CheckSymbols(library, functions_or_variables):
for miss in sorted(missing):
sys.stderr.write(' %s\n' % miss)
extra = actual_symbols - expected_symbols
if len(extra) > 0:
sys.stderr.write('%d extra %s in %s for %s:\n' % (len(extra), functions_or_variables, library, arch))
for s in sorted(extra):
sys.stderr.write(' %s\n' % s)
return len(missing) == 0
CheckSymbols("libc", "functions")

View File

@@ -1,4 +1,9 @@
LIBC {
global:
/* Work-around for http://b/20065774. */
__clear_cache;
_Unwind_Backtrace;
_Unwind_GetIP;
local:
_ZSt7nothrow;
_ZdaPv;

46
libdl/Android.bp Normal file
View File

@@ -0,0 +1,46 @@
//
// libdl
//
cc_library {
// NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so pulls from
// libgcc.a are made static to libdl.so. This in turn ensures that libraries that
// a) pull symbols from libgcc.a and b) depend on libdl.so will not rely on libdl.so
// to provide those symbols, but will instead pull them from libgcc.a. Specifically,
// we use this property to make sure libc.so has its own copy of the code from
// libgcc.a it uses.
//
// DO NOT REMOVE --exclude-libs!
ldflags: ["-Wl,--exclude-libs=libgcc.a"],
// for x86, exclude libgcc_eh.a for the same reasons as above
arch: {
x86: {
ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
},
x86_64: {
ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
},
},
srcs: ["libdl.c"],
cflags: [
"-Wall",
"-Wextra",
"-Wunused",
"-Werror",
],
stl: "none",
name: "libdl",
// NOTE: libdl needs __aeabi_unwind_cpp_pr0 from libgcc.a but libgcc.a needs a
// few symbols from libc. Using --no-undefined here results in having to link
// against libc creating a circular dependency which is removed and we end up
// with missing symbols. Since this library is just a bunch of stubs, we set
// LOCAL_ALLOW_UNDEFINED_SYMBOLS to remove --no-undefined from the linker flags.
allow_undefined_symbols: true,
system_shared_libs: [],
asan: false,
}

View File

@@ -15,7 +15,7 @@ include $(CLEAR_VARS)
#
# DO NOT REMOVE --exclude-libs!
LOCAL_LDFLAGS := -Wl,--exclude-libs=libgcc.a -Wl,--version-script=$(LOCAL_PATH)/libdl.map
LOCAL_LDFLAGS := -Wl,--exclude-libs=libgcc.a
# for x86, exclude libgcc_eh.a for the same reasons as above
LOCAL_LDFLAGS_x86 := -Wl,--exclude-libs=libgcc_eh.a

View File

@@ -17,7 +17,6 @@
#include <dlfcn.h>
#include <link.h>
#include <stdlib.h>
#include <stdbool.h>
#include <android/dlext.h>
// These are stubs for functions that are actually defined
@@ -39,6 +38,3 @@ void android_get_LD_LIBRARY_PATH(char* buffer __unused, size_t buffer_size __unu
void android_update_LD_LIBRARY_PATH(const char* ld_library_path __unused) { }
void* android_dlopen_ext(const char* filename __unused, int flag __unused, const android_dlextinfo* extinfo __unused) { return 0; }
void android_set_application_target_sdk_version(uint32_t target __unused) { }
uint32_t android_get_application_target_sdk_version() { return 0; }

View File

@@ -1,39 +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.
#
LIBC {
global:
android_dlopen_ext;
dl_iterate_phdr;
# begin arm-only
dl_unwind_find_exidx;
# end arm-only
dladdr;
dlclose;
dlerror;
dlopen;
dlsym;
local:
*;
};
LIBC_PRIVATE {
global:
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
} LIBC;

381
libm/Android.bp Normal file
View File

@@ -0,0 +1,381 @@
// ANDROIDMK TRANSLATION ERROR: unsupported directive
// ifneq ($(TARGET_USE_PRIVATE_LIBM),true)
bionic_coverage = false
// TODO: this comes from from upstream's libc, not libm, but it's an
// implementation detail that should have hidden visibility, so it needs
// to be in whatever library the math code is in.
libm_common_src_files = ["digittoint.c"]
// TODO: this is not in the BSDs.
libm_common_src_files += [
"significandl.c",
"sincos.c",
]
libm_common_src_files += [
"upstream-freebsd/lib/msun/bsdsrc/b_exp.c",
"upstream-freebsd/lib/msun/bsdsrc/b_log.c",
"upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c",
"upstream-freebsd/lib/msun/src/catrig.c",
"upstream-freebsd/lib/msun/src/catrigf.c",
"upstream-freebsd/lib/msun/src/e_acos.c",
"upstream-freebsd/lib/msun/src/e_acosf.c",
"upstream-freebsd/lib/msun/src/e_acosh.c",
"upstream-freebsd/lib/msun/src/e_acoshf.c",
"upstream-freebsd/lib/msun/src/e_asin.c",
"upstream-freebsd/lib/msun/src/e_asinf.c",
"upstream-freebsd/lib/msun/src/e_atan2.c",
"upstream-freebsd/lib/msun/src/e_atan2f.c",
"upstream-freebsd/lib/msun/src/e_atanh.c",
"upstream-freebsd/lib/msun/src/e_atanhf.c",
"upstream-freebsd/lib/msun/src/e_cosh.c",
"upstream-freebsd/lib/msun/src/e_coshf.c",
"upstream-freebsd/lib/msun/src/e_exp.c",
"upstream-freebsd/lib/msun/src/e_expf.c",
"upstream-freebsd/lib/msun/src/e_fmod.c",
"upstream-freebsd/lib/msun/src/e_fmodf.c",
"upstream-freebsd/lib/msun/src/e_gamma.c",
"upstream-freebsd/lib/msun/src/e_gammaf.c",
"upstream-freebsd/lib/msun/src/e_gammaf_r.c",
"upstream-freebsd/lib/msun/src/e_gamma_r.c",
"upstream-freebsd/lib/msun/src/e_hypot.c",
"upstream-freebsd/lib/msun/src/e_hypotf.c",
"upstream-freebsd/lib/msun/src/e_j0.c",
"upstream-freebsd/lib/msun/src/e_j0f.c",
"upstream-freebsd/lib/msun/src/e_j1.c",
"upstream-freebsd/lib/msun/src/e_j1f.c",
"upstream-freebsd/lib/msun/src/e_jn.c",
"upstream-freebsd/lib/msun/src/e_jnf.c",
"upstream-freebsd/lib/msun/src/e_lgamma.c",
"upstream-freebsd/lib/msun/src/e_lgammaf.c",
"upstream-freebsd/lib/msun/src/e_lgammaf_r.c",
"upstream-freebsd/lib/msun/src/e_lgamma_r.c",
"upstream-freebsd/lib/msun/src/e_log10.c",
"upstream-freebsd/lib/msun/src/e_log10f.c",
"upstream-freebsd/lib/msun/src/e_log2.c",
"upstream-freebsd/lib/msun/src/e_log2f.c",
"upstream-freebsd/lib/msun/src/e_log.c",
"upstream-freebsd/lib/msun/src/e_logf.c",
"upstream-freebsd/lib/msun/src/e_pow.c",
"upstream-freebsd/lib/msun/src/e_powf.c",
"upstream-freebsd/lib/msun/src/e_remainder.c",
"upstream-freebsd/lib/msun/src/e_remainderf.c",
"upstream-freebsd/lib/msun/src/e_rem_pio2.c",
"upstream-freebsd/lib/msun/src/e_rem_pio2f.c",
"upstream-freebsd/lib/msun/src/e_scalb.c",
"upstream-freebsd/lib/msun/src/e_scalbf.c",
"upstream-freebsd/lib/msun/src/e_sinh.c",
"upstream-freebsd/lib/msun/src/e_sinhf.c",
"upstream-freebsd/lib/msun/src/e_sqrt.c",
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
"upstream-freebsd/lib/msun/src/imprecise.c",
"upstream-freebsd/lib/msun/src/k_cos.c",
"upstream-freebsd/lib/msun/src/k_cosf.c",
"upstream-freebsd/lib/msun/src/k_exp.c",
"upstream-freebsd/lib/msun/src/k_expf.c",
"upstream-freebsd/lib/msun/src/k_rem_pio2.c",
"upstream-freebsd/lib/msun/src/k_sin.c",
"upstream-freebsd/lib/msun/src/k_sinf.c",
"upstream-freebsd/lib/msun/src/k_tan.c",
"upstream-freebsd/lib/msun/src/k_tanf.c",
"upstream-freebsd/lib/msun/src/s_asinh.c",
"upstream-freebsd/lib/msun/src/s_asinhf.c",
"upstream-freebsd/lib/msun/src/s_atan.c",
"upstream-freebsd/lib/msun/src/s_atanf.c",
"upstream-freebsd/lib/msun/src/s_carg.c",
"upstream-freebsd/lib/msun/src/s_cargf.c",
"upstream-freebsd/lib/msun/src/s_cargl.c",
"upstream-freebsd/lib/msun/src/s_cbrt.c",
"upstream-freebsd/lib/msun/src/s_cbrtf.c",
"upstream-freebsd/lib/msun/src/s_ccosh.c",
"upstream-freebsd/lib/msun/src/s_ccoshf.c",
"upstream-freebsd/lib/msun/src/s_ceil.c",
"upstream-freebsd/lib/msun/src/s_ceilf.c",
"upstream-freebsd/lib/msun/src/s_cexp.c",
"upstream-freebsd/lib/msun/src/s_cexpf.c",
"upstream-freebsd/lib/msun/src/s_cimag.c",
"upstream-freebsd/lib/msun/src/s_cimagf.c",
"upstream-freebsd/lib/msun/src/s_cimagl.c",
"upstream-freebsd/lib/msun/src/s_conj.c",
"upstream-freebsd/lib/msun/src/s_conjf.c",
"upstream-freebsd/lib/msun/src/s_conjl.c",
"upstream-freebsd/lib/msun/src/s_copysign.c",
"upstream-freebsd/lib/msun/src/s_copysignf.c",
"upstream-freebsd/lib/msun/src/s_cos.c",
"upstream-freebsd/lib/msun/src/s_cosf.c",
"upstream-freebsd/lib/msun/src/s_cproj.c",
"upstream-freebsd/lib/msun/src/s_cprojf.c",
"upstream-freebsd/lib/msun/src/s_cprojl.c",
"upstream-freebsd/lib/msun/src/s_creal.c",
"upstream-freebsd/lib/msun/src/s_crealf.c",
"upstream-freebsd/lib/msun/src/s_creall.c",
"upstream-freebsd/lib/msun/src/s_csinh.c",
"upstream-freebsd/lib/msun/src/s_csinhf.c",
"upstream-freebsd/lib/msun/src/s_csqrt.c",
"upstream-freebsd/lib/msun/src/s_csqrtf.c",
"upstream-freebsd/lib/msun/src/s_csqrtl.c",
"upstream-freebsd/lib/msun/src/s_ctanh.c",
"upstream-freebsd/lib/msun/src/s_ctanhf.c",
"upstream-freebsd/lib/msun/src/s_erf.c",
"upstream-freebsd/lib/msun/src/s_erff.c",
"upstream-freebsd/lib/msun/src/s_exp2.c",
"upstream-freebsd/lib/msun/src/s_exp2f.c",
"upstream-freebsd/lib/msun/src/s_expm1.c",
"upstream-freebsd/lib/msun/src/s_expm1f.c",
"upstream-freebsd/lib/msun/src/s_fabs.c",
"upstream-freebsd/lib/msun/src/s_fabsf.c",
"upstream-freebsd/lib/msun/src/s_fdim.c",
"upstream-freebsd/lib/msun/src/s_finite.c",
"upstream-freebsd/lib/msun/src/s_finitef.c",
"upstream-freebsd/lib/msun/src/s_floor.c",
"upstream-freebsd/lib/msun/src/s_floorf.c",
"upstream-freebsd/lib/msun/src/s_fma.c",
"upstream-freebsd/lib/msun/src/s_fmaf.c",
"upstream-freebsd/lib/msun/src/s_fmax.c",
"upstream-freebsd/lib/msun/src/s_fmaxf.c",
"upstream-freebsd/lib/msun/src/s_fmin.c",
"upstream-freebsd/lib/msun/src/s_fminf.c",
"upstream-freebsd/lib/msun/src/s_frexp.c",
"upstream-freebsd/lib/msun/src/s_frexpf.c",
"upstream-freebsd/lib/msun/src/s_ilogb.c",
"upstream-freebsd/lib/msun/src/s_ilogbf.c",
"upstream-freebsd/lib/msun/src/s_llrint.c",
"upstream-freebsd/lib/msun/src/s_llrintf.c",
"upstream-freebsd/lib/msun/src/s_llround.c",
"upstream-freebsd/lib/msun/src/s_llroundf.c",
"upstream-freebsd/lib/msun/src/s_log1p.c",
"upstream-freebsd/lib/msun/src/s_log1pf.c",
"upstream-freebsd/lib/msun/src/s_logb.c",
"upstream-freebsd/lib/msun/src/s_logbf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
"upstream-freebsd/lib/msun/src/s_lrintf.c",
"upstream-freebsd/lib/msun/src/s_lround.c",
"upstream-freebsd/lib/msun/src/s_lroundf.c",
"upstream-freebsd/lib/msun/src/s_modf.c",
"upstream-freebsd/lib/msun/src/s_modff.c",
"upstream-freebsd/lib/msun/src/s_nan.c",
"upstream-freebsd/lib/msun/src/s_nearbyint.c",
"upstream-freebsd/lib/msun/src/s_nextafter.c",
"upstream-freebsd/lib/msun/src/s_nextafterf.c",
"upstream-freebsd/lib/msun/src/s_remquo.c",
"upstream-freebsd/lib/msun/src/s_remquof.c",
"upstream-freebsd/lib/msun/src/s_rint.c",
"upstream-freebsd/lib/msun/src/s_rintf.c",
"upstream-freebsd/lib/msun/src/s_round.c",
"upstream-freebsd/lib/msun/src/s_roundf.c",
"upstream-freebsd/lib/msun/src/s_scalbln.c",
"upstream-freebsd/lib/msun/src/s_scalbn.c",
"upstream-freebsd/lib/msun/src/s_scalbnf.c",
"upstream-freebsd/lib/msun/src/s_signgam.c",
"upstream-freebsd/lib/msun/src/s_significand.c",
"upstream-freebsd/lib/msun/src/s_significandf.c",
"upstream-freebsd/lib/msun/src/s_sin.c",
"upstream-freebsd/lib/msun/src/s_sinf.c",
"upstream-freebsd/lib/msun/src/s_tan.c",
"upstream-freebsd/lib/msun/src/s_tanf.c",
"upstream-freebsd/lib/msun/src/s_tanh.c",
"upstream-freebsd/lib/msun/src/s_tanhf.c",
"upstream-freebsd/lib/msun/src/s_tgammaf.c",
"upstream-freebsd/lib/msun/src/s_trunc.c",
"upstream-freebsd/lib/msun/src/s_truncf.c",
"upstream-freebsd/lib/msun/src/w_cabs.c",
"upstream-freebsd/lib/msun/src/w_cabsf.c",
"upstream-freebsd/lib/msun/src/w_cabsl.c",
"upstream-freebsd/lib/msun/src/w_drem.c",
"upstream-freebsd/lib/msun/src/w_dremf.c",
]
libm_common_src_files += [
"fake_long_double.c",
"signbit.c",
]
libm_ld128_src_files = [
"upstream-freebsd/lib/msun/src/e_acosl.c",
"upstream-freebsd/lib/msun/src/e_acoshl.c",
"upstream-freebsd/lib/msun/src/e_asinl.c",
"upstream-freebsd/lib/msun/src/e_atan2l.c",
"upstream-freebsd/lib/msun/src/e_atanhl.c",
"upstream-freebsd/lib/msun/src/e_fmodl.c",
"upstream-freebsd/lib/msun/src/e_hypotl.c",
"upstream-freebsd/lib/msun/src/e_lgammal.c",
"upstream-freebsd/lib/msun/src/e_remainderl.c",
"upstream-freebsd/lib/msun/src/e_sqrtl.c",
"upstream-freebsd/lib/msun/src/s_asinhl.c",
"upstream-freebsd/lib/msun/src/s_atanl.c",
"upstream-freebsd/lib/msun/src/s_cbrtl.c",
"upstream-freebsd/lib/msun/src/s_ceill.c",
"upstream-freebsd/lib/msun/src/s_copysignl.c",
"upstream-freebsd/lib/msun/src/e_coshl.c",
"upstream-freebsd/lib/msun/src/s_cosl.c",
"upstream-freebsd/lib/msun/src/s_fabsl.c",
"upstream-freebsd/lib/msun/src/s_floorl.c",
"upstream-freebsd/lib/msun/src/s_fmal.c",
"upstream-freebsd/lib/msun/src/s_fmaxl.c",
"upstream-freebsd/lib/msun/src/s_fminl.c",
"upstream-freebsd/lib/msun/src/s_modfl.c",
"upstream-freebsd/lib/msun/src/s_frexpl.c",
"upstream-freebsd/lib/msun/src/s_ilogbl.c",
"upstream-freebsd/lib/msun/src/s_llrintl.c",
"upstream-freebsd/lib/msun/src/s_llroundl.c",
"upstream-freebsd/lib/msun/src/s_logbl.c",
"upstream-freebsd/lib/msun/src/s_lrintl.c",
"upstream-freebsd/lib/msun/src/s_lroundl.c",
"upstream-freebsd/lib/msun/src/s_nextafterl.c",
"upstream-freebsd/lib/msun/src/s_nexttoward.c",
"upstream-freebsd/lib/msun/src/s_nexttowardf.c",
"upstream-freebsd/lib/msun/src/s_remquol.c",
"upstream-freebsd/lib/msun/src/s_rintl.c",
"upstream-freebsd/lib/msun/src/s_roundl.c",
"upstream-freebsd/lib/msun/src/s_scalbnl.c",
"upstream-freebsd/lib/msun/src/e_sinhl.c",
"upstream-freebsd/lib/msun/src/s_sinl.c",
"upstream-freebsd/lib/msun/src/s_tanhl.c",
"upstream-freebsd/lib/msun/src/s_tanl.c",
"upstream-freebsd/lib/msun/src/s_truncl.c",
]
libm_ld128_src_files += [
"upstream-freebsd/lib/msun/ld128/invtrig.c",
"upstream-freebsd/lib/msun/ld128/e_lgammal_r.c",
"upstream-freebsd/lib/msun/ld128/k_cosl.c",
"upstream-freebsd/lib/msun/ld128/k_sinl.c",
"upstream-freebsd/lib/msun/ld128/k_tanl.c",
"upstream-freebsd/lib/msun/ld128/s_erfl.c",
"upstream-freebsd/lib/msun/ld128/s_exp2l.c",
"upstream-freebsd/lib/msun/ld128/s_expl.c",
"upstream-freebsd/lib/msun/ld128/s_logl.c",
"upstream-freebsd/lib/msun/ld128/s_nanl.c",
]
// TODO: re-enable i387/e_sqrtf.S for x86, and maybe others.
libm_common_cflags = [
"-DFLT_EVAL_METHOD=0",
"-std=c99",
"-include freebsd-compat.h",
"-Wno-missing-braces",
"-Wno-parentheses",
"-Wno-sign-compare",
"-Wno-uninitialized",
"-Wno-unknown-pragmas",
"-fvisibility=hidden",
]
// Workaround the GCC "(long)fn -> lfn" optimization bug which will result in
// self recursions for lrint, lrintf, and lrintl.
// BUG: 14225968
libm_common_cflags += [
"-fno-builtin-rint",
"-fno-builtin-rintf",
"-fno-builtin-rintl",
]
libm_common_local_includes = ["upstream-freebsd/lib/msun/src/"]
libm_ld_local_includes = ["upstream-freebsd/lib/msun/ld128/"]
//
// libm.so and libm.a for target.
//
cc_library {
name: "libm",
cflags: libm_common_cflags,
include_dirs: ["bionic/libc"],
local_include_dirs: libm_common_local_includes,
srcs: libm_common_src_files,
system_shared_libs: ["libc"],
native_coverage: bionic_coverage,
asan: false,
multilib: {
lib64: {
srcs: libm_ld128_src_files,
local_include_dirs: libm_ld_local_includes,
// We'd really like to do this for all architectures, but since this wasn't done
// before, these symbols must continue to be exported on LP32 for binary
// compatibility.
ldflags: ["-Wl,--exclude-libs,libgcc.a"],
},
},
// arch-specific settings
arch: {
arm: {
srcs: [
"arm/fenv.c",
"arm/e_sqrt.S",
"arm/e_sqrtf.S",
"arm/s_floor.S",
],
exclude_srcs: [
// TODO: these require neon not available in arm
"upstream-freebsd/lib/msun/src/e_sqrt.c",
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
"upstream-freebsd/lib/msun/src/s_floor.c",
],
instruction_set: "arm",
},
arm64: {
srcs: [
"arm64/fenv.c",
"arm64/ceil.S",
"arm64/fma.S",
"arm64/floor.S",
"arm64/lrint.S",
"arm64/rint.S",
"arm64/sqrt.S",
"arm64/trunc.S",
],
exclude_srcs: [
"upstream-freebsd/lib/msun/src/s_ceil.c",
"upstream-freebsd/lib/msun/src/s_ceilf.c",
"upstream-freebsd/lib/msun/src/s_fma.c",
"upstream-freebsd/lib/msun/src/s_fmaf.c",
"upstream-freebsd/lib/msun/src/s_floor.c",
"upstream-freebsd/lib/msun/src/s_floorf.c",
"upstream-freebsd/lib/msun/src/s_llrint.c",
"upstream-freebsd/lib/msun/src/s_llrintf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
"upstream-freebsd/lib/msun/src/s_lrintf.c",
"upstream-freebsd/lib/msun/src/s_rint.c",
"upstream-freebsd/lib/msun/src/s_rintf.c",
"upstream-freebsd/lib/msun/src/e_sqrt.c",
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
"upstream-freebsd/lib/msun/src/s_trunc.c",
"upstream-freebsd/lib/msun/src/s_truncf.c",
],
},
mips: {
srcs: ["mips/fenv.c"],
},
mips64: {
srcs: ["mips/fenv.c"],
},
x86: {
local_include_dirs: ["i387"],
srcs: ["i387/fenv.c"],
// Clang has wrong long double sizes for x86.
clang: false,
},
x86_64: {
srcs: ["amd64/fenv.c"],
// Clang has wrong long double sizes for x86.
clang: false,
},
},
stl: "none",
}
// ANDROIDMK TRANSLATION ERROR: unsupported directive
// endif

View File

@@ -501,6 +501,9 @@ LOCAL_CFLAGS += \
-fno-builtin-rintf \
-fno-builtin-rintl \
LOCAL_CONLY_FLAGS := \
-std=c99 \
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
LOCAL_ADDRESS_SANITIZER := false
include $(BUILD_STATIC_LIBRARY)
@@ -511,8 +514,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
# TODO: This is to work around b/19059885. Remove after root cause is fixed
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
LOCAL_MODULE := libm
LOCAL_CLANG := $(libm_clang)

View File

@@ -1002,114 +1002,6 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
Johhnny Qiu <joqiu@nvidia.com>
Shu Zhang <chazhang@nvidia.com>
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.
* Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
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.
-------------------------------------------------------------------
Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
Johnny Qiu <joqiu@nvidia.com>
Shu Zhang <chazhang@nvidia.com>
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.
* Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
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.
-------------------------------------------------------------------
Copyright (c) 2014, Intel Corporation
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.
* Neither the name of Intel Corporation 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 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.
-------------------------------------------------------------------
Copyright 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.
-------------------------------------------------------------------
From: @(#)s_ilogb.c 5.1 93/09/24
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.

117
linker/Android.bp Normal file
View File

@@ -0,0 +1,117 @@
linker_cflags = [
"-fno-stack-protector",
"-Wstrict-overflow=5",
"-fvisibility=hidden",
"-Wall",
"-Wextra",
"-Wunused",
"-Werror",
]
cc_binary {
srcs: [
"debugger.cpp",
"dlfcn.cpp",
"linker.cpp",
"linker_allocator.cpp",
"linker_block_allocator.cpp",
"linker_environ.cpp",
"linker_libc_support.c",
"linker_memory.cpp",
"linker_phdr.cpp",
"rt.cpp",
],
arch: {
arm: {
srcs: ["arch/arm/begin.S"],
},
arm64: {
srcs: ["arch/arm64/begin.S"],
},
x86: {
srcs: ["arch/x86/begin.c"],
},
x86_64: {
srcs: ["arch/x86_64/begin.S"],
},
mips: {
srcs: [
"arch/mips/begin.S",
"linker_mips.cpp",
],
},
mips64: {
srcs: [
"arch/mips64/begin.S",
"linker_mips.cpp",
],
},
},
// -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.
ldflags: [
"-shared",
"-Wl,-Bsymbolic",
"-Wl,--exclude-libs,ALL",
],
cflags: linker_cflags,
// TODO: split out the asflags.
asflags: linker_cflags,
target: {
android64: {
cflags: ["-DTARGET_IS_64_BIT"],
},
},
// We need to access Bionic private headers in the linker.
local_include_dirs: ["../libc/"],
conlyflags: ["-std=gnu99"],
cppflags: [
"-std=gnu++11",
"-Wold-style-cast",
],
// we don't want crtbegin.o (because we have begin.o), so unset it
// just for this module
nocrt: true,
static_libs: [
"libc_nomalloc",
"libziparchive",
"libutils",
"libz",
"liblog",
],
static_executable: true,
name: "linker",
multilib: {
lib32: {
stem: "linker",
},
lib64: {
stem: "linker64",
},
},
compile_multilib: "both",
// Leave the symbols in the shared library so that stack unwinders can
// produce meaningful name resolution.
strip: "keep_symbols",
// 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_",
}
subdirs = ["tests"]

View File

@@ -7,7 +7,6 @@ LOCAL_SRC_FILES:= \
dlfcn.cpp \
linker.cpp \
linker_allocator.cpp \
linker_sdk_versions.cpp \
linker_block_allocator.cpp \
linker_environ.cpp \
linker_libc_support.c \
@@ -36,9 +35,6 @@ LOCAL_CFLAGS += \
-fvisibility=hidden \
-Wall -Wextra -Wunused -Werror \
LOCAL_CFLAGS_arm += -D__work_around_b_19059885__
LOCAL_CFLAGS_x86 += -D__work_around_b_19059885__
LOCAL_CONLYFLAGS += \
-std=gnu99 \

View File

@@ -42,6 +42,62 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2008, 2009 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.
-------------------------------------------------------------------
Copyright (C) 2008-2010 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.
-------------------------------------------------------------------
Copyright (C) 2010 The Android Open Source Project
All rights reserved.
@@ -158,47 +214,3 @@ limitations under the License.
-------------------------------------------------------------------
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.
-------------------------------------------------------------------
Copyright (C) 2015 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.
-------------------------------------------------------------------

View File

@@ -205,6 +205,15 @@ static bool have_siginfo(int signum) {
}
static void send_debuggerd_packet(siginfo_t* info) {
if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) {
// process has disabled core dumps and PTRACE_ATTACH, and does not want to be dumped.
// Honor that intention by not connecting to debuggerd and asking it
// to dump our internal state.
__libc_format_log(ANDROID_LOG_INFO, "libc",
"Suppressing debuggerd output because prctl(PR_GET_DUMPABLE)==0");
return;
}
// Mutex to prevent multiple crashing threads from trying to talk
// to debuggerd at the same time.
static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;

View File

@@ -157,14 +157,6 @@ int dlclose(void* handle) {
return 0;
}
void android_set_application_target_sdk_version(uint32_t target) {
set_application_target_sdk_version(target);
}
uint32_t android_get_application_target_sdk_version() {
return get_application_target_sdk_version();
}
// name_offset: starting index of the name in libdl_info.strtab
#define ELF32_SYM_INITIALIZER(name_offset, value, shndx) \
{ name_offset, \
@@ -184,21 +176,19 @@ uint32_t android_get_application_target_sdk_version() {
/* st_size */ 0, \
}
static const char ANDROID_LIBDL_STRTAB[] =
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888888888899999 99999
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012345678901234 56789
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0android_get_LD_LIBRARY_PATH\0dl_it"
// 00000000001 1111111112222222222 3333333333444444444455555555556666666666777 777777788888888889999999999
// 01234567890 1234567890123456789 0123456789012345678901234567890123456789012 345678901234567890123456789
"erate_phdr\0android_dlopen_ext\0android_set_application_target_sdk_version\0android_get_application_tar"
// 0000000000111111
// 0123456789012345
"get_sdk_version\0"
#if defined(__arm__)
// 216
"dl_unwind_find_exidx\0"
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888888888899999 9999900000000001 1111111112222222222 333333333344444444445
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012345678901234 5678901234567890 1234567890123456789 012345678901234567890
# define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0android_get_LD_LIBRARY_PATH\0dl_iterate_phdr\0android_dlopen_ext\0dl_unwind_find_exidx\0"
#elif defined(__aarch64__) || defined(__i386__) || defined(__mips__) || defined(__x86_64__)
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888888888899999 9999900000000001 1111111112222222222
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012345678901234 5678901234567890 1234567890123456789
# define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0android_get_LD_LIBRARY_PATH\0dl_iterate_phdr\0android_dlopen_ext\0"
#else
# error Unsupported architecture. Only arm, arm64, mips, mips64, x86 and x86_64 are presently supported.
#endif
;
static ElfW(Sym) g_libdl_symtab[] = {
// Total length of libdl_info.strtab, including trailing 0.
@@ -215,10 +205,8 @@ static ElfW(Sym) g_libdl_symtab[] = {
ELFW(SYM_INITIALIZER)( 67, &android_get_LD_LIBRARY_PATH, 1),
ELFW(SYM_INITIALIZER)( 95, &dl_iterate_phdr, 1),
ELFW(SYM_INITIALIZER)(111, &android_dlopen_ext, 1),
ELFW(SYM_INITIALIZER)(130, &android_set_application_target_sdk_version, 1),
ELFW(SYM_INITIALIZER)(173, &android_get_application_target_sdk_version, 1),
#if defined(__arm__)
ELFW(SYM_INITIALIZER)(216, &dl_unwind_find_exidx, 1),
ELFW(SYM_INITIALIZER)(130, &dl_unwind_find_exidx, 1),
#endif
};
@@ -235,9 +223,9 @@ static ElfW(Sym) g_libdl_symtab[] = {
// Note that adding any new symbols here requires stubbing them out in libdl.
static unsigned g_libdl_buckets[1] = { 1 };
#if defined(__arm__)
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0 };
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 };
#else
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 };
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
#endif
static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));

View File

@@ -47,6 +47,7 @@
#include "private/bionic_tls.h"
#include "private/KernelArgumentBlock.h"
#include "private/ScopedPthreadMutexLocker.h"
#include "private/ScopedFd.h"
#include "private/ScopeGuard.h"
#include "private/UniquePtr.h"
@@ -251,7 +252,7 @@ static void soinfo_free(soinfo* si) {
soinfo *prev = nullptr, *trav;
TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
TRACE("name %s: freeing soinfo @ %p", si->get_soname(), si);
for (trav = solist; trav != nullptr; trav = trav->next) {
if (trav == si) {
@@ -262,7 +263,7 @@ static void soinfo_free(soinfo* si) {
if (trav == nullptr) {
// si was not in solist
DL_ERR("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
DL_ERR("name \"%s\"@%p is not in solist!", si->get_soname(), si);
return;
}
@@ -427,7 +428,7 @@ static bool for_each_verdef(const soinfo* si, F functor) {
if (verdef->vd_version != 1) {
DL_ERR("unsupported verdef[%zd] vd_version: %d (expected 1) library: %s",
i, verdef->vd_version, si->get_realpath());
i, verdef->vd_version, si->get_soname());
return false;
}
@@ -497,7 +498,7 @@ static bool is_symbol_global_and_defined(const soinfo* si, const ElfW(Sym)* s) {
return s->st_shndx != SHN_UNDEF;
} else if (ELF_ST_BIND(s->st_info) != STB_LOCAL) {
DL_WARN("unexpected ST_BIND value: %d for '%s' in '%s'",
ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_soname());
}
return false;
@@ -530,12 +531,12 @@ bool soinfo::gnu_lookup(SymbolName& symbol_name,
*symbol_index = 0;
TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p (gnu)",
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
// test against bloom filter
if ((1 & (bloom_word >> (hash % bloom_mask_bits)) & (bloom_word >> (h2 % bloom_mask_bits))) == 0) {
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
return true;
}
@@ -545,7 +546,7 @@ bool soinfo::gnu_lookup(SymbolName& symbol_name,
if (n == 0) {
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
return true;
}
@@ -573,7 +574,7 @@ bool soinfo::gnu_lookup(SymbolName& symbol_name,
strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
is_symbol_global_and_defined(this, s)) {
TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(s->st_value),
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(s->st_value),
static_cast<size_t>(s->st_size));
*symbol_index = n;
return true;
@@ -581,7 +582,7 @@ bool soinfo::gnu_lookup(SymbolName& symbol_name,
} while ((gnu_chain_[n++] & 1) == 0);
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
return true;
}
@@ -592,7 +593,7 @@ bool soinfo::elf_lookup(SymbolName& symbol_name,
uint32_t hash = symbol_name.elf_hash();
TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p h=%x(elf) %zd",
symbol_name.get_name(), get_realpath(),
symbol_name.get_name(), get_soname(),
reinterpret_cast<void*>(base), hash, hash % nbucket_);
ElfW(Versym) verneed = 0;
@@ -613,7 +614,7 @@ bool soinfo::elf_lookup(SymbolName& symbol_name,
strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
is_symbol_global_and_defined(this, s)) {
TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
symbol_name.get_name(), get_realpath(),
symbol_name.get_name(), get_soname(),
reinterpret_cast<void*>(s->st_value),
static_cast<size_t>(s->st_size));
*symbol_index = n;
@@ -622,7 +623,7 @@ bool soinfo::elf_lookup(SymbolName& symbol_name,
}
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p %x %zd",
symbol_name.get_name(), get_realpath(),
symbol_name.get_name(), get_soname(),
reinterpret_cast<void*>(base), hash, hash % nbucket_);
*symbol_index = 0;
@@ -702,7 +703,7 @@ bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
* relocations for -Bsymbolic linked dynamic executables.
*/
if (si_from->has_DT_SYMBOLIC) {
DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_realpath(), name);
DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_soname(), name);
if (!si_from->find_symbol_by_name(symbol_name, vi, &s)) {
return false;
}
@@ -717,7 +718,7 @@ bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
bool error = false;
global_group.visit([&](soinfo* global_si) {
DEBUG("%s: looking up %s in %s (from global group)",
si_from->get_realpath(), name, global_si->get_realpath());
si_from->get_soname(), name, global_si->get_soname());
if (!global_si->find_symbol_by_name(symbol_name, vi, &s)) {
error = true;
return false;
@@ -746,7 +747,7 @@ bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
}
DEBUG("%s: looking up %s in %s (from local group)",
si_from->get_realpath(), name, local_si->get_realpath());
si_from->get_soname(), name, local_si->get_soname());
if (!local_si->find_symbol_by_name(symbol_name, vi, &s)) {
error = true;
return false;
@@ -768,8 +769,8 @@ bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
if (s != nullptr) {
TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, "
"found in %s, base = %p, load bias = %p",
si_from->get_realpath(), name, reinterpret_cast<void*>(s->st_value),
(*si_found_in)->get_realpath(), reinterpret_cast<void*>((*si_found_in)->base),
si_from->get_soname(), name, reinterpret_cast<void*>(s->st_value),
(*si_found_in)->get_soname(), reinterpret_cast<void*>((*si_found_in)->base),
reinterpret_cast<void*>((*si_found_in)->load_bias));
}
@@ -917,17 +918,13 @@ static bool walk_dependencies_tree(soinfo* root_soinfos[], size_t root_soinfos_s
}
static const ElfW(Sym)* dlsym_handle_lookup(soinfo* root, soinfo* skip_until,
soinfo** found, SymbolName& symbol_name) {
// This is used by dlsym(3). It performs symbol lookup only within the
// specified soinfo object and its dependencies in breadth first order.
const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name) {
const ElfW(Sym)* result = nullptr;
bool skip_lookup = skip_until != nullptr;
walk_dependencies_tree(&root, 1, [&](soinfo* current_soinfo) {
if (skip_lookup) {
skip_lookup = current_soinfo != skip_until;
return true;
}
SymbolName symbol_name(name);
walk_dependencies_tree(&si, 1, [&](soinfo* current_soinfo) {
if (!current_soinfo->find_symbol_by_name(symbol_name, nullptr, &result)) {
result = nullptr;
return false;
@@ -944,13 +941,6 @@ static const ElfW(Sym)* dlsym_handle_lookup(soinfo* root, soinfo* skip_until,
return result;
}
// This is used by dlsym(3). It performs symbol lookup only within the
// specified soinfo object and its dependencies in breadth first order.
const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name) {
SymbolName symbol_name(name);
return dlsym_handle_lookup(si, nullptr, found, symbol_name);
}
/* This is used by dlsym(3) to performs a global symbol lookup. If the
start value is null (for RTLD_DEFAULT), the search starts at the
beginning of the global solist. Otherwise the search starts at the
@@ -965,7 +955,7 @@ const ElfW(Sym)* dlsym_linear_lookup(const char* name,
soinfo* start = solist;
if (handle == RTLD_NEXT) {
if (caller == nullptr) {
if (caller == nullptr || caller->next == nullptr) {
return nullptr;
} else {
start = caller->next;
@@ -988,13 +978,31 @@ const ElfW(Sym)* dlsym_linear_lookup(const char* name,
}
}
// If not found - use dlsym_handle_lookup for caller's
// local_group unless it is part of the global group in which
// If not found - look into local_group unless
// caller is part of the global group in which
// case we already did it.
if (s == nullptr && caller != nullptr &&
(caller->get_rtld_flags() & RTLD_GLOBAL) == 0) {
return dlsym_handle_lookup(caller->get_local_group_root(),
(handle == RTLD_NEXT) ? caller : nullptr, found, symbol_name);
soinfo* local_group_root = caller->get_local_group_root();
if (handle == RTLD_DEFAULT) {
start = local_group_root;
}
for (soinfo* si = start; si != nullptr; si = si->next) {
if (si->get_local_group_root() != local_group_root) {
break;
}
if (!si->find_symbol_by_name(symbol_name, nullptr, &s)) {
return nullptr;
}
if (s != nullptr) {
*found = si;
break;
}
}
}
if (s != nullptr) {
@@ -1209,10 +1217,29 @@ static void for_each_dt_needed(const soinfo* si, F action) {
}
}
static soinfo* load_library(int fd, off64_t file_offset,
LoadTaskList& load_tasks,
static soinfo* load_library(LoadTaskList& load_tasks,
const char* name, int rtld_flags,
const android_dlextinfo* extinfo) {
int fd = -1;
off64_t file_offset = 0;
ScopedFd file_guard(-1);
if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
fd = extinfo->library_fd;
if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
file_offset = extinfo->library_fd_offset;
}
} else {
// Open the file.
fd = open_library(name, &file_offset);
if (fd == -1) {
DL_ERR("library \"%s\" not found", name);
return nullptr;
}
file_guard.reset(fd);
}
if ((file_offset % PAGE_SIZE) != 0) {
DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
return nullptr;
@@ -1288,29 +1315,6 @@ static soinfo* load_library(int fd, off64_t file_offset,
return si;
}
static soinfo* load_library(LoadTaskList& load_tasks,
const char* name, int rtld_flags,
const android_dlextinfo* extinfo) {
if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
off64_t file_offset = 0;
if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
file_offset = extinfo->library_fd_offset;
}
return load_library(extinfo->library_fd, file_offset, load_tasks, name, rtld_flags, extinfo);
}
// Open the file.
off64_t file_offset;
int fd = open_library(name, &file_offset);
if (fd == -1) {
DL_ERR("library \"%s\" not found", name);
return nullptr;
}
soinfo* result = load_library(fd, file_offset, load_tasks, name, rtld_flags, extinfo);
close(fd);
return result;
}
static soinfo *find_loaded_library_by_soname(const char* name) {
// Ignore filename with path.
if (strchr(name, '/') != nullptr) {
@@ -1494,7 +1498,7 @@ static void soinfo_unload(soinfo* root) {
}
if (!root->can_unload()) {
TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_realpath());
TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_soname());
return;
}
@@ -1517,9 +1521,7 @@ static void soinfo_unload(soinfo* root) {
if (si->has_min_version(0)) {
soinfo* child = nullptr;
while ((child = si->get_children().pop_front()) != nullptr) {
TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
child->get_realpath(), child);
TRACE("%s@%p needs to unload %s@%p", si->get_soname(), si, child->get_soname(), child);
if (local_unload_list.contains(child)) {
continue;
} else if (child->is_linked() && child->get_local_group_root() != root) {
@@ -1529,20 +1531,20 @@ static void soinfo_unload(soinfo* root) {
}
}
} else {
#if !defined(__work_around_b_19059885__)
__libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
#if !defined(__arm__)
__libc_fatal("soinfo for \"%s\"@%p has no version", si->get_soname(), si);
#else
PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_soname(), si);
for_each_dt_needed(si, [&] (const char* library_name) {
TRACE("deprecated (old format of soinfo): %s needs to unload %s",
si->get_realpath(), library_name);
si->get_soname(), library_name);
soinfo* needed = find_library(library_name, RTLD_NOLOAD, nullptr);
if (needed != nullptr) {
// Not found: for example if symlink was deleted between dlopen and dlclose
// Since we cannot really handle errors at this point - print and continue.
PRINT("warning: couldn't find %s needed by %s on unload.",
library_name, si->get_realpath());
library_name, si->get_soname());
return;
} else if (local_unload_list.contains(needed)) {
// already visited
@@ -1572,8 +1574,7 @@ static void soinfo_unload(soinfo* root) {
soinfo_unload(si);
}
} else {
TRACE("not unloading '%s' group, decrementing ref_count to %zd",
root->get_realpath(), ref_count);
TRACE("not unloading '%s' group, decrementing ref_count to %zd", root->get_soname(), ref_count);
}
}
@@ -1685,12 +1686,12 @@ bool VersionTracker::init_verneed(const soinfo* si_from) {
const char* target_soname = si_from->get_string(verneed->vn_file);
// find it in dependencies
soinfo* target_si = si_from->get_children().find_if([&](const soinfo* si) {
return si->get_soname() != nullptr && strcmp(si->get_soname(), target_soname) == 0;
return strcmp(si->get_soname(), target_soname) == 0;
});
if (target_si == nullptr) {
DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"",
target_soname, i, si_from->get_realpath());
target_soname, i, si_from->get_soname());
return false;
}
@@ -1727,27 +1728,6 @@ bool VersionTracker::init(const soinfo* si_from) {
return init_verneed(si_from) && init_verdef(si_from);
}
bool soinfo::lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
const char* sym_name, const version_info** vi) {
const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
if (sym_ver != VER_NDX_LOCAL && sym_ver != VER_NDX_GLOBAL) {
*vi = version_tracker.get_version_info(sym_ver);
if (*vi == nullptr) {
DL_ERR("cannot find verneed/verdef for version index=%d "
"referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_realpath());
return false;
}
} else {
// there is no version info
*vi = nullptr;
}
return true;
}
#if !defined(__mips__)
#if defined(USE_RELA)
static ElfW(Addr) get_addend(ElfW(Rela)* rela, ElfW(Addr) reloc_addr __unused) {
@@ -1764,8 +1744,14 @@ static ElfW(Addr) get_addend(ElfW(Rel)* rel, ElfW(Addr) reloc_addr) {
#endif
template<typename ElfRelIteratorT>
bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
bool soinfo::relocate(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& global_group,
const soinfo_list_t& local_group) {
VersionTracker version_tracker;
if (!version_tracker.init(this)) {
return false;
}
for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
const auto rel = rel_iterator.next();
if (rel == nullptr) {
@@ -1780,7 +1766,7 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
const char* sym_name = nullptr;
ElfW(Addr) addend = get_addend(rel, reloc);
DEBUG("Processing '%s' relocation at index %zd", get_realpath(), idx);
DEBUG("Processing '%s' relocation at index %zd", get_soname(), idx);
if (type == R_GENERIC_NONE) {
continue;
}
@@ -1790,21 +1776,32 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
if (sym != 0) {
sym_name = get_string(symtab_[sym].st_name);
const version_info* vi = nullptr;
const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
return false;
if (sym_ver == VER_NDX_LOCAL || sym_ver == VER_NDX_GLOBAL) {
// there is no version info for this one
if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) {
return false;
}
} else {
const version_info* vi = version_tracker.get_version_info(sym_ver);
if (vi == nullptr) {
DL_ERR("cannot find verneed/verdef for version index=%d "
"referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_soname());
return false;
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
if (s == nullptr) {
// We only allow an undefined symbol if this is a weak reference...
s = &symtab_[sym];
if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_realpath());
DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_soname());
return false;
}
@@ -2000,7 +1997,7 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
* R_AARCH64_COPY may only appear in executable objects where e_type is
* set to ET_EXEC.
*/
DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_soname());
return false;
case R_AARCH64_TLS_TPREL64:
TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n",
@@ -2057,7 +2054,7 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
* R_ARM_COPY may only appear in executable objects where e_type is
* set to ET_EXEC.
*/
DL_ERR("%s R_ARM_COPY relocations are not supported", get_realpath());
DL_ERR("%s R_ARM_COPY relocations are not supported", get_soname());
return false;
#elif defined(__i386__)
case R_386_32:
@@ -2089,7 +2086,7 @@ void soinfo::call_array(const char* array_name __unused, linker_function_t* func
return;
}
TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_realpath());
TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_soname());
int begin = reverse ? (count - 1) : 0;
int end = reverse ? -1 : count;
@@ -2100,7 +2097,7 @@ void soinfo::call_array(const char* array_name __unused, linker_function_t* func
call_function("function", functions[i]);
}
TRACE("[ Done calling %s for '%s' ]", array_name, get_realpath());
TRACE("[ Done calling %s for '%s' ]", array_name, get_soname());
}
void soinfo::call_function(const char* function_name __unused, linker_function_t function) {
@@ -2108,9 +2105,9 @@ void soinfo::call_function(const char* function_name __unused, linker_function_t
return;
}
TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_realpath());
TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_soname());
function();
TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_realpath());
TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_soname());
}
void soinfo::call_pre_init_constructors() {
@@ -2139,14 +2136,14 @@ void soinfo::call_constructors() {
if (!is_main_executable() && preinit_array_ != nullptr) {
// The GNU dynamic linker silently ignores these, but we warn the developer.
PRINT("\"%s\": ignoring %zd-entry DT_PREINIT_ARRAY in shared library!",
get_realpath(), preinit_array_count_);
get_soname(), preinit_array_count_);
}
get_children().for_each([] (soinfo* si) {
si->call_constructors();
});
TRACE("\"%s\": calling constructors", get_realpath());
TRACE("\"%s\": calling constructors", get_soname());
// DT_INIT should be called before DT_INIT_ARRAY if both are present.
call_function("DT_INIT", init_func_);
@@ -2157,7 +2154,7 @@ void soinfo::call_destructors() {
if (!constructors_called) {
return;
}
TRACE("\"%s\": calling destructors", get_realpath());
TRACE("\"%s\": calling destructors", get_soname());
// DT_FINI_ARRAY must be parsed in reverse order.
call_array("DT_FINI_ARRAY", fini_array_, fini_array_count_, true);
@@ -2255,7 +2252,7 @@ void soinfo::set_dt_flags_1(uint32_t dt_flags_1) {
}
const char* soinfo::get_realpath() const {
#if defined(__work_around_b_19059885__)
#if defined(__arm__)
if (has_min_version(2)) {
return realpath_.c_str();
} else {
@@ -2267,7 +2264,7 @@ const char* soinfo::get_realpath() const {
}
const char* soinfo::get_soname() const {
#if defined(__work_around_b_19059885__)
#if defined(__arm__)
if (has_min_version(2)) {
return soname_;
} else {
@@ -2317,7 +2314,7 @@ ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const {
const char* soinfo::get_string(ElfW(Word) index) const {
if (has_min_version(1) && (index >= strtab_size_)) {
__libc_fatal("%s: strtab out of bounds error; STRSZ=%zd, name=%d",
get_realpath(), strtab_size_, index);
get_soname(), strtab_size_, index);
}
return strtab_ + index;
@@ -2414,7 +2411,8 @@ static int nullify_closed_stdio() {
/* If /dev/null is not one of the stdio file descriptors, close it. */
if (dev_null > 2) {
TRACE("[ Closing /dev/null file-descriptor=%d]", dev_null);
if (close(dev_null) == -1) {
status = TEMP_FAILURE_RETRY(close(dev_null));
if (status == -1) {
DL_ERR("close failed: %s", strerror(errno));
return_value = -1;
}
@@ -2437,7 +2435,7 @@ bool soinfo::prelink_image() {
if (dynamic == nullptr) {
if (!relocating_linker) {
DL_ERR("missing PT_DYNAMIC in \"%s\"", get_realpath());
DL_ERR("missing PT_DYNAMIC in \"%s\"", get_soname());
}
return false;
} else {
@@ -2804,7 +2802,7 @@ bool soinfo::prelink_image() {
for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
if (d->d_tag == DT_SONAME) {
soname_ = get_string(d->d_un.d_val);
#if defined(__work_around_b_19059885__)
#if defined(__arm__)
strlcpy(old_name_, soname_, sizeof(old_name_));
#endif
break;
@@ -2821,15 +2819,15 @@ bool soinfo::prelink_image() {
}
if (nbucket_ == 0 && gnu_nbucket_ == 0) {
DL_ERR("empty/missing DT_HASH/DT_GNU_HASH in \"%s\" "
"(new hash type from the future?)", get_realpath());
"(new hash type from the future?)", get_soname());
return false;
}
if (strtab_ == 0) {
DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_realpath());
DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_soname());
return false;
}
if (symtab_ == 0) {
DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_realpath());
DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_soname());
return false;
}
return true;
@@ -2843,21 +2841,15 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
local_group_root_ = this;
}
VersionTracker version_tracker;
if (!version_tracker.init(this)) {
return false;
}
#if !defined(__LP64__)
if (has_text_relocations) {
// Make segments writable to allow text relocations to work properly. We will later call
// phdr_table_protect_segments() after all of them are applied and all constructors are run.
DL_WARN("%s has text relocations. This is wasting memory and prevents "
"security hardening. Please fix.", get_realpath());
"security hardening. Please fix.", get_soname());
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
DL_ERR("can't unprotect loadable segments for \"%s\": %s",
get_realpath(), strerror(errno));
get_soname(), strerror(errno));
return false;
}
}
@@ -2870,14 +2862,13 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
android_relocs_[1] == 'P' &&
android_relocs_[2] == 'S' &&
android_relocs_[3] == '2') {
DEBUG("[ android relocating %s ]", get_realpath());
DEBUG("[ android relocating %s ]", get_soname());
bool relocated = false;
const uint8_t* packed_relocs = android_relocs_ + 4;
const size_t packed_relocs_size = android_relocs_size_ - 4;
relocated = relocate(
version_tracker,
packed_reloc_iterator<sleb128_decoder>(
sleb128_decoder(packed_relocs, packed_relocs_size)),
global_group, local_group);
@@ -2893,50 +2884,46 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
#if defined(USE_RELA)
if (rela_ != nullptr) {
DEBUG("[ relocating %s ]", get_realpath());
if (!relocate(version_tracker,
plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
DEBUG("[ relocating %s ]", get_soname());
if (!relocate(plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
return false;
}
}
if (plt_rela_ != nullptr) {
DEBUG("[ relocating %s plt ]", get_realpath());
if (!relocate(version_tracker,
plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
DEBUG("[ relocating %s plt ]", get_soname());
if (!relocate(plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
return false;
}
}
#else
if (rel_ != nullptr) {
DEBUG("[ relocating %s ]", get_realpath());
if (!relocate(version_tracker,
plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
DEBUG("[ relocating %s ]", get_soname());
if (!relocate(plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
return false;
}
}
if (plt_rel_ != nullptr) {
DEBUG("[ relocating %s plt ]", get_realpath());
if (!relocate(version_tracker,
plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
DEBUG("[ relocating %s plt ]", get_soname());
if (!relocate(plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
return false;
}
}
#endif
#if defined(__mips__)
if (!mips_relocate_got(version_tracker, global_group, local_group)) {
if (!mips_relocate_got(global_group, local_group)) {
return false;
}
#endif
DEBUG("[ finished linking %s ]", get_realpath());
DEBUG("[ finished linking %s ]", get_soname());
#if !defined(__LP64__)
if (has_text_relocations) {
// All relocations are done, we can protect our segments back to read-only.
if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
DL_ERR("can't protect segments for \"%s\": %s",
get_realpath(), strerror(errno));
get_soname(), strerror(errno));
return false;
}
}
@@ -2945,7 +2932,7 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
/* We can also turn on GNU RELRO protection */
if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
get_realpath(), strerror(errno));
get_soname(), strerror(errno));
return false;
}
@@ -2954,14 +2941,14 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
extinfo->relro_fd) < 0) {
DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
get_realpath(), strerror(errno));
get_soname(), strerror(errno));
return false;
}
} else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
extinfo->relro_fd) < 0) {
DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
get_realpath(), strerror(errno));
get_soname(), strerror(errno));
return false;
}
}
@@ -3035,8 +3022,6 @@ static void init_linker_info_for_gdb(ElfW(Addr) linker_base) {
insert_soinfo_into_debug_map(linker_soinfo_for_gdb);
}
extern "C" int __system_properties_init(void);
/*
* This code is called after the linker has linked itself and
* fixed it's own GOT. It is safe to make references to externs
@@ -3051,9 +3036,6 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
// Initialize environment functions, and get to the ELF aux vectors table.
linker_env_init(args);
// Initialize system properties
__system_properties_init(); // may use 'environ'
// If this is a setuid/setgid program, close the security hole described in
// ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
if (get_AT_SECURE()) {
@@ -3236,7 +3218,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
fflush(stdout);
#endif
TRACE("[ Ready to execute '%s' @ %p ]", si->get_realpath(), reinterpret_cast<void*>(si->entry));
TRACE("[ Ready to execute '%s' @ %p ]", si->get_soname(), reinterpret_cast<void*>(si->entry));
return si->entry;
}
@@ -3252,8 +3234,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
*/
static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf) {
ElfW(Addr) offset = elf->e_phoff;
const ElfW(Phdr)* phdr_table =
reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
const ElfW(Phdr)* phdr_table = reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
const ElfW(Phdr)* phdr_end = phdr_table + elf->e_phnum;
for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_end; phdr++) {

View File

@@ -97,7 +97,7 @@
#define SOINFO_VERSION 2
#if defined(__work_around_b_19059885__)
#if defined(__arm__)
#define SOINFO_NAME_LEN 128
#endif
@@ -172,7 +172,7 @@ class VersionTracker {
struct soinfo {
public:
typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
#if defined(__work_around_b_19059885__)
#if defined(__arm__)
private:
char old_name_[SOINFO_NAME_LEN];
#endif
@@ -183,13 +183,13 @@ struct soinfo {
ElfW(Addr) base;
size_t size;
#if defined(__work_around_b_19059885__)
#if defined(__arm__)
uint32_t unused1; // DO NOT USE, maintained for compatibility.
#endif
ElfW(Dyn)* dynamic;
#if defined(__work_around_b_19059885__)
#if defined(__arm__)
uint32_t unused2; // DO NOT USE, maintained for compatibility
uint32_t unused3; // DO NOT USE, maintained for compatibility
#endif
@@ -247,9 +247,7 @@ struct soinfo {
uint32_t mips_symtabno_;
uint32_t mips_local_gotno_;
uint32_t mips_gotsym_;
bool mips_relocate_got(const VersionTracker& version_tracker,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group);
bool mips_relocate_got(const soinfo_list_t& global_group, const soinfo_list_t& local_group);
#endif
size_t ref_count_;
@@ -305,7 +303,7 @@ struct soinfo {
bool is_gnu_hash() const;
bool inline has_min_version(uint32_t min_version __unused) const {
#if defined(__work_around_b_19059885__)
#if defined(__arm__)
return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
#else
return true;
@@ -340,14 +338,11 @@ struct soinfo {
bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
ElfW(Sym)* gnu_addr_lookup(const void* addr);
bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
const char* sym_name, const version_info** vi);
void call_array(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
void call_function(const char* function_name, linker_function_t function);
template<typename ElfRelIteratorT>
bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
const soinfo_list_t& global_group, const soinfo_list_t& local_group);
bool relocate(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& global_group,
const soinfo_list_t& local_group);
private:
// This part of the structure is only available
@@ -429,7 +424,4 @@ extern "C" void notify_gdb_of_libraries();
char* linker_get_error_buffer();
size_t linker_get_error_buffer_size();
void set_application_target_sdk_version(uint32_t target);
uint32_t get_application_target_sdk_version();
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (C) 2008-2010 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -32,22 +32,25 @@
#include "linker_reloc_iterators.h"
#include "linker_sleb128.h"
template bool soinfo::relocate<plain_reloc_iterator>(const VersionTracker& version_tracker,
plain_reloc_iterator&& rel_iterator,
template bool soinfo::relocate<plain_reloc_iterator>(plain_reloc_iterator&& rel_iterator,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group);
template bool soinfo::relocate<packed_reloc_iterator<sleb128_decoder>>(
const VersionTracker& version_tracker,
packed_reloc_iterator<sleb128_decoder>&& rel_iterator,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group);
template <typename ElfRelIteratorT>
bool soinfo::relocate(const VersionTracker& version_tracker,
ElfRelIteratorT&& rel_iterator,
bool soinfo::relocate(ElfRelIteratorT&& rel_iterator,
const soinfo_list_t& global_group,
const soinfo_list_t& local_group) {
VersionTracker version_tracker;
if (!version_tracker.init(this)) {
return false;
}
for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
const auto rel = rel_iterator.next();
@@ -72,14 +75,26 @@ bool soinfo::relocate(const VersionTracker& version_tracker,
if (sym != 0) {
sym_name = get_string(symtab_[sym].st_name);
const version_info* vi = nullptr;
const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
return false;
}
if (sym_ver == VER_NDX_LOCAL || sym_ver == VER_NDX_GLOBAL) {
// there is no version info for this one
if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) {
return false;
}
} else {
const version_info* vi = version_tracker.get_version_info(sym_ver);
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
if (vi == nullptr) {
DL_ERR("cannot find verneed/verdef for version index=%d "
"referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_soname());
return false;
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
}
if (s == nullptr) {
@@ -113,7 +128,7 @@ bool soinfo::relocate(const VersionTracker& version_tracker,
if (s != nullptr) {
*reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
} else {
*reinterpret_cast<ElfW(Addr)*>(reloc) += load_bias;
*reinterpret_cast<ElfW(Addr)*>(reloc) += base;
}
break;
default:
@@ -124,8 +139,7 @@ bool soinfo::relocate(const VersionTracker& version_tracker,
return true;
}
bool soinfo::mips_relocate_got(const VersionTracker& version_tracker,
const soinfo_list_t& global_group,
bool soinfo::mips_relocate_got(const soinfo_list_t& global_group,
const soinfo_list_t& local_group) {
ElfW(Addr)** got = plt_got_;
if (got == nullptr) {
@@ -149,42 +163,22 @@ bool soinfo::mips_relocate_got(const VersionTracker& version_tracker,
}
// Now for the global GOT entries...
ElfW(Sym)* sym = symtab_ + mips_gotsym_;
got = plt_got_ + mips_local_gotno_;
for (ElfW(Word) sym = mips_gotsym_; sym < mips_symtabno_; sym++, got++) {
for (size_t g = mips_gotsym_; g < mips_symtabno_; g++, sym++, got++) {
// This is an undefined reference... try to locate it.
const ElfW(Sym)* local_sym = symtab_ + sym;
const char* sym_name = get_string(local_sym->st_name);
const char* sym_name = get_string(sym->st_name);
soinfo* lsi = nullptr;
const ElfW(Sym)* s = nullptr;
ElfW(Word) st_visibility = (local_sym->st_other & 0x3);
if (st_visibility == STV_DEFAULT) {
const version_info* vi = nullptr;
if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
return false;
}
if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
return false;
}
} else if (st_visibility == STV_PROTECTED) {
if (local_sym->st_value == 0) {
DL_ERR("%s: invalid symbol \"%s\" (PROTECTED/UNDEFINED) ", get_soname(), sym_name);
return false;
}
s = local_sym;
lsi = this;
} else {
DL_ERR("%s: invalid symbol \"%s\" visibility: 0x%x", get_soname(), sym_name, st_visibility);
if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) {
return false;
}
if (s == nullptr) {
// We only allow an undefined symbol if this is a weak reference.
if (ELF_ST_BIND(local_sym->st_info) != STB_WEAK) {
DL_ERR("%s: cannot locate \"%s\"...", get_soname(), sym_name);
s = &symtab_[g];
if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
DL_ERR("cannot locate \"%s\"...", sym_name);
return false;
}
*got = 0;

View File

@@ -1,29 +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 "linker.h"
#include <atomic>
static std::atomic<uint32_t> g_target_sdk_version;
void set_application_target_sdk_version(uint32_t target) {
g_target_sdk_version = target;
}
uint32_t get_application_target_sdk_version() {
return g_target_sdk_version;
}

47
linker/tests/Android.bp Normal file
View File

@@ -0,0 +1,47 @@
//
// Copyright (C) 2012 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.
//
cc_test {
name: "linker-unit-tests",
multilib: {
lib32: {
stem: "linker-unit-tests32",
},
lib64: {
stem: "linker-unit-tests64",
},
},
cflags: [
"-g",
"-Wall",
"-Wextra",
"-Wunused",
"-Werror",
"-std=gnu++11",
],
local_include_dirs: ["/../../libc/"],
srcs: [
"linked_list_test.cpp",
"linker_block_allocator_test.cpp",
"../linker_block_allocator.cpp",
"linker_memory_allocator_test.cpp",
"../linker_allocator.cpp",
// for __libc_fatal
"../../libc/bionic/libc_logging.cpp",
],
}

View File

@@ -49,9 +49,6 @@ endif
test_cppflags = \
-std=gnu++11 \
libBionicStandardTests_src_files_target := \
libdl_test.cpp \
libBionicStandardTests_src_files := \
arpa_inet_test.cpp \
buffer_tests.cpp \
@@ -272,7 +269,6 @@ bionic-unit-tests_src_files := \
dlext_test.cpp \
__cxa_thread_atexit_test.cpp \
dlfcn_test.cpp \
pthread_dlfcn_test.cpp \
bionic-unit-tests_cflags := $(test_cflags)
@@ -350,7 +346,6 @@ bionic-unit-tests-glibc_src_files := \
atexit_test.cpp \
dlfcn_test.cpp \
dl_test.cpp \
pthread_dlfcn_test.cpp \
bionic-unit-tests-glibc_shared_libraries := \
libdl_preempt_test_1 \

View File

@@ -71,80 +71,23 @@ TEST(dlfcn, dlsym_from_sofile) {
void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_LAZY | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
// check that we can't find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
// check that we cant find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
void* symbol = dlsym(RTLD_DEFAULT, "test_dlsym_symbol");
ASSERT_TRUE(symbol == nullptr);
ASSERT_SUBSTR("undefined symbol: test_dlsym_symbol", dlerror());
typedef int* (*fn_t)();
fn_t lookup_dlsym_symbol_using_RTLD_DEFAULT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_DEFAULT != nullptr) << dlerror();
fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
int* ptr = lookup_dlsym_symbol_using_RTLD_DEFAULT();
ASSERT_TRUE(fn != nullptr) << dlerror();
int* ptr = fn();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(42, *ptr);
fn_t lookup_dlsym_symbol2_using_RTLD_DEFAULT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol2_using_RTLD_DEFAULT"));
ASSERT_TRUE(lookup_dlsym_symbol2_using_RTLD_DEFAULT != nullptr) << dlerror();
ptr = lookup_dlsym_symbol2_using_RTLD_DEFAULT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(44, *ptr);
fn_t lookup_dlsym_symbol_using_RTLD_NEXT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_NEXT"));
ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_NEXT != nullptr) << dlerror();
ptr = lookup_dlsym_symbol_using_RTLD_NEXT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(43, *ptr);
dlclose(handle);
}
TEST(dlfcn, dlsym_from_sofile_with_preload) {
void* preload = dlopen("libtest_dlsym_from_this_grandchild.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(preload != nullptr) << dlerror();
void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
// check that we can't find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
void* symbol = dlsym(RTLD_DEFAULT, "test_dlsym_symbol");
ASSERT_TRUE(symbol == nullptr);
ASSERT_SUBSTR("undefined symbol: test_dlsym_symbol", dlerror());
typedef int* (*fn_t)();
fn_t lookup_dlsym_symbol_using_RTLD_DEFAULT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_DEFAULT != nullptr) << dlerror();
int* ptr = lookup_dlsym_symbol_using_RTLD_DEFAULT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(42, *ptr);
fn_t lookup_dlsym_symbol2_using_RTLD_DEFAULT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol2_using_RTLD_DEFAULT"));
ASSERT_TRUE(lookup_dlsym_symbol2_using_RTLD_DEFAULT != nullptr) << dlerror();
ptr = lookup_dlsym_symbol2_using_RTLD_DEFAULT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(44, *ptr);
fn_t lookup_dlsym_symbol_using_RTLD_NEXT =
reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_NEXT"));
ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_NEXT != nullptr) << dlerror();
ptr = lookup_dlsym_symbol_using_RTLD_NEXT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(43, *ptr);
dlclose(handle);
dlclose(preload);
}
TEST(dlfcn, dlsym_with_dependencies) {
void* handle = dlopen("libtest_with_dependency.so", RTLD_NOW);
ASSERT_TRUE(handle != NULL);

View File

@@ -1,32 +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 <gtest/gtest.h>
extern "C" uint32_t android_get_application_target_sdk_version();
extern "C" void android_set_application_target_sdk_version(uint32_t target);
TEST(libdl, application_sdk_versions_smoke) {
// Check initial values
ASSERT_EQ(0U, android_get_application_target_sdk_version());
android_set_application_target_sdk_version(20U);
ASSERT_EQ(20U, android_get_application_target_sdk_version());
android_set_application_target_sdk_version(22U);
ASSERT_EQ(22U, android_get_application_target_sdk_version());
}

View File

@@ -355,7 +355,10 @@ include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
libdl_test_df_1_global_src_files := dl_df_1_global.cpp
libdl_test_df_1_global_ldflags := -Wl,-z,global
# TODO (dimitry): x86* toolchain does not support -z global - switch to bfd
ifeq ($(filter $(TARGET_ARCH),x86 x86_64),$(TARGET_ARCH))
libdl_test_df_1_global_ldflags_target := -fuse-ld=bfd
endif
# TODO (dimitry): host ld.gold does not yet support -z global
# remove this line once it is updated.
libdl_test_df_1_global_ldflags_host := -fuse-ld=bfd
@@ -382,26 +385,11 @@ include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
# Library to check RTLD_LOCAL with dlsym in 'this'
# -----------------------------------------------------------------------------
libtest_dlsym_from_this_src_files := dlsym_from_this_symbol.cpp
libtest_dlsym_from_this_shared_libraries_target := libdl
libtest_dlsym_from_this_shared_libraries := libtest_dlsym_from_this_child
libtest_dlsym_from_this_src_files := dlsym_from_this.cpp
module := libtest_dlsym_from_this
include $(LOCAL_PATH)/Android.build.testlib.mk
libtest_dlsym_from_this_shared_libraries_target := libdl
# -----------------------------------------------------------------------------
libtest_dlsym_from_this_child_src_files := dlsym_from_this_functions.cpp
libtest_dlsym_from_this_child_shared_libraries := libtest_dlsym_from_this_grandchild
module := libtest_dlsym_from_this_child
include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
libtest_dlsym_from_this_grandchild_src_files := dlsym_from_this_symbol2.cpp
module := libtest_dlsym_from_this_grandchild
include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2014 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.
@@ -13,5 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dlfcn.h>
#include <stdio.h>
int test_dlsym_symbol = 42;
extern "C" int* lookup_dlsym_symbol_using_RTLD_DEFAULT() {
dlerror();
int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol"));
// TODO: remove this once b/20049306 is fixed
if (result == nullptr) {
printf("Cannot find the answer\n");
}
return result;
}

View File

@@ -1,52 +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 <dlfcn.h>
#include <stdio.h>
extern int test_dlsym_symbol;
int test_dlsym_symbol = -1;
extern "C" int* lookup_dlsym_symbol_using_RTLD_DEFAULT() {
dlerror();
int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol"));
// TODO: remove this once b/20049306 is fixed
if (result == nullptr) {
printf("Cannot find the answer\n");
}
return result;
}
extern "C" int* lookup_dlsym_symbol2_using_RTLD_DEFAULT() {
dlerror();
int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol2"));
// TODO: remove this once b/20049306 is fixed
if (result == nullptr) {
printf("Cannot find the answer\n");
}
return result;
}
extern "C" int* lookup_dlsym_symbol_using_RTLD_NEXT() {
dlerror();
int* result = static_cast<int*>(dlsym(RTLD_NEXT, "test_dlsym_symbol"));
// TODO: remove this once b/20049306 is fixed
if (result == nullptr) {
printf("Cannot find the answer\n");
}
return result;
}

View File

@@ -1,18 +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.
*/
int test_dlsym_symbol = 43;
int test_dlsym_symbol2 = 44;

View File

@@ -1,83 +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 <gtest/gtest.h>
#include <dlfcn.h>
static int g_atfork_prepare_calls = 0;
static void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 1; }
static void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 2; }
static void AtForkPrepare3() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 3; }
static void AtForkPrepare4() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 4; }
static int g_atfork_parent_calls = 0;
static void AtForkParent1() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 1; }
static void AtForkParent2() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 2; }
static void AtForkParent3() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 3; }
static void AtForkParent4() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 4; }
static int g_atfork_child_calls = 0;
static void AtForkChild1() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 1; }
static void AtForkChild2() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 2; }
static void AtForkChild3() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 3; }
static void AtForkChild4() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 4; }
TEST(pthread, pthread_atfork_with_dlclose) {
ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
void* handle = dlopen("libtest_pthread_atfork.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
typedef int (*fn_t)(void (*)(void), void (*)(void), void (*)(void));
fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "proxy_pthread_atfork"));
ASSERT_TRUE(fn != nullptr) << dlerror();
// the library registers 2 additional atfork handlers in a constructor
ASSERT_EQ(0, fn(AtForkPrepare2, AtForkParent2, AtForkChild2));
ASSERT_EQ(0, fn(AtForkPrepare3, AtForkParent3, AtForkChild3));
ASSERT_EQ(0, pthread_atfork(AtForkPrepare4, AtForkParent4, AtForkChild4));
int pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
if (pid == 0) {
ASSERT_EQ(1234, g_atfork_child_calls);
_exit(0);
}
ASSERT_EQ(1234, g_atfork_parent_calls);
ASSERT_EQ(4321, g_atfork_prepare_calls);
EXPECT_EQ(0, dlclose(handle));
g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
int status;
ASSERT_EQ(pid, waitpid(pid, &status, 0));
pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
if (pid == 0) {
ASSERT_EQ(14, g_atfork_child_calls);
_exit(0);
}
ASSERT_EQ(14, g_atfork_parent_calls);
ASSERT_EQ(41, g_atfork_prepare_calls);
ASSERT_EQ(pid, waitpid(pid, &status, 0));
}

View File

@@ -16,6 +16,7 @@
#include <gtest/gtest.h>
#include <dlfcn.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
@@ -458,6 +459,42 @@ TEST(pthread, pthread_detach__no_such_thread) {
ASSERT_EQ(ESRCH, pthread_detach(dead_thread));
}
TEST(pthread, pthread_detach_no_leak) {
size_t initial_bytes = 0;
// Run this loop more than once since the first loop causes some memory
// to be allocated permenantly. Run an extra loop to help catch any subtle
// memory leaks.
for (size_t loop = 0; loop < 3; loop++) {
// Set the initial bytes on the second loop since the memory in use
// should have stabilized.
if (loop == 1) {
initial_bytes = mallinfo().uordblks;
}
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
std::vector<pthread_t> threads;
for (size_t i = 0; i < 32; ++i) {
pthread_t t;
ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL));
threads.push_back(t);
}
sleep(1);
for (size_t i = 0; i < 32; ++i) {
ASSERT_EQ(0, pthread_detach(threads[i])) << i;
}
}
size_t final_bytes = mallinfo().uordblks;
int leaked_bytes = (final_bytes - initial_bytes);
ASSERT_EQ(0, leaked_bytes);
}
TEST(pthread, pthread_getcpuclockid__clock_gettime) {
SpinFunctionHelper spinhelper;
@@ -982,6 +1019,62 @@ TEST(pthread, pthread_atfork_smoke) {
ASSERT_EQ(pid, waitpid(pid, &status, 0));
}
static void AtForkPrepare3() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 3; }
static void AtForkPrepare4() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 4; }
static void AtForkParent3() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 3; }
static void AtForkParent4() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 4; }
static void AtForkChild3() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 3; }
static void AtForkChild4() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 4; }
TEST(pthread, pthread_atfork_with_dlclose) {
ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
void* handle = dlopen("libtest_pthread_atfork.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
typedef int (*fn_t)(void (*)(void), void (*)(void), void (*)(void));
fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "proxy_pthread_atfork"));
ASSERT_TRUE(fn != nullptr) << dlerror();
// the library registers 2 additional atfork handlers in a constructor
ASSERT_EQ(0, fn(AtForkPrepare2, AtForkParent2, AtForkChild2));
ASSERT_EQ(0, fn(AtForkPrepare3, AtForkParent3, AtForkChild3));
ASSERT_EQ(0, pthread_atfork(AtForkPrepare4, AtForkParent4, AtForkChild4));
int pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
if (pid == 0) {
ASSERT_EQ(1234, g_atfork_child_calls);
_exit(0);
}
ASSERT_EQ(1234, g_atfork_parent_calls);
ASSERT_EQ(4321, g_atfork_prepare_calls);
EXPECT_EQ(0, dlclose(handle));
g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
int status;
ASSERT_EQ(pid, waitpid(pid, &status, 0));
pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
if (pid == 0) {
ASSERT_EQ(14, g_atfork_child_calls);
_exit(0);
}
ASSERT_EQ(14, g_atfork_parent_calls);
ASSERT_EQ(41, g_atfork_prepare_calls);
ASSERT_EQ(pid, waitpid(pid, &status, 0));
}
TEST(pthread, pthread_attr_getscope) {
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
@@ -1154,7 +1247,6 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
// The two methods of asking for the stack size should agree.
EXPECT_EQ(stack_size, stack_size2);
#if defined(__BIONIC__)
// What does /proc/self/maps' [stack] line say?
void* maps_stack_hi = NULL;
FILE* fp = fopen("/proc/self/maps", "r");
@@ -1171,18 +1263,15 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
}
fclose(fp);
// The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
// Remember that the stack grows down (and is mapped in on demand), so the low address of the
// region isn't very interesting.
EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);
// The stack size should correspond to RLIMIT_STACK.
rlimit rl;
ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
uint64_t original_rlim_cur = rl.rlim_cur;
#if defined(__BIONIC__)
if (rl.rlim_cur == RLIM_INFINITY) {
rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
}
#endif
EXPECT_EQ(rl.rlim_cur, stack_size);
auto guard = make_scope_guard([&rl, original_rlim_cur]() {
@@ -1190,6 +1279,11 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
});
// The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
// Remember that the stack grows down (and is mapped in on demand), so the low address of the
// region isn't very interesting.
EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);
//
// What if RLIMIT_STACK is smaller than the stack's current extent?
//
@@ -1217,7 +1311,6 @@ TEST(pthread, pthread_attr_getstack__main_thread) {
EXPECT_EQ(stack_size, stack_size2);
ASSERT_EQ(6666U, stack_size);
#endif
}
static void pthread_attr_getstack_18908062_helper(void*) {

View File

@@ -456,11 +456,11 @@ TEST(time, timer_delete_from_timer_thread) {
ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
itimerspec ts;
ts.it_value.tv_sec = 1;
ts.it_value.tv_nsec = 0;
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 100;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, NULL));
ASSERT_EQ(0, timer_settime(tdd.timer_id, TIMER_ABSTIME, &ts, NULL));
time_t cur_time = time(NULL);
while (!tdd.complete && (time(NULL) - cur_time) < 5);

View File

@@ -176,15 +176,6 @@ TEST(unistd, ftruncate64) {
ASSERT_EQ(123, sb.st_size);
}
TEST(unistd, ftruncate_negative) {
TemporaryFile tf;
errno = 0;
int rc = ftruncate(tf.fd, -123);
int err = errno;
ASSERT_EQ(-1, rc);
ASSERT_EQ(EINVAL, err);
}
static bool g_pause_test_flag = false;
static void PauseTestSignalHandler(int) {
g_pause_test_flag = true;

1
tools/Android.bp Normal file
View File

@@ -0,0 +1 @@
subdirs = ["relocation_packer"]

View File

@@ -73,10 +73,8 @@ def clean_project(dry_run):
build = 'clean-bionic-presubmit'
if build in jenkins:
if not dry_run:
_ = jenkins[build].invoke()
# https://issues.jenkins-ci.org/browse/JENKINS-27256
# url = job.get_build().baseurl
url = 'URL UNAVAILABLE'
job = jenkins[build].invoke()
url = job.get_build().baseurl
else:
url = 'DRY_RUN_URL'
logging.info('Cleaning: %s %s', build, url)

View File

@@ -0,0 +1,119 @@
//
// 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.
//
common_cppflags = [
"-Wall",
"-Wextra",
"-Wunused",
"-Werror",
"-Wold-style-cast",
]
cc_library_host_static {
srcs: [
"src/debug.cc",
"src/delta_encoder.cc",
"src/elf_file.cc",
"src/packer.cc",
"src/sleb128.cc",
],
static_libs: ["libelf"],
include_dirs: ["external/elfutils/src/libelf"],
name: "lib_relocation_packer",
cppflags: common_cppflags,
target: {
darwin: {
disabled: true
},
},
}
cc_binary_host {
srcs: ["src/main.cc"],
static_libs: [
"lib_relocation_packer",
"libelf",
],
stl: "libc++_static",
include_dirs: [
"external/elfutils/src/libelf",
"libnativehelper/include",
],
name: "relocation_packer",
cppflags: common_cppflags,
target: {
darwin: {
disabled: true
},
},
}
cc_test_host {
srcs: [
"src/debug_unittest.cc",
"src/delta_encoder_unittest.cc",
"src/elf_file_unittest.cc",
"src/sleb128_unittest.cc",
"src/packer_unittest.cc",
],
static_libs: [
"lib_relocation_packer",
"libelf",
],
include_dirs: ["external/elfutils/src/libelf"],
cppflags: common_cppflags,
name: "relocation_packer_unit_tests",
target: {
darwin: {
disabled: true
},
},
}
// $(1) library name
// ANDROIDMK TRANSLATION ERROR: unsupported directive
// define copy-test-library
// include $(CLEAR_VARS)
// LOCAL_IS_HOST_MODULE := true
// LOCAL_MODULE := $(1)
// LOCAL_MODULE_CLASS := SHARED_LIBRARIES
// LOCAL_MODULE_PATH := $(HOST_OUT_EXECUTABLES)
// LOCAL_STRIP_MODULE := false
// LOCAL_SRC_FILES := test_data/$(1)
// include $(BUILD_PREBUILT)
//
// ANDROIDMK TRANSLATION ERROR: unsupported line
// $(eval $(call copy-test-library,elf_file_unittest_relocs_arm32.so))
// ANDROIDMK TRANSLATION ERROR: unsupported line
// $(eval $(call copy-test-library,elf_file_unittest_relocs_arm32_packed.so))
// ANDROIDMK TRANSLATION ERROR: unsupported line
// $(eval $(call copy-test-library,elf_file_unittest_relocs_arm64.so))
// ANDROIDMK TRANSLATION ERROR: unsupported line
// $(eval $(call copy-test-library,elf_file_unittest_relocs_arm64_packed.so))

View File

@@ -95,9 +95,3 @@ $(eval $(call copy-test-library,elf_file_unittest_relocs_arm32.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm32_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_x64.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_x64_packed.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32.so))
$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32_packed.so))

View File

@@ -302,85 +302,16 @@ static void AdjustSectionHeadersForHole(Elf* elf,
}
}
// Helpers for ResizeSection(). On packing, reduce p_align for LOAD segments
// to 4kb if larger. On unpacking, restore p_align for LOAD segments if
// packing reduced it to 4kb. Return true if p_align was changed.
template <typename ELF>
static bool ClampLoadSegmentAlignment(typename ELF::Phdr* program_header) {
CHECK(program_header->p_type == PT_LOAD);
// If large, reduce p_align for a LOAD segment to page size on packing.
if (program_header->p_align > kPageSize) {
program_header->p_align = kPageSize;
return true;
}
return false;
}
template <typename ELF>
static bool RestoreLoadSegmentAlignment(typename ELF::Phdr* program_headers,
size_t count,
typename ELF::Phdr* program_header) {
CHECK(program_header->p_type == PT_LOAD);
// If p_align was reduced on packing, restore it to its previous value
// on unpacking. We do this by searching for a different LOAD segment
// and setting p_align to that of the other LOAD segment found.
//
// Relies on the following observations:
// - a packable ELF executable has more than one LOAD segment;
// - before packing all LOAD segments have the same p_align;
// - on packing we reduce only one LOAD segment's p_align.
if (program_header->p_align == kPageSize) {
for (size_t i = 0; i < count; ++i) {
typename ELF::Phdr* other_header = &program_headers[i];
if (other_header->p_type == PT_LOAD && other_header != program_header) {
program_header->p_align = other_header->p_align;
return true;
}
}
LOG(WARNING) << "Cannot find a LOAD segment from which to restore p_align";
}
return false;
}
template <typename ELF>
static bool AdjustLoadSegmentAlignment(typename ELF::Phdr* program_headers,
size_t count,
typename ELF::Phdr* program_header,
ssize_t hole_size) {
CHECK(program_header->p_type == PT_LOAD);
bool status = false;
if (hole_size < 0) {
status = ClampLoadSegmentAlignment<ELF>(program_header);
} else if (hole_size > 0) {
status = RestoreLoadSegmentAlignment<ELF>(program_headers,
count,
program_header);
}
return status;
}
// Helper for ResizeSection(). Adjust the offsets of any program headers
// that have offsets currently beyond the hole start, and adjust the
// virtual and physical addrs (and perhaps alignment) of the others.
// that have offsets currently beyond the hole start.
template <typename ELF>
static void AdjustProgramHeaderFields(typename ELF::Phdr* program_headers,
size_t count,
typename ELF::Off hole_start,
ssize_t hole_size) {
int alignment_changes = 0;
static void AdjustProgramHeaderOffsets(typename ELF::Phdr* program_headers,
size_t count,
typename ELF::Off hole_start,
ssize_t hole_size) {
for (size_t i = 0; i < count; ++i) {
typename ELF::Phdr* program_header = &program_headers[i];
// Do not adjust PT_GNU_STACK - it confuses gdb and results
// in incorrect unwinding if the executable is stripped after
// packing.
if (program_header->p_type == PT_GNU_STACK) {
continue;
}
if (program_header->p_offset > hole_start) {
// The hole start is past this segment, so adjust offset.
program_header->p_offset += hole_size;
@@ -389,20 +320,9 @@ static void AdjustProgramHeaderFields(typename ELF::Phdr* program_headers,
} else {
program_header->p_vaddr -= hole_size;
program_header->p_paddr -= hole_size;
// If packing, clamp LOAD segment alignment to 4kb to prevent strip
// from adjusting it unnecessarily if run on a packed file. If
// unpacking, attempt to restore a reduced alignment to its previous
// value. Ensure that we do this on at most one LOAD segment.
if (program_header->p_type == PT_LOAD) {
alignment_changes += AdjustLoadSegmentAlignment<ELF>(program_headers,
count,
program_header,
hole_size);
LOG_IF(FATAL, alignment_changes > 1)
<< "Changed p_align on more than one LOAD segment";
if (program_header->p_align > kPageSize) {
program_header->p_align = kPageSize;
}
VLOG(1) << "phdr[" << i
<< "] p_vaddr adjusted to "<< program_header->p_vaddr
<< "; p_paddr adjusted to "<< program_header->p_paddr
@@ -456,10 +376,10 @@ static void RewriteProgramHeadersForHole(Elf* elf,
target_load_header->p_memsz += hole_size;
// Adjust the offsets and p_vaddrs
AdjustProgramHeaderFields<ELF>(elf_program_header,
program_header_count,
hole_start,
hole_size);
AdjustProgramHeaderOffsets<ELF>(elf_program_header,
program_header_count,
hole_start,
hole_size);
}
// Helper for ResizeSection(). Locate and return the dynamic section.
@@ -552,16 +472,6 @@ void ElfFile<ELF>::AdjustDynamicSectionForHole(Elf_Scn* dynamic_section,
<< " d_val adjusted to " << dynamic->d_un.d_val;
}
// Special case: DT_MIPS_RLD_MAP2 stores the difference between dynamic
// entry address and the address of the _r_debug (used by GDB)
// since the dynamic section and target address are on the
// different sides of the hole it needs to be adjusted accordingly
if (tag == DT_MIPS_RLD_MAP2) {
dynamic->d_un.d_val += hole_size;
VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
<< " d_val adjusted to " << dynamic->d_un.d_val;
}
// Ignore DT_RELCOUNT and DT_RELACOUNT: (1) nobody uses them and
// technically (2) the relative relocation count is not changed.

View File

@@ -183,18 +183,6 @@ TEST(ElfFile, PackRelocationsArm64) {
RunPackRelocationsTestFor("arm64");
}
TEST(ElfFile, PackRelocationsMips32) {
RunPackRelocationsTestFor("mips32");
}
TEST(ElfFile, PackRelocationsIa32) {
RunPackRelocationsTestFor("ia32");
}
TEST(ElfFile, PackRelocationsX64) {
RunPackRelocationsTestFor("x64");
}
TEST(ElfFile, UnpackRelocationsArm32) {
RunUnpackRelocationsTestFor("arm32");
}
@@ -203,16 +191,4 @@ TEST(ElfFile, UnpackRelocationsArm64) {
RunUnpackRelocationsTestFor("arm64");
}
TEST(ElfFile, UnpackRelocationsMips32) {
RunUnpackRelocationsTestFor("mips32");
}
TEST(ElfFile, UnpackRelocationsIa32) {
RunUnpackRelocationsTestFor("ia32");
}
TEST(ElfFile, UnpackRelocationsX64) {
RunUnpackRelocationsTestFor("x64");
}
} // namespace relocation_packer

View File

@@ -10,10 +10,6 @@
#include "elf.h"
#include "libelf.h"
#if !defined(DT_MIPS_RLD_MAP2)
#define DT_MIPS_RLD_MAP2 0x70000035
#endif
// ELF is a traits structure used to provide convenient aliases for
// 32/64 bit Elf types and functions, depending on the target file.