Compare commits

..

50 Commits

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

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

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

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

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

Change-Id: I918a2fa5fb3104f4c2d86930ed2b9c5e00820ec6
2015-05-07 15:51:37 -07:00
Colin Cross
faa14d4de8 Merge "Fix Blueprints for building on Darwin" into master-soong 2015-05-07 21:31:49 +00:00
Colin Cross
abc97e2e71 Fix Blueprints for building on Darwin
Change-Id: I252e1b8a9ace397609f056f69aff83331b92aab7
2015-05-05 16:52:38 -07:00
Colin Cross
6549fe249c Update Blueprints files for AOSP changes
Change-Id: I915fc1e00b6e6eb1d6c08233893517b1d56c74fa
2015-04-29 11:34:24 -07:00
Colin Cross
c15e8fdb8d Merge remote-tracking branch 'aosp/master' into aosp 2015-04-29 11:29:05 -07:00
Neil Fuller
fa6f649607 Merge "Update to tzdata 2015d" 2015-04-29 10:42:16 +00:00
Dmitriy Ivanov
e1a61f5e93 Merge "Fix LD_PRELOAD for dlopen()" 2015-04-29 01:59:53 +00:00
Jeff Brown
0bf650373e Merge "Add float support to binary event log." 2015-04-29 01:42:49 +00:00
Jeff Brown
11331f60dd Add float support to binary event log.
Bug: 20664753
Change-Id: I6e43c07daa727c19d87f5192bb719af63dd93654
2015-04-28 18:20:22 -07:00
Dmitriy Ivanov
f8093a9485 Fix LD_PRELOAD for dlopen()
We did not set DF_1_GLOBAL flag for LD_PRELOADed
 libraries which led to the situation when ld_preloads
 where ignored during on dlopen()

Change-Id: I696b3b2506a8ed4c0984ad2c803210a7a4f8e686
2015-04-28 18:09:53 -07:00
Mark Salyzyn
b904afa16e Merge "bionic: add __system_property_area_serial()" 2015-04-28 22:11:52 +00:00
Dmitriy Ivanov
9f0d99d298 Merge "Do not pack relocations for libc.so" 2015-04-28 22:06:43 +00:00
Dmitriy Ivanov
62d6533c1a Do not pack relocations for libc.so
Bug: http://b/20645321
Bug: http://b/20655855
(cherry picked from commit 452742d2bf)

Change-Id: Ic9125cc1bc4c9ba9eb20d030de72e3ce1fb86fa6
2015-04-28 15:05:20 -07:00
Dmitriy Ivanov
bed7a7e5eb Merge "linker: use libc's environ variable to store envp" 2015-04-28 21:35:59 +00:00
Dmitriy Ivanov
a85bcc2e99 linker: use libc's environ variable to store envp
This is to make getenv() work correctly.

Bug: http://b/20567629
Change-Id: I148627e1efea1649fb0822c95876811652fb4082
2015-04-28 14:21:36 -07:00
Christopher Ferris
6fa65e7cd5 Merge "cortex-a9: Fix reference to __memcpy_base_aligned." 2015-04-28 20:28:42 +00:00
Kyle Repinski
e0905c94d3 cortex-a9: Fix reference to __memcpy_base_aligned.
With a different memcpy, __memcpy_base_aligned ceased to exist.
Instead, point to the name defined by whatever includes memcpy_base.S

Change-Id: I242cf49cbada35337ba155d7f170e86a905ff55f
2015-04-28 14:29:15 -05:00
Neil Fuller
520cbf51b1 Update to tzdata 2015d
Changes affecting future time stamps

    Egypt will not observe DST in 2015 and will consider canceling it
    permanently.  For now, assume no DST indefinitely.
    (Thanks to Ahmed Nazmy and Tim Parenti.)

  Changes affecting past time stamps

    America/Whitehorse switched from UTC-9 to UTC-8 on 1967-05-28, not
    1966-07-01.  Also, Yukon's time zone history is documented better.
    (Thanks to Brian Inglis and Dennis Ferguson.)

  Change affecting past and future time zone abbreviations

    The abbreviations for Hawaii-Aleutian standard and daylight times
    have been changed from HAST/HADT to HST/HDT, as per US Government
    Printing Office style.  This affects only America/Adak since 1983,
    as America/Honolulu was already using the new style.

Bug: 20551453
Change-Id: I02364f15ca4ae20ed1a3b327f8517214bee938e5
2015-04-28 17:11:03 +01:00
Dmitriy Ivanov
42d7468f99 Merge "Reduce p_align for program header to page size." 2015-04-28 03:38:27 +00:00
Dmitriy Ivanov
b293969c6d Reduce p_align for program header to page size.
Having p_align > page_size leads to the situation when striping
 packed executables results in unnecessary p_vaddr adjustments.
 And it also may result (with probability 1 - 1/sizeof(uintptr_t)) in
 misaligned segments following .dynstr

Bug: http://b/20629834
Bug: http://b/18051137
Change-Id: I1c5da4911e4409d63cb09f6b6b0a16ef54f6501b
2015-04-27 20:37:17 -07:00
Dmitriy Ivanov
032907d8c7 Merge "Remove outdated warning" 2015-04-27 18:28:31 +00:00
Dmitriy Ivanov
2ea504fed1 Remove outdated warning
It is ok to use malloc in linker.

Bug: http://b/20567629
Change-Id: I54183dbe8ebcd223a44e710e511c339688a65dba
2015-04-27 11:24:36 -07:00
Chih-Hung Hsieh
59bce688c7 Merge "Fix opcode to compile with both gcc and llvm." 2015-04-27 17:17:45 +00:00
Mark Salyzyn
bfd65279a5 bionic: add __system_property_area_serial()
Adds a new _internal_ function. Provide a global serial number to
support more efficient private caching algorithms. This allows
to skip re-running the __system_property_find() call on misses until
there is a global change in the properties. This call is a read
barrier, the property data to be read following this call will be
read sequentially and up to date.

Bug: 19544788
Change-Id: I58e6a92baa0f3e8e7b9ec79b10af6d56407dab48
2015-04-27 07:44:03 -07:00
Neil Fuller
682a240c5d Merge "Update to tzdata 2015c" 2015-04-27 08:19:16 +00:00
Neil Fuller
d2177404e2 Update to tzdata 2015c
Changes affecting future time stamps

    Egypt's spring-forward transition is at 24:00 on April's last Thursday,
    not 00:00 on April's last Friday.  2015's transition will therefore be on
    Thursday, April 30 at 24:00, not Friday, April 24 at 00:00.  Similar fixes
    apply to 2026, 2037, 2043, etc.  (Thanks to Steffen Thorsen.)

  Changes affecting past time stamps

    The following changes affect some pre-1991 Chile-related time stamps
    in America/Santiago, Antarctica/Palmer, and Pacific/Easter.

      The 1910 transition was January 10, not January 1.

      The 1918 transition was September 10, not September 1.

      The UTC-4 time observed from 1932 to 1942 is now considered to be
      standard time, not year-round DST.

      Santiago observed DST (UTC-3) from 1946-07-15 through 1946-08-31,
      then reverted to standard time, then switched its time zone to
      UTC-5 on 1947-04-01.

      Assume transitions before 1968 were at 00:00, since we have no data
      saying otherwise.

      The spring 1988 transition was 1988-10-09, not 1988-10-02.
      The fall 1990 transition was 1990-03-11, not 1990-03-18.

      Assume no UTC offset change for Pacific/Easter on 1890-01-01,
      and omit all transitions on Pacific/Easter from 1942 through 1946
      since we have no data suggesting that they existed.

    One more zone has been turned into a link, as it differed
    from an existing zone only for older time stamps.  As usual,
    this change affects UTC offsets in pre-1970 time stamps only.
    The zone's old contents have been moved to the 'backzone' file.
    The affected zone is America/Montreal.

Bug: 20287125
Change-Id: I8512c4e9ab09725395b256aba59ca34a23d1c995
2015-04-24 13:56:11 +01:00
Chih-Hung Hsieh
0a93df369c Fix opcode to compile with both gcc and llvm.
BUG: 17302991

Change-Id: I31febd9ad24312388068803ce247b295bd73b607
2015-04-23 21:40:31 +00:00
Colin Cross
90d6279802 Merge "Add Blueprints files for remaining bionic modules" into master-soong 2015-03-28 01:15:36 +00:00
Colin Cross
22d8776587 Add Blueprints files for remaining bionic modules
Change-Id: Ic9440fddb44ca1f17aad5b249535d7b96dd8d690
2015-03-27 11:14:39 -07:00
Colin Cross
51b8912253 Merge "Merge remote-tracking branch 'aosp/master' into HEAD" into master-soong 2015-03-17 19:31:44 +00:00
Colin Cross
270f2ea800 Merge remote-tracking branch 'aosp/master' into HEAD
Change-Id: Ia313444a62bcdeb676185b56ce730d0f997c8226
2015-03-17 12:30:41 -07:00
Colin Cross
7357ad0875 Merge "Update bionic Blueprints to match latest AOSP master" into master-soong 2015-03-17 00:44:29 +00:00
Colin Cross
959bc099a3 Merge remote-tracking branch 'aosp/master' into HEAD 2015-03-16 16:54:58 -07:00
Colin Cross
68a3b658b1 Update bionic Blueprints to match latest AOSP master
Change-Id: I90410ec60acfc3dcbdbcd0be6f283a90f4395643
2015-03-16 16:31:26 -07:00
Colin Cross
062d498e28 Merge "Initial bionic Blueprints files" into master-soong 2015-03-14 06:41:45 +00:00
Colin Cross
d2b8741e1b Initial bionic Blueprints files
Change-Id: Iafe8e84e0dc62e7d7c830e2c272ec92abdf6a801
2015-03-10 14:11:55 -07:00
162 changed files with 6223 additions and 5964 deletions

1
Android.bp Normal file
View File

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

123
benchmarks/Android.bp Normal file
View File

@@ -0,0 +1,123 @@
//
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// Benchmarks library, usable by projects outside this directory.
// -----------------------------------------------------------------------------
benchmark_cflags = [
"-O2",
"-fno-builtin",
"-Wall",
"-Wextra",
"-Werror",
"-Wunused",
]
benchmark_cppflags = ["-std=gnu++11"]
benchmarklib_src_files = [
"Benchmark.cpp",
"utils.cpp",
"main.cpp",
]
cc_library_static {
name: "libbenchmark",
host_supported: true,
cflags: benchmark_cflags,
cppflags: benchmark_cppflags,
srcs: benchmarklib_src_files,
static_libs: ["libbase"],
export_include_dirs: ["."],
target: {
darwin: {
// Only supported on linux systems.
disabled: true,
},
},
}
// -----------------------------------------------------------------------------
// Benchmarks.
// -----------------------------------------------------------------------------
benchmark_src_files = [
"math_benchmark.cpp",
"property_benchmark.cpp",
"pthread_benchmark.cpp",
"semaphore_benchmark.cpp",
"stdio_benchmark.cpp",
"string_benchmark.cpp",
"time_benchmark.cpp",
"unistd_benchmark.cpp",
]
// Build benchmarks for the device (with bionic's .so). Run with:
// adb shell bionic-benchmarks32
// adb shell bionic-benchmarks64
cc_binary {
name: "bionic-benchmarks",
multilib: {
lib32: {
suffix: "32",
},
lib64: {
suffix: "64",
},
},
compile_multilib: "both",
cflags: benchmark_cflags,
cppflags: benchmark_cppflags,
srcs: benchmark_src_files,
static_libs: [
"libbenchmark",
"libbase",
],
}
// We don't build a static benchmark executable because it's not usually
// useful. If you're trying to run the current benchmarks on an older
// release, it's (so far at least) always because you want to measure the
// performance of the old release's libc, and a static benchmark isn't
// going to let you do that.
// Build benchmarks for the host (against glibc!). Run with:
cc_binary_host {
name: "bionic-benchmarks-glibc",
multilib: {
lib32: {
stem: "bionic-benchmarks-glibc32",
},
lib64: {
stem: "bionic-benchmarks-glibc64",
},
},
compile_multilib: "both",
cflags: benchmark_cflags,
cppflags: benchmark_cppflags,
ldflags: ["-lrt"],
srcs: benchmark_src_files,
static_libs: [
"libbenchmark",
"libbase",
],
target: {
darwin: {
// Only supported on linux systems.
disabled: true,
},
},
}

2261
libc/Android.bp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -129,11 +129,8 @@ libc_bionic_ndk_src_files := \
bionic/fchmod.cpp \
bionic/fchmodat.cpp \
bionic/ffs.cpp \
bionic/fgetxattr.cpp \
bionic/flockfile.cpp \
bionic/fpclassify.cpp \
bionic/fsetxattr.cpp \
bionic/ftruncate.cpp \
bionic/futimens.cpp \
bionic/getcwd.cpp \
bionic/gethostname.cpp \
@@ -309,7 +306,6 @@ libc_upstream_netbsd_src_files := \
upstream-netbsd/lib/libc/stdlib/nrand48.c \
upstream-netbsd/lib/libc/stdlib/_rand48.c \
upstream-netbsd/lib/libc/stdlib/rand_r.c \
upstream-netbsd/lib/libc/stdlib/reallocarr.c \
upstream-netbsd/lib/libc/stdlib/seed48.c \
upstream-netbsd/lib/libc/stdlib/srand48.c \
upstream-netbsd/lib/libc/string/memccpy.c \
@@ -550,16 +546,14 @@ libc_thread_atexit_impl_src_files := \
libc_arch_static_src_files := \
bionic/dl_iterate_phdr_static.cpp \
# Various kinds of cruft.
# Various kinds of LP32 cruft.
# ========================================================
libc_common_src_files += \
bionic/ndk_cruft.cpp \
libc_bionic_ndk_src_files_32 += \
libc_bionic_src_files_32 += \
bionic/mmap.cpp \
libc_common_src_files_32 += \
bionic/legacy_32_bit_support.cpp \
bionic/ndk_cruft.cpp \
bionic/time64.c \
libc_netbsd_src_files_32 += \
@@ -947,6 +941,10 @@ LOCAL_SRC_FILES := $(libc_bionic_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
@@ -959,7 +957,6 @@ LOCAL_ADDRESS_SANITIZER := false
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_src_files))
include $(BUILD_STATIC_LIBRARY)
@@ -975,6 +972,10 @@ LOCAL_SRC_FILES := $(libc_bionic_ndk_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
@@ -987,7 +988,7 @@ LOCAL_ADDRESS_SANITIZER := false
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_ndk_src_files))
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_src_files))
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
@@ -1023,6 +1024,10 @@ LOCAL_SRC_FILES := $(libc_pthread_src_files)
LOCAL_CFLAGS := $(libc_common_cflags) \
-Wframe-larger-than=2048 \
# memcpy.S, memchr.S, etc. do not compile with Clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
LOCAL_C_INCLUDES := $(libc_common_c_includes)
@@ -1341,7 +1346,7 @@ LOCAL_CLANG := $(use_clang)
LOCAL_REQUIRED_MODULES := tzdata
LOCAL_ADDITIONAL_DEPENDENCIES := \
$(libc_common_additional_dependencies) \
$(LOCAL_PATH)/libc.map \
$(LOCAL_PATH)/version_script.txt \
# Leave the symbols in the shared library so that stack unwinders can produce
# meaningful name resolution.
@@ -1369,16 +1374,16 @@ LOCAL_CXX_STL := none
LOCAL_SYSTEM_SHARED_LIBRARIES :=
# Don't re-export new/delete and friends, even if the compiler really wants to.
LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/libc.map
LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/version_script.txt
# We'd really like to do this for all architectures, but since this wasn't done
# before, these symbols must continue to be exported on LP32 for binary
# compatibility.
LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
# TODO: disabled for http://b/20065774.
#LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
# TODO: This is to work around b/19059885. Remove after root cause is fixed
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_dynamic_src_files))
@@ -1508,8 +1513,7 @@ LOCAL_CFLAGS := $(libc_common_cflags)
LOCAL_CPPFLAGS := $(libc_common_cppflags)
# TODO: This is to work around b/19059885. Remove after root cause is fixed
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
LOCAL_MODULE:= libstdc++

View File

@@ -307,6 +307,34 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2008-2010 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -426,6 +454,22 @@ Android adaptation and tweak by Jim Huang <jserv@0xlab.org>.
-------------------------------------------------------------------
Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------
Copyright (C) 2011 The Android Open Source Project
All rights reserved.
@@ -644,50 +688,6 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------
Copyright (C) 2015 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 1980, 1983, 1988, 1993
The Regents of the University of California. All rights reserved.
@@ -2550,6 +2550,33 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (c) 1995, 1996 Carnegie-Mellon University.
All rights reserved.
Author: Chris G. Demetriou
Permission to use, copy, modify and distribute this software and
its documentation is hereby granted, provided that both the copyright
notice and this permission notice appear in all copies of the
software, derivative works or modified versions, and any portions
thereof, and that both notices appear in supporting documentation.
CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
Carnegie Mellon requests users of this software to return to
Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
School of Computer Science
Carnegie Mellon University
Pittsburgh PA 15213-3890
any improvements or extensions that they make and grant Carnegie the
rights to redistribute these changes.
-------------------------------------------------------------------
Copyright (c) 1996 by Internet Software Consortium.
Permission to use, copy, modify, and distribute this software for any
@@ -3768,22 +3795,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-------------------------------------------------------------------
Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-------------------------------------------------------------------
Copyright (c) 2007-2008 Michael G Schwern
This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
@@ -4722,6 +4733,31 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright 2000 David E. O'Brien, John D. Polstra.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------
Copyright 2008 Android Open Source Project (source port randomization)
Copyright (c) 1985, 1989, 1993
The Regents of the University of California. All rights reserved.

View File

@@ -122,8 +122,8 @@ int fdatasync(int) all
int fchown:fchown32(int, uid_t, gid_t) arm,x86
int fchown:fchown(int, uid_t, gid_t) arm64,mips,mips64,x86_64
void sync(void) all
int ___fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all
ssize_t ___fgetxattr:fgetxattr(int, const char*, void*, size_t) all
int fsetxattr(int, const char*, const void*, size_t, int) all
ssize_t fgetxattr(int, const char*, void*, size_t) all
ssize_t flistxattr(int, char*, size_t) all
int fremovexattr(int, const char*) all
@@ -151,6 +151,7 @@ int utimensat(int, const char*, const struct timespec times[2], int) all
off_t lseek(int, off_t, int) arm,mips,x86
int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86
off_t lseek|lseek64(int, off_t, int) arm64,mips64,x86_64
int ftruncate(int, off_t) arm,mips,x86
int ftruncate64(int, off64_t) arm,mips,x86
int ftruncate|ftruncate64(int, off_t) arm64,mips64,x86_64
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) arm,mips,x86
@@ -203,7 +204,7 @@ clock_t times(struct tms*) all
int nanosleep(const struct timespec*, struct timespec*) all
int clock_settime(clockid_t, const struct timespec*) all
int clock_getres(clockid_t, struct timespec*) all
int ___clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) all
int __clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) all
int getitimer(int, const struct itimerval*) all
int setitimer(int, const struct itimerval*, struct itimerval*) all
int __timer_create:timer_create(clockid_t clockid, struct sigevent* evp, __kernel_timer_t* timerid) all
@@ -222,7 +223,7 @@ int __rt_sigpending:rt_sigpending(sigset_t*, size_t) all
int __rt_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t) all
int __rt_sigsuspend:rt_sigsuspend(const sigset_t*, size_t) all
int __rt_sigtimedwait:rt_sigtimedwait(const sigset_t*, struct siginfo_t*, struct timespec_t*, size_t) all
int ___rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all
int __rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all
int __signalfd4:signalfd4(int, const sigset_t*, size_t, int) all
# sockets
@@ -308,9 +309,6 @@ int inotify_rm_watch(int, unsigned int) all
int __pselect6:pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*) all
int __ppoll:ppoll(pollfd*, unsigned int, timespec*, const sigset_t*, size_t) all
ssize_t process_vm_readv(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long) all
ssize_t process_vm_writev(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long) all
int __set_tid_address:set_tid_address(int*) all
int setfsgid(gid_t) all

View File

@@ -39,6 +39,7 @@ libc_bionic_src_files_arm += \
arch-arm/bionic/__bionic_clone.S \
arch-arm/bionic/_exit_with_stack_teardown.S \
arch-arm/bionic/libgcc_compat.c \
arch-arm/bionic/libgcc_protect_unwind.c \
arch-arm/bionic/__restore.S \
arch-arm/bionic/setjmp.S \
arch-arm/bionic/syscall.S \

View File

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

View File

@@ -0,0 +1,93 @@
/*
* 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.
*/
// TODO: This file should go away once unwinder migration to libc++.so is complete.
extern char _Unwind_Backtrace __attribute((visibility("protected")));
extern char __gnu_Unwind_Find_exidx __attribute((visibility("protected")));
extern char __gnu_Unwind_Restore_VFP_D __attribute((visibility("protected")));
extern char __gnu_Unwind_Restore_VFP __attribute((visibility("protected")));
extern char __gnu_Unwind_Restore_VFP_D_16_to_31 __attribute((visibility("protected")));
extern char __gnu_Unwind_Restore_WMMXD __attribute((visibility("protected")));
extern char __gnu_Unwind_Restore_WMMXC __attribute((visibility("protected")));
extern char _Unwind_GetCFA __attribute((visibility("protected")));
extern char __gnu_Unwind_RaiseException __attribute((visibility("protected")));
extern char __gnu_Unwind_ForcedUnwind __attribute((visibility("protected")));
extern char __gnu_Unwind_Resume __attribute((visibility("protected")));
extern char __gnu_Unwind_Resume_or_Rethrow __attribute((visibility("protected")));
extern char _Unwind_Complete __attribute((visibility("protected")));
extern char _Unwind_DeleteException __attribute((visibility("protected")));
extern char _Unwind_VRS_Get __attribute((visibility("protected")));
extern char _Unwind_VRS_Set __attribute((visibility("protected")));
extern char __gnu_Unwind_Backtrace __attribute((visibility("protected")));
extern char _Unwind_VRS_Pop __attribute((visibility("protected")));
extern char __gnu_Unwind_Save_VFP_D __attribute((visibility("protected")));
extern char __gnu_Unwind_Save_VFP __attribute((visibility("protected")));
extern char __gnu_Unwind_Save_VFP_D_16_to_31 __attribute((visibility("protected")));
extern char __gnu_Unwind_Save_WMMXD __attribute((visibility("protected")));
extern char __gnu_Unwind_Save_WMMXC __attribute((visibility("protected")));
extern char ___Unwind_RaiseException __attribute((visibility("protected")));
extern char _Unwind_RaiseException __attribute((visibility("protected")));
extern char ___Unwind_Resume __attribute((visibility("protected")));
extern char _Unwind_Resume __attribute((visibility("protected")));
extern char ___Unwind_Resume_or_Rethrow __attribute((visibility("protected")));
extern char _Unwind_Resume_or_Rethrow __attribute((visibility("protected")));
extern char ___Unwind_ForcedUnwind __attribute((visibility("protected")));
extern char _Unwind_ForcedUnwind __attribute((visibility("protected")));
extern char ___Unwind_Backtrace __attribute((visibility("protected")));
extern char _Unwind_GetRegionStart __attribute((visibility("protected")));
extern char _Unwind_GetLanguageSpecificData __attribute((visibility("protected")));
extern char _Unwind_GetDataRelBase __attribute((visibility("protected")));
extern char _Unwind_GetTextRelBase __attribute((visibility("protected")));
void* __bionic_libgcc_unwind_symbols[] = {
&_Unwind_Backtrace,
&__gnu_Unwind_Find_exidx,
&__gnu_Unwind_Restore_VFP_D,
&__gnu_Unwind_Restore_VFP,
&__gnu_Unwind_Restore_VFP_D_16_to_31,
&__gnu_Unwind_Restore_WMMXD,
&__gnu_Unwind_Restore_WMMXC,
&_Unwind_GetCFA,
&__gnu_Unwind_RaiseException,
&__gnu_Unwind_ForcedUnwind,
&__gnu_Unwind_Resume,
&__gnu_Unwind_Resume_or_Rethrow,
&_Unwind_Complete,
&_Unwind_DeleteException,
&_Unwind_VRS_Get,
&_Unwind_VRS_Set,
&__gnu_Unwind_Backtrace,
&_Unwind_VRS_Pop,
&__gnu_Unwind_Save_VFP_D,
&__gnu_Unwind_Save_VFP,
&__gnu_Unwind_Save_VFP_D_16_to_31,
&__gnu_Unwind_Save_WMMXD,
&__gnu_Unwind_Save_WMMXC,
&___Unwind_RaiseException,
&_Unwind_RaiseException,
&___Unwind_Resume,
&_Unwind_Resume,
&___Unwind_Resume_or_Rethrow,
&_Unwind_Resume_or_Rethrow,
&___Unwind_ForcedUnwind,
&_Unwind_ForcedUnwind,
&___Unwind_Backtrace,
&_Unwind_GetRegionStart,
&_Unwind_GetLanguageSpecificData,
&_Unwind_GetDataRelBase,
&_Unwind_GetTextRelBase,
};

View File

@@ -1 +0,0 @@
include bionic/libc/arch-arm/cortex-a7/cortex-a7.mk

View File

@@ -44,7 +44,7 @@ ENTRY_PRIVATE(MEMCPY_BASE)
/* check if buffers are aligned. If so, run arm-only version */
eor r3, r0, r1
ands r3, r3, #0x3
beq __memcpy_base_aligned
beq MEMCPY_BASE_ALIGNED
/* Check the upper size limit for Neon unaligned memory access in memcpy */
cmp r2, #224

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___fsetxattr)
ENTRY(fsetxattr)
mov ip, sp
stmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 16
@@ -19,5 +19,4 @@ ENTRY(___fsetxattr)
bxls lr
neg r0, r0
b __set_errno_internal
END(___fsetxattr)
.hidden ___fsetxattr
END(fsetxattr)

View File

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

View File

@@ -1,22 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_readv)
mov ip, sp
stmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 16
.cfi_rel_offset r4, 0
.cfi_rel_offset r5, 4
.cfi_rel_offset r6, 8
.cfi_rel_offset r7, 12
ldmfd ip, {r4, r5, r6}
ldr r7, =__NR_process_vm_readv
swi #0
ldmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 0
cmn r0, #(MAX_ERRNO + 1)
bxls lr
neg r0, r0
b __set_errno_internal
END(process_vm_readv)

View File

@@ -1,22 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_writev)
mov ip, sp
stmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 16
.cfi_rel_offset r4, 0
.cfi_rel_offset r5, 4
.cfi_rel_offset r6, 8
.cfi_rel_offset r7, 12
ldmfd ip, {r4, r5, r6}
ldr r7, =__NR_process_vm_writev
swi #0
ldmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 0
cmn r0, #(MAX_ERRNO + 1)
bxls lr
neg r0, r0
b __set_errno_internal
END(process_vm_writev)

View File

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

View File

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

View File

@@ -1 +0,0 @@
include bionic/libc/arch-arm64/generic/generic.mk

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,14 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_readv)
mov x8, __NR_process_vm_readv
svc #0
cmn x0, #(MAX_ERRNO + 1)
cneg x0, x0, hi
b.hi __set_errno_internal
ret
END(process_vm_readv)

View File

@@ -1,14 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_writev)
mov x8, __NR_process_vm_writev
svc #0
cmn x0, #(MAX_ERRNO + 1)
cneg x0, x0, hi
b.hi __set_errno_internal
ret
END(process_vm_writev)

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,9 +6,6 @@
libc_bionic_src_files_mips += \
arch-mips/string/memcmp.c \
arch-mips/string/memcpy.S \
arch-mips/string/memset.S \
arch-mips/string/strcmp.S \
bionic/__memcpy_chk.cpp \
bionic/__memset_chk.cpp \
bionic/__strcpy_chk.cpp \
@@ -34,6 +31,7 @@ libc_openbsd_src_files_mips += \
upstream-openbsd/lib/libc/string/stpcpy.c \
upstream-openbsd/lib/libc/string/stpncpy.c \
upstream-openbsd/lib/libc/string/strcat.c \
upstream-openbsd/lib/libc/string/strcmp.c \
upstream-openbsd/lib/libc/string/strcpy.c \
upstream-openbsd/lib/libc/string/strlcat.c \
upstream-openbsd/lib/libc/string/strlcpy.c \
@@ -56,10 +54,14 @@ libc_bionic_src_files_mips += \
ifndef ARCH_MIPS_REV6
libc_bionic_src_files_mips += \
arch-mips/string/memcpy.S \
arch-mips/string/memset.S \
arch-mips/string/mips_strlen.c \
else
libc_bionic_src_files_mips += \
arch-mips/string/memcpy.c \
arch-mips/string/memset.c \
arch-mips/string/strlen.c \
endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,91 @@
/* $OpenBSD: memcpy.c,v 1.1 2014/11/30 19:43:56 deraadt Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* 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.
* 3. Neither the name of the University 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 REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
/*
* sizeof(word) MUST BE A POWER OF TWO
* SO THAT wmask BELOW IS ALL ONES
*/
typedef long word; /* "word" used for optimal copy speed */
#define wsize sizeof(word)
#define wmask (wsize - 1)
/*
* Copy a block of memory, not handling overlap.
*/
void *
memcpy(void *dst0, const void *src0, size_t length)
{
char *dst = dst0;
const char *src = src0;
size_t t;
if (length == 0 || dst == src) /* nothing to do */
goto done;
/*
* Macros: loop-t-times; and loop-t-times, t>0
*/
#define TLOOP(s) if (t) TLOOP1(s)
#define TLOOP1(s) do { s; } while (--t)
/*
* Copy forward.
*/
t = (long)src; /* only need low bits */
if ((t | (long)dst) & wmask) {
/*
* Try to align operands. This cannot be done
* unless the low bits match.
*/
if ((t ^ (long)dst) & wmask || length < wsize)
t = length;
else
t = wsize - (t & wmask);
length -= t;
TLOOP1(*dst++ = *src++);
}
/*
* Copy whole words, then mop up any trailing bytes.
*/
t = length / wsize;
TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
t = length & wmask;
TLOOP(*dst++ = *src++);
done:
return (dst0);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013
* Copyright (c) 2009
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,410 +27,216 @@
* SUCH DAMAGE.
*/
#ifdef __ANDROID__
# include <private/bionic_asm.h>
# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
#elif _LIBC
# include <sysdep.h>
# include <regdef.h>
# include <sys/asm.h>
# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
#elif _COMPILING_NEWLIB
# include "machine/asm.h"
# include "machine/regdef.h"
# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
/************************************************************************
*
* memset.S, version "64h" with 1 cache line horizon for "pref 30" and 14 nops
* Version: "043009"
*
************************************************************************/
/************************************************************************
* Include files
************************************************************************/
#include <private/bionic_asm.h>
/*
* This routine could be optimized for MIPS64. The current code only
* uses MIPS32 instructions.
*/
#if defined(__MIPSEB__)
# define SWHI swl /* high part is left in big-endian */
# define SWLO swr /* low part is right in big-endian */
#endif
#if defined(__MIPSEL__)
# define SWHI swr /* high part is right in little-endian */
# define SWLO swl /* low part is left in little-endian */
#endif
#if !(defined(XGPROF) || defined(XPROF))
#undef SETUP_GP
#define SETUP_GP
#endif
#ifdef NDEBUG
#define DBG #
#else
# include <regdef.h>
# include <sys/asm.h>
#define DBG
#endif
/* Check to see if the MIPS architecture we are compiling for supports
prefetching. */
LEAF(memset,0)
#if (__mips == 4) || (__mips == 5) || (__mips == 32) || (__mips == 64)
# ifndef DISABLE_PREFETCH
# define USE_PREFETCH
# endif
#endif
#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32))
# ifndef DISABLE_DOUBLE
# define USE_DOUBLE
# endif
#endif
#ifndef USE_DOUBLE
# ifndef DISABLE_DOUBLE_ALIGN
# define DOUBLE_ALIGN
# endif
#endif
/* Some asm.h files do not have the L macro definition. */
#ifndef L
# if _MIPS_SIM == _ABIO32
# define L(label) $L ## label
# else
# define L(label) .L ## label
# endif
#endif
/* Some asm.h files do not have the PTR_ADDIU macro definition. */
#ifndef PTR_ADDIU
# if _MIPS_SIM == _ABIO32
# define PTR_ADDIU addiu
# else
# define PTR_ADDIU daddiu
# endif
#endif
/* New R6 instructions that may not be in asm.h. */
#ifndef PTR_LSA
# if _MIPS_SIM == _ABIO32
# define PTR_LSA lsa
# else
# define PTR_LSA dlsa
# endif
#endif
/* Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE
or PREFETCH_STORE_STREAMED offers a large performance advantage
but PREPAREFORSTORE has some special restrictions to consider.
Prefetch with the 'prepare for store' hint does not copy a memory
location into the cache, it just allocates a cache line and zeros
it out. This means that if you do not write to the entire cache
line before writing it out to memory some data will get zero'ed out
when the cache line is written back to memory and data will be lost.
There are ifdef'ed sections of this memcpy to make sure that it does not
do prefetches on cache lines that are not going to be completely written.
This code is only needed and only used when PREFETCH_STORE_HINT is set to
PREFETCH_HINT_PREPAREFORSTORE. This code assumes that cache lines are
less than MAX_PREFETCH_SIZE bytes and if the cache line is larger it will
not work correctly. */
#ifdef USE_PREFETCH
# define PREFETCH_HINT_STORE 1
# define PREFETCH_HINT_STORE_STREAMED 5
# define PREFETCH_HINT_STORE_RETAINED 7
# define PREFETCH_HINT_PREPAREFORSTORE 30
/* If we have not picked out what hints to use at this point use the
standard load and store prefetch hints. */
# ifndef PREFETCH_STORE_HINT
# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE
# endif
/* We double everything when USE_DOUBLE is true so we do 2 prefetches to
get 64 bytes in that case. The assumption is that each individual
prefetch brings in 32 bytes. */
# ifdef USE_DOUBLE
# define PREFETCH_CHUNK 64
# define PREFETCH_FOR_STORE(chunk, reg) \
pref PREFETCH_STORE_HINT, (chunk)*64(reg); \
pref PREFETCH_STORE_HINT, ((chunk)*64)+32(reg)
# else
# define PREFETCH_CHUNK 32
# define PREFETCH_FOR_STORE(chunk, reg) \
pref PREFETCH_STORE_HINT, (chunk)*32(reg)
# endif
/* MAX_PREFETCH_SIZE is the maximum size of a prefetch, it must not be less
than PREFETCH_CHUNK, the assumed size of each prefetch. If the real size
of a prefetch is greater than MAX_PREFETCH_SIZE and the PREPAREFORSTORE
hint is used, the code will not work correctly. If PREPAREFORSTORE is not
used than MAX_PREFETCH_SIZE does not matter. */
# define MAX_PREFETCH_SIZE 128
/* PREFETCH_LIMIT is set based on the fact that we never use an offset greater
than 5 on a STORE prefetch and that a single prefetch can never be larger
than MAX_PREFETCH_SIZE. We add the extra 32 when USE_DOUBLE is set because
we actually do two prefetches in that case, one 32 bytes after the other. */
# ifdef USE_DOUBLE
# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + 32 + MAX_PREFETCH_SIZE
# else
# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + MAX_PREFETCH_SIZE
# endif
# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) \
&& ((PREFETCH_CHUNK * 4) < MAX_PREFETCH_SIZE)
/* We cannot handle this because the initial prefetches may fetch bytes that
are before the buffer being copied. We start copies with an offset
of 4 so avoid this situation when using PREPAREFORSTORE. */
# error "PREFETCH_CHUNK is too large and/or MAX_PREFETCH_SIZE is too small."
# endif
#else /* USE_PREFETCH not defined */
# define PREFETCH_FOR_STORE(offset, reg)
#endif
#if __mips_isa_rev > 5
# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
# undef PREFETCH_STORE_HINT
# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED
# endif
# define R6_CODE
#endif
/* Allow the routine to be named something else if desired. */
#ifndef MEMSET_NAME
# define MEMSET_NAME memset
#endif
/* We load/store 64 bits at a time when USE_DOUBLE is true.
The C_ prefix stands for CHUNK and is used to avoid macro name
conflicts with system header files. */
#ifdef USE_DOUBLE
# define C_ST sd
# if __MIPSEB
# define C_STHI sdl /* high part is left in big-endian */
# else
# define C_STHI sdr /* high part is right in little-endian */
# endif
#else
# define C_ST sw
# if __MIPSEB
# define C_STHI swl /* high part is left in big-endian */
# else
# define C_STHI swr /* high part is right in little-endian */
# endif
#endif
/* Bookkeeping values for 32 vs. 64 bit mode. */
#ifdef USE_DOUBLE
# define NSIZE 8
# define NSIZEMASK 0x3f
# define NSIZEDMASK 0x7f
#else
# define NSIZE 4
# define NSIZEMASK 0x1f
# define NSIZEDMASK 0x3f
#endif
#define UNIT(unit) ((unit)*NSIZE)
#define UNITM1(unit) (((unit)*NSIZE)-1)
#ifdef __ANDROID__
LEAF(MEMSET_NAME,0)
#else
LEAF(MEMSET_NAME)
#endif
.set nomips16
.set noreorder
/* If the size is less than 2*NSIZE (8 or 16), go to L(lastb). Regardless of
size, copy dst pointer to v0 for the return value. */
slti t2,a2,(2 * NSIZE)
bne t2,zero,L(lastb)
move v0,a0
.set noat
/* If memset value is not zero, we copy it to all the bytes in a 32 or 64
bit word. */
beq a1,zero,L(set0) /* If memset value is zero no smear */
PTR_SUBU a3,zero,a0
nop
addu t0,a0,a2 # t0 is the "past the end" address
slti AT,a2,4 # is a2 less than 4?
bne AT,zero,.Llast4 # if yes, go to last4
move v0,a0 # memset returns the dst pointer
/* smear byte into 32 or 64 bit word */
#if ((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)
# ifdef USE_DOUBLE
dins a1, a1, 8, 8 /* Replicate fill byte into half-word. */
dins a1, a1, 16, 16 /* Replicate fill byte into word. */
dins a1, a1, 32, 32 /* Replicate fill byte into dbl word. */
# else
ins a1, a1, 8, 8 /* Replicate fill byte into half-word. */
ins a1, a1, 16, 16 /* Replicate fill byte into word. */
# endif
beq a1,zero,.Lset0
subu v1,zero,a0
# smear byte into 32 bit word
#if (__mips==32) && (__mips_isa_rev>=2)
ins a1, a1, 8, 8 # Replicate fill byte into half-word.
ins a1, a1, 16, 16 # Replicate fill byte into word.
#else
# ifdef USE_DOUBLE
and a1,0xff
dsll t2,a1,8
or a1,t2
dsll t2,a1,16
or a1,t2
dsll t2,a1,32
or a1,t2
# else
and a1,0xff
sll t2,a1,8
or a1,t2
sll t2,a1,16
or a1,t2
# endif
and a1,0xff
sll AT,a1,8
or a1,AT
sll AT,a1,16
or a1,AT
#endif
/* If the destination address is not aligned do a partial store to get it
aligned. If it is already aligned just jump to L(aligned). */
L(set0):
#ifndef R6_CODE
andi t2,a3,(NSIZE-1) /* word-unaligned address? */
beq t2,zero,L(aligned) /* t2 is the unalignment count */
PTR_SUBU a2,a2,t2
C_STHI a1,0(a0)
PTR_ADDU a0,a0,t2
#else /* R6_CODE */
andi t2,a0,(NSIZE-1)
lapc t9,L(atable)
PTR_LSA t9,t2,t9,2
jrc t9
L(atable):
bc L(aligned)
# ifdef USE_DOUBLE
bc L(lb7)
bc L(lb6)
bc L(lb5)
bc L(lb4)
# endif
bc L(lb3)
bc L(lb2)
bc L(lb1)
L(lb7):
sb a1,6(a0)
L(lb6):
sb a1,5(a0)
L(lb5):
sb a1,4(a0)
L(lb4):
sb a1,3(a0)
L(lb3):
sb a1,2(a0)
L(lb2):
sb a1,1(a0)
L(lb1):
sb a1,0(a0)
.Lset0:
andi v1,v1,0x3 # word-unaligned address?
beq v1,zero,.Laligned # v1 is the unalignment count
subu a2,a2,v1
SWHI a1,0(a0)
addu a0,a0,v1
li t9,NSIZE
subu t2,t9,t2
PTR_SUBU a2,a2,t2
PTR_ADDU a0,a0,t2
#endif /* R6_CODE */
# Here we have the "word-aligned" a0 (until the "last4")
.Laligned:
andi t8,a2,0x3f # any 64-byte chunks?
# t8 is the byte count past 64-byte chunks
beq a2,t8,.Lchk8w # when a2==t8, no 64-byte chunks
# There will be at most 1 32-byte chunk then
subu a3,a2,t8 # subtract from a2 the reminder
# Here a3 counts bytes in 16w chunks
addu a3,a0,a3 # Now a3 is the final dst after 64-byte chunks
# Find out, if there are any 64-byte chunks after which will be still at least
# 96 bytes left. The value "96" is calculated as needed buffer for
# "pref 30,64(a0)" prefetch, which can be used as "pref 30,0(a0)" after
# incrementing "a0" by 64.
# For "a2" below 160 there will be no such "pref 30 safe" 64-byte chunk.
#
sltiu v1,a2,160
bgtz v1,.Lloop16w_nopref30 # skip "pref 30,0(a0)"
subu t7,a2,96 # subtract "pref 30 unsafe" region
# below we have at least 1 64-byte chunk which is "pref 30 safe"
andi t6,t7,0x3f # t6 is past "64-byte safe chunks" reminder
subu t5,t7,t6 # subtract from t7 the reminder
# Here t5 counts bytes in 16w "safe" chunks
addu t4,a0,t5 # Now t4 is the dst after 64-byte "safe" chunks
# Don't use "pref 30,0(a0)" for a0 in a "middle" of a cache line
# pref 30,0(a0)
# Here we are in the region, where it is safe to use "pref 30,64(a0)"
.Lloop16w:
addiu a0,a0,64
pref 30,-32(a0) # continue setting up the dest, addr 64-32
sw a1,-64(a0)
sw a1,-60(a0)
sw a1,-56(a0)
sw a1,-52(a0)
sw a1,-48(a0)
sw a1,-44(a0)
sw a1,-40(a0)
sw a1,-36(a0)
nop
nop # the extra nop instructions help to balance
nop # cycles needed for "store" + "fill" + "evict"
nop # For 64byte store there are needed 8 fill
nop # and 8 evict cycles, i.e. at least 32 instr.
nop
nop
pref 30,0(a0) # continue setting up the dest, addr 64-0
sw a1,-32(a0)
sw a1,-28(a0)
sw a1,-24(a0)
sw a1,-20(a0)
sw a1,-16(a0)
sw a1,-12(a0)
sw a1,-8(a0)
sw a1,-4(a0)
nop
nop
nop
nop # NOTE: adding 14 nop-s instead of 12 nop-s
nop # gives better results for "fast" memory
nop
bne a0,t4,.Lloop16w
nop
beq a0,a3,.Lchk8w # maybe no more 64-byte chunks?
nop # this "delayed slot" is useless ...
.Lloop16w_nopref30: # there could be up to 3 "64-byte nopref30" chunks
addiu a0,a0,64
sw a1,-64(a0)
sw a1,-60(a0)
sw a1,-56(a0)
sw a1,-52(a0)
sw a1,-48(a0)
sw a1,-44(a0)
sw a1,-40(a0)
sw a1,-36(a0)
sw a1,-32(a0)
sw a1,-28(a0)
sw a1,-24(a0)
sw a1,-20(a0)
sw a1,-16(a0)
sw a1,-12(a0)
sw a1,-8(a0)
bne a0,a3,.Lloop16w_nopref30
sw a1,-4(a0)
.Lchk8w: # t8 here is the byte count past 64-byte chunks
andi t7,t8,0x1f # is there a 32-byte chunk?
# the t7 is the reminder count past 32-bytes
beq t8,t7,.Lchk1w # when t8==t7, no 32-byte chunk
move a2,t7
L(aligned):
/* If USE_DOUBLE is not set we may still want to align the data on a 16
byte boundry instead of an 8 byte boundry to maximize the opportunity
of proAptiv chips to do memory bonding (combining two sequential 4
byte stores into one 8 byte store). We know there are at least 4 bytes
left to store or we would have jumped to L(lastb) earlier in the code. */
#ifdef DOUBLE_ALIGN
andi t2,a3,4
beq t2,zero,L(double_aligned)
PTR_SUBU a2,a2,t2
sw a1,0(a0)
PTR_ADDU a0,a0,t2
L(double_aligned):
#endif
sw a1,4(a0)
sw a1,8(a0)
sw a1,12(a0)
sw a1,16(a0)
sw a1,20(a0)
sw a1,24(a0)
sw a1,28(a0)
addiu a0,a0,32
/* Now the destination is aligned to (word or double word) aligned address
Set a2 to count how many bytes we have to copy after all the 64/128 byte
chunks are copied and a3 to the dest pointer after all the 64/128 byte
chunks have been copied. We will loop, incrementing a0 until it equals
a3. */
andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
beq a2,t8,L(chkw) /* if a2==t8, no 64-byte/128-byte chunks */
PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */
PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */
.Lchk1w:
andi t8,a2,0x3 # now t8 is the reminder past 1w chunks
beq a2,t8,.Llast4aligned
subu a3,a2,t8 # a3 is the count of bytes in 1w chunks
addu a3,a0,a3 # now a3 is the dst address past the 1w chunks
/* When in the loop we may prefetch with the 'prepare to store' hint,
in this case the a0+x should not be past the "t0-32" address. This
means: for x=128 the last "safe" a0 address is "t0-160". Alternatively,
for x=64 the last "safe" a0 address is "t0-96" In the current version we
will use "prefetch hint,128(a0)", so "t0-160" is the limit. */
#if defined(USE_PREFETCH) \
&& (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */
PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */
#endif
#if defined(USE_PREFETCH) \
&& (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
PREFETCH_FOR_STORE (1, a0)
PREFETCH_FOR_STORE (2, a0)
PREFETCH_FOR_STORE (3, a0)
#endif
# copying in words (4-byte chunks)
.LwordCopy_loop:
addiu a0,a0,4
bne a0,a3,.LwordCopy_loop
sw a1,-4(a0)
L(loop16w):
#if defined(USE_PREFETCH) \
&& (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
sltu v1,t9,a0 /* If a0 > t9 don't use next prefetch */
bgtz v1,L(skip_pref)
nop
#endif
#ifndef R6_CODE
PREFETCH_FOR_STORE (4, a0)
PREFETCH_FOR_STORE (5, a0)
#else
PREFETCH_FOR_STORE (2, a0)
#endif
L(skip_pref):
C_ST a1,UNIT(0)(a0)
C_ST a1,UNIT(1)(a0)
C_ST a1,UNIT(2)(a0)
C_ST a1,UNIT(3)(a0)
C_ST a1,UNIT(4)(a0)
C_ST a1,UNIT(5)(a0)
C_ST a1,UNIT(6)(a0)
C_ST a1,UNIT(7)(a0)
C_ST a1,UNIT(8)(a0)
C_ST a1,UNIT(9)(a0)
C_ST a1,UNIT(10)(a0)
C_ST a1,UNIT(11)(a0)
C_ST a1,UNIT(12)(a0)
C_ST a1,UNIT(13)(a0)
C_ST a1,UNIT(14)(a0)
C_ST a1,UNIT(15)(a0)
PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */
bne a0,a3,L(loop16w)
nop
move a2,t8
/* Here we have dest word-aligned but less than 64-bytes or 128 bytes to go.
Check for a 32(64) byte chunk and copy if if there is one. Otherwise
jump down to L(chk1w) to handle the tail end of the copy. */
L(chkw):
andi t8,a2,NSIZEMASK /* is there a 32-byte/64-byte chunk. */
/* the t8 is the reminder count past 32-bytes */
beq a2,t8,L(chk1w)/* when a2==t8, no 32-byte chunk */
nop
C_ST a1,UNIT(0)(a0)
C_ST a1,UNIT(1)(a0)
C_ST a1,UNIT(2)(a0)
C_ST a1,UNIT(3)(a0)
C_ST a1,UNIT(4)(a0)
C_ST a1,UNIT(5)(a0)
C_ST a1,UNIT(6)(a0)
C_ST a1,UNIT(7)(a0)
PTR_ADDIU a0,a0,UNIT(8)
/* Here we have less than 32(64) bytes to set. Set up for a loop to
copy one word (or double word) at a time. Set a2 to count how many
bytes we have to copy after all the word (or double word) chunks are
copied and a3 to the dest pointer after all the (d)word chunks have
been copied. We will loop, incrementing a0 until a0 equals a3. */
L(chk1w):
andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */
beq a2,t8,L(lastb)
PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */
PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */
/* copying in words (4-byte or 8 byte chunks) */
L(wordCopy_loop):
PTR_ADDIU a0,a0,UNIT(1)
bne a0,a3,L(wordCopy_loop)
C_ST a1,UNIT(-1)(a0)
/* Copy the last 8 (or 16) bytes */
L(lastb):
blez a2,L(leave)
PTR_ADDU a3,a0,a2 /* a3 is the last dst address */
L(lastbloop):
PTR_ADDIU a0,a0,1
bne a0,a3,L(lastbloop)
sb a1,-1(a0)
L(leave):
# store last 0-3 bytes
# this will repeat the last store if the memset finishes on a word boundary
.Llast4aligned:
j ra
nop
SWLO a1,-1(t0)
.Llast4:
beq a0,t0,.Llast4e
.Llast4l:
addiu a0,a0,1
bne a0,t0,.Llast4l
sb a1,-1(a0)
.Llast4e:
j ra
nop
.set at
.set reorder
END(MEMSET_NAME)
#ifndef __ANDROID__
# ifdef _LIBC
libc_hidden_builtin_def (MEMSET_NAME)
# endif
#endif
END(memset)
/************************************************************************
* Implementation : Static functions
************************************************************************/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 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
@@ -25,26 +25,20 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
#include <stdint.h>
#ifndef _SYS_PROCFS_H_
#define _SYS_PROCFS_H_
void* memset(void* dst, int c, size_t n)
{
char* q = dst;
char* end = q + n;
#include <sys/cdefs.h>
#include <sys/ucontext.h>
for (;;) {
if (q >= end) break; *q++ = (char) c;
if (q >= end) break; *q++ = (char) c;
if (q >= end) break; *q++ = (char) c;
if (q >= end) break; *q++ = (char) c;
}
__BEGIN_DECLS
typedef unsigned long elf_greg_t;
typedef elf_greg_t elf_gregset_t[NGREG];
typedef fpregset_t elf_fpregset_t;
typedef elf_gregset_t prgregset_t;
typedef elf_fpregset_t prfpregset_t;
typedef pid_t lwpid_t;
typedef void* psaddr_t;
__END_DECLS
#endif /* _SYS_PROCFS_H_ */
return dst;
}

View File

@@ -1,260 +0,0 @@
/*
* Copyright (c) 2014
* Imagination Technologies Limited.
*
* 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.
* 3. Neither the name of the MIPS Technologies, Inc., 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 IMAGINATION TECHNOLOGIES LIMITED ``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 IMAGINATION TECHNOLOGIES LIMITED 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.
*/
#ifdef __ANDROID__
# include <private/bionic_asm.h>
#elif _LIBC
# include <sysdep.h>
# include <regdef.h>
# include <sys/asm.h>
#elif _COMPILING_NEWLIB
# include "machine/asm.h"
# include "machine/regdef.h"
#else
# include <regdef.h>
# include <sys/asm.h>
#endif
/* Technically strcmp should not read past the end of the strings being
compared. We will read a full word that may contain excess bits beyond
the NULL string terminator but unless ENABLE_READAHEAD is set, we will not
read the next word after the end of string. Setting ENABLE_READAHEAD will
improve performance but is technically illegal based on the definition of
strcmp. */
#ifdef ENABLE_READAHEAD
# define DELAY_READ
#else
# define DELAY_READ nop
#endif
/* Testing on a little endian machine showed using CLZ was a
performance loss, so we are not turning it on by default. */
#if defined(ENABLE_CLZ) && (__mips_isa_rev > 1)
# define USE_CLZ
#endif
/* Some asm.h files do not have the L macro definition. */
#ifndef L
# if _MIPS_SIM == _ABIO32
# define L(label) $L ## label
# else
# define L(label) .L ## label
# endif
#endif
/* Some asm.h files do not have the PTR_ADDIU macro definition. */
#ifndef PTR_ADDIU
# if _MIPS_SIM == _ABIO32
# define PTR_ADDIU addiu
# else
# define PTR_ADDIU daddiu
# endif
#endif
/* Allow the routine to be named something else if desired. */
#ifndef STRCMP_NAME
# define STRCMP_NAME strcmp
#endif
#ifdef __ANDROID__
LEAF(STRCMP_NAME, 0)
#else
LEAF(STRCMP_NAME)
#endif
.set nomips16
.set noreorder
or t0, a0, a1
andi t0,0x3
bne t0, zero, L(byteloop)
/* Both strings are 4 byte aligned at this point. */
lui t8, 0x0101
ori t8, t8, 0x0101
lui t9, 0x7f7f
ori t9, 0x7f7f
#define STRCMP32(OFFSET) \
lw v0, OFFSET(a0); \
lw v1, OFFSET(a1); \
subu t0, v0, t8; \
bne v0, v1, L(worddiff); \
nor t1, v0, t9; \
and t0, t0, t1; \
bne t0, zero, L(returnzero)
L(wordloop):
STRCMP32(0)
DELAY_READ
STRCMP32(4)
DELAY_READ
STRCMP32(8)
DELAY_READ
STRCMP32(12)
DELAY_READ
STRCMP32(16)
DELAY_READ
STRCMP32(20)
DELAY_READ
STRCMP32(24)
DELAY_READ
STRCMP32(28)
PTR_ADDIU a0, a0, 32
b L(wordloop)
PTR_ADDIU a1, a1, 32
L(returnzero):
j ra
move v0, zero
L(worddiff):
#ifdef USE_CLZ
subu t0, v0, t8
nor t1, v0, t9
and t1, t0, t1
xor t0, v0, v1
or t0, t0, t1
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
wsbh t0, t0
rotr t0, t0, 16
# endif
clz t1, t0
and t1, 0xf8
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
neg t1
addu t1, 24
# endif
rotrv v0, v0, t1
rotrv v1, v1, t1
and v0, v0, 0xff
and v1, v1, 0xff
j ra
subu v0, v0, v1
#else /* USE_CLZ */
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
andi t0, v0, 0xff
beq t0, zero, L(wexit01)
andi t1, v1, 0xff
bne t0, t1, L(wexit01)
srl t8, v0, 8
srl t9, v1, 8
andi t8, t8, 0xff
beq t8, zero, L(wexit89)
andi t9, t9, 0xff
bne t8, t9, L(wexit89)
srl t0, v0, 16
srl t1, v1, 16
andi t0, t0, 0xff
beq t0, zero, L(wexit01)
andi t1, t1, 0xff
bne t0, t1, L(wexit01)
srl t8, v0, 24
srl t9, v1, 24
# else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
srl t0, v0, 24
beq t0, zero, L(wexit01)
srl t1, v1, 24
bne t0, t1, L(wexit01)
srl t8, v0, 16
srl t9, v1, 16
andi t8, t8, 0xff
beq t8, zero, L(wexit89)
andi t9, t9, 0xff
bne t8, t9, L(wexit89)
srl t0, v0, 8
srl t1, v1, 8
andi t0, t0, 0xff
beq t0, zero, L(wexit01)
andi t1, t1, 0xff
bne t0, t1, L(wexit01)
andi t8, v0, 0xff
andi t9, v1, 0xff
# endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
L(wexit89):
j ra
subu v0, t8, t9
L(wexit01):
j ra
subu v0, t0, t1
#endif /* USE_CLZ */
/* It might seem better to do the 'beq' instruction between the two 'lbu'
instructions so that the nop is not needed but testing showed that this
code is actually faster (based on glibc strcmp test). */
#define BYTECMP01(OFFSET) \
lbu v0, OFFSET(a0); \
lbu v1, OFFSET(a1); \
beq v0, zero, L(bexit01); \
nop; \
bne v0, v1, L(bexit01)
#define BYTECMP89(OFFSET) \
lbu t8, OFFSET(a0); \
lbu t9, OFFSET(a1); \
beq t8, zero, L(bexit89); \
nop; \
bne t8, t9, L(bexit89)
L(byteloop):
BYTECMP01(0)
BYTECMP89(1)
BYTECMP01(2)
BYTECMP89(3)
BYTECMP01(4)
BYTECMP89(5)
BYTECMP01(6)
BYTECMP89(7)
PTR_ADDIU a0, a0, 8
b L(byteloop)
PTR_ADDIU a1, a1, 8
L(bexit01):
j ra
subu v0, v0, v1
L(bexit89):
j ra
subu v0, t8, t9
.set at
.set reorder
END(STRCMP_NAME)
#ifndef __ANDROID__
# ifdef _LIBC
libc_hidden_builtin_def (STRCMP_NAME)
# endif
#endif

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,10 +2,10 @@
#include <private/bionic_asm.h>
ENTRY(process_vm_readv)
ENTRY(ftruncate)
.set noreorder
.cpload t9
li v0, __NR_process_vm_readv
li v0, __NR_ftruncate
syscall
bnez a3, 1f
move a0, v0
@@ -16,4 +16,4 @@ ENTRY(process_vm_readv)
j t9
nop
.set reorder
END(process_vm_readv)
END(ftruncate)

View File

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

View File

@@ -32,28 +32,29 @@
#include <unistd.h>
struct kernel_stat {
unsigned int st_dev;
unsigned int st_pad0[3];
unsigned long st_ino;
mode_t st_mode;
__u32 st_nlink;
uid_t st_uid;
gid_t st_gid;
unsigned int st_rdev;
unsigned int st_pad1[3];
__kernel_off_t st_size;
unsigned int _st_atime;
unsigned int st_atime_nsec;
unsigned int _st_mtime;
unsigned int st_mtime_nsec;
unsigned int _st_ctime;
unsigned int st_ctime_nsec;
unsigned int st_blksize;
unsigned int st_pad2;
unsigned long st_blocks;
unsigned int st_dev;
unsigned int st_pad0[3];
unsigned long st_ino;
mode_t st_mode;
__u32 st_nlink;
uid_t st_uid;
gid_t st_gid;
unsigned int st_rdev;
unsigned int st_pad1[3];
__kernel_off_t st_size;
unsigned int _st_atime;
unsigned int st_atime_nsec;
unsigned int _st_mtime;
unsigned int st_mtime_nsec;
unsigned int _st_ctime;
unsigned int st_ctime_nsec;
unsigned int st_blksize;
unsigned int st_pad2;
unsigned long st_blocks;
};
static void copy_stat(struct stat* st, struct kernel_stat* s) {
void copy_stat(struct stat *st, struct kernel_stat *s)
{
st->st_dev = static_cast<dev_t>(s->st_dev);
st->st_ino = static_cast<ino_t>(s->st_ino);
st->st_mode = static_cast<mode_t>(s->st_mode);
@@ -72,17 +73,30 @@ static void copy_stat(struct stat* st, struct kernel_stat* s) {
st->st_ctim.tv_nsec = static_cast<long>(s->st_ctime_nsec);
}
int fstat(int fp, struct stat* st) {
int fstat(int fp, struct stat *st)
{
kernel_stat s;
int ret = syscall(__NR_fstat, fp, &s);
copy_stat(st, &s);
int ret;
ret = syscall (__NR_fstat, fp, &s);
copy_stat (st, &s);
return ret;
}
__strong_alias(fstat64, fstat);
int fstatat(int dirfd, const char* pathname, struct stat* buf, int flags) {
int newfstatat(int dirfd, const char *pathname, struct stat *buf, int flags)
{
kernel_stat s;
int ret = syscall(__NR_newfstatat, dirfd, pathname, &s, flags);
int ret;
ret = syscall(__NR_newfstatat, dirfd, pathname, &s, flags);
copy_stat(buf, &s);
return ret;
}
int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags)
{
kernel_stat s;
int ret;
ret = syscall(__NR_newfstatat, dirfd, pathname, &s, flags);
copy_stat(buf, &s);
return ret;
}

View File

@@ -5,11 +5,6 @@
#
libc_bionic_src_files_mips64 += \
arch-mips/string/memcmp.c \
arch-mips/string/memcpy.S \
arch-mips/string/memset.S \
arch-mips/string/strcmp.S \
arch-mips/string/strlen.c \
bionic/__memcpy_chk.cpp \
bionic/__memset_chk.cpp \
bionic/__strcpy_chk.cpp \
@@ -17,6 +12,10 @@ libc_bionic_src_files_mips64 += \
bionic/strchr.cpp \
bionic/strnlen.c \
bionic/strrchr.cpp \
arch-mips/string/memcmp.c \
arch-mips/string/memcpy.c \
arch-mips/string/memset.c \
arch-mips/string/strlen.c \
libc_freebsd_src_files_mips64 += \
upstream-freebsd/lib/libc/string/wcscat.c \
@@ -35,6 +34,7 @@ libc_openbsd_src_files_mips64 += \
upstream-openbsd/lib/libc/string/stpcpy.c \
upstream-openbsd/lib/libc/string/stpncpy.c \
upstream-openbsd/lib/libc/string/strcat.c \
upstream-openbsd/lib/libc/string/strcmp.c \
upstream-openbsd/lib/libc/string/strcpy.c \
upstream-openbsd/lib/libc/string/strlcat.c \
upstream-openbsd/lib/libc/string/strlcpy.c \

View File

@@ -0,0 +1,423 @@
/*
* Copyright (c) 2009
* MIPS Technologies, Inc., California.
*
* 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.
* 3. Neither the name of the MIPS Technologies, Inc., 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 MIPS TECHNOLOGIES, INC. ``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 MIPS TECHNOLOGIES, INC. 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.
*/
/************************************************************************
*
* memcpy.S
* Version: "043009"
*
************************************************************************/
/************************************************************************
* Include files
************************************************************************/
#include <private/bionic_asm.h>
/*
* This routine could be optimized for MIPS64. The current code only
* uses MIPS32 instructions.
*/
#if defined(__MIPSEB__)
# define LWHI lwl /* high part is left in big-endian */
# define SWHI swl /* high part is left in big-endian */
# define LWLO lwr /* low part is right in big-endian */
# define SWLO swr /* low part is right in big-endian */
#endif
#if defined(__MIPSEL__)
# define LWHI lwr /* high part is right in little-endian */
# define SWHI swr /* high part is right in little-endian */
# define LWLO lwl /* low part is left in big-endian */
# define SWLO swl /* low part is left in big-endian */
#endif
LEAF(memcpy,0)
.set noreorder
.set noat
/*
* Below we handle the case where memcpy is called with overlapping src and dst.
* Although memcpy is not required to handle this case, some parts of Android like Skia
* rely on such usage. We call memmove to handle such cases.
*/
subu t0,a0,a1
sra AT,t0,31
xor t1,t0,AT
subu t0,t1,AT
sltu AT,t0,a2
beq AT,zero,.Lmemcpy
la t9,memmove
jr t9
nop
.Lmemcpy:
slti AT,a2,8
bne AT,zero,.Llast8
move v0,a0 # memcpy returns the dst pointer
# Test if the src and dst are word-aligned, or can be made word-aligned
xor t8,a1,a0
andi t8,t8,0x3 # t8 is a0/a1 word-displacement
bne t8,zero,.Lunaligned
negu a3,a0
andi a3,a3,0x3 # we need to copy a3 bytes to make a0/a1 aligned
beq a3,zero,.Lchk16w # when a3=0 then the dst (a0) is word-aligned
subu a2,a2,a3 # now a2 is the remining bytes count
LWHI t8,0(a1)
addu a1,a1,a3
SWHI t8,0(a0)
addu a0,a0,a3
# Now the dst/src are mutually word-aligned with word-aligned addresses
.Lchk16w:
andi t8,a2,0x3f # any whole 64-byte chunks?
# t8 is the byte count after 64-byte chunks
beq a2,t8,.Lchk8w # if a2==t8, no 64-byte chunks
# There will be at most 1 32-byte chunk after it
subu a3,a2,t8 # subtract from a2 the reminder
# Here a3 counts bytes in 16w chunks
addu a3,a0,a3 # Now a3 is the final dst after 64-byte chunks
addu t0,a0,a2 # t0 is the "past the end" address
# When in the loop we exercise "pref 30,x(a0)", the a0+x should not be past
# the "t0-32" address
# This means: for x=128 the last "safe" a0 address is "t0-160"
# Alternatively, for x=64 the last "safe" a0 address is "t0-96"
# In the current version we will use "pref 30,128(a0)", so "t0-160" is the limit
subu t9,t0,160 # t9 is the "last safe pref 30,128(a0)" address
pref 0,0(a1) # bring the first line of src, addr 0
pref 0,32(a1) # bring the second line of src, addr 32
pref 0,64(a1) # bring the third line of src, addr 64
pref 30,32(a0) # safe, as we have at least 64 bytes ahead
# In case the a0 > t9 don't use "pref 30" at all
sgtu v1,a0,t9
bgtz v1,.Lloop16w # skip "pref 30,64(a0)" for too short arrays
nop
# otherwise, start with using pref30
pref 30,64(a0)
.Lloop16w:
pref 0,96(a1)
lw t0,0(a1)
bgtz v1,.Lskip_pref30_96 # skip "pref 30,96(a0)"
lw t1,4(a1)
pref 30,96(a0) # continue setting up the dest, addr 96
.Lskip_pref30_96:
lw t2,8(a1)
lw t3,12(a1)
lw t4,16(a1)
lw t5,20(a1)
lw t6,24(a1)
lw t7,28(a1)
pref 0,128(a1) # bring the next lines of src, addr 128
sw t0,0(a0)
sw t1,4(a0)
sw t2,8(a0)
sw t3,12(a0)
sw t4,16(a0)
sw t5,20(a0)
sw t6,24(a0)
sw t7,28(a0)
lw t0,32(a1)
bgtz v1,.Lskip_pref30_128 # skip "pref 30,128(a0)"
lw t1,36(a1)
pref 30,128(a0) # continue setting up the dest, addr 128
.Lskip_pref30_128:
lw t2,40(a1)
lw t3,44(a1)
lw t4,48(a1)
lw t5,52(a1)
lw t6,56(a1)
lw t7,60(a1)
pref 0, 160(a1) # bring the next lines of src, addr 160
sw t0,32(a0)
sw t1,36(a0)
sw t2,40(a0)
sw t3,44(a0)
sw t4,48(a0)
sw t5,52(a0)
sw t6,56(a0)
sw t7,60(a0)
addiu a0,a0,64 # adding 64 to dest
sgtu v1,a0,t9
bne a0,a3,.Lloop16w
addiu a1,a1,64 # adding 64 to src
move a2,t8
# Here we have src and dest word-aligned but less than 64-bytes to go
.Lchk8w:
pref 0, 0x0(a1)
andi t8,a2,0x1f # is there a 32-byte chunk?
# the t8 is the reminder count past 32-bytes
beq a2,t8,.Lchk1w # when a2=t8, no 32-byte chunk
nop
lw t0,0(a1)
lw t1,4(a1)
lw t2,8(a1)
lw t3,12(a1)
lw t4,16(a1)
lw t5,20(a1)
lw t6,24(a1)
lw t7,28(a1)
addiu a1,a1,32
sw t0,0(a0)
sw t1,4(a0)
sw t2,8(a0)
sw t3,12(a0)
sw t4,16(a0)
sw t5,20(a0)
sw t6,24(a0)
sw t7,28(a0)
addiu a0,a0,32
.Lchk1w:
andi a2,t8,0x3 # now a2 is the reminder past 1w chunks
beq a2,t8,.Llast8
subu a3,t8,a2 # a3 is count of bytes in 1w chunks
addu a3,a0,a3 # now a3 is the dst address past the 1w chunks
# copying in words (4-byte chunks)
.LwordCopy_loop:
lw t3,0(a1) # the first t3 may be equal t0 ... optimize?
addiu a1,a1,4
addiu a0,a0,4
bne a0,a3,.LwordCopy_loop
sw t3,-4(a0)
# For the last (<8) bytes
.Llast8:
blez a2,.Lleave
addu a3,a0,a2 # a3 is the last dst address
.Llast8loop:
lb v1,0(a1)
addiu a1,a1,1
addiu a0,a0,1
bne a0,a3,.Llast8loop
sb v1,-1(a0)
.Lleave:
j ra
nop
#
# UNALIGNED case
#
.Lunaligned:
# got here with a3="negu a0"
andi a3,a3,0x3 # test if the a0 is word aligned
beqz a3,.Lua_chk16w
subu a2,a2,a3 # bytes left after initial a3 bytes
LWHI v1,0(a1)
LWLO v1,3(a1)
addu a1,a1,a3 # a3 may be here 1, 2 or 3
SWHI v1,0(a0)
addu a0,a0,a3 # below the dst will be word aligned (NOTE1)
.Lua_chk16w:
andi t8,a2,0x3f # any whole 64-byte chunks?
# t8 is the byte count after 64-byte chunks
beq a2,t8,.Lua_chk8w # if a2==t8, no 64-byte chunks
# There will be at most 1 32-byte chunk after it
subu a3,a2,t8 # subtract from a2 the reminder
# Here a3 counts bytes in 16w chunks
addu a3,a0,a3 # Now a3 is the final dst after 64-byte chunks
addu t0,a0,a2 # t0 is the "past the end" address
subu t9,t0,160 # t9 is the "last safe pref 30,128(a0)" address
pref 0,0(a1) # bring the first line of src, addr 0
pref 0,32(a1) # bring the second line of src, addr 32
pref 0,64(a1) # bring the third line of src, addr 64
pref 30,32(a0) # safe, as we have at least 64 bytes ahead
# In case the a0 > t9 don't use "pref 30" at all
sgtu v1,a0,t9
bgtz v1,.Lua_loop16w # skip "pref 30,64(a0)" for too short arrays
nop
# otherwise, start with using pref30
pref 30,64(a0)
.Lua_loop16w:
pref 0,96(a1)
LWHI t0,0(a1)
LWLO t0,3(a1)
LWHI t1,4(a1)
bgtz v1,.Lua_skip_pref30_96
LWLO t1,7(a1)
pref 30,96(a0) # continue setting up the dest, addr 96
.Lua_skip_pref30_96:
LWHI t2,8(a1)
LWLO t2,11(a1)
LWHI t3,12(a1)
LWLO t3,15(a1)
LWHI t4,16(a1)
LWLO t4,19(a1)
LWHI t5,20(a1)
LWLO t5,23(a1)
LWHI t6,24(a1)
LWLO t6,27(a1)
LWHI t7,28(a1)
LWLO t7,31(a1)
pref 0,128(a1) # bring the next lines of src, addr 128
sw t0,0(a0)
sw t1,4(a0)
sw t2,8(a0)
sw t3,12(a0)
sw t4,16(a0)
sw t5,20(a0)
sw t6,24(a0)
sw t7,28(a0)
LWHI t0,32(a1)
LWLO t0,35(a1)
LWHI t1,36(a1)
bgtz v1,.Lua_skip_pref30_128
LWLO t1,39(a1)
pref 30,128(a0) # continue setting up the dest, addr 128
.Lua_skip_pref30_128:
LWHI t2,40(a1)
LWLO t2,43(a1)
LWHI t3,44(a1)
LWLO t3,47(a1)
LWHI t4,48(a1)
LWLO t4,51(a1)
LWHI t5,52(a1)
LWLO t5,55(a1)
LWHI t6,56(a1)
LWLO t6,59(a1)
LWHI t7,60(a1)
LWLO t7,63(a1)
pref 0, 160(a1) # bring the next lines of src, addr 160
sw t0,32(a0)
sw t1,36(a0)
sw t2,40(a0)
sw t3,44(a0)
sw t4,48(a0)
sw t5,52(a0)
sw t6,56(a0)
sw t7,60(a0)
addiu a0,a0,64 # adding 64 to dest
sgtu v1,a0,t9
bne a0,a3,.Lua_loop16w
addiu a1,a1,64 # adding 64 to src
move a2,t8
# Here we have src and dest word-aligned but less than 64-bytes to go
.Lua_chk8w:
pref 0, 0x0(a1)
andi t8,a2,0x1f # is there a 32-byte chunk?
# the t8 is the reminder count
beq a2,t8,.Lua_chk1w # when a2=t8, no 32-byte chunk
nop
LWHI t0,0(a1)
LWLO t0,3(a1)
LWHI t1,4(a1)
LWLO t1,7(a1)
LWHI t2,8(a1)
LWLO t2,11(a1)
LWHI t3,12(a1)
LWLO t3,15(a1)
LWHI t4,16(a1)
LWLO t4,19(a1)
LWHI t5,20(a1)
LWLO t5,23(a1)
LWHI t6,24(a1)
LWLO t6,27(a1)
LWHI t7,28(a1)
LWLO t7,31(a1)
addiu a1,a1,32
sw t0,0(a0)
sw t1,4(a0)
sw t2,8(a0)
sw t3,12(a0)
sw t4,16(a0)
sw t5,20(a0)
sw t6,24(a0)
sw t7,28(a0)
addiu a0,a0,32
.Lua_chk1w:
andi a2,t8,0x3 # now a2 is the reminder past 1w chunks
beq a2,t8,.Lua_smallCopy
subu a3,t8,a2 # a3 is count of bytes in 1w chunks
addu a3,a0,a3 # now a3 is the dst address past the 1w chunks
# copying in words (4-byte chunks)
.Lua_wordCopy_loop:
LWHI v1,0(a1)
LWLO v1,3(a1)
addiu a1,a1,4
addiu a0,a0,4 # note: dst=a0 is word aligned here, see NOTE1
bne a0,a3,.Lua_wordCopy_loop
sw v1,-4(a0)
# Now less than 4 bytes (value in a2) left to copy
.Lua_smallCopy:
beqz a2,.Lleave
addu a3,a0,a2 # a3 is the last dst address
.Lua_smallCopy_loop:
lb v1,0(a1)
addiu a1,a1,1
addiu a0,a0,1
bne a0,a3,.Lua_smallCopy_loop
sb v1,-1(a0)
j ra
nop
.set at
.set reorder
END(memcpy)
/************************************************************************
* Implementation : Static functions
************************************************************************/

View File

@@ -0,0 +1,242 @@
/*
* Copyright (c) 2009
* MIPS Technologies, Inc., California.
*
* 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.
* 3. Neither the name of the MIPS Technologies, Inc., 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 MIPS TECHNOLOGIES, INC. ``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 MIPS TECHNOLOGIES, INC. 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.
*/
/************************************************************************
*
* memset.S, version "64h" with 1 cache line horizon for "pref 30" and 14 nops
* Version: "043009"
*
************************************************************************/
/************************************************************************
* Include files
************************************************************************/
#include <private/bionic_asm.h>
/*
* This routine could be optimized for MIPS64. The current code only
* uses MIPS32 instructions.
*/
#if defined(__MIPSEB__)
# define SWHI swl /* high part is left in big-endian */
# define SWLO swr /* low part is right in big-endian */
#endif
#if defined(__MIPSEL__)
# define SWHI swr /* high part is right in little-endian */
# define SWLO swl /* low part is left in little-endian */
#endif
#if !(defined(XGPROF) || defined(XPROF))
#undef SETUP_GP
#define SETUP_GP
#endif
#ifdef NDEBUG
#define DBG #
#else
#define DBG
#endif
LEAF(memset,0)
.set noreorder
.set noat
addu t0,a0,a2 # t0 is the "past the end" address
slti AT,a2,4 # is a2 less than 4?
bne AT,zero,.Llast4 # if yes, go to last4
move v0,a0 # memset returns the dst pointer
beq a1,zero,.Lset0
subu v1,zero,a0
# smear byte into 32 bit word
#if (__mips==32) && (__mips_isa_rev>=2)
ins a1, a1, 8, 8 # Replicate fill byte into half-word.
ins a1, a1, 16, 16 # Replicate fill byte into word.
#else
and a1,0xff
sll AT,a1,8
or a1,AT
sll AT,a1,16
or a1,AT
#endif
.Lset0:
andi v1,v1,0x3 # word-unaligned address?
beq v1,zero,.Laligned # v1 is the unalignment count
subu a2,a2,v1
SWHI a1,0(a0)
addu a0,a0,v1
# Here we have the "word-aligned" a0 (until the "last4")
.Laligned:
andi t8,a2,0x3f # any 64-byte chunks?
# t8 is the byte count past 64-byte chunks
beq a2,t8,.Lchk8w # when a2==t8, no 64-byte chunks
# There will be at most 1 32-byte chunk then
subu a3,a2,t8 # subtract from a2 the reminder
# Here a3 counts bytes in 16w chunks
addu a3,a0,a3 # Now a3 is the final dst after 64-byte chunks
# Find out, if there are any 64-byte chunks after which will be still at least
# 96 bytes left. The value "96" is calculated as needed buffer for
# "pref 30,64(a0)" prefetch, which can be used as "pref 30,0(a0)" after
# incrementing "a0" by 64.
# For "a2" below 160 there will be no such "pref 30 safe" 64-byte chunk.
#
sltiu v1,a2,160
bgtz v1,.Lloop16w_nopref30 # skip "pref 30,0(a0)"
subu t7,a2,96 # subtract "pref 30 unsafe" region
# below we have at least 1 64-byte chunk which is "pref 30 safe"
andi t6,t7,0x3f # t6 is past "64-byte safe chunks" reminder
subu t5,t7,t6 # subtract from t7 the reminder
# Here t5 counts bytes in 16w "safe" chunks
addu t4,a0,t5 # Now t4 is the dst after 64-byte "safe" chunks
# Don't use "pref 30,0(a0)" for a0 in a "middle" of a cache line
# pref 30,0(a0)
# Here we are in the region, where it is safe to use "pref 30,64(a0)"
.Lloop16w:
addiu a0,a0,64
pref 30,-32(a0) # continue setting up the dest, addr 64-32
sw a1,-64(a0)
sw a1,-60(a0)
sw a1,-56(a0)
sw a1,-52(a0)
sw a1,-48(a0)
sw a1,-44(a0)
sw a1,-40(a0)
sw a1,-36(a0)
nop
nop # the extra nop instructions help to balance
nop # cycles needed for "store" + "fill" + "evict"
nop # For 64byte store there are needed 8 fill
nop # and 8 evict cycles, i.e. at least 32 instr.
nop
nop
pref 30,0(a0) # continue setting up the dest, addr 64-0
sw a1,-32(a0)
sw a1,-28(a0)
sw a1,-24(a0)
sw a1,-20(a0)
sw a1,-16(a0)
sw a1,-12(a0)
sw a1,-8(a0)
sw a1,-4(a0)
nop
nop
nop
nop # NOTE: adding 14 nop-s instead of 12 nop-s
nop # gives better results for "fast" memory
nop
bne a0,t4,.Lloop16w
nop
beq a0,a3,.Lchk8w # maybe no more 64-byte chunks?
nop # this "delayed slot" is useless ...
.Lloop16w_nopref30: # there could be up to 3 "64-byte nopref30" chunks
addiu a0,a0,64
sw a1,-64(a0)
sw a1,-60(a0)
sw a1,-56(a0)
sw a1,-52(a0)
sw a1,-48(a0)
sw a1,-44(a0)
sw a1,-40(a0)
sw a1,-36(a0)
sw a1,-32(a0)
sw a1,-28(a0)
sw a1,-24(a0)
sw a1,-20(a0)
sw a1,-16(a0)
sw a1,-12(a0)
sw a1,-8(a0)
bne a0,a3,.Lloop16w_nopref30
sw a1,-4(a0)
.Lchk8w: # t8 here is the byte count past 64-byte chunks
andi t7,t8,0x1f # is there a 32-byte chunk?
# the t7 is the reminder count past 32-bytes
beq t8,t7,.Lchk1w # when t8==t7, no 32-byte chunk
move a2,t7
sw a1,0(a0)
sw a1,4(a0)
sw a1,8(a0)
sw a1,12(a0)
sw a1,16(a0)
sw a1,20(a0)
sw a1,24(a0)
sw a1,28(a0)
addiu a0,a0,32
.Lchk1w:
andi t8,a2,0x3 # now t8 is the reminder past 1w chunks
beq a2,t8,.Llast4aligned
subu a3,a2,t8 # a3 is the count of bytes in 1w chunks
addu a3,a0,a3 # now a3 is the dst address past the 1w chunks
# copying in words (4-byte chunks)
.LwordCopy_loop:
addiu a0,a0,4
bne a0,a3,.LwordCopy_loop
sw a1,-4(a0)
# store last 0-3 bytes
# this will repeat the last store if the memset finishes on a word boundary
.Llast4aligned:
j ra
SWLO a1,-1(t0)
.Llast4:
beq a0,t0,.Llast4e
.Llast4l:
addiu a0,a0,1
bne a0,t0,.Llast4l
sb a1,-1(a0)
.Llast4e:
j ra
nop
.set at
.set reorder
END(memset)
/************************************************************************
* Implementation : Static functions
************************************************************************/

View File

@@ -0,0 +1,148 @@
/*
* Copyright (c) 2010 MIPS Technologies, Inc.
*
* 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 MIPS Technologies Inc. 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.
*/
#ifndef __MIPS_STRING_OPS_H
#define __MIPS_STRING_OPS_H
/* This definition of the byte bitfields uses the
assumption that the layout of the bitfields is
equivalent to the layout in memory. Generally,
for the MIPS ABIs, this is true. If you compile
the strcmp.c file with -DSMOKE_TEST_NEW_STRCMP,
this assumption will be tested.
Also, regardless of char signedness, ANSI C dictates that
strcmp() treats each character as unsigned char. For
strlen and the like, signedness doesn't matter.
Also, this code assumes that there are 8-bits per 'char'. */
#if __mips64
typedef struct bits
{
unsigned long B0:8, B1:8, B2:8, B3:8, B4:8, B5:8, B6:8, B7:8;
} bits_t;
#else
typedef struct bits
{
unsigned long B0:8, B1:8, B2:8, B3:8;
} bits_t;
#endif
#ifndef _ULW
/* for MIPS GCC, there is no unaligned builtins - so this code forces
the compiler to treat the pointer access as unaligned. */
struct ulw
{
unsigned long b;
} __attribute__ ((packed));
#define _ULW(__x) ((struct ulw *) ((char *)(&__x)))->b;
#endif
/* This union assumes that small structures can be in registers. If
not, then memory accesses will be done - not optimal, but ok. */
typedef union
{
unsigned long v;
bits_t b;
} bitfields_t;
#ifndef detect_zero
/* __mips_dsp, __mips_dspr2, and __mips64 are predefined by
the compiler, based on command line options. */
#if (__mips_dsp || __mips_dspr2) && !__mips64
#define __mips_using_dsp 1
/* DSP 4-lane (8 unsigned bits per line) subtract and saturate
* Intrinsic operation. How this works:
* Given a 4-byte string of "ABC\0", subtract this as
* an unsigned integer from 0x01010101:
* 0x01010101
* - 0x41424300
* -----------
( 0xbfbebe01 <-- answer without saturation
* 0x00000001 <-- answer with saturation
* When this 4-lane vector is treated as an unsigned int value,
* a non-zero answer indicates the presence of a zero in the
* original 4-byte argument. */
typedef signed char v4i8 __attribute__ ((vector_size (4)));
#define detect_zero(__x,__y,__01s,__80s)\
((unsigned) __builtin_mips_subu_s_qb((v4i8) __01s,(v4i8) __x))
/* sets all 4 lanes to requested byte. */
#define set_byte_lanes(__x) ((unsigned) __builtin_mips_repl_qb(__x))
/* sets all 4 lanes to 0x01. */
#define def_and_set_01(__x) unsigned long __x = (unsigned) __builtin_mips_repl_qb(0x01)
/* sets all 4 lanes to 0x80. Not needed when subu_s.qb used. */
#define def_and_set_80(__x) /* do nothing */
#else
/* this version, originally published in the 80's, uses
a reverse-carry-set like determination of the zero byte.
The steps are, for __x = 0x31ff0001:
__x - _01s = 0x30fdff00
~__x = 0xce00fffe
((__x - _01s) & ~__x) = 0x0000ff00
x & _80s = 0x00008000 <- byte 3 was zero
Some implementaions naively assume that characters are
always 7-bit unsigned ASCII. With that assumption, the
"& ~x" is usually discarded. Since character strings
are 8-bit, the and is needed to catch the case of
a false positive when the byte is 0x80. */
#define detect_zero(__x,__y,_01s,_80s)\
((unsigned) (((__x) - _01s) & ~(__x)) & _80s)
#if __mips64
#define def_and_set_80(__x) unsigned long __x = 0x8080808080808080ul
#define def_and_set_01(__x) unsigned long __x = 0x0101010101010101ul
#else
#define def_and_set_80(__x) unsigned long __x = 0x80808080ul
#define def_and_set_01(__x) unsigned long __x = 0x01010101ul
#endif
#endif
#endif
/* dealing with 'void *' conversions without using extra variables. */
#define get_byte(__x,__idx) (((unsigned char *) (__x))[__idx])
#define set_byte(__x,__idx,__fill) ((unsigned char *) (__x))[__idx] = (__fill)
#define get_word(__x,__idx) (((unsigned long *) (__x))[__idx])
#define set_word(__x,__idx,__fill) ((unsigned long *) (__x))[__idx] = (__fill)
#define inc_ptr_as(__type,__x,__inc) __x = (void *) (((__type) __x) + (__inc))
#define cvt_ptr_to(__type,__x) ((__type) (__x))
#endif

View File

@@ -0,0 +1,224 @@
/*
* Copyright (c) 2010 MIPS Technologies, Inc.
*
* 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 MIPS Technologies Inc. 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.
*/
#include <string.h>
#include "mips-string-ops.h"
#define do_strlen_word(__av) {\
if (detect_zero(x,x,_01s,_80s)) break;\
x = __av;\
cnt += sizeof (unsigned);\
}
#define do_strlen_byte(__x) {\
if ((bx.b.B##__x) == 0) break;\
++cnt;\
}
#if SMOKE_TEST_MIPS_STRLEN
#define strlen my_strlen
#endif
size_t
strlen (const char *_a)
{
int cnt = 0;
unsigned long x;
/* align the string to word boundary so we can do word at a time. */
if ((cvt_ptr_to (unsigned long, _a) & (sizeof (unsigned long) - 1)) != 0)
{
if ((cvt_ptr_to (unsigned long, _a) & 1) != 0)
{
if (get_byte (_a, 0) == 0)
return cnt;
/* set bit 1 so 2-bytes are checked and incremented. */
inc_ptr_as (char *, _a, 1);
++cnt;
}
if ((cvt_ptr_to (unsigned long, _a) & 2) != 0)
{
if (get_byte (_a, 0) == 0)
return cnt + 0;
if (get_byte (_a, 1) == 0)
return cnt + 1;
inc_ptr_as (char *, _a, 2);
cnt += 2;
}
}
#if __mips64
#error strlen: mips64 check for 4-byte alignment not implemented.
#endif
if (1)
{
def_and_set_01 (_01s);
def_and_set_80 (_80s);
/* as advantagous as it is to performance, this code cannot pre-load
the following word, nor can it prefetch the next line at the start
of the loop since the string can be at the end of a page with the
following page unmapped. There are tests in the suite to catch
any attempt to go beyond the current word. */
x = get_word (_a, 0);
while (1)
{
/* doing 8 words should cover most strings. */
do_strlen_word (get_word (_a, 1));
do_strlen_word (get_word (_a, 2));
do_strlen_word (get_word (_a, 3));
do_strlen_word (get_word (_a, 4));
do_strlen_word (get_word (_a, 5));
do_strlen_word (get_word (_a, 6));
do_strlen_word (get_word (_a, 7));
do_strlen_word (get_word (_a, 8));
inc_ptr_as (unsigned long*, _a, 8);
}
}
while (1)
{
/* pull apart the last word processed and find the zero. */
bitfields_t bx;
bx.v = x;
#if __mips64
do_strlen_byte (0);
do_strlen_byte (1);
do_strlen_byte (2);
do_strlen_byte (3);
do_strlen_byte (4);
do_strlen_byte (5);
do_strlen_byte (6);
#else
do_strlen_byte (0);
do_strlen_byte (1);
do_strlen_byte (2);
#endif
/* last byte is zero */
break;
}
return cnt;
}
#undef do_strlen_byte
#undef do_strlen_word
#if SMOKE_TEST_MIPS_STRLEN
#include <stdio.h>
char str1[] = "DHRYSTONE PROGRAM, 1'ST STRING";
char str2[] = "DHRYSTONE PROGRAM, 2'ST STRING";
char str3[] = "another string";
char str4[] = "another";
char str5[] = "somes tring";
char str6[] = "somes_tring";
char str7[16], str8[16];
static char *
chk (unsigned long mine, unsigned long libs, int *errors)
{
static char answer[1024];
char *result = mine == libs ? "PASS" : "FAIL";
sprintf (answer, "new_strlen=%d: lib_strlen=%d: %s!", mine, libs, result);
if (mine != libs)
(*errors)++;
return answer;
}
int
main (int argc, char **argv)
{
int errors = 0;
/* set -1 in one position */
str6[5] = 0xff;
/* set zero in same position with junk in following 3 */
str7[0] = str8[0] = 0;
str7[1] = 0xff;
str7[2] = 'a';
str7[3] = 2;
str8[1] = 's';
str8[2] = -2;
str8[3] = 0;
fprintf (stderr, "========== mips_strlen%s test...\n",
argv[0] ? argv[0] : "unknown strlen");
#define P(__x,__y) {\
int a = my_strlen(__x + __y);\
int b = (strlen)(__x + __y) /* library version */;\
fprintf(stderr,"%s+%d: %s\n",#__x,__y,chk(a,b,&errors));\
}
P (str1, 0);
P (str1, 1);
P (str1, 2);
P (str1, 3);
P (str2, 0);
P (str2, 1);
P (str2, 2);
P (str2, 3);
P (str3, 0);
P (str3, 1);
P (str3, 2);
P (str3, 3);
P (str4, 0);
P (str4, 1);
P (str4, 2);
P (str4, 3);
P (str5, 0);
P (str5, 1);
P (str5, 2);
P (str5, 3);
P (str6, 0);
P (str6, 1);
P (str6, 2);
P (str6, 3);
P (str7, 0);
P (str7, 1);
P (str7, 2);
P (str7, 3);
P (str8, 0);
P (str8, 1);
P (str8, 2);
P (str8, 3);
return errors;
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,25 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_readv)
.set push
.set noreorder
li v0, __NR_process_vm_readv
syscall
bnez a3, 1f
move a0, v0
j ra
nop
1:
move t0, ra
bal 2f
nop
2:
.cpsetup ra, t1, 2b
LA t9,__set_errno_internal
.cpreturn
j t9
move ra, t0
.set pop
END(process_vm_readv)

View File

@@ -1,25 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_writev)
.set push
.set noreorder
li v0, __NR_process_vm_writev
syscall
bnez a3, 1f
move a0, v0
j ra
nop
1:
move t0, ra
bal 2f
nop
2:
.cpsetup ra, t1, 2b
LA t9,__set_errno_internal
.cpreturn
j t9
move ra, t0
.set pop
END(process_vm_writev)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,46 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_readv)
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_rel_offset ebx, 0
pushl %ecx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset ecx, 0
pushl %edx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset edx, 0
pushl %esi
.cfi_adjust_cfa_offset 4
.cfi_rel_offset esi, 0
pushl %edi
.cfi_adjust_cfa_offset 4
.cfi_rel_offset edi, 0
pushl %ebp
.cfi_adjust_cfa_offset 4
.cfi_rel_offset ebp, 0
mov 28(%esp), %ebx
mov 32(%esp), %ecx
mov 36(%esp), %edx
mov 40(%esp), %esi
mov 44(%esp), %edi
mov 48(%esp), %ebp
movl $__NR_process_vm_readv, %eax
int $0x80
cmpl $-MAX_ERRNO, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno_internal
addl $4, %esp
1:
popl %ebp
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
ret
END(process_vm_readv)

View File

@@ -1,46 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_writev)
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_rel_offset ebx, 0
pushl %ecx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset ecx, 0
pushl %edx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset edx, 0
pushl %esi
.cfi_adjust_cfa_offset 4
.cfi_rel_offset esi, 0
pushl %edi
.cfi_adjust_cfa_offset 4
.cfi_rel_offset edi, 0
pushl %ebp
.cfi_adjust_cfa_offset 4
.cfi_rel_offset ebp, 0
mov 28(%esp), %ebx
mov 32(%esp), %ecx
mov 36(%esp), %edx
mov 40(%esp), %esi
mov 44(%esp), %edi
mov 48(%esp), %ebp
movl $__NR_process_vm_writev, %eax
int $0x80
cmpl $-MAX_ERRNO, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno_internal
addl $4, %esp
1:
popl %ebp
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
ret
END(process_vm_writev)

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___clock_nanosleep)
ENTRY(__clock_nanosleep)
movq %rcx, %r10
movl $__NR_clock_nanosleep, %eax
syscall
@@ -13,5 +13,5 @@ ENTRY(___clock_nanosleep)
call __set_errno_internal
1:
ret
END(___clock_nanosleep)
.hidden ___clock_nanosleep
END(__clock_nanosleep)
.hidden __clock_nanosleep

View File

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

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___fgetxattr)
ENTRY(fgetxattr)
movq %rcx, %r10
movl $__NR_fgetxattr, %eax
syscall
@@ -13,5 +13,4 @@ ENTRY(___fgetxattr)
call __set_errno_internal
1:
ret
END(___fgetxattr)
.hidden ___fgetxattr
END(fgetxattr)

View File

@@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(___fsetxattr)
ENTRY(fsetxattr)
movq %rcx, %r10
movl $__NR_fsetxattr, %eax
syscall
@@ -13,5 +13,4 @@ ENTRY(___fsetxattr)
call __set_errno_internal
1:
ret
END(___fsetxattr)
.hidden ___fsetxattr
END(fsetxattr)

View File

@@ -1,16 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_readv)
movq %rcx, %r10
movl $__NR_process_vm_readv, %eax
syscall
cmpq $-MAX_ERRNO, %rax
jb 1f
negl %eax
movl %eax, %edi
call __set_errno_internal
1:
ret
END(process_vm_readv)

View File

@@ -1,16 +0,0 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(process_vm_writev)
movq %rcx, %r10
movl $__NR_process_vm_writev, %eax
syscall
cmpq $-MAX_ERRNO, %rax
jb 1f
negl %eax
movl %eax, %edi
call __set_errno_internal
1:
ret
END(process_vm_writev)

View File

@@ -21,7 +21,6 @@
#include <stdlib.h>
#include <string.h>
#include "private/bionic_lock.h"
#include "private/bionic_systrace.h"
#include "private/libc_logging.h"
@@ -30,17 +29,12 @@
#define WRITE_OFFSET 32
constexpr char SYSTRACE_PROPERTY_NAME[] = "debug.atrace.tags.enableflags";
static Lock g_lock;
static const prop_info* g_pinfo;
static const prop_info* g_pinfo = NULL;
static uint32_t g_serial = -1;
static uint64_t g_tags;
static uint64_t g_tags = 0;
static int g_trace_marker_fd = -1;
static bool should_trace() {
bool result = false;
g_lock.lock();
// If g_pinfo is null, this means that systrace hasn't been run and it's safe to
// assume that no trace writing will need to take place. However, to avoid running
// this costly find check each time, we set it to a non-tracing value so that next
@@ -48,39 +42,32 @@ static bool should_trace() {
// this function also deals with the bootup case, during which the call to property
// set will fail if the property server hasn't yet started.
if (g_pinfo == NULL) {
g_pinfo = __system_property_find(SYSTRACE_PROPERTY_NAME);
g_pinfo = __system_property_find("debug.atrace.tags.enableflags");
if (g_pinfo == NULL) {
__system_property_set(SYSTRACE_PROPERTY_NAME, "0");
g_pinfo = __system_property_find(SYSTRACE_PROPERTY_NAME);
__system_property_set("debug.atrace.tags.enableflags", "0");
g_pinfo = __system_property_find("debug.atrace.tags.enableflags");
if (g_pinfo == NULL) {
return false;
}
}
}
if (g_pinfo != NULL) {
// Find out which tags have been enabled on the command line and set
// the value of tags accordingly. If the value of the property changes,
// the serial will also change, so the costly system_property_read function
// can be avoided by calling the much cheaper system_property_serial
// first. The values within pinfo may change, but its location is guaranteed
// not to move.
uint32_t cur_serial = __system_property_serial(g_pinfo);
if (cur_serial != g_serial) {
g_serial = cur_serial;
char value[PROP_VALUE_MAX];
__system_property_read(g_pinfo, 0, value);
g_tags = strtoull(value, NULL, 0);
}
result = ((g_tags & ATRACE_TAG_BIONIC) != 0);
}
g_lock.unlock();
return result;
}
static int get_trace_marker_fd() {
g_lock.lock();
if (g_trace_marker_fd == -1) {
g_trace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_CLOEXEC | O_WRONLY);
// Find out which tags have been enabled on the command line and set
// the value of tags accordingly. If the value of the property changes,
// the serial will also change, so the costly system_property_read function
// can be avoided by calling the much cheaper system_property_serial
// first. The values within pinfo may change, but its location is guaranteed
// not to move.
const uint32_t cur_serial = __system_property_serial(g_pinfo);
if (cur_serial != g_serial) {
g_serial = cur_serial;
char value[PROP_VALUE_MAX];
__system_property_read(g_pinfo, 0, value);
g_tags = strtoull(value, NULL, 0);
}
g_lock.unlock();
return g_trace_marker_fd;
// Finally, verify that this tag value enables bionic tracing.
return ((g_tags & ATRACE_TAG_BIONIC) != 0);
}
ScopedTrace::ScopedTrace(const char* message) {
@@ -88,9 +75,11 @@ ScopedTrace::ScopedTrace(const char* message) {
return;
}
int trace_marker_fd = get_trace_marker_fd();
if (trace_marker_fd == -1) {
return;
if (g_trace_marker_fd == -1) {
g_trace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_CLOEXEC | O_WRONLY);
if (g_trace_marker_fd == -1) {
__libc_fatal("Could not open kernel trace file: %s\n", strerror(errno));
}
}
// If bionic tracing has been enabled, then write the message to the
@@ -98,10 +87,12 @@ ScopedTrace::ScopedTrace(const char* message) {
int length = strlen(message);
char buf[length + WRITE_OFFSET];
size_t len = snprintf(buf, length + WRITE_OFFSET, "B|%d|%s", getpid(), message);
ssize_t wbytes = TEMP_FAILURE_RETRY(write(g_trace_marker_fd, buf, len));
// Tracing may stop just after checking property and before writing the message.
// So the write is acceptable to fail. See b/20666100.
TEMP_FAILURE_RETRY(write(trace_marker_fd, buf, len));
// Error while writing
if (static_cast<size_t>(wbytes) != len) {
__libc_fatal("Could not write to kernel trace file: %s\n", strerror(errno));
}
}
ScopedTrace::~ScopedTrace() {
@@ -109,10 +100,10 @@ ScopedTrace::~ScopedTrace() {
return;
}
int trace_marker_fd = get_trace_marker_fd();
if (trace_marker_fd == -1) {
return;
}
ssize_t wbytes = TEMP_FAILURE_RETRY(write(g_trace_marker_fd, "E", 1));
TEMP_FAILURE_RETRY(write(trace_marker_fd, "E", 1));
// Error while writing
if (static_cast<size_t>(wbytes) != 1) {
__libc_fatal("Could not write to kernel trace file: %s\n", strerror(errno));
}
}

View File

@@ -30,9 +30,9 @@
#include "private/ErrnoRestorer.h"
extern "C" int ___clock_nanosleep(clockid_t, int, const timespec*, timespec*);
extern "C" int __clock_nanosleep(clockid_t, int, const timespec*, timespec*);
int clock_nanosleep(clockid_t clock_id, int flags, const timespec* in, timespec* out) {
ErrnoRestorer errno_restorer;
return (___clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
return (__clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
}

View File

@@ -27,7 +27,6 @@
*/
#include <ctype.h>
#include <elf.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
@@ -36,22 +35,14 @@
#include "debug_mapinfo.h"
#include "malloc_debug_disable.h"
#if defined(__LP64__)
#define Elf_W(x) Elf64_##x
#else
#define Elf_W(x) Elf32_##x
#endif
// Format of /proc/<PID>/maps:
// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so
static mapinfo_t* parse_maps_line(char* line) {
uintptr_t start;
uintptr_t end;
uintptr_t offset;
char permissions[4];
int name_pos;
if (sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %4s %" PRIxPTR " %*x:%*x %*d%n", &start,
&end, permissions, &offset, &name_pos) < 2) {
if (sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d%n", &start,
&end, &name_pos) < 2) {
return NULL;
}
@@ -68,14 +59,6 @@ static mapinfo_t* parse_maps_line(char* line) {
if (mi) {
mi->start = start;
mi->end = end;
mi->offset = offset;
if (permissions[0] != 'r') {
// Any unreadable map will just get a zero load base.
mi->load_base = 0;
mi->load_base_read = true;
} else {
mi->load_base_read = false;
}
memcpy(mi->name, name, name_len);
mi->name[name_len] = '\0';
}
@@ -112,58 +95,11 @@ __LIBC_HIDDEN__ void mapinfo_destroy(mapinfo_t* mi) {
}
}
template<typename T>
static inline bool get_val(mapinfo_t* mi, uintptr_t addr, T* store) {
if (addr < mi->start || addr + sizeof(T) > mi->end) {
return false;
}
// Make sure the address is aligned properly.
if (addr & (sizeof(T)-1)) {
return false;
}
*store = *reinterpret_cast<T*>(addr);
return true;
}
__LIBC_HIDDEN__ void mapinfo_read_loadbase(mapinfo_t* mi) {
mi->load_base = 0;
mi->load_base_read = true;
uintptr_t addr = mi->start;
Elf_W(Ehdr) ehdr;
if (!get_val<Elf_W(Half)>(mi, addr + offsetof(Elf_W(Ehdr), e_phnum), &ehdr.e_phnum)) {
return;
}
if (!get_val<Elf_W(Off)>(mi, addr + offsetof(Elf_W(Ehdr), e_phoff), &ehdr.e_phoff)) {
return;
}
addr += ehdr.e_phoff;
for (size_t i = 0; i < ehdr.e_phnum; i++) {
Elf_W(Phdr) phdr;
if (!get_val<Elf_W(Word)>(mi, addr + offsetof(Elf_W(Phdr), p_type), &phdr.p_type)) {
return;
}
if (!get_val<Elf_W(Off)>(mi, addr + offsetof(Elf_W(Phdr), p_offset), &phdr.p_offset)) {
return;
}
if (phdr.p_type == PT_LOAD && phdr.p_offset == mi->offset) {
if (!get_val<Elf_W(Addr)>(mi, addr + offsetof(Elf_W(Phdr), p_vaddr), &phdr.p_vaddr)) {
return;
}
mi->load_base = phdr.p_vaddr;
return;
}
addr += sizeof(phdr);
}
}
// Find the containing map info for the PC.
__LIBC_HIDDEN__ const mapinfo_t* mapinfo_find(mapinfo_t* mi, uintptr_t pc, uintptr_t* rel_pc) {
for (; mi != NULL; mi = mi->next) {
if ((pc >= mi->start) && (pc < mi->end)) {
if (!mi->load_base_read) {
mapinfo_read_loadbase(mi);
}
*rel_pc = pc - mi->start + mi->load_base;
*rel_pc = pc - mi->start;
return mi;
}
}

View File

@@ -35,9 +35,6 @@ struct mapinfo_t {
struct mapinfo_t* next;
uintptr_t start;
uintptr_t end;
uintptr_t offset;
uintptr_t load_base;
bool load_base_read;
char name[];
};

View File

@@ -41,19 +41,13 @@
extern "C" int __getdents64(unsigned int, dirent*, unsigned int);
// Apportable decided to copy the data structure from this file
// and use it in their own code, but they also call into readdir.
// In order to avoid a lockup, the structure must be maintained in
// the exact same order as in L and below. New structure members
// need to be added to the end of this structure.
// See b/21037208 for more details.
struct DIR {
int fd_;
size_t available_bytes_;
dirent* next_;
long current_pos_;
pthread_mutex_t mutex_;
dirent buff_[15];
long current_pos_;
};
static DIR* __allocate_DIR(int fd) {

View File

@@ -44,13 +44,11 @@
#define dlmalloc dlmalloc_real
#endif
/* These two symbols are exported on devices that use dlmalloc.
* In order to be consistent across all devices, they will
* be exported everywhere. Move the real symbols out of the way
* so that ndk_cruft.cpp can export these symbols.
*/
#define dlmalloc_inspect_all dlmalloc_inspect_all_real
#define dlmalloc_trim dlmalloc_trim_real
/* Export two symbols used by the VM. */
__BEGIN_DECLS
int dlmalloc_trim(size_t) __LIBC_ABI_PUBLIC__;
void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void*) __LIBC_ABI_PUBLIC__;
__END_DECLS
/* Include the proper definitions. */
#include "../upstream-dlmalloc/malloc.h"

View File

@@ -1,59 +0,0 @@
/*
* 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.
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
extern "C" int ___fsetxattr(int, const char*, const void*, size_t, int);
int fsetxattr(int fd, const char* name, const void* value, size_t size, int flags) {
int saved_errno = errno;
int result = ___fsetxattr(fd, name, value, size, flags);
if ((result == 0) || (errno != EBADF)) {
return result;
}
// fd could be an O_PATH file descriptor, and the kernel
// may not directly support fsetxattr() on such a file descriptor.
// Use /proc/self/fd instead to emulate this support.
int fd_flag = fcntl(fd, F_GETFL);
if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
errno = EBADF;
return -1;
}
char buf[40];
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
errno = saved_errno;
return setxattr(buf, name, value, size, flags);
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <sys/cdefs.h>
#include <unistd.h>
#if !defined(__LP64__)
static_assert(sizeof(off_t) == 4,
"libc can't be built with _FILE_OFFSET_BITS=64.");
// The kernel's implementation of ftruncate uses an unsigned long for the length
// parameter, so it will not catch negative values. On the other hand
// ftruncate64 does check for this, so just forward the call.
int ftruncate(int filedes, off_t length) {
return ftruncate64(filedes, length);
}
#endif // !defined(__LP64__)

View File

@@ -30,14 +30,11 @@
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/auxv.h>
#include <sys/personality.h>
#include <sys/time.h>
#include <unistd.h>
@@ -45,7 +42,6 @@
#include "private/bionic_ssp.h"
#include "private/bionic_tls.h"
#include "private/KernelArgumentBlock.h"
#include "private/libc_logging.h"
#include "pthread_internal.h"
extern "C" abort_msg_t** __abort_message_ptr;
@@ -124,213 +120,6 @@ void __libc_init_common(KernelArgumentBlock& args) {
__libc_init_vdso();
}
__noreturn static void __early_abort(int line) {
// We can't write to stdout or stderr because we're aborting before we've checked that
// it's safe for us to use those file descriptors. We probably can't strace either, so
// we rely on the fact that if we dereference a low address, either debuggerd or the
// kernel's crash dump will show the fault address.
*reinterpret_cast<int*>(line) = 0;
_exit(EXIT_FAILURE);
}
// Force any of the closed stdin, stdout and stderr to be associated with /dev/null.
static void __nullify_closed_stdio() {
int dev_null = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
if (dev_null == -1) {
// init won't have /dev/null available, but SELinux provides an equivalent.
dev_null = TEMP_FAILURE_RETRY(open("/sys/fs/selinux/null", O_RDWR));
}
if (dev_null == -1) {
__early_abort(__LINE__);
}
// If any of the stdio file descriptors is valid and not associated
// with /dev/null, dup /dev/null to it.
for (int i = 0; i < 3; i++) {
// If it is /dev/null already, we are done.
if (i == dev_null) {
continue;
}
// Is this fd already open?
int status = TEMP_FAILURE_RETRY(fcntl(i, F_GETFL));
if (status != -1) {
continue;
}
// The only error we allow is that the file descriptor does not
// exist, in which case we dup /dev/null to it.
if (errno == EBADF) {
// Try dupping /dev/null to this stdio file descriptor and
// repeat if there is a signal. Note that any errors in closing
// the stdio descriptor are lost.
status = TEMP_FAILURE_RETRY(dup2(dev_null, i));
if (status == -1) {
__early_abort(__LINE__);
}
} else {
__early_abort(__LINE__);
}
}
// If /dev/null is not one of the stdio file descriptors, close it.
if (dev_null > 2) {
if (close(dev_null) == -1) {
__early_abort(__LINE__);
}
}
}
// Check if the environment variable definition at 'envstr'
// starts with '<name>=', and if so return the address of the
// first character after the equal sign. Otherwise return null.
static const char* env_match(const char* envstr, const char* name) {
size_t i = 0;
while (envstr[i] == name[i] && name[i] != '\0') {
++i;
}
if (name[i] == '\0' && envstr[i] == '=') {
return envstr + i + 1;
}
return nullptr;
}
static bool __is_valid_environment_variable(const char* name) {
// According to the kernel source, by default the kernel uses 32*PAGE_SIZE
// as the maximum size for an environment variable definition.
const int MAX_ENV_LEN = 32*4096;
if (name == nullptr) {
return false;
}
// Parse the string, looking for the first '=' there, and its size.
int pos = 0;
int first_equal_pos = -1;
while (pos < MAX_ENV_LEN) {
if (name[pos] == '\0') {
break;
}
if (name[pos] == '=' && first_equal_pos < 0) {
first_equal_pos = pos;
}
pos++;
}
// Check that it's smaller than MAX_ENV_LEN (to detect non-zero terminated strings).
if (pos >= MAX_ENV_LEN) {
return false;
}
// Check that it contains at least one equal sign that is not the first character
if (first_equal_pos < 1) {
return false;
}
return true;
}
static bool __is_unsafe_environment_variable(const char* name) {
// None of these should be allowed in setuid programs.
static const char* const UNSAFE_VARIABLE_NAMES[] = {
"GCONV_PATH",
"GETCONF_DIR",
"HOSTALIASES",
"JE_MALLOC_CONF",
"LD_AOUT_LIBRARY_PATH",
"LD_AOUT_PRELOAD",
"LD_AUDIT",
"LD_DEBUG",
"LD_DEBUG_OUTPUT",
"LD_DYNAMIC_WEAK",
"LD_LIBRARY_PATH",
"LD_ORIGIN_PATH",
"LD_PRELOAD",
"LD_PROFILE",
"LD_SHOW_AUXV",
"LD_USE_LOAD_BIAS",
"LOCALDOMAIN",
"LOCPATH",
"MALLOC_CHECK_",
"MALLOC_CONF",
"MALLOC_TRACE",
"NIS_PATH",
"NLSPATH",
"RESOLV_HOST_CONF",
"RES_OPTIONS",
"TMPDIR",
"TZDIR",
nullptr
};
for (size_t i = 0; UNSAFE_VARIABLE_NAMES[i] != nullptr; ++i) {
if (env_match(name, UNSAFE_VARIABLE_NAMES[i]) != nullptr) {
return true;
}
}
return false;
}
static void __sanitize_environment_variables(char** env) {
bool is_AT_SECURE = getauxval(AT_SECURE);
char** src = env;
char** dst = env;
for (; src[0] != nullptr; ++src) {
if (!__is_valid_environment_variable(src[0])) {
continue;
}
// Remove various unsafe environment variables if we're loading a setuid program.
if (is_AT_SECURE && __is_unsafe_environment_variable(src[0])) {
continue;
}
dst[0] = src[0];
++dst;
}
dst[0] = nullptr;
}
static void __initialize_personality() {
#if !defined(__LP64__)
int old_value = personality(0xffffffff);
if (old_value == -1) {
__libc_fatal("error getting old personality value: %s", strerror(errno));
}
if (personality((static_cast<unsigned int>(old_value) & ~PER_MASK) | PER_LINUX32) == -1) {
__libc_fatal("error setting PER_LINUX32 personality: %s", strerror(errno));
}
#endif
}
void __libc_init_AT_SECURE(KernelArgumentBlock& args) {
__libc_auxv = args.auxv;
// Check that the kernel provided a value for AT_SECURE.
bool found_AT_SECURE = false;
for (ElfW(auxv_t)* v = __libc_auxv; v->a_type != AT_NULL; ++v) {
if (v->a_type == AT_SECURE) {
found_AT_SECURE = true;
break;
}
}
if (!found_AT_SECURE) __early_abort(__LINE__);
if (getauxval(AT_SECURE)) {
// 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
__nullify_closed_stdio();
__sanitize_environment_variables(args.envp);
}
// Now the environment has been sanitized, make it available.
environ = args.envp;
__initialize_personality();
}
/* This function will be called during normal program termination
* to run the destructors that are listed in the .fini_array section
* of the executable, if any.

View File

@@ -49,12 +49,8 @@ __LIBC_HIDDEN__ void __libc_fini(void* finit_array);
__END_DECLS
#if defined(__cplusplus)
class KernelArgumentBlock;
__LIBC_HIDDEN__ void __libc_init_common(KernelArgumentBlock& args);
__LIBC_HIDDEN__ void __libc_init_AT_SECURE(KernelArgumentBlock& args);
#endif
#endif

View File

@@ -91,7 +91,6 @@ __noreturn void __libc_init(void* raw_args,
structors_array_t const * const structors) {
KernelArgumentBlock args(raw_args);
__libc_init_tls(args);
__libc_init_AT_SECURE(args);
__libc_init_common(args);
apply_gnu_relro();

View File

@@ -133,9 +133,8 @@ static HashEntry* record_backtrace(uintptr_t* backtrace, size_t numEntries, size
size |= SIZE_FLAG_ZYGOTE_CHILD;
}
// Keep the lock held for as little time as possible to prevent deadlocks.
ScopedPthreadMutexLocker locker(&g_hash_table->lock);
HashEntry* entry = find_entry(g_hash_table, slot, backtrace, numEntries, size);
if (entry != NULL) {
entry->allocations++;
} else {
@@ -303,6 +302,8 @@ extern "C" void* leak_malloc(size_t bytes) {
void* base = g_malloc_dispatch->malloc(size);
if (base != NULL) {
ScopedPthreadMutexLocker locker(&g_hash_table->lock);
uintptr_t backtrace[BACKTRACE_SIZE];
size_t numEntries = GET_BACKTRACE(backtrace, BACKTRACE_SIZE);
@@ -327,6 +328,8 @@ extern "C" void leak_free(void* mem) {
return;
}
ScopedPthreadMutexLocker locker(&g_hash_table->lock);
// check the guard to make sure it is valid
AllocationEntry* header = to_header(mem);
@@ -339,7 +342,6 @@ extern "C" void leak_free(void* mem) {
}
}
ScopedPthreadMutexLocker locker(&g_hash_table->lock);
if (header->guard == GUARD || is_valid_entry(header->entry)) {
// decrement the allocations
HashEntry* entry = header->entry;

View File

@@ -340,7 +340,7 @@ extern "C" pid_t __pthread_gettid(pthread_t t) {
return pthread_gettid_np(t);
}
// Older versions of apportable used dlmalloc directly instead of malloc,
// Older versions of appportable used dlmalloc directly instead of malloc,
// so export this compatibility shim that simply calls malloc.
extern "C" void* dlmalloc(size_t size) {
return malloc(size);
@@ -369,26 +369,3 @@ extern "C" void endusershell() { }
// This is never implemented in bionic, only needed for ABI compatibility with the NDK.
extern "C" void endpwent() { }
// Since dlmalloc_inspect_all and dlmalloc_trim are exported for systems
// that use dlmalloc, be consistent and export them everywhere.
#if defined(USE_JEMALLOC)
extern "C" void dlmalloc_inspect_all(void (*)(void*, void*, size_t, void*), void*) {
}
#else
extern "C" void dlmalloc_inspect_all_real(void (*)(void*, void*, size_t, void*), void*);
extern "C" void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg) {
dlmalloc_inspect_all_real(handler, arg);
}
#endif
#if defined(USE_JEMALLOC)
extern "C" int dlmalloc_trim(size_t) {
return 0;
}
#else
extern "C" int dlmalloc_trim_real(size_t);
extern "C" int dlmalloc_trim(size_t pad) {
return dlmalloc_trim_real(pad);
}
#endif

View File

@@ -130,13 +130,8 @@ __LIBC_HIDDEN__ void pthread_key_clean_all(void);
*/
#define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGSTKSZ)
// Leave room for a guard page in the internally created signal stacks.
#if defined(__LP64__)
// SIGSTKSZ is not big enough for 64-bit arch. See http://b/23041777.
#define SIGNAL_STACK_SIZE (16 * 1024 + PAGE_SIZE)
#else
/* Leave room for a guard page in the internally created signal stacks. */
#define SIGNAL_STACK_SIZE (SIGSTKSZ + PAGE_SIZE)
#endif
/* Needed by fork. */
__LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();

View File

@@ -501,12 +501,6 @@ static int __pthread_mutex_lock_with_timeout(pthread_mutex_internal_t* mutex,
}
int pthread_mutex_lock(pthread_mutex_t* mutex_interface) {
#if !defined(__LP64__)
if (mutex_interface == NULL) {
return EINVAL;
}
#endif
pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
@@ -522,12 +516,6 @@ int pthread_mutex_lock(pthread_mutex_t* mutex_interface) {
}
int pthread_mutex_unlock(pthread_mutex_t* mutex_interface) {
#if !defined(__LP64__)
if (mutex_interface == NULL) {
return EINVAL;
}
#endif
pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);

View File

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

View File

@@ -53,37 +53,10 @@ struct addrinfo;
#define __used_in_netd __attribute__((visibility ("default")))
/*
* A struct to capture context relevant to network operations.
*
* Application and DNS netids/marks can differ from one another under certain
* circumstances, notably when a VPN applies to the given uid's traffic but the
* VPN network does not have its own DNS servers explicitly provisioned.
*
* The introduction of per-UID routing means the uid is also an essential part
* of the evaluation context. Its proper uninitialized value is
* NET_CONTEXT_INVALID_UID.
*/
struct android_net_context {
unsigned app_netid;
unsigned app_mark;
unsigned dns_netid;
unsigned dns_mark;
uid_t uid;
} __attribute__((packed));
#define NET_CONTEXT_INVALID_UID ((uid_t)-1)
struct hostent *android_gethostbyaddrfornet(const void *, socklen_t, int, unsigned, unsigned) __used_in_netd;
struct hostent *android_gethostbynamefornet(const char *, int, unsigned, unsigned) __used_in_netd;
int android_getaddrinfofornet(const char *, const char *, const struct addrinfo *, unsigned,
unsigned, struct addrinfo **) __used_in_netd;
/*
* TODO: consider refactoring android_getaddrinfo_proxy() to serve as an
* explore_fqdn() dispatch table method, with the below function only making DNS calls.
*/
int android_getaddrinfofornetcontext(const char *, const char *, const struct addrinfo *,
const struct android_net_context *, struct addrinfo **) __used_in_netd;
unsigned, struct addrinfo **) __used_in_netd;
/* set name servers for a network */
extern void _resolv_set_nameservers_for_net(unsigned netid,

View File

@@ -218,7 +218,7 @@ struct res_target {
static int str2number(const char *);
static int explore_fqdn(const struct addrinfo *, const char *,
const char *, struct addrinfo **, const struct android_net_context *);
const char *, struct addrinfo **, unsigned netid, unsigned mark);
static int explore_null(const struct addrinfo *,
const char *, struct addrinfo **);
static int explore_numeric(const struct addrinfo *, const char *,
@@ -244,7 +244,6 @@ static void _endhtent(FILE **);
static struct addrinfo *_gethtent(FILE **, const char *,
const struct addrinfo *);
static int _files_getaddrinfo(void *, void *, va_list);
static int _find_src_addr(const struct sockaddr *, struct sockaddr *, unsigned , uid_t);
static int res_queryN(const char *, struct res_target *, res_state);
static int res_searchN(const char *, struct res_target *, res_state);
@@ -360,6 +359,29 @@ str2number(const char *p)
return -1;
}
/*
* Connect a UDP socket to a given unicast address. This will cause no network
* traffic, but will fail fast if the system has no or limited reachability to
* the destination (e.g., no IPv4 address, no IPv6 default route, ...).
*/
static int
_test_connect(int pf, struct sockaddr *addr, size_t addrlen, unsigned mark) {
int s = socket(pf, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
if (s < 0)
return 0;
if (mark != MARK_UNSET && setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
return 0;
int ret;
do {
ret = __connect(s, addr, addrlen);
} while (ret < 0 && errno == EINTR);
int success = (ret == 0);
do {
ret = close(s);
} while (ret < 0 && errno == EINTR);
return success;
}
/*
* The following functions determine whether IPv4 or IPv6 connectivity is
* available in order to implement AI_ADDRCONFIG.
@@ -370,24 +392,24 @@ str2number(const char *p)
* so checking for connectivity is the next best thing.
*/
static int
_have_ipv6(unsigned mark, uid_t uid) {
_have_ipv6(unsigned mark) {
static const struct sockaddr_in6 sin6_test = {
.sin6_family = AF_INET6,
.sin6_addr.s6_addr = { // 2000::
0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
sockaddr_union addr = { .in6 = sin6_test };
return _find_src_addr(&addr.generic, NULL, mark, uid) == 1;
return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6), mark);
}
static int
_have_ipv4(unsigned mark, uid_t uid) {
_have_ipv4(unsigned mark) {
static const struct sockaddr_in sin_test = {
.sin_family = AF_INET,
.sin_addr.s_addr = __constant_htonl(0x08080808L) // 8.8.8.8
};
sockaddr_union addr = { .in = sin_test };
return _find_src_addr(&addr.generic, NULL, mark, uid) == 1;
return _test_connect(PF_INET, &addr.generic, sizeof(addr.in), mark);
}
bool readBE32(FILE* fp, int32_t* result) {
@@ -452,7 +474,7 @@ android_getaddrinfo_proxy(
int result_code = (int)strtol(buf, NULL, 10);
// verify the code itself
if (result_code != DnsProxyQueryResult) {
if (result_code != DnsProxyQueryResult ) {
fread(buf, 1, sizeof(buf), proxy);
goto exit;
}
@@ -566,21 +588,6 @@ getaddrinfo(const char *hostname, const char *servname,
int
android_getaddrinfofornet(const char *hostname, const char *servname,
const struct addrinfo *hints, unsigned netid, unsigned mark, struct addrinfo **res)
{
struct android_net_context netcontext = {
.app_netid = netid,
.app_mark = mark,
.dns_netid = netid,
.dns_mark = mark,
.uid = NET_CONTEXT_INVALID_UID,
};
return android_getaddrinfofornetcontext(hostname, servname, hints, &netcontext, res);
}
int
android_getaddrinfofornetcontext(const char *hostname, const char *servname,
const struct addrinfo *hints, const struct android_net_context *netcontext,
struct addrinfo **res)
{
struct addrinfo sentinel;
struct addrinfo *cur;
@@ -594,7 +601,6 @@ android_getaddrinfofornetcontext(const char *hostname, const char *servname,
/* servname is allowed to be NULL */
/* hints is allowed to be NULL */
assert(res != NULL);
assert(netcontext != NULL);
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
pai = &ai;
@@ -725,8 +731,7 @@ android_getaddrinfofornetcontext(const char *hostname, const char *servname,
ERR(EAI_NONAME);
#if defined(__ANDROID__)
int gai_error = android_getaddrinfo_proxy(
hostname, servname, hints, res, netcontext->app_netid);
int gai_error = android_getaddrinfo_proxy(hostname, servname, hints, res, netid);
if (gai_error != EAI_SYSTEM) {
return gai_error;
}
@@ -758,8 +763,8 @@ android_getaddrinfofornetcontext(const char *hostname, const char *servname,
if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
pai->ai_protocol = ex->e_protocol;
error = explore_fqdn(
pai, hostname, servname, &cur->ai_next, netcontext);
error = explore_fqdn(pai, hostname, servname,
&cur->ai_next, netid, mark);
while (cur && cur->ai_next)
cur = cur->ai_next;
@@ -792,8 +797,7 @@ android_getaddrinfofornetcontext(const char *hostname, const char *servname,
*/
static int
explore_fqdn(const struct addrinfo *pai, const char *hostname,
const char *servname, struct addrinfo **res,
const struct android_net_context *netcontext)
const char *servname, struct addrinfo **res, unsigned netid, unsigned mark)
{
struct addrinfo *result;
struct addrinfo *cur;
@@ -819,7 +823,7 @@ explore_fqdn(const struct addrinfo *pai, const char *hostname,
return 0;
switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
default_dns_files, hostname, pai, netcontext)) {
default_dns_files, hostname, pai, netid, mark)) {
case NS_TRYAGAIN:
error = EAI_AGAIN;
goto free;
@@ -1759,13 +1763,13 @@ _rfc6724_compare(const void *ptr1, const void* ptr2)
* address. src_addr must be large enough to hold a struct sockaddr_in6.
*
* Returns 1 if a source address was found, 0 if the address is unreachable,
* and -1 if a fatal error occurred. If 0 or -1, the contents of src_addr are
* and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
* undefined.
*/
/*ARGSUSED*/
static int
_find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned mark, uid_t uid)
_find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned mark)
{
int sock;
int ret;
@@ -1793,8 +1797,6 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned
}
if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
return 0;
if (uid > 0 && uid != NET_CONTEXT_INVALID_UID && fchown(sock, uid, (gid_t)-1) < 0)
return 0;
do {
ret = __connect(sock, addr, len);
} while (ret == -1 && errno == EINTR);
@@ -1804,7 +1806,7 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned
return 0;
}
if (src_addr && getsockname(sock, src_addr, &len) == -1) {
if (getsockname(sock, src_addr, &len) == -1) {
close(sock);
return -1;
}
@@ -1819,7 +1821,7 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned
/*ARGSUSED*/
static void
_rfc6724_sort(struct addrinfo *list_sentinel, unsigned mark, uid_t uid)
_rfc6724_sort(struct addrinfo *list_sentinel, unsigned mark)
{
struct addrinfo *cur;
int nelem = 0, i;
@@ -1846,7 +1848,7 @@ _rfc6724_sort(struct addrinfo *list_sentinel, unsigned mark, uid_t uid)
elems[i].ai = cur;
elems[i].original_order = i;
has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic, mark, uid);
has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic, mark);
if (has_src_addr == -1) {
goto error;
}
@@ -1877,11 +1879,12 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
struct addrinfo sentinel, *cur;
struct res_target q, q2;
res_state res;
const struct android_net_context *netcontext;
unsigned netid, mark;
name = va_arg(ap, char *);
pai = va_arg(ap, const struct addrinfo *);
netcontext = va_arg(ap, const struct android_net_context *);
netid = va_arg(ap, unsigned);
mark = va_arg(ap, unsigned);
//fprintf(stderr, "_dns_getaddrinfo() name = '%s'\n", name);
memset(&q, 0, sizeof(q));
@@ -1910,8 +1913,8 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
q.anslen = sizeof(buf->buf);
int query_ipv6 = 1, query_ipv4 = 1;
if (pai->ai_flags & AI_ADDRCONFIG) {
query_ipv6 = _have_ipv6(netcontext->app_mark, netcontext->uid);
query_ipv4 = _have_ipv4(netcontext->app_mark, netcontext->uid);
query_ipv6 = _have_ipv6(mark);
query_ipv4 = _have_ipv4(mark);
}
if (query_ipv6) {
q.qtype = T_AAAA;
@@ -1963,8 +1966,8 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
* fully populate the thread private data here, but if we get down there
* and have a cache hit that would be wasted, so we do the rest there on miss
*/
res_setnetid(res, netcontext->dns_netid);
res_setmark(res, netcontext->dns_mark);
res_setnetid(res, netid);
res_setmark(res, mark);
if (res_searchN(name, &q, res) < 0) {
__res_put_state(res);
free(buf);
@@ -1996,7 +1999,7 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
}
}
_rfc6724_sort(&sentinel, netcontext->app_mark, netcontext->uid);
_rfc6724_sort(&sentinel, netid);
__res_put_state(res);

View File

@@ -640,9 +640,6 @@ android_read_hostent(FILE* proxy, struct hostent* hp, char* hbuf, size_t hbuflen
ptr += size;
}
// Fix alignment after variable-length data.
ptr = (char*)ALIGN(ptr);
int aliases_len = ((int)(aliases - aliases_ptrs) + 1) * sizeof(*hp->h_aliases);
if (ptr + aliases_len > hbuf_end) {
goto nospc;
@@ -677,9 +674,6 @@ android_read_hostent(FILE* proxy, struct hostent* hp, char* hbuf, size_t hbuflen
ptr += size;
}
// Fix alignment after variable-length data.
ptr = (char*)ALIGN(ptr);
int addrs_len = ((int)(addr_p - addr_ptrs) + 1) * sizeof(*hp->h_addr_list);
if (ptr + addrs_len > hbuf_end) {
goto nospc;

View File

@@ -73,13 +73,6 @@ enum {
*/
ANDROID_DLEXT_FORCE_LOAD = 0x40,
/* When set, if the minimum p_vaddr of the ELF file's PT_LOAD segments is non-zero,
* the dynamic linker will load it at that address.
*
* This flag is for ART internal use only.
*/
ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80,
/* Mask of valid bits */
ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS |
ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
@@ -87,8 +80,7 @@ enum {
ANDROID_DLEXT_USE_RELRO |
ANDROID_DLEXT_USE_LIBRARY_FD |
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
ANDROID_DLEXT_FORCE_LOAD |
ANDROID_DLEXT_FORCE_FIXED_VADDR,
ANDROID_DLEXT_FORCE_LOAD,
};
typedef struct {

View File

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

View File

@@ -176,18 +176,10 @@ int pthread_mutexattr_settype(pthread_mutexattr_t*, int) __nonnull((1));
int pthread_mutex_destroy(pthread_mutex_t*) __nonnull((1));
int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*) __nonnull((1));
#if !defined(__LP64__)
int pthread_mutex_lock(pthread_mutex_t*) /* __nonnull((1)) */;
#else
int pthread_mutex_lock(pthread_mutex_t*) __nonnull((1));
#endif
int pthread_mutex_timedlock(pthread_mutex_t*, const struct timespec*) __nonnull((1, 2));
int pthread_mutex_trylock(pthread_mutex_t*) __nonnull((1));
#if !defined(__LP4__)
int pthread_mutex_unlock(pthread_mutex_t*) /* __nonnull((1)) */;
#else
int pthread_mutex_unlock(pthread_mutex_t*) __nonnull((1));
#endif
int pthread_once(pthread_once_t*, void (*)(void)) __nonnull((1, 2));

View File

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

View File

@@ -34,7 +34,7 @@
__BEGIN_DECLS
extern int personality (unsigned int persona);
extern int personality (unsigned long persona);
__END_DECLS

Some files were not shown because too many files have changed in this diff Show More