am fd20a8c2: resolved conflicts for merge of 473d96c0 to lmp-mr1-ub-dev
* commit 'fd20a8c2d669b3f2d63e2d33a32b90d1b7f17b82':
Fix timer flaky test in lollipop-mr1-cts-dev.
diff --git a/libc/Android.mk b/libc/Android.mk
index 2c33a8f..f09733e 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -941,13 +941,6 @@
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
-# ssse3-strcmp-slm.S does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
-
-# 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
@@ -975,13 +968,6 @@
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
-# ssse3-strcmp-slm.S does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
-
-# 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
@@ -1030,13 +1016,6 @@
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
-# ssse3-strcmp-slm.S does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
-
-# 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)
@@ -1361,6 +1340,9 @@
# meaningful name resolution.
LOCAL_STRIP_MODULE := keep_symbols
+# Do not pack libc.so relocations; see http://b/20645321 for details.
+LOCAL_PACK_MODULE_RELOCATIONS := false
+
# WARNING: The only library libc.so should depend on is libdl.so! If you add other libraries,
# make sure to add -Wl,--exclude-libs=libgcc.a to the LOCAL_LDFLAGS for those libraries. This
# ensures that symbols that are pulled into those new libraries from libgcc.a are not declared
@@ -1385,11 +1367,11 @@
# 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.
-# TODO: disabled for http://b/20065774.
-#LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
+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=sysv
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
+LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
$(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))
@@ -1519,7 +1501,8 @@
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=sysv
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
+LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
LOCAL_MODULE:= libstdc++
diff --git a/libc/NOTICE b/libc/NOTICE
index 1fa31c2..dbe3944 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -307,34 +307,6 @@
-------------------------------------------------------------------
-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");
@@ -455,22 +427,6 @@
-------------------------------------------------------------------
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.
Redistribution and use in source and binary forms, with or without
@@ -688,6 +644,50 @@
-------------------------------------------------------------------
+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,33 +2550,6 @@
-------------------------------------------------------------------
-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
@@ -3795,6 +3768,22 @@
-------------------------------------------------------------------
+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.
@@ -4733,31 +4722,6 @@
-------------------------------------------------------------------
-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.
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 33e30eb..0246833 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -223,7 +223,7 @@
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
diff --git a/libc/arch-arm/bionic/__bionic_clone.S b/libc/arch-arm/bionic/__bionic_clone.S
index a268f9d..b771357 100644
--- a/libc/arch-arm/bionic/__bionic_clone.S
+++ b/libc/arch-arm/bionic/__bionic_clone.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/libc/arch-arm/cortex-a9/bionic/memset.S b/libc/arch-arm/cortex-a9/bionic/memset.S
index 299f5a2..8ee6ac2 100644
--- a/libc/arch-arm/cortex-a9/bionic/memset.S
+++ b/libc/arch-arm/cortex-a9/bionic/memset.S
@@ -35,6 +35,7 @@
*/
.fpu neon
+ .syntax unified
ENTRY(__memset_chk)
cmp r2, r3
@@ -100,9 +101,9 @@
1: bge 2f
vst1.32 {d0[0]}, [r0]!
2: movs ip, r2, lsl #31
- strmib r1, [r0], #1
- strcsb r1, [r0], #1
- strcsb r1, [r0], #1
+ strbmi r1, [r0], #1
+ strbcs r1, [r0], #1
+ strbcs r1, [r0], #1
ldmfd sp!, {r0}
bx lr
END(memset)
@@ -131,11 +132,11 @@
orr r1, r1, r1, lsr #16
movs r12, r3, lsl #31
- strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
- strcsb r1, [r0], #1
- strmib r1, [r0], #1
+ strbcs r1, [r0], #1 /* can't use strh (alignment unknown) */
+ strbcs r1, [r0], #1
+ strbmi r1, [r0], #1
subs r2, r2, r3
- ldmlsfd sp!, {r0, r4-r7, lr} /* return */
+ popls {r0, r4-r7, lr} /* return */
bxls lr
/* align the destination to a cache-line */
@@ -155,9 +156,9 @@
/* conditionally writes 0 to 7 words (length in r3) */
movs r3, r3, lsl #28
- stmcsia r0!, {r1, lr}
- stmcsia r0!, {r1, lr}
- stmmiia r0!, {r1, lr}
+ stmcs r0!, {r1, lr}
+ stmcs r0!, {r1, lr}
+ stmmi r0!, {r1, lr}
movs r3, r3, lsl #2
strcs r1, [r0], #4
@@ -172,13 +173,13 @@
/* conditionally stores 0 to 31 bytes */
movs r2, r2, lsl #28
- stmcsia r0!, {r1,r3,r12,lr}
- stmmiia r0!, {r1, lr}
+ stmcs r0!, {r1,r3,r12,lr}
+ stmmi r0!, {r1, lr}
movs r2, r2, lsl #2
strcs r1, [r0], #4
- strmih r1, [r0], #2
+ strhmi r1, [r0], #2
movs r2, r2, lsl #2
- strcsb r1, [r0]
+ strbcs r1, [r0]
ldmfd sp!, {r0, r4-r7, lr}
bx lr
END(__memset_large_copy)
diff --git a/libc/arch-arm/generic/bionic/memcmp.S b/libc/arch-arm/generic/bionic/memcmp.S
index 70a2a58..c78dbd4 100644
--- a/libc/arch-arm/generic/bionic/memcmp.S
+++ b/libc/arch-arm/generic/bionic/memcmp.S
@@ -40,6 +40,8 @@
* Optimized memcmp() for Cortex-A9.
*/
+.syntax unified
+
ENTRY(memcmp)
pld [r0, #(CACHE_LINE_SIZE * 0)]
pld [r0, #(CACHE_LINE_SIZE * 1)]
@@ -161,25 +163,25 @@
eors r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
- eoreqs r0, r0, lr
+ eorseq r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
- eoreqs r0, r0, ip
+ eorseq r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
- eoreqs r0, r0, lr
+ eorseq r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
- eoreqs r0, r0, ip
+ eorseq r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
- eoreqs r0, r0, lr
+ eorseq r0, r0, lr
ldreq r0, [r4], #4
ldreq lr, [r1, #4]!
- eoreqs r0, r0, ip
+ eorseq r0, r0, ip
ldreq r0, [r4], #4
ldreq ip, [r1, #4]!
- eoreqs r0, r0, lr
+ eorseq r0, r0, lr
bne 2f
subs r2, r2, #32
bhs 0b
@@ -263,17 +265,17 @@
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
- eoreqs r0, r0, ip
+ eorseq r0, r0, ip
moveq ip, lr, lsr #16
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
- eoreqs r0, r0, ip
+ eorseq r0, r0, ip
moveq ip, lr, lsr #16
ldreq lr, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, lr, lsl #16
- eoreqs r0, r0, ip
+ eorseq r0, r0, ip
bne 7f
subs r2, r2, #16
bhs 6b
@@ -317,7 +319,7 @@
ldreq r7, [r1], #4
ldreq r0, [r4], #4
orreq ip, ip, r7, lsl r6
- eoreqs r0, r0, ip
+ eorseq r0, r0, ip
bne 7f
subs r2, r2, #8
bhs 6b
diff --git a/libc/arch-arm/generic/bionic/memcpy.S b/libc/arch-arm/generic/bionic/memcpy.S
index b0c79ab..ea5a399 100644
--- a/libc/arch-arm/generic/bionic/memcpy.S
+++ b/libc/arch-arm/generic/bionic/memcpy.S
@@ -37,6 +37,8 @@
* so we have to preserve R0.
*/
+ .syntax unified
+
ENTRY(__memcpy_chk)
cmp r2, r3
bhi __memcpy_chk_fail
@@ -81,12 +83,12 @@
*/
movs r12, r3, lsl #31
sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
- ldrmib r3, [r1], #1
- ldrcsb r4, [r1], #1
- ldrcsb r12,[r1], #1
- strmib r3, [r0], #1
- strcsb r4, [r0], #1
- strcsb r12,[r0], #1
+ ldrbmi r3, [r1], #1
+ ldrbcs r4, [r1], #1
+ ldrbcs r12,[r1], #1
+ strbmi r3, [r0], #1
+ strbcs r4, [r0], #1
+ strbcs r12,[r0], #1
.Lsrc_aligned:
@@ -109,10 +111,10 @@
/* conditionally copies 0 to 7 words (length in r3) */
movs r12, r3, lsl #28
- ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */
- ldmmiia r1!, {r8, r9} /* 8 bytes */
- stmcsia r0!, {r4, r5, r6, r7}
- stmmiia r0!, {r8, r9}
+ ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
+ ldmmi r1!, {r8, r9} /* 8 bytes */
+ stmcs r0!, {r4, r5, r6, r7}
+ stmmi r0!, {r8, r9}
tst r3, #0x4
ldrne r10,[r1], #4 /* 4 bytes */
strne r10,[r0], #4
@@ -177,18 +179,18 @@
/* conditionnaly copies 0 to 31 bytes */
movs r12, r2, lsl #28
- ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */
- ldmmiia r1!, {r8, r9} /* 8 bytes */
- stmcsia r0!, {r4, r5, r6, r7}
- stmmiia r0!, {r8, r9}
+ ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
+ ldmmi r1!, {r8, r9} /* 8 bytes */
+ stmcs r0!, {r4, r5, r6, r7}
+ stmmi r0!, {r8, r9}
movs r12, r2, lsl #30
ldrcs r3, [r1], #4 /* 4 bytes */
- ldrmih r4, [r1], #2 /* 2 bytes */
+ ldrhmi r4, [r1], #2 /* 2 bytes */
strcs r3, [r0], #4
- strmih r4, [r0], #2
+ strhmi r4, [r0], #2
tst r2, #0x1
- ldrneb r3, [r1] /* last byte */
- strneb r3, [r0]
+ ldrbne r3, [r1] /* last byte */
+ strbne r3, [r0]
/* we're done! restore everything and return */
1: ldmfd sp!, {r5-r11}
@@ -228,11 +230,11 @@
* becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
*/
movs r5, r5, lsl #31
- strmib r3, [r0], #1
+ strbmi r3, [r0], #1
movmi r3, r3, lsr #8
- strcsb r3, [r0], #1
+ strbcs r3, [r0], #1
movcs r3, r3, lsr #8
- strcsb r3, [r0], #1
+ strbcs r3, [r0], #1
movcs r3, r3, lsr #8
cmp r2, #4
@@ -363,23 +365,23 @@
.Lpartial_word_tail:
/* we have a partial word in the input buffer */
movs r5, lr, lsl #(31-3)
- strmib r3, [r0], #1
+ strbmi r3, [r0], #1
movmi r3, r3, lsr #8
- strcsb r3, [r0], #1
+ strbcs r3, [r0], #1
movcs r3, r3, lsr #8
- strcsb r3, [r0], #1
+ strbcs 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 */
- ldrmib r2, [r1], #1
- ldrcsb r3, [r1], #1
- ldrcsb r12,[r1]
- strmib r2, [r0], #1
- strcsb r3, [r0], #1
- strcsb r12,[r0]
+ ldrbmi r2, [r1], #1
+ ldrbcs r3, [r1], #1
+ ldrbcs r12,[r1]
+ strbmi r2, [r0], #1
+ strbcs r3, [r0], #1
+ strbcs r12,[r0]
/* we're done! restore sp and spilled registers and return */
add sp, sp, #28
diff --git a/libc/arch-arm/generic/bionic/memset.S b/libc/arch-arm/generic/bionic/memset.S
index be35de9..d17a9c4 100644
--- a/libc/arch-arm/generic/bionic/memset.S
+++ b/libc/arch-arm/generic/bionic/memset.S
@@ -35,6 +35,8 @@
* memset() returns its first argument.
*/
+ .syntax unified
+
ENTRY(__memset_chk)
cmp r2, r3
bls done
@@ -76,11 +78,11 @@
orr r1, r1, r1, lsr #16
movs r12, r3, lsl #31
- strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
- strcsb r1, [r0], #1
- strmib r1, [r0], #1
+ strbcs r1, [r0], #1 /* can't use strh (alignment unknown) */
+ strbcs r1, [r0], #1
+ strbmi r1, [r0], #1
subs r2, r2, r3
- ldmlsfd sp!, {r0, r4-r7, lr} /* return */
+ popls {r0, r4-r7, lr} /* return */
bxls lr
/* align the destination to a cache-line */
@@ -100,9 +102,9 @@
/* conditionally writes 0 to 7 words (length in r3) */
movs r3, r3, lsl #28
- stmcsia r0!, {r1, lr}
- stmcsia r0!, {r1, lr}
- stmmiia r0!, {r1, lr}
+ stmcs r0!, {r1, lr}
+ stmcs r0!, {r1, lr}
+ stmmi r0!, {r1, lr}
movs r3, r3, lsl #2
strcs r1, [r0], #4
@@ -117,13 +119,13 @@
/* conditionally stores 0 to 31 bytes */
movs r2, r2, lsl #28
- stmcsia r0!, {r1,r3,r12,lr}
- stmmiia r0!, {r1, lr}
+ stmcs r0!, {r1,r3,r12,lr}
+ stmmi r0!, {r1, lr}
movs r2, r2, lsl #2
strcs r1, [r0], #4
- strmih r1, [r0], #2
+ strhmi r1, [r0], #2
movs r2, r2, lsl #2
- strcsb r1, [r0]
+ strbcs r1, [r0]
ldmfd sp!, {r0, r4-r7, lr}
bx lr
END(memset)
diff --git a/libc/arch-arm/generic/bionic/strcpy.S b/libc/arch-arm/generic/bionic/strcpy.S
index 802a62d..89ea098 100644
--- a/libc/arch-arm/generic/bionic/strcpy.S
+++ b/libc/arch-arm/generic/bionic/strcpy.S
@@ -32,6 +32,8 @@
#include <machine/cpu-features.h>
#include <private/bionic_asm.h>
+.syntax unified
+
ENTRY(strcpy)
pld [r1, #0]
eor r2, r0, r1
@@ -108,15 +110,15 @@
#ifdef __ARMEB__
tst r2, #0xff00
iteet ne
- strneh r2, [ip], #2
+ strhne r2, [ip], #2
lsreq r2, r2, #8
- streqb r2, [ip]
+ strbeq r2, [ip]
tstne r2, #0xff
#else
tst r2, #0xff
itet ne
- strneh r2, [ip], #2
- streqb r2, [ip]
+ strhne r2, [ip], #2
+ strbeq r2, [ip]
tstne r2, #0xff00
#endif
bne 5b
diff --git a/libc/arch-arm/krait/bionic/memset.S b/libc/arch-arm/krait/bionic/memset.S
index e9f6431..a4fbe17 100644
--- a/libc/arch-arm/krait/bionic/memset.S
+++ b/libc/arch-arm/krait/bionic/memset.S
@@ -37,6 +37,7 @@
*/
.fpu neon
+ .syntax unified
ENTRY(__memset_chk)
cmp r2, r3
@@ -98,9 +99,9 @@
1: bge 2f
vst1.32 {d0[0]}, [r0]!
2: movs ip, r2, lsl #31
- strmib r1, [r0], #1
- strcsb r1, [r0], #1
- strcsb r1, [r0], #1
+ strbmi r1, [r0], #1
+ strbcs r1, [r0], #1
+ strbcs r1, [r0], #1
ldmfd sp!, {r0}
bx lr
END(memset)
diff --git a/libc/arch-arm/syscalls/__rt_sigqueueinfo.S b/libc/arch-arm/syscalls/___rt_sigqueueinfo.S
similarity index 78%
rename from libc/arch-arm/syscalls/__rt_sigqueueinfo.S
rename to libc/arch-arm/syscalls/___rt_sigqueueinfo.S
index c823cee..25b0d57 100644
--- a/libc/arch-arm/syscalls/__rt_sigqueueinfo.S
+++ b/libc/arch-arm/syscalls/___rt_sigqueueinfo.S
@@ -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,4 +11,5 @@
bxls lr
neg r0, r0
b __set_errno_internal
-END(__rt_sigqueueinfo)
+END(___rt_sigqueueinfo)
+.hidden ___rt_sigqueueinfo
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index 6a2f313..470a038 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -40,8 +40,6 @@
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
diff --git a/libc/arch-arm64/bionic/libgcc_compat.c b/libc/arch-arm64/bionic/libgcc_compat.c
deleted file mode 100644
index 2dae3f5..0000000
--- a/libc/arch-arm64/bionic/libgcc_compat.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* 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
diff --git a/libc/arch-arm64/generic/bionic/memchr.S b/libc/arch-arm64/generic/bionic/memchr.S
index e5ea57d..a00dd8d 100644
--- a/libc/arch-arm64/generic/bionic/memchr.S
+++ b/libc/arch-arm64/generic/bionic/memchr.S
@@ -101,7 +101,7 @@
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.2d[0]
+ mov synd, vend.d[0]
/* Clear the soff*2 lower bits */
lsl tmp, soff, #1
lsr synd, synd, tmp
@@ -121,7 +121,7 @@
/* 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.2d[0]
+ mov synd, vend.d[0]
/* We're not out of data, loop if we haven't found the character */
cbz synd, .Lloop
@@ -131,7 +131,7 @@
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.2d[0]
+ mov synd, vend.d[0]
/* Only do the clear for the last possible block */
b.hi .Ltail
diff --git a/libc/arch-arm64/generic/bionic/strchr.S b/libc/arch-arm64/generic/bionic/strchr.S
index 469b83c..b54106d 100644
--- a/libc/arch-arm64/generic/bionic/strchr.S
+++ b/libc/arch-arm64/generic/bionic/strchr.S
@@ -109,7 +109,7 @@
addp vend1.16b, vend1.16b, vend2.16b // 128->64
lsr tmp1, tmp3, tmp1
- mov tmp3, vend1.2d[0]
+ mov tmp3, vend1.d[0]
bic tmp1, tmp3, tmp1 // Mask padding bits.
cbnz tmp1, .Ltail
@@ -124,7 +124,7 @@
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.2d[0]
+ mov tmp1, vend1.d[0]
cbz tmp1, .Lloop
/* Termination condition found. Now need to establish exactly why
@@ -138,7 +138,7 @@
addp vend1.16b, vend1.16b, vend2.16b // 256->128
addp vend1.16b, vend1.16b, vend2.16b // 128->64
- mov tmp1, vend1.2d[0]
+ mov tmp1, vend1.d[0]
.Ltail:
/* Count the trailing zeros, by bit reversing... */
rbit tmp1, tmp1
diff --git a/libc/arch-arm64/syscalls/__rt_sigqueueinfo.S b/libc/arch-arm64/syscalls/___rt_sigqueueinfo.S
similarity index 75%
rename from libc/arch-arm64/syscalls/__rt_sigqueueinfo.S
rename to libc/arch-arm64/syscalls/___rt_sigqueueinfo.S
index 2b23e18..85ea132 100644
--- a/libc/arch-arm64/syscalls/__rt_sigqueueinfo.S
+++ b/libc/arch-arm64/syscalls/___rt_sigqueueinfo.S
@@ -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 @@
b.hi __set_errno_internal
ret
-END(__rt_sigqueueinfo)
-.hidden __rt_sigqueueinfo
+END(___rt_sigqueueinfo)
+.hidden ___rt_sigqueueinfo
diff --git a/libc/arch-common/bionic/asm_multiarch.h b/libc/arch-common/bionic/asm_multiarch.h
index 85e1b57..91cb8af 100644
--- a/libc/arch-common/bionic/asm_multiarch.h
+++ b/libc/arch-common/bionic/asm_multiarch.h
@@ -28,9 +28,9 @@
#ifdef __LP64__
# define ASM_PTR_SIZE(x) .quad x
-# define ASM_ALIGN(x)
+# define ASM_ALIGN_TO_PTR_SIZE .balign 8
#else
# define ASM_PTR_SIZE(x) .long x
-# define ASM_ALIGN(x) .align x
+# define ASM_ALIGN_TO_PTR_SIZE .balign 4
#endif
diff --git a/libc/arch-common/bionic/crtend.S b/libc/arch-common/bionic/crtend.S
index a4cf8de..87d1120 100644
--- a/libc/arch-common/bionic/crtend.S
+++ b/libc/arch-common/bionic/crtend.S
@@ -29,12 +29,15 @@
#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__)
@@ -42,7 +45,9 @@
#endif
#if defined(__i386__) || defined(__x86_64__)
.section .eh_frame,"a",@progbits
- ASM_ALIGN(4)
+#if defined(__i386__)
+ .balign 4
+#endif
.type __FRAME_END__, @object
.size __FRAME_END__, 4
__FRAME_END__:
diff --git a/libc/arch-common/bionic/crtend_so.S b/libc/arch-common/bionic/crtend_so.S
index f745109..e7b8cac 100644
--- a/libc/arch-common/bionic/crtend_so.S
+++ b/libc/arch-common/bionic/crtend_so.S
@@ -26,22 +26,14 @@
* 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
- ASM_ALIGN(4)
+#if defined(__i386__)
+ .balign 4
+#endif
.type __FRAME_END__, @object
.size __FRAME_END__, 4
__FRAME_END__:
diff --git a/libc/arch-mips/bionic/setjmp.S b/libc/arch-mips/bionic/setjmp.S
index bed9562..3ef0f11 100644
--- a/libc/arch-mips/bionic/setjmp.S
+++ b/libc/arch-mips/bionic/setjmp.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2015 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/libc/arch-mips/syscalls/__rt_sigqueueinfo.S b/libc/arch-mips/syscalls/___rt_sigqueueinfo.S
similarity index 78%
rename from libc/arch-mips/syscalls/__rt_sigqueueinfo.S
rename to libc/arch-mips/syscalls/___rt_sigqueueinfo.S
index a978bc4..95af36f 100644
--- a/libc/arch-mips/syscalls/__rt_sigqueueinfo.S
+++ b/libc/arch-mips/syscalls/___rt_sigqueueinfo.S
@@ -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,4 +16,5 @@
j t9
nop
.set reorder
-END(__rt_sigqueueinfo)
+END(___rt_sigqueueinfo)
+.hidden ___rt_sigqueueinfo
diff --git a/libc/arch-mips64/syscalls/__rt_sigqueueinfo.S b/libc/arch-mips64/syscalls/___rt_sigqueueinfo.S
similarity index 82%
rename from libc/arch-mips64/syscalls/__rt_sigqueueinfo.S
rename to libc/arch-mips64/syscalls/___rt_sigqueueinfo.S
index e97aeba..1503f51 100644
--- a/libc/arch-mips64/syscalls/__rt_sigqueueinfo.S
+++ b/libc/arch-mips64/syscalls/___rt_sigqueueinfo.S
@@ -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 @@
j t9
move ra, t0
.set pop
-END(__rt_sigqueueinfo)
-.hidden __rt_sigqueueinfo
+END(___rt_sigqueueinfo)
+.hidden ___rt_sigqueueinfo
diff --git a/libc/arch-x86/syscalls/__rt_sigqueueinfo.S b/libc/arch-x86/syscalls/___rt_sigqueueinfo.S
similarity index 89%
rename from libc/arch-x86/syscalls/__rt_sigqueueinfo.S
rename to libc/arch-x86/syscalls/___rt_sigqueueinfo.S
index 4152100..97d167f 100644
--- a/libc/arch-x86/syscalls/__rt_sigqueueinfo.S
+++ b/libc/arch-x86/syscalls/___rt_sigqueueinfo.S
@@ -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,4 +28,5 @@
popl %ecx
popl %ebx
ret
-END(__rt_sigqueueinfo)
+END(___rt_sigqueueinfo)
+.hidden ___rt_sigqueueinfo
diff --git a/libc/arch-x86_64/string/ssse3-strcmp-slm.S b/libc/arch-x86_64/string/ssse3-strcmp-slm.S
index 0dd8c27..e8acd5b 100644
--- a/libc/arch-x86_64/string/ssse3-strcmp-slm.S
+++ b/libc/arch-x86_64/string/ssse3-strcmp-slm.S
@@ -1897,8 +1897,8 @@
.p2align 4
L(Byte0):
- movzx (%rsi), %ecx
- movzx (%rdi), %eax
+ movzbl (%rsi), %ecx
+ movzbl (%rdi), %eax
sub %ecx, %eax
ret
diff --git a/libc/arch-x86_64/syscalls/__rt_sigqueueinfo.S b/libc/arch-x86_64/syscalls/___rt_sigqueueinfo.S
similarity index 77%
rename from libc/arch-x86_64/syscalls/__rt_sigqueueinfo.S
rename to libc/arch-x86_64/syscalls/___rt_sigqueueinfo.S
index 52b6863..8c6b30b 100644
--- a/libc/arch-x86_64/syscalls/__rt_sigqueueinfo.S
+++ b/libc/arch-x86_64/syscalls/___rt_sigqueueinfo.S
@@ -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 @@
call __set_errno_internal
1:
ret
-END(__rt_sigqueueinfo)
-.hidden __rt_sigqueueinfo
+END(___rt_sigqueueinfo)
+.hidden ___rt_sigqueueinfo
diff --git a/libc/bionic/libc_logging.cpp b/libc/bionic/libc_logging.cpp
index 7ad21c4..cb0b334 100644
--- a/libc/bionic/libc_logging.cpp
+++ b/libc/bionic/libc_logging.cpp
@@ -56,6 +56,7 @@
EVENT_TYPE_LONG = 1,
EVENT_TYPE_STRING = 2,
EVENT_TYPE_LIST = 3,
+ EVENT_TYPE_FLOAT = 4,
};
struct BufferOutputStream {
diff --git a/libc/bionic/sigqueue.cpp b/libc/bionic/sigqueue.cpp
index 39c8798..8741460 100644
--- a/libc/bionic/sigqueue.cpp
+++ b/libc/bionic/sigqueue.cpp
@@ -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 @@
info.si_uid = getuid();
info.si_value = value;
- return __rt_sigqueueinfo(pid, signo, &info);
+ return ___rt_sigqueueinfo(pid, signo, &info);
}
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index aae99b1..c436a16 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -598,6 +598,16 @@
return map_prop_area_rw();
}
+unsigned int __system_property_area_serial()
+{
+ prop_area *pa = __system_property_area__;
+ if (!pa) {
+ return -1;
+ }
+ // Make sure this read fulfilled before __system_property_serial
+ return atomic_load_explicit(&(pa->serial), memory_order_acquire);
+}
+
const prop_info *__system_property_find(const char *name)
{
if (__predict_false(compat_mode)) {
diff --git a/libc/include/elf.h b/libc/include/elf.h
index df768ba..eaad1d3 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -34,6 +34,11 @@
#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 {
@@ -187,6 +192,11 @@
#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
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index 7ff3ded..a0315b5 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -81,7 +81,6 @@
#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"
@@ -98,6 +97,30 @@
*/
int __system_property_area_init();
+/* Read the global serial number of the system properties
+**
+** Called to predict if a series of cached __system_property_find
+** 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
+** 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
+** __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.
+**
+** Returns the serial number on success, -1 on error.
+*/
+unsigned int __system_property_area_serial();
+
/* Add a new system property. Can only be done by a single
** process that has write access to the property area, and
** that process must handle sequencing to ensure the property
diff --git a/libc/private/ScopedFd.h b/libc/private/ScopedFd.h
deleted file mode 100644
index e56c139..0000000
--- a/libc/private/ScopedFd.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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
diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c
index 13b9887..fc2115e 100644
--- a/libc/stdio/stdio.c
+++ b/libc/stdio/stdio.c
@@ -86,5 +86,5 @@
int
__sclose(void *cookie)
{
- return TEMP_FAILURE_RETRY(close(((FILE *)cookie)->_file));
+ return close(((FILE *)cookie)->_file);
}
diff --git a/libc/version_script.txt b/libc/version_script.txt
index 349a2fc..afc5e5c 100644
--- a/libc/version_script.txt
+++ b/libc/version_script.txt
@@ -1,9 +1,4 @@
LIBC {
- global:
- /* Work-around for http://b/20065774. */
- __clear_cache;
- _Unwind_Backtrace;
- _Unwind_GetIP;
local:
_ZSt7nothrow;
_ZdaPv;
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
index 3661b68..2c734fa 100644
--- a/libc/zoneinfo/tzdata
+++ b/libc/zoneinfo/tzdata
Binary files differ
diff --git a/libm/Android.mk b/libm/Android.mk
index 6472a15..4a5bbad 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -514,7 +514,8 @@
include $(CLEAR_VARS)
# TODO: This is to work around b/19059885. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
+LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_MODULE := libm
LOCAL_CLANG := $(libm_clang)
diff --git a/libm/NOTICE b/libm/NOTICE
index 70f2f46..a2cfad3 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -1002,6 +1002,114 @@
-------------------------------------------------------------------
+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.
diff --git a/linker/Android.mk b/linker/Android.mk
index 5bdc2f9..4a7da76 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -35,6 +35,9 @@
-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 \
diff --git a/linker/NOTICE b/linker/NOTICE
index cb3a1dd..139b26e 100644
--- a/linker/NOTICE
+++ b/linker/NOTICE
@@ -42,62 +42,6 @@
-------------------------------------------------------------------
-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.
@@ -214,3 +158,47 @@
-------------------------------------------------------------------
+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.
+
+-------------------------------------------------------------------
+
diff --git a/linker/debugger.cpp b/linker/debugger.cpp
index 357fbdc..46c97af 100644
--- a/linker/debugger.cpp
+++ b/linker/debugger.cpp
@@ -205,15 +205,6 @@
}
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;
diff --git a/linker/linker.cpp b/linker/linker.cpp
index be7b10c..4c98afe 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -47,7 +47,6 @@
#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"
@@ -267,7 +266,7 @@
soinfo *prev = nullptr, *trav;
- TRACE("name %s: freeing soinfo @ %p", si->get_soname(), si);
+ TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
for (trav = solist; trav != nullptr; trav = trav->next) {
if (trav == si) {
@@ -278,7 +277,7 @@
if (trav == nullptr) {
// si was not in solist
- DL_ERR("name \"%s\"@%p is not in solist!", si->get_soname(), si);
+ DL_ERR("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
return;
}
@@ -443,7 +442,7 @@
if (verdef->vd_version != 1) {
DL_ERR("unsupported verdef[%zd] vd_version: %d (expected 1) library: %s",
- i, verdef->vd_version, si->get_soname());
+ i, verdef->vd_version, si->get_realpath());
return false;
}
@@ -513,7 +512,7 @@
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_soname());
+ ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
}
return false;
@@ -546,12 +545,12 @@
*symbol_index = 0;
TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p (gnu)",
- symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
+ symbol_name.get_name(), get_realpath(), 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_soname(), reinterpret_cast<void*>(base));
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
return true;
}
@@ -561,7 +560,7 @@
if (n == 0) {
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
- symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
return true;
}
@@ -589,7 +588,7 @@
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_soname(), reinterpret_cast<void*>(s->st_value),
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(s->st_value),
static_cast<size_t>(s->st_size));
*symbol_index = n;
return true;
@@ -597,7 +596,7 @@
} while ((gnu_chain_[n++] & 1) == 0);
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
- symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
return true;
}
@@ -608,7 +607,7 @@
uint32_t hash = symbol_name.elf_hash();
TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p h=%x(elf) %zd",
- symbol_name.get_name(), get_soname(),
+ symbol_name.get_name(), get_realpath(),
reinterpret_cast<void*>(base), hash, hash % nbucket_);
ElfW(Versym) verneed = 0;
@@ -629,7 +628,7 @@
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_soname(),
+ symbol_name.get_name(), get_realpath(),
reinterpret_cast<void*>(s->st_value),
static_cast<size_t>(s->st_size));
*symbol_index = n;
@@ -638,7 +637,7 @@
}
TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p %x %zd",
- symbol_name.get_name(), get_soname(),
+ symbol_name.get_name(), get_realpath(),
reinterpret_cast<void*>(base), hash, hash % nbucket_);
*symbol_index = 0;
@@ -718,7 +717,7 @@
* 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_soname(), name);
+ DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_realpath(), name);
if (!si_from->find_symbol_by_name(symbol_name, vi, &s)) {
return false;
}
@@ -733,7 +732,7 @@
bool error = false;
global_group.visit([&](soinfo* global_si) {
DEBUG("%s: looking up %s in %s (from global group)",
- si_from->get_soname(), name, global_si->get_soname());
+ si_from->get_realpath(), name, global_si->get_realpath());
if (!global_si->find_symbol_by_name(symbol_name, vi, &s)) {
error = true;
return false;
@@ -762,7 +761,7 @@
}
DEBUG("%s: looking up %s in %s (from local group)",
- si_from->get_soname(), name, local_si->get_soname());
+ si_from->get_realpath(), name, local_si->get_realpath());
if (!local_si->find_symbol_by_name(symbol_name, vi, &s)) {
error = true;
return false;
@@ -784,8 +783,8 @@
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_soname(), name, reinterpret_cast<void*>(s->st_value),
- (*si_found_in)->get_soname(), reinterpret_cast<void*>((*si_found_in)->base),
+ si_from->get_realpath(), name, reinterpret_cast<void*>(s->st_value),
+ (*si_found_in)->get_realpath(), reinterpret_cast<void*>((*si_found_in)->base),
reinterpret_cast<void*>((*si_found_in)->load_bias));
}
@@ -933,13 +932,17 @@
}
-// 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) {
+static const ElfW(Sym)* dlsym_handle_lookup(soinfo* root, soinfo* skip_until,
+ soinfo** found, SymbolName& symbol_name) {
const ElfW(Sym)* result = nullptr;
- SymbolName symbol_name(name);
+ bool skip_lookup = skip_until != nullptr;
- walk_dependencies_tree(&si, 1, [&](soinfo* current_soinfo) {
+ walk_dependencies_tree(&root, 1, [&](soinfo* current_soinfo) {
+ if (skip_lookup) {
+ skip_lookup = current_soinfo != skip_until;
+ return true;
+ }
+
if (!current_soinfo->find_symbol_by_name(symbol_name, nullptr, &result)) {
result = nullptr;
return false;
@@ -956,6 +959,13 @@
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
@@ -993,31 +1003,13 @@
}
}
- // If not found - look into local_group unless
- // caller is part of the global group in which
+ // If not found - use dlsym_handle_lookup for caller's
+ // local_group unless it 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) {
- 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;
- }
- }
+ return dlsym_handle_lookup(caller->get_local_group_root(),
+ (handle == RTLD_NEXT) ? caller : nullptr, found, symbol_name);
}
if (s != nullptr) {
@@ -1232,29 +1224,10 @@
}
}
-static soinfo* load_library(LoadTaskList& load_tasks,
+static soinfo* load_library(int fd, off64_t file_offset,
+ 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;
@@ -1330,6 +1303,29 @@
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) {
@@ -1513,7 +1509,7 @@
}
if (!root->can_unload()) {
- TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_soname());
+ TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_realpath());
return;
}
@@ -1536,7 +1532,9 @@
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_soname(), si, child->get_soname(), child);
+ TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
+ child->get_realpath(), child);
+
if (local_unload_list.contains(child)) {
continue;
} else if (child->is_linked() && child->get_local_group_root() != root) {
@@ -1546,20 +1544,20 @@
}
}
} else {
-#if !defined(__arm__)
- __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_soname(), si);
+#if !defined(__work_around_b_19059885__)
+ __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
#else
- PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_soname(), si);
+ PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
for_each_dt_needed(si, [&] (const char* library_name) {
TRACE("deprecated (old format of soinfo): %s needs to unload %s",
- si->get_soname(), library_name);
+ si->get_realpath(), 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_soname());
+ library_name, si->get_realpath());
return;
} else if (local_unload_list.contains(needed)) {
// already visited
@@ -1589,7 +1587,8 @@
soinfo_unload(si);
}
} else {
- TRACE("not unloading '%s' group, decrementing ref_count to %zd", root->get_soname(), ref_count);
+ TRACE("not unloading '%s' group, decrementing ref_count to %zd",
+ root->get_realpath(), ref_count);
}
}
@@ -1701,12 +1700,12 @@
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 strcmp(si->get_soname(), target_soname) == 0;
+ return si->get_soname() != nullptr && 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_soname());
+ target_soname, i, si_from->get_realpath());
return false;
}
@@ -1743,6 +1742,27 @@
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) {
@@ -1759,14 +1779,8 @@
#endif
template<typename ElfRelIteratorT>
-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;
- }
-
+bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
+ const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
const auto rel = rel_iterator.next();
if (rel == nullptr) {
@@ -1781,7 +1795,7 @@
const char* sym_name = nullptr;
ElfW(Addr) addend = get_addend(rel, reloc);
- DEBUG("Processing '%s' relocation at index %zd", get_soname(), idx);
+ DEBUG("Processing '%s' relocation at index %zd", get_realpath(), idx);
if (type == R_GENERIC_NONE) {
continue;
}
@@ -1791,32 +1805,21 @@
if (sym != 0) {
sym_name = get_string(symtab_[sym].st_name);
- const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
- ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
+ const version_info* vi = nullptr;
- 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 (!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;
+ }
+
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_soname());
+ DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_realpath());
return false;
}
@@ -2012,7 +2015,7 @@
* 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_soname());
+ DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
return false;
case R_AARCH64_TLS_TPREL64:
TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n",
@@ -2069,7 +2072,7 @@
* 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_soname());
+ DL_ERR("%s R_ARM_COPY relocations are not supported", get_realpath());
return false;
#elif defined(__i386__)
case R_386_32:
@@ -2101,7 +2104,7 @@
return;
}
- TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_soname());
+ TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_realpath());
int begin = reverse ? (count - 1) : 0;
int end = reverse ? -1 : count;
@@ -2112,7 +2115,7 @@
call_function("function", functions[i]);
}
- TRACE("[ Done calling %s for '%s' ]", array_name, get_soname());
+ TRACE("[ Done calling %s for '%s' ]", array_name, get_realpath());
}
void soinfo::call_function(const char* function_name __unused, linker_function_t function) {
@@ -2120,9 +2123,9 @@
return;
}
- TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_soname());
+ TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_realpath());
function();
- TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_soname());
+ TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_realpath());
}
void soinfo::call_pre_init_constructors() {
@@ -2151,14 +2154,14 @@
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_soname(), preinit_array_count_);
+ get_realpath(), preinit_array_count_);
}
get_children().for_each([] (soinfo* si) {
si->call_constructors();
});
- TRACE("\"%s\": calling constructors", get_soname());
+ TRACE("\"%s\": calling constructors", get_realpath());
// DT_INIT should be called before DT_INIT_ARRAY if both are present.
call_function("DT_INIT", init_func_);
@@ -2169,7 +2172,7 @@
if (!constructors_called) {
return;
}
- TRACE("\"%s\": calling destructors", get_soname());
+ TRACE("\"%s\": calling destructors", get_realpath());
// DT_FINI_ARRAY must be parsed in reverse order.
call_array("DT_FINI_ARRAY", fini_array_, fini_array_count_, true);
@@ -2267,7 +2270,7 @@
}
const char* soinfo::get_realpath() const {
-#if defined(__arm__)
+#if defined(__work_around_b_19059885__)
if (has_min_version(2)) {
return realpath_.c_str();
} else {
@@ -2279,7 +2282,7 @@
}
const char* soinfo::get_soname() const {
-#if defined(__arm__)
+#if defined(__work_around_b_19059885__)
if (has_min_version(2)) {
return soname_;
} else {
@@ -2329,7 +2332,7 @@
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_soname(), strtab_size_, index);
+ get_realpath(), strtab_size_, index);
}
return strtab_ + index;
@@ -2426,8 +2429,7 @@
/* 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);
- status = TEMP_FAILURE_RETRY(close(dev_null));
- if (status == -1) {
+ if (close(dev_null) == -1) {
DL_ERR("close failed: %s", strerror(errno));
return_value = -1;
}
@@ -2444,13 +2446,13 @@
/* We can't log anything until the linker is relocated */
bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
if (!relocating_linker) {
- INFO("[ linking %s ]", get_soname());
+ INFO("[ linking %s ]", get_realpath());
DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
}
if (dynamic == nullptr) {
if (!relocating_linker) {
- DL_ERR("missing PT_DYNAMIC in \"%s\"", get_soname());
+ DL_ERR("missing PT_DYNAMIC in \"%s\"", get_realpath());
}
return false;
} else {
@@ -2817,7 +2819,7 @@
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(__arm__)
+#if defined(__work_around_b_19059885__)
strlcpy(old_name_, soname_, sizeof(old_name_));
#endif
break;
@@ -2834,15 +2836,15 @@
}
if (nbucket_ == 0 && gnu_nbucket_ == 0) {
DL_ERR("empty/missing DT_HASH/DT_GNU_HASH in \"%s\" "
- "(new hash type from the future?)", get_soname());
+ "(new hash type from the future?)", get_realpath());
return false;
}
if (strtab_ == 0) {
- DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_soname());
+ DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_realpath());
return false;
}
if (symtab_ == 0) {
- DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_soname());
+ DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_realpath());
return false;
}
return true;
@@ -2856,15 +2858,21 @@
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_soname());
+ "security hardening. Please fix.", get_realpath());
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
DL_ERR("can't unprotect loadable segments for \"%s\": %s",
- get_soname(), strerror(errno));
+ get_realpath(), strerror(errno));
return false;
}
}
@@ -2877,13 +2885,14 @@
android_relocs_[1] == 'P' &&
android_relocs_[2] == 'S' &&
android_relocs_[3] == '2') {
- DEBUG("[ android relocating %s ]", get_soname());
+ DEBUG("[ android relocating %s ]", get_realpath());
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);
@@ -2899,46 +2908,50 @@
#if defined(USE_RELA)
if (rela_ != nullptr) {
- DEBUG("[ relocating %s ]", get_soname());
- if (!relocate(plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
+ DEBUG("[ relocating %s ]", get_realpath());
+ if (!relocate(version_tracker,
+ plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
return false;
}
}
if (plt_rela_ != nullptr) {
- DEBUG("[ relocating %s plt ]", get_soname());
- if (!relocate(plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
+ DEBUG("[ relocating %s plt ]", get_realpath());
+ if (!relocate(version_tracker,
+ plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
return false;
}
}
#else
if (rel_ != nullptr) {
- DEBUG("[ relocating %s ]", get_soname());
- if (!relocate(plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
+ DEBUG("[ relocating %s ]", get_realpath());
+ if (!relocate(version_tracker,
+ plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
return false;
}
}
if (plt_rel_ != nullptr) {
- DEBUG("[ relocating %s plt ]", get_soname());
- if (!relocate(plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
+ DEBUG("[ relocating %s plt ]", get_realpath());
+ if (!relocate(version_tracker,
+ plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
return false;
}
}
#endif
#if defined(__mips__)
- if (!mips_relocate_got(global_group, local_group)) {
+ if (!mips_relocate_got(version_tracker, global_group, local_group)) {
return false;
}
#endif
- DEBUG("[ finished linking %s ]", get_soname());
+ DEBUG("[ finished linking %s ]", get_realpath());
#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_soname(), strerror(errno));
+ get_realpath(), strerror(errno));
return false;
}
}
@@ -2947,7 +2960,7 @@
/* 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_soname(), strerror(errno));
+ get_realpath(), strerror(errno));
return false;
}
@@ -2956,14 +2969,14 @@
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_soname(), strerror(errno));
+ get_realpath(), 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_soname(), strerror(errno));
+ get_realpath(), strerror(errno));
return false;
}
}
@@ -3037,6 +3050,8 @@
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,6 +3066,9 @@
// 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()) {
@@ -3150,6 +3168,7 @@
for (const auto& ld_preload_name : g_ld_preload_names) {
needed_library_name_list.push_back(ld_preload_name.c_str());
++needed_libraries_count;
+ ++ld_preloads_count;
}
for_each_dt_needed(si, [&](const char* name) {
@@ -3232,7 +3251,7 @@
fflush(stdout);
#endif
- TRACE("[ Ready to execute '%s' @ %p ]", si->get_soname(), reinterpret_cast<void*>(si->entry));
+ TRACE("[ Ready to execute '%s' @ %p ]", si->get_realpath(), reinterpret_cast<void*>(si->entry));
return si->entry;
}
@@ -3248,7 +3267,8 @@
*/
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++) {
diff --git a/linker/linker.h b/linker/linker.h
index dae3972..c7118ea 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -97,7 +97,7 @@
#define SOINFO_VERSION 2
-#if defined(__arm__)
+#if defined(__work_around_b_19059885__)
#define SOINFO_NAME_LEN 128
#endif
@@ -172,7 +172,7 @@
struct soinfo {
public:
typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
-#if defined(__arm__)
+#if defined(__work_around_b_19059885__)
private:
char old_name_[SOINFO_NAME_LEN];
#endif
@@ -183,13 +183,13 @@
ElfW(Addr) base;
size_t size;
-#if defined(__arm__)
+#if defined(__work_around_b_19059885__)
uint32_t unused1; // DO NOT USE, maintained for compatibility.
#endif
ElfW(Dyn)* dynamic;
-#if defined(__arm__)
+#if defined(__work_around_b_19059885__)
uint32_t unused2; // DO NOT USE, maintained for compatibility
uint32_t unused3; // DO NOT USE, maintained for compatibility
#endif
@@ -247,7 +247,9 @@
uint32_t mips_symtabno_;
uint32_t mips_local_gotno_;
uint32_t mips_gotsym_;
- bool mips_relocate_got(const soinfo_list_t& global_group, const soinfo_list_t& local_group);
+ bool mips_relocate_got(const VersionTracker& version_tracker,
+ const soinfo_list_t& global_group,
+ const soinfo_list_t& local_group);
#endif
size_t ref_count_;
@@ -303,7 +305,7 @@
bool is_gnu_hash() const;
bool inline has_min_version(uint32_t min_version __unused) const {
-#if defined(__arm__)
+#if defined(__work_around_b_19059885__)
return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
#else
return true;
@@ -338,11 +340,14 @@
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(ElfRelIteratorT&& rel_iterator, const soinfo_list_t& global_group,
- const soinfo_list_t& local_group);
+ bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
+ const soinfo_list_t& global_group, const soinfo_list_t& local_group);
private:
// This part of the structure is only available
diff --git a/linker/linker_debug.h b/linker/linker_debug.h
index 5ded5ab..51f8d4c 100644
--- a/linker/linker_debug.h
+++ b/linker/linker_debug.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/linker/linker_environ.cpp b/linker/linker_environ.cpp
index 9a0f009..3c466a2 100644
--- a/linker/linker_environ.cpp
+++ b/linker/linker_environ.cpp
@@ -36,7 +36,6 @@
#include "private/KernelArgumentBlock.h"
-static char** _envp;
static bool _AT_SECURE_value = true;
bool get_AT_SECURE() {
@@ -150,8 +149,8 @@
}
static void __sanitize_environment_variables() {
- char** src = _envp;
- char** dst = _envp;
+ char** src = environ;
+ char** dst = environ;
for (; src[0] != nullptr; ++src) {
if (!__is_valid_environment_variable(src[0])) {
continue;
@@ -168,7 +167,7 @@
void linker_env_init(KernelArgumentBlock& args) {
// Store environment pointer - can't be null.
- _envp = args.envp;
+ environ = args.envp;
__init_AT_SECURE(args);
__sanitize_environment_variables();
@@ -179,7 +178,7 @@
return nullptr;
}
- for (char** p = _envp; p[0] != nullptr; ++p) {
+ for (char** p = environ; p[0] != nullptr; ++p) {
const char* val = env_match(p[0], name);
if (val != nullptr) {
if (val[0] == '\0') {
diff --git a/linker/linker_mips.cpp b/linker/linker_mips.cpp
index 0769f82..a7a4bc0 100644
--- a/linker/linker_mips.cpp
+++ b/linker/linker_mips.cpp
@@ -32,25 +32,22 @@
#include "linker_reloc_iterators.h"
#include "linker_sleb128.h"
-template bool soinfo::relocate<plain_reloc_iterator>(plain_reloc_iterator&& rel_iterator,
+template bool soinfo::relocate<plain_reloc_iterator>(const VersionTracker& version_tracker,
+ 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(ElfRelIteratorT&& rel_iterator,
+bool soinfo::relocate(const VersionTracker& version_tracker,
+ 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();
@@ -75,26 +72,14 @@
if (sym != 0) {
sym_name = get_string(symtab_[sym].st_name);
- const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
- ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
+ const version_info* vi = nullptr;
- 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 (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
+ 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 (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
+ return false;
}
if (s == nullptr) {
@@ -128,7 +113,7 @@
if (s != nullptr) {
*reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
} else {
- *reinterpret_cast<ElfW(Addr)*>(reloc) += base;
+ *reinterpret_cast<ElfW(Addr)*>(reloc) += load_bias;
}
break;
default:
@@ -139,7 +124,8 @@
return true;
}
-bool soinfo::mips_relocate_got(const soinfo_list_t& global_group,
+bool soinfo::mips_relocate_got(const VersionTracker& version_tracker,
+ const soinfo_list_t& global_group,
const soinfo_list_t& local_group) {
ElfW(Addr)** got = plt_got_;
if (got == nullptr) {
@@ -163,22 +149,42 @@
}
// Now for the global GOT entries...
- ElfW(Sym)* sym = symtab_ + mips_gotsym_;
got = plt_got_ + mips_local_gotno_;
- for (size_t g = mips_gotsym_; g < mips_symtabno_; g++, sym++, got++) {
+ for (ElfW(Word) sym = mips_gotsym_; sym < mips_symtabno_; sym++, got++) {
// This is an undefined reference... try to locate it.
- const char* sym_name = get_string(sym->st_name);
+ const ElfW(Sym)* local_sym = symtab_ + sym;
+ const char* sym_name = get_string(local_sym->st_name);
soinfo* lsi = nullptr;
const ElfW(Sym)* s = nullptr;
- if (!soinfo_do_lookup(this, sym_name, nullptr, &lsi, global_group, local_group, &s)) {
+
+ 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);
return false;
}
if (s == nullptr) {
// We only allow an undefined symbol if this is a weak reference.
- s = &symtab_[g];
- if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
- DL_ERR("cannot locate \"%s\"...", sym_name);
+ if (ELF_ST_BIND(local_sym->st_info) != STB_WEAK) {
+ DL_ERR("%s: cannot locate \"%s\"...", get_soname(), sym_name);
return false;
}
*got = 0;
diff --git a/tests/Android.mk b/tests/Android.mk
index cd65c10..14f0d32 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -269,6 +269,7 @@
dlext_test.cpp \
__cxa_thread_atexit_test.cpp \
dlfcn_test.cpp \
+ pthread_dlfcn_test.cpp \
bionic-unit-tests_cflags := $(test_cflags)
@@ -346,6 +347,7 @@
atexit_test.cpp \
dlfcn_test.cpp \
dl_test.cpp \
+ pthread_dlfcn_test.cpp \
bionic-unit-tests-glibc_shared_libraries := \
libdl_preempt_test_1 \
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 6b1f109..a5abda7 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -71,23 +71,80 @@
void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_LAZY | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
- // check that we cant find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
+ // 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 fn = reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
+ 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();
- ASSERT_TRUE(fn != nullptr) << dlerror();
-
- int* ptr = fn();
+ 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);
}
+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);
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index c432c2e..15fa55c 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -355,10 +355,7 @@
# -----------------------------------------------------------------------------
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
@@ -385,11 +382,26 @@
# -----------------------------------------------------------------------------
# Library to check RTLD_LOCAL with dlsym in 'this'
# -----------------------------------------------------------------------------
-libtest_dlsym_from_this_src_files := dlsym_from_this.cpp
+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
module := libtest_dlsym_from_this
-libtest_dlsym_from_this_shared_libraries_target := libdl
+include $(LOCAL_PATH)/Android.build.testlib.mk
+# -----------------------------------------------------------------------------
+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
# -----------------------------------------------------------------------------
diff --git a/tests/libs/dlsym_from_this_functions.cpp b/tests/libs/dlsym_from_this_functions.cpp
new file mode 100644
index 0000000..1f357e0
--- /dev/null
+++ b/tests/libs/dlsym_from_this_functions.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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;
+}
+
diff --git a/tests/libs/dlsym_from_this.cpp b/tests/libs/dlsym_from_this_symbol.cpp
similarity index 60%
rename from tests/libs/dlsym_from_this.cpp
rename to tests/libs/dlsym_from_this_symbol.cpp
index b5215c9..c3ec255 100644
--- a/tests/libs/dlsym_from_this.cpp
+++ b/tests/libs/dlsym_from_this_symbol.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -13,18 +13,5 @@
* 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;
-}
-
diff --git a/tests/libs/dlsym_from_this_symbol2.cpp b/tests/libs/dlsym_from_this_symbol2.cpp
new file mode 100644
index 0000000..20da1d5
--- /dev/null
+++ b/tests/libs/dlsym_from_this_symbol2.cpp
@@ -0,0 +1,18 @@
+/*
+ * 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;
diff --git a/tests/pthread_dlfcn_test.cpp b/tests/pthread_dlfcn_test.cpp
new file mode 100644
index 0000000..5e8b206
--- /dev/null
+++ b/tests/pthread_dlfcn_test.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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));
+}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index cb5e818..201b8a9 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -16,7 +16,6 @@
#include <gtest/gtest.h>
-#include <dlfcn.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
@@ -459,42 +458,6 @@
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;
@@ -1019,62 +982,6 @@
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));
diff --git a/tools/relocation_packer/src/elf_file.cc b/tools/relocation_packer/src/elf_file.cc
index c8ddde6..102d614 100644
--- a/tools/relocation_packer/src/elf_file.cc
+++ b/tools/relocation_packer/src/elf_file.cc
@@ -37,11 +37,13 @@
static constexpr uint32_t SHT_ANDROID_REL = SHT_LOOS + 1;
static constexpr uint32_t SHT_ANDROID_RELA = SHT_LOOS + 2;
+static const size_t kPageSize = 4096;
+
// Alignment to preserve, in bytes. This must be at least as large as the
// largest d_align and sh_addralign values found in the loaded file.
// Out of caution for RELRO page alignment, we preserve to a complete target
// page. See http://www.airs.com/blog/archives/189.
-static constexpr size_t kPreserveAlignment = 4096;
+static const size_t kPreserveAlignment = kPageSize;
// Get section data. Checks that the section has exactly one data entry,
// so that the section size and the data size are the same. True in
@@ -310,6 +312,13 @@
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;
@@ -318,9 +327,13 @@
} else {
program_header->p_vaddr -= hole_size;
program_header->p_paddr -= hole_size;
+ 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;
+ << "; p_paddr adjusted to "<< program_header->p_paddr
+ << "; p_align adjusted to "<< program_header->p_align;
}
}
}
@@ -466,6 +479,16 @@
<< " 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.
diff --git a/tools/relocation_packer/src/elf_traits.h b/tools/relocation_packer/src/elf_traits.h
index 41b06c8..1c938fa 100644
--- a/tools/relocation_packer/src/elf_traits.h
+++ b/tools/relocation_packer/src/elf_traits.h
@@ -10,6 +10,10 @@
#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.
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
index a2b0039..ed85ce1 100755
--- a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
Binary files differ