Compare commits
77 Commits
android-we
...
android-5.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
944e192df6 | ||
![]() |
2155882080 | ||
![]() |
c32cd431fa | ||
![]() |
1840121a6a | ||
![]() |
90a1ed4f45 | ||
![]() |
48116b3024 | ||
![]() |
614ff987ce | ||
![]() |
8e06009fcd | ||
![]() |
8a2d72d586 | ||
![]() |
d690d19dd0 | ||
![]() |
b7672222a9 | ||
![]() |
24a365fbe4 | ||
![]() |
6c1389bf5f | ||
![]() |
397c90bf3e | ||
![]() |
5579bf649f | ||
![]() |
ce77e55ce5 | ||
![]() |
8eac9d69d8 | ||
![]() |
28a7ed042f | ||
![]() |
7ac9e617b8 | ||
![]() |
9416df8139 | ||
![]() |
3ae2ad2aea | ||
![]() |
ad4be8f64f | ||
![]() |
7ed41f97bb | ||
![]() |
59551b8144 | ||
![]() |
194ca8df2d | ||
![]() |
44da474bb8 | ||
![]() |
dc922ade9f | ||
![]() |
b3613b4efd | ||
![]() |
6078d68321 | ||
![]() |
277c1b00f5 | ||
![]() |
50982fd0c4 | ||
![]() |
25232c43fc | ||
![]() |
1d12f186ed | ||
![]() |
fab4d76b46 | ||
![]() |
604b2f5789 | ||
![]() |
ddca20bda4 | ||
![]() |
d0beefdcd3 | ||
![]() |
ee809b90e8 | ||
![]() |
b2c6088b1e | ||
![]() |
dc3814bcf9 | ||
![]() |
d9bead2357 | ||
![]() |
8c673ec8e9 | ||
![]() |
daebe2764b | ||
![]() |
2fcb94d52c | ||
![]() |
20dc3f8fa4 | ||
![]() |
54a6221cc2 | ||
![]() |
489b5d23fd | ||
![]() |
5f17e16e92 | ||
![]() |
3bd669c605 | ||
![]() |
cb278332cb | ||
![]() |
fe9787ece9 | ||
![]() |
bae5898f3d | ||
![]() |
08f6f664ed | ||
![]() |
a0108accb2 | ||
![]() |
58df7d814e | ||
![]() |
147ce71ddc | ||
![]() |
2e7c8634b7 | ||
![]() |
25ffdd7b9f | ||
![]() |
e9f34a3ee7 | ||
![]() |
c323d5efb8 | ||
![]() |
6cde02273f | ||
![]() |
e3ff5fca61 | ||
![]() |
b5e0854284 | ||
![]() |
6b9b454d55 | ||
![]() |
5984773a8d | ||
![]() |
b4725def2e | ||
![]() |
b8d00ef3ba | ||
![]() |
39978ccb7f | ||
![]() |
6447d2f4de | ||
![]() |
1183762969 | ||
![]() |
bdf601894f | ||
![]() |
6a20f051a2 | ||
![]() |
8bc74887c1 | ||
![]() |
1b710ff000 | ||
![]() |
13fb0584e1 | ||
![]() |
4514aa630c | ||
![]() |
0caf70e98e |
@@ -4,52 +4,40 @@ Working on bionic
|
||||
What are the big pieces of bionic?
|
||||
----------------------------------
|
||||
|
||||
#### libc/ --- libc.so, libc.a
|
||||
libc/ --- libc.so, libc.a
|
||||
The C library. Stuff like fopen(3) and kill(2).
|
||||
libm/ --- libm.so, libm.a
|
||||
The math library. Traditionally Unix systems kept stuff like sin(3) and
|
||||
cos(3) in a separate library to save space in the days before shared
|
||||
libraries.
|
||||
libdl/ --- libdl.so
|
||||
The dynamic linker interface library. This is actually just a bunch of
|
||||
stubs that the dynamic linker replaces with pointers to its own
|
||||
implementation at runtime. This is where stuff like dlopen(3) lives.
|
||||
libstdc++/ --- libstdc++.so
|
||||
The C++ ABI support functions. The C++ compiler doesn't know how to
|
||||
implement thread-safe static initialization and the like, so it just calls
|
||||
functions that are supplied by the system. Stuff like __cxa_guard_acquire
|
||||
and __cxa_pure_virtual live here.
|
||||
|
||||
The C library. Stuff like `fopen(3)` and `kill(2)`.
|
||||
linker/ --- /system/bin/linker and /system/bin/linker64
|
||||
The dynamic linker. When you run a dynamically-linked executable, its ELF
|
||||
file has a DT_INTERP entry that says "use the following program to start me".
|
||||
On Android, that's either linker or linker64 (depending on whether it's a
|
||||
32-bit or 64-bit executable). It's responsible for loading the ELF executable
|
||||
into memory and resolving references to symbols (so that when your code tries
|
||||
to jump to fopen(3), say, it lands in the right place).
|
||||
|
||||
#### libm/ --- libm.so, libm.a
|
||||
|
||||
The math library. Traditionally Unix systems kept stuff like `sin(3)` and
|
||||
`cos(3)` in a separate library to save space in the days before shared
|
||||
libraries.
|
||||
|
||||
#### libdl/ --- libdl.so
|
||||
|
||||
The dynamic linker interface library. This is actually just a bunch of stubs
|
||||
that the dynamic linker replaces with pointers to its own implementation at
|
||||
runtime. This is where stuff like `dlopen(3)` lives.
|
||||
|
||||
#### libstdc++/ --- libstdc++.so
|
||||
|
||||
The C++ ABI support functions. The C++ compiler doesn't know how to implement
|
||||
thread-safe static initialization and the like, so it just calls functions that
|
||||
are supplied by the system. Stuff like `__cxa_guard_acquire` and
|
||||
`__cxa_pure_virtual` live here.
|
||||
|
||||
#### linker/ --- /system/bin/linker and /system/bin/linker64
|
||||
|
||||
The dynamic linker. When you run a dynamically-linked executable, its ELF file
|
||||
has a `DT_INTERP` entry that says "use the following program to start me". On
|
||||
Android, that's either `linker` or `linker64` (depending on whether it's a
|
||||
32-bit or 64-bit executable). It's responsible for loading the ELF executable
|
||||
into memory and resolving references to symbols (so that when your code tries to
|
||||
jump to `fopen(3)`, say, it lands in the right place).
|
||||
|
||||
#### tests/ --- unit tests
|
||||
|
||||
The `tests/` directory contains unit tests. Roughly arranged as one file per
|
||||
publicly-exported header file.
|
||||
|
||||
#### benchmarks/ --- benchmarks
|
||||
|
||||
The `benchmarks/` directory contains benchmarks.
|
||||
tests/ --- unit tests
|
||||
The tests/ directory contains unit tests. Roughly arranged as one file per
|
||||
publicly-exported header file.
|
||||
benchmarks/ --- benchmarks
|
||||
The benchmarks/ directory contains benchmarks.
|
||||
|
||||
|
||||
What's in libc/?
|
||||
----------------
|
||||
|
||||
<pre>
|
||||
libc/
|
||||
arch-arm/
|
||||
arch-arm64/
|
||||
@@ -133,7 +121,6 @@ libc/
|
||||
zoneinfo/
|
||||
# Android-format time zone data.
|
||||
# See 'Updating tzdata' later.
|
||||
</pre>
|
||||
|
||||
|
||||
Adding system calls
|
||||
@@ -173,86 +160,3 @@ This is fully automated:
|
||||
|
||||
1. Run update-tzdata.py.
|
||||
|
||||
|
||||
Verifying changes
|
||||
-----------------
|
||||
|
||||
If you make a change that is likely to have a wide effect on the tree (such as a
|
||||
libc header change), you should run `make checkbuild`. A regular `make` will
|
||||
_not_ build the entire tree; just the minimum number of projects that are
|
||||
required for the device. Tests, additional developer tools, and various other
|
||||
modules will not be built. Note that `make checkbuild` will not be complete
|
||||
either, as `make tests` covers a few additional modules, but generally speaking
|
||||
`make checkbuild` is enough.
|
||||
|
||||
|
||||
Running the tests
|
||||
-----------------
|
||||
|
||||
The tests are all built from the tests/ directory.
|
||||
|
||||
### Device tests
|
||||
|
||||
$ mma
|
||||
$ adb sync
|
||||
$ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests32
|
||||
$ adb shell \
|
||||
/data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static32
|
||||
# Only for 64-bit targets
|
||||
$ adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests64
|
||||
$ adb shell \
|
||||
/data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static64
|
||||
|
||||
### Host tests
|
||||
|
||||
The host tests require that you have `lunch`ed either an x86 or x86_64 target.
|
||||
|
||||
$ mma
|
||||
# 64-bit tests for 64-bit targets, 32-bit otherwise.
|
||||
$ mm bionic-unit-tests-run-on-host
|
||||
# Only exists for 64-bit targets.
|
||||
$ mm bionic-unit-tests-run-on-host32
|
||||
|
||||
### Against glibc
|
||||
|
||||
As a way to check that our tests do in fact test the correct behavior (and not
|
||||
just the behavior we think is correct), it is possible to run the tests against
|
||||
the host's glibc.
|
||||
|
||||
$ mma
|
||||
$ bionic-unit-tests-glibc32 # already in your path
|
||||
$ bionic-unit-tests-glibc64
|
||||
|
||||
|
||||
Gathering test coverage
|
||||
-----------------------
|
||||
|
||||
For either host or target coverage, you must first:
|
||||
|
||||
* `$ export NATIVE_COVERAGE=true`
|
||||
* Note that the build system is ignorant to this flag being toggled, i.e. if
|
||||
you change this flag, you will have to manually rebuild bionic.
|
||||
* Set `bionic_coverage=true` in `libc/Android.mk` and `libm/Android.mk`.
|
||||
|
||||
### Coverage from device tests
|
||||
|
||||
$ mma
|
||||
$ adb sync
|
||||
$ adb shell \
|
||||
GCOV_PREFIX=/data/local/tmp/gcov \
|
||||
GCOV_PREFIX_STRIP=`echo $ANDROID_BUILD_TOP | grep -o / | wc -l` \
|
||||
/data/nativetest/bionic-unit-tests/bionic-unit-tests32
|
||||
$ acov
|
||||
|
||||
`acov` will pull all coverage information from the device, push it to the right
|
||||
directories, run `lcov`, and open the coverage report in your browser.
|
||||
|
||||
### Coverage from host tests
|
||||
|
||||
First, build and run the host tests as usual (see above).
|
||||
|
||||
$ croot
|
||||
$ lcov -c -d $ANDROID_PRODUCT_OUT -o coverage.info
|
||||
$ genhtml -o covreport coverage.info # or lcov --list coverage.info
|
||||
|
||||
The coverage report is now available at `covreport/index.html`.
|
@@ -32,6 +32,7 @@ benchmark_c_flags = \
|
||||
benchmark_src_files = \
|
||||
benchmark_main.cpp \
|
||||
math_benchmark.cpp \
|
||||
property_benchmark.cpp \
|
||||
pthread_benchmark.cpp \
|
||||
semaphore_benchmark.cpp \
|
||||
stdio_benchmark.cpp \
|
||||
@@ -40,8 +41,7 @@ benchmark_src_files = \
|
||||
unistd_benchmark.cpp \
|
||||
|
||||
# Build benchmarks for the device (with bionic's .so). Run with:
|
||||
# adb shell bionic-benchmarks32
|
||||
# adb shell bionic-benchmarks64
|
||||
# adb shell bionic-benchmarks
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := bionic-benchmarks
|
||||
LOCAL_MODULE_STEM_32 := bionic-benchmarks32
|
||||
@@ -49,46 +49,32 @@ LOCAL_MODULE_STEM_64 := bionic-benchmarks64
|
||||
LOCAL_MULTILIB := both
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
LOCAL_CFLAGS += $(benchmark_c_flags)
|
||||
LOCAL_SRC_FILES := $(benchmark_src_files) property_benchmark.cpp
|
||||
LOCAL_CXX_STL := libc++
|
||||
LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
|
||||
LOCAL_SHARED_LIBRARIES += libstlport
|
||||
LOCAL_SRC_FILES := $(benchmark_src_files)
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# 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:
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := bionic-benchmarks-glibc
|
||||
LOCAL_MODULE_STEM_32 := bionic-benchmarks-glibc32
|
||||
LOCAL_MODULE_STEM_64 := bionic-benchmarks-glibc64
|
||||
LOCAL_MULTILIB := both
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
LOCAL_CFLAGS += $(benchmark_c_flags)
|
||||
LOCAL_LDFLAGS += -lrt
|
||||
LOCAL_SRC_FILES := $(benchmark_src_files)
|
||||
LOCAL_CXX_STL := libc++
|
||||
include $(BUILD_HOST_EXECUTABLE)
|
||||
|
||||
ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
|
||||
include $(LOCAL_PATH)/../build/run-on-host.mk
|
||||
ifeq ($(TARGET_ARCH),x86)
|
||||
LINKER = linker
|
||||
NATIVE_SUFFIX=32
|
||||
else
|
||||
LINKER = linker64
|
||||
NATIVE_SUFFIX=64
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
|
||||
bionic-benchmarks-run-on-host32: bionic-benchmarks bionic-prepare-run-on-host
|
||||
bionic-benchmarks-run-on-host: bionic-benchmarks $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT_EXECUTABLES)/sh
|
||||
if [ ! -d /system -o ! -d /system/bin ]; then \
|
||||
echo "Attempting to create /system/bin"; \
|
||||
sudo mkdir -p -m 0777 /system/bin; \
|
||||
fi
|
||||
mkdir -p $(TARGET_OUT_DATA)/local/tmp
|
||||
cp $(TARGET_OUT_EXECUTABLES)/$(LINKER) /system/bin
|
||||
cp $(TARGET_OUT_EXECUTABLES)/sh /system/bin
|
||||
ANDROID_DATA=$(TARGET_OUT_DATA) \
|
||||
ANDROID_ROOT=$(TARGET_OUT) \
|
||||
$(TARGET_OUT_EXECUTABLES)/bionic-benchmarks32 $(BIONIC_BENCHMARKS_FLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_IS_64_BIT),true)
|
||||
bionic-benchmarks-run-on-host64: bionic-benchmarks bionic-prepare-run-on-host
|
||||
ANDROID_DATA=$(TARGET_OUT_DATA) \
|
||||
ANDROID_ROOT=$(TARGET_OUT) \
|
||||
$(TARGET_OUT_EXECUTABLES)/bionic-benchmarks64 $(BIONIC_BENCHMARKS_FLAGS)
|
||||
endif
|
||||
|
||||
endif
|
||||
LD_LIBRARY_PATH=$(TARGET_OUT_SHARED_LIBRARIES) \
|
||||
$(TARGET_OUT_EXECUTABLES)/bionic-benchmarks$(NATIVE_SUFFIX) $(BIONIC_BENCHMARKS_FLAGS)
|
||||
endif # linux-x86
|
||||
|
||||
endif # !BUILD_TINY_ANDROID
|
||||
|
@@ -19,7 +19,6 @@
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
@@ -20,8 +20,8 @@
|
||||
#include <math.h>
|
||||
|
||||
// Avoid optimization.
|
||||
volatile double d;
|
||||
volatile double v;
|
||||
double d;
|
||||
double v;
|
||||
|
||||
static void BM_math_sqrt(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
@@ -80,7 +80,7 @@ BENCHMARK(BM_pthread_mutex_lock);
|
||||
|
||||
static void BM_pthread_mutex_lock_ERRORCHECK(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
|
||||
pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
|
||||
StartBenchmarkTiming();
|
||||
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
@@ -94,7 +94,7 @@ BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
|
||||
|
||||
static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||
pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
|
||||
StartBenchmarkTiming();
|
||||
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
@@ -105,35 +105,3 @@ static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
}
|
||||
BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
|
||||
|
||||
static void BM_pthread_rw_lock_read(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
pthread_rwlock_t lock;
|
||||
pthread_rwlock_init(&lock, NULL);
|
||||
StartBenchmarkTiming();
|
||||
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
pthread_rwlock_rdlock(&lock);
|
||||
pthread_rwlock_unlock(&lock);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
pthread_rwlock_destroy(&lock);
|
||||
}
|
||||
BENCHMARK(BM_pthread_rw_lock_read);
|
||||
|
||||
static void BM_pthread_rw_lock_write(int iters) {
|
||||
StopBenchmarkTiming();
|
||||
pthread_rwlock_t lock;
|
||||
pthread_rwlock_init(&lock, NULL);
|
||||
StartBenchmarkTiming();
|
||||
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
pthread_rwlock_wrlock(&lock);
|
||||
pthread_rwlock_unlock(&lock);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
pthread_rwlock_destroy(&lock);
|
||||
}
|
||||
BENCHMARK(BM_pthread_rw_lock_write);
|
||||
|
@@ -25,19 +25,14 @@
|
||||
Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(8)->Arg(16)->Arg(32)->Arg(64)->Arg(512)-> \
|
||||
Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB)
|
||||
|
||||
template <typename Fn>
|
||||
static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
|
||||
static void BM_stdio_fread(int iters, int chunk_size) {
|
||||
StopBenchmarkTiming();
|
||||
FILE* fp = fopen("/dev/zero", "rw");
|
||||
char* buf = new char[chunk_size];
|
||||
StartBenchmarkTiming();
|
||||
|
||||
if (!buffered) {
|
||||
setvbuf(fp, 0, _IONBF, 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
f(buf, chunk_size, 1, fp);
|
||||
fread(buf, chunk_size, 1, fp);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
@@ -45,23 +40,22 @@ static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
|
||||
delete[] buf;
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static void BM_stdio_fread(int iters, int chunk_size) {
|
||||
ReadWriteTest(iters, chunk_size, fread, true);
|
||||
}
|
||||
BENCHMARK(BM_stdio_fread)->AT_COMMON_SIZES;
|
||||
|
||||
|
||||
static void BM_stdio_fwrite(int iters, int chunk_size) {
|
||||
ReadWriteTest(iters, chunk_size, fwrite, true);
|
||||
StopBenchmarkTiming();
|
||||
FILE* fp = fopen("/dev/zero", "rw");
|
||||
char* buf = new char[chunk_size];
|
||||
StartBenchmarkTiming();
|
||||
|
||||
for (int i = 0; i < iters; ++i) {
|
||||
fwrite(buf, chunk_size, 1, fp);
|
||||
}
|
||||
|
||||
StopBenchmarkTiming();
|
||||
SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
|
||||
delete[] buf;
|
||||
fclose(fp);
|
||||
}
|
||||
BENCHMARK(BM_stdio_fwrite)->AT_COMMON_SIZES;
|
||||
|
||||
static void BM_stdio_fread_unbuffered(int iters, int chunk_size) {
|
||||
ReadWriteTest(iters, chunk_size, fread, false);
|
||||
}
|
||||
BENCHMARK(BM_stdio_fread_unbuffered)->AT_COMMON_SIZES;
|
||||
|
||||
static void BM_stdio_fwrite_unbuffered(int iters, int chunk_size) {
|
||||
ReadWriteTest(iters, chunk_size, fwrite, false);
|
||||
}
|
||||
BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES;
|
||||
|
@@ -16,9 +16,7 @@
|
||||
|
||||
#include "benchmark.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
static void BM_time_clock_gettime(int iters) {
|
||||
|
@@ -41,8 +41,6 @@ static void BM_unistd_getpid_syscall(int iters) {
|
||||
}
|
||||
BENCHMARK(BM_unistd_getpid_syscall);
|
||||
|
||||
#if defined(__BIONIC__)
|
||||
|
||||
// Stop GCC optimizing out our pure function.
|
||||
/* Must not be static! */ pid_t (*gettid_fp)() = gettid;
|
||||
|
||||
@@ -57,8 +55,6 @@ static void BM_unistd_gettid(int iters) {
|
||||
}
|
||||
BENCHMARK(BM_unistd_gettid);
|
||||
|
||||
#endif
|
||||
|
||||
static void BM_unistd_gettid_syscall(int iters) {
|
||||
StartBenchmarkTiming();
|
||||
|
||||
|
@@ -1,44 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2014 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# 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 once
|
||||
ifneq ($(bionic_run_on_host_mk_included),true)
|
||||
bionic_run_on_host_mk_included:=true
|
||||
|
||||
ifneq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),arm mips x86))
|
||||
LINKER = linker64
|
||||
else
|
||||
LINKER = linker
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
|
||||
# gtest needs ANDROID_DATA/local/tmp for death test output.
|
||||
# Make sure to create ANDROID_DATA/local/tmp if doesn't exist.
|
||||
# bionic itself should always work relative to ANDROID_DATA or ANDROID_ROOT.
|
||||
bionic-prepare-run-on-host: $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT)/etc/hosts $(TARGET_OUT_EXECUTABLES)/sh
|
||||
if [ ! -d /system ]; then \
|
||||
echo "Attempting to create /system"; \
|
||||
sudo mkdir -p -m 0777 /system; \
|
||||
fi
|
||||
mkdir -p $(TARGET_OUT_DATA)/local/tmp
|
||||
ln -fs `realpath $(TARGET_OUT)/bin` /system/
|
||||
ln -fs `realpath $(TARGET_OUT)/etc` /system/
|
||||
ln -fs `realpath $(TARGET_OUT)/lib` /system/
|
||||
if [ -d "$(TARGET_OUT)/lib64" ]; then \
|
||||
ln -fs `realpath $(TARGET_OUT)/lib64` /system/; \
|
||||
fi
|
||||
endif
|
||||
endif
|
186
libc/Android.mk
186
libc/Android.mk
@@ -1,7 +1,5 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
bionic_coverage := false
|
||||
|
||||
# Make everything depend on any changes to included makefiles.
|
||||
libc_common_additional_dependencies := $(LOCAL_PATH)/Android.mk
|
||||
|
||||
@@ -40,9 +38,12 @@ endif
|
||||
# =========================================================
|
||||
libc_common_src_files := \
|
||||
bionic/bindresvport.c \
|
||||
bionic/daemon.c \
|
||||
bionic/err.c \
|
||||
bionic/ether_aton.c \
|
||||
bionic/ether_ntoa.c \
|
||||
bionic/fts.c \
|
||||
bionic/gethostname.c \
|
||||
bionic/getpriority.c \
|
||||
bionic/if_indextoname.c \
|
||||
bionic/if_nametoindex.c \
|
||||
@@ -50,18 +51,17 @@ libc_common_src_files := \
|
||||
bionic/ioctl.c \
|
||||
bionic/isatty.c \
|
||||
bionic/memmem.c \
|
||||
bionic/pathconf.c \
|
||||
bionic/pututline.c \
|
||||
bionic/sched_cpualloc.c \
|
||||
bionic/sched_cpucount.c \
|
||||
bionic/semaphore.c \
|
||||
bionic/sigblock.c \
|
||||
bionic/siginterrupt.c \
|
||||
bionic/sigsetmask.c \
|
||||
bionic/system_properties_compat.c \
|
||||
stdio/findfp.c \
|
||||
stdio/fread.c \
|
||||
stdio/snprintf.c\
|
||||
stdio/sprintf.c \
|
||||
stdio/stdio_ext.cpp \
|
||||
|
||||
# Fortify implementations of libc functions.
|
||||
libc_common_src_files += \
|
||||
@@ -90,7 +90,6 @@ libc_bionic_src_files := \
|
||||
bionic/access.cpp \
|
||||
bionic/assert.cpp \
|
||||
bionic/atof.cpp \
|
||||
bionic/bionic_systrace.cpp \
|
||||
bionic/bionic_time_conversions.cpp \
|
||||
bionic/brk.cpp \
|
||||
bionic/c16rtomb.cpp \
|
||||
@@ -99,8 +98,6 @@ libc_bionic_src_files := \
|
||||
bionic/chown.cpp \
|
||||
bionic/clearenv.cpp \
|
||||
bionic/clock.cpp \
|
||||
bionic/clock_getcpuclockid.cpp \
|
||||
bionic/clock_nanosleep.cpp \
|
||||
bionic/clone.cpp \
|
||||
bionic/__cmsg_nxthdr.cpp \
|
||||
bionic/connect.cpp \
|
||||
@@ -121,11 +118,9 @@ libc_bionic_src_files := \
|
||||
bionic/getauxval.cpp \
|
||||
bionic/getcwd.cpp \
|
||||
bionic/getentropy_linux.c \
|
||||
bionic/gethostname.cpp \
|
||||
bionic/getpgrp.cpp \
|
||||
bionic/getpid.cpp \
|
||||
bionic/gettid.cpp \
|
||||
bionic/__gnu_basename.cpp \
|
||||
bionic/inotify_init.cpp \
|
||||
bionic/lchown.cpp \
|
||||
bionic/lfs64_support.cpp \
|
||||
@@ -137,7 +132,6 @@ libc_bionic_src_files := \
|
||||
bionic/link.cpp \
|
||||
bionic/locale.cpp \
|
||||
bionic/lstat.cpp \
|
||||
bionic/malloc_info.cpp \
|
||||
bionic/mbrtoc16.cpp \
|
||||
bionic/mbrtoc32.cpp \
|
||||
bionic/mbstate.cpp \
|
||||
@@ -147,13 +141,11 @@ libc_bionic_src_files := \
|
||||
bionic/mntent.cpp \
|
||||
bionic/NetdClientDispatch.cpp \
|
||||
bionic/open.cpp \
|
||||
bionic/pathconf.cpp \
|
||||
bionic/pause.cpp \
|
||||
bionic/pipe.cpp \
|
||||
bionic/poll.cpp \
|
||||
bionic/posix_fadvise.cpp \
|
||||
bionic/posix_fallocate.cpp \
|
||||
bionic/posix_madvise.cpp \
|
||||
bionic/posix_timers.cpp \
|
||||
bionic/pthread_atfork.cpp \
|
||||
bionic/pthread_attr.cpp \
|
||||
@@ -188,7 +180,6 @@ libc_bionic_src_files := \
|
||||
bionic/scandir.cpp \
|
||||
bionic/sched_getaffinity.cpp \
|
||||
bionic/sched_getcpu.cpp \
|
||||
bionic/semaphore.cpp \
|
||||
bionic/send.cpp \
|
||||
bionic/setegid.cpp \
|
||||
bionic/__set_errno.cpp \
|
||||
@@ -204,22 +195,24 @@ libc_bionic_src_files := \
|
||||
bionic/signalfd.cpp \
|
||||
bionic/sigpending.cpp \
|
||||
bionic/sigprocmask.cpp \
|
||||
bionic/sigqueue.cpp \
|
||||
bionic/sigsuspend.cpp \
|
||||
bionic/sigtimedwait.cpp \
|
||||
bionic/sigwait.cpp \
|
||||
bionic/sigwaitinfo.cpp \
|
||||
bionic/socket.cpp \
|
||||
bionic/stat.cpp \
|
||||
bionic/statvfs.cpp \
|
||||
bionic/strcoll_l.cpp \
|
||||
bionic/strerror.cpp \
|
||||
bionic/strerror_r.cpp \
|
||||
bionic/strftime_l.cpp \
|
||||
bionic/strsignal.cpp \
|
||||
bionic/strtold.cpp \
|
||||
bionic/strtold_l.cpp \
|
||||
bionic/strtoll_l.cpp \
|
||||
bionic/strtoull_l.cpp \
|
||||
bionic/strxfrm_l.cpp \
|
||||
bionic/stubs.cpp \
|
||||
bionic/symlink.cpp \
|
||||
bionic/sysconf.cpp \
|
||||
bionic/sysinfo.cpp \
|
||||
bionic/syslog.cpp \
|
||||
bionic/sys_siglist.c \
|
||||
bionic/sys_signame.c \
|
||||
@@ -245,6 +238,9 @@ libc_upstream_freebsd_src_files := \
|
||||
upstream-freebsd/lib/libc/gen/ldexp.c \
|
||||
upstream-freebsd/lib/libc/gen/sleep.c \
|
||||
upstream-freebsd/lib/libc/gen/usleep.c \
|
||||
upstream-freebsd/lib/libc/stdio/fclose.c \
|
||||
upstream-freebsd/lib/libc/stdio/flags.c \
|
||||
upstream-freebsd/lib/libc/stdio/fopen.c \
|
||||
upstream-freebsd/lib/libc/stdlib/abs.c \
|
||||
upstream-freebsd/lib/libc/stdlib/getopt_long.c \
|
||||
upstream-freebsd/lib/libc/stdlib/imaxabs.c \
|
||||
@@ -290,8 +286,8 @@ libc_upstream_netbsd_src_files := \
|
||||
upstream-netbsd/lib/libc/stdlib/div.c \
|
||||
upstream-netbsd/lib/libc/stdlib/drand48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/erand48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/insque.c \
|
||||
upstream-netbsd/lib/libc/stdlib/jrand48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/lcong48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/ldiv.c \
|
||||
upstream-netbsd/lib/libc/stdlib/lldiv.c \
|
||||
upstream-netbsd/lib/libc/stdlib/lrand48.c \
|
||||
@@ -299,12 +295,14 @@ 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/remque.c \
|
||||
upstream-netbsd/lib/libc/stdlib/seed48.c \
|
||||
upstream-netbsd/lib/libc/stdlib/srand48.c \
|
||||
upstream-netbsd/lib/libc/string/memccpy.c \
|
||||
upstream-netbsd/lib/libc/string/strcasestr.c \
|
||||
upstream-netbsd/lib/libc/string/strcoll.c \
|
||||
upstream-netbsd/lib/libc/string/strxfrm.c \
|
||||
upstream-netbsd/lib/libc/unistd/killpg.c \
|
||||
|
||||
libc_upstream_openbsd_gdtoa_src_files := \
|
||||
upstream-openbsd/android/gdtoa_support.cpp \
|
||||
@@ -334,14 +332,10 @@ libc_upstream_openbsd_gdtoa_src_files_64 := \
|
||||
upstream-openbsd/lib/libc/gdtoa/strtorQ.c \
|
||||
|
||||
libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/compat-43/killpg.c \
|
||||
upstream-openbsd/lib/libc/crypt/arc4random.c \
|
||||
upstream-openbsd/lib/libc/crypt/arc4random_uniform.c \
|
||||
upstream-openbsd/lib/libc/gen/alarm.c \
|
||||
upstream-openbsd/lib/libc/gen/ctype_.c \
|
||||
upstream-openbsd/lib/libc/gen/daemon.c \
|
||||
upstream-openbsd/lib/libc/gen/err.c \
|
||||
upstream-openbsd/lib/libc/gen/errx.c \
|
||||
upstream-openbsd/lib/libc/gen/exec.c \
|
||||
upstream-openbsd/lib/libc/gen/fnmatch.c \
|
||||
upstream-openbsd/lib/libc/gen/ftok.c \
|
||||
@@ -351,12 +345,6 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/gen/time.c \
|
||||
upstream-openbsd/lib/libc/gen/tolower_.c \
|
||||
upstream-openbsd/lib/libc/gen/toupper_.c \
|
||||
upstream-openbsd/lib/libc/gen/verr.c \
|
||||
upstream-openbsd/lib/libc/gen/verrx.c \
|
||||
upstream-openbsd/lib/libc/gen/vwarn.c \
|
||||
upstream-openbsd/lib/libc/gen/vwarnx.c \
|
||||
upstream-openbsd/lib/libc/gen/warn.c \
|
||||
upstream-openbsd/lib/libc/gen/warnx.c \
|
||||
upstream-openbsd/lib/libc/locale/btowc.c \
|
||||
upstream-openbsd/lib/libc/locale/mbrlen.c \
|
||||
upstream-openbsd/lib/libc/locale/mbstowcs.c \
|
||||
@@ -390,7 +378,6 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdio/asprintf.c \
|
||||
upstream-openbsd/lib/libc/stdio/clrerr.c \
|
||||
upstream-openbsd/lib/libc/stdio/dprintf.c \
|
||||
upstream-openbsd/lib/libc/stdio/fclose.c \
|
||||
upstream-openbsd/lib/libc/stdio/fdopen.c \
|
||||
upstream-openbsd/lib/libc/stdio/feof.c \
|
||||
upstream-openbsd/lib/libc/stdio/ferror.c \
|
||||
@@ -402,15 +389,14 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdio/fgetwc.c \
|
||||
upstream-openbsd/lib/libc/stdio/fgetws.c \
|
||||
upstream-openbsd/lib/libc/stdio/fileno.c \
|
||||
upstream-openbsd/lib/libc/stdio/flags.c \
|
||||
upstream-openbsd/lib/libc/stdio/fmemopen.c \
|
||||
upstream-openbsd/lib/libc/stdio/fopen.c \
|
||||
upstream-openbsd/lib/libc/stdio/findfp.c \
|
||||
upstream-openbsd/lib/libc/stdio/fprintf.c \
|
||||
upstream-openbsd/lib/libc/stdio/fpurge.c \
|
||||
upstream-openbsd/lib/libc/stdio/fputc.c \
|
||||
upstream-openbsd/lib/libc/stdio/fputs.c \
|
||||
upstream-openbsd/lib/libc/stdio/fputwc.c \
|
||||
upstream-openbsd/lib/libc/stdio/fputws.c \
|
||||
upstream-openbsd/lib/libc/stdio/fread.c \
|
||||
upstream-openbsd/lib/libc/stdio/freopen.c \
|
||||
upstream-openbsd/lib/libc/stdio/fscanf.c \
|
||||
upstream-openbsd/lib/libc/stdio/fseek.c \
|
||||
@@ -432,8 +418,6 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdio/getwchar.c \
|
||||
upstream-openbsd/lib/libc/stdio/makebuf.c \
|
||||
upstream-openbsd/lib/libc/stdio/mktemp.c \
|
||||
upstream-openbsd/lib/libc/stdio/open_memstream.c \
|
||||
upstream-openbsd/lib/libc/stdio/open_wmemstream.c \
|
||||
upstream-openbsd/lib/libc/stdio/perror.c \
|
||||
upstream-openbsd/lib/libc/stdio/printf.c \
|
||||
upstream-openbsd/lib/libc/stdio/putc.c \
|
||||
@@ -482,10 +466,7 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdlib/atoll.c \
|
||||
upstream-openbsd/lib/libc/stdlib/exit.c \
|
||||
upstream-openbsd/lib/libc/stdlib/getenv.c \
|
||||
upstream-openbsd/lib/libc/stdlib/insque.c \
|
||||
upstream-openbsd/lib/libc/stdlib/lsearch.c \
|
||||
upstream-openbsd/lib/libc/stdlib/reallocarray.c \
|
||||
upstream-openbsd/lib/libc/stdlib/remque.c \
|
||||
upstream-openbsd/lib/libc/stdlib/setenv.c \
|
||||
upstream-openbsd/lib/libc/stdlib/strtoimax.c \
|
||||
upstream-openbsd/lib/libc/stdlib/strtol.c \
|
||||
@@ -522,10 +503,7 @@ ifneq ($(TARGET_USES_LOGD),false)
|
||||
libc_common_cflags += -DTARGET_USES_LOGD
|
||||
endif
|
||||
|
||||
use_clang := $(USE_CLANG_PLATFORM_BUILD)
|
||||
ifeq ($(use_clang),)
|
||||
use_clang := false
|
||||
endif
|
||||
use_clang := false
|
||||
|
||||
# Try to catch typical 32-bit assumptions that break with 64-bit pointers.
|
||||
libc_common_cflags += \
|
||||
@@ -554,6 +532,13 @@ ifneq ($(BOARD_MALLOC_ALIGNMENT),)
|
||||
libc_common_cflags += -DMALLOC_ALIGNMENT=$(BOARD_MALLOC_ALIGNMENT)
|
||||
endif
|
||||
|
||||
# Define ANDROID_SMP appropriately.
|
||||
ifeq ($(TARGET_CPU_SMP),true)
|
||||
libc_common_cflags += -DANDROID_SMP=1
|
||||
else
|
||||
libc_common_cflags += -DANDROID_SMP=0
|
||||
endif
|
||||
|
||||
# Define some common conlyflags
|
||||
libc_common_conlyflags := \
|
||||
-std=gnu99
|
||||
@@ -598,10 +583,7 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_stack_protector
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -639,10 +621,7 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes) $(LOCAL_PATH)/tzcode/
|
||||
LOCAL_MODULE := libc_tzcode
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -660,13 +639,7 @@ LOCAL_SRC_FILES := \
|
||||
upstream-netbsd/lib/libc/isc/ev_timers.c \
|
||||
upstream-netbsd/lib/libc/resolv/mtctxres.c \
|
||||
|
||||
# We use the OpenBSD res_random.
|
||||
LOCAL_CFLAGS += \
|
||||
-Dres_randomid=__res_randomid
|
||||
LOCAL_SRC_FILES += \
|
||||
upstream-openbsd/lib/libc/net/res_random.c \
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
LOCAL_CFLAGS := \
|
||||
$(libc_common_cflags) \
|
||||
-DANDROID_CHANGES \
|
||||
-DINET6 \
|
||||
@@ -684,10 +657,7 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_dns
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -716,13 +686,9 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_freebsd
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
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_freebsd_src_files))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
@@ -750,10 +716,7 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_netbsd
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
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_netbsd_src_files))
|
||||
@@ -770,18 +733,9 @@ include $(BUILD_STATIC_LIBRARY)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := $(libc_upstream_openbsd_src_files)
|
||||
ifneq (,$(filter $(TARGET_ARCH),x86 x86_64))
|
||||
# Clang has wrong long double size or LDBL_MANT_DIG, http://b/17163651.
|
||||
LOCAL_CLANG := false
|
||||
else
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
$(libc_common_cflags) \
|
||||
-Wno-sign-compare \
|
||||
-Wno-uninitialized \
|
||||
-Wno-unused-parameter \
|
||||
-Wno-sign-compare -Wno-uninitialized -Wno-unused-parameter \
|
||||
-I$(LOCAL_PATH)/private \
|
||||
-I$(LOCAL_PATH)/upstream-openbsd/android/include \
|
||||
-I$(LOCAL_PATH)/upstream-openbsd/lib/libc/include \
|
||||
@@ -792,14 +746,11 @@ LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_openbsd
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
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_openbsd_src_files))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
@@ -814,13 +765,6 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES_32 := $(libc_upstream_openbsd_gdtoa_src_files_32)
|
||||
LOCAL_SRC_FILES_64 := $(libc_upstream_openbsd_gdtoa_src_files_64)
|
||||
ifneq (,$(filter $(TARGET_ARCH),x86 x86_64))
|
||||
# Clang has wrong long double size or LDBL_MANT_DIG, http://b/17163651.
|
||||
LOCAL_CLANG := false
|
||||
else
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
$(libc_common_cflags) \
|
||||
-Wno-sign-compare -Wno-uninitialized \
|
||||
@@ -834,11 +778,9 @@ LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_gdtoa
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -854,23 +796,13 @@ LOCAL_SRC_FILES := $(libc_bionic_src_files)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||
-Wframe-larger-than=2048 \
|
||||
|
||||
# ssse3-strcmp-slm.S does not compile with Clang.
|
||||
LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
|
||||
|
||||
# memcpy.S, memchr.S, etc. do not compile with Clang.
|
||||
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
|
||||
LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
|
||||
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_bionic
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
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))
|
||||
@@ -889,14 +821,12 @@ LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_cxa
|
||||
LOCAL_CLANG := true # GCC refuses to hide new/delete
|
||||
# GCC refuses to hide new/delete
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -914,10 +844,7 @@ endif
|
||||
LOCAL_MODULE := libc_syscalls
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -936,10 +863,7 @@ LOCAL_MODULE := libc_aeabi
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) -fno-builtin
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -976,13 +900,10 @@ ifneq ($(MALLOC_IMPL),dlmalloc)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += libjemalloc
|
||||
endif
|
||||
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
|
||||
# TODO: split out the asflags.
|
||||
LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
|
||||
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_common_src_files))
|
||||
@@ -1018,10 +939,7 @@ LOCAL_MODULE := libc_nomalloc
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
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_arch_static_src_files))
|
||||
@@ -1042,9 +960,6 @@ LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_MODULE := libc_malloc
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -1070,10 +985,7 @@ LOCAL_MODULE := libc
|
||||
LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
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_arch_static_src_files))
|
||||
@@ -1115,7 +1027,6 @@ LOCAL_STRIP_MODULE := keep_symbols
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libdl
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
|
||||
# We'd really like to do this for all architectures, but since this wasn't done
|
||||
@@ -1135,8 +1046,6 @@ LOCAL_SRC_FILES_arm += \
|
||||
arch-common/bionic/crtbegin_so.c \
|
||||
arch-arm/bionic/atexit_legacy.c \
|
||||
arch-common/bionic/crtend_so.S
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -1154,7 +1063,10 @@ ifneq ($(TARGET_BUILD_VARIANT),user)
|
||||
# ========================================================
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_CFLAGS := $(libc_common_cflags)
|
||||
LOCAL_CFLAGS := \
|
||||
$(libc_common_cflags) \
|
||||
-DMALLOC_LEAK_CHECK \
|
||||
|
||||
LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
|
||||
@@ -1174,17 +1086,14 @@ LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libc libdl
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
# Only need this for arm since libc++ uses its own unwind code that
|
||||
# doesn't mix with the other default unwind code.
|
||||
LOCAL_STATIC_LIBRARIES_arm := libunwind_llvm libc++abi
|
||||
LOCAL_STATIC_LIBRARIES_arm := libc++
|
||||
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
|
||||
|
||||
# Don't install on release build
|
||||
LOCAL_MODULE_TAGS := eng debug
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1213,13 +1122,10 @@ LOCAL_CLANG := $(use_clang)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libc libdl
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
|
||||
|
||||
# Don't install on release build
|
||||
LOCAL_MODULE_TAGS := eng debug
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
|
||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1236,32 +1142,24 @@ libstdcxx_common_src_files := \
|
||||
bionic/libc_logging.cpp \
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
|
||||
LOCAL_MODULE:= libstdc++
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
# ========================================================
|
||||
# libstdc++.a
|
||||
# ========================================================
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags)
|
||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
|
||||
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
|
||||
LOCAL_MODULE:= libstdc++
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
LOCAL_CXX_STL := none
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||
LOCAL_ADDRESS_SANITIZER := false
|
||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
|
130
libc/NOTICE
130
libc/NOTICE
@@ -2510,6 +2510,35 @@ SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1993
|
||||
The Regents of the University of California. 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.
|
||||
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.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1993
|
||||
The Regents of the University of California. All rights reserved.
|
||||
|
||||
@@ -3102,6 +3131,38 @@ SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1999 Kungliga Tekniska Högskolan
|
||||
(Royal Institute of Technology, Stockholm, Sweden).
|
||||
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.
|
||||
|
||||
3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2000 Ben Harris.
|
||||
Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
All rights reserved.
|
||||
@@ -4361,39 +4422,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
|
||||
|
||||
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) 2011 Martin Pieuchot <mpi@openbsd.org>
|
||||
Copyright (c) 2009 Ted Unangst
|
||||
|
||||
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) 2011 The Android Open Source Project
|
||||
Copyright (c) 2008 ARM Ltd
|
||||
All rights reserved.
|
||||
@@ -4825,42 +4853,6 @@ SUCH DAMAGE.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
|
||||
Copyright 2008 Damien Miller <djm@openbsd.org>
|
||||
All rights reserved.
|
||||
|
||||
Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
|
||||
such a mathematical system to generate more random (yet non-repeating)
|
||||
ids to solve the resolver/named problem. But Niels designed the
|
||||
actual system based on the constraints.
|
||||
|
||||
Later modified by Damien Miller to wrap the LCG output in a 15-bit
|
||||
permutation generator based on a Luby-Rackoff block cipher. This
|
||||
ensures the output is non-repeating and preserves the MSB twiddle
|
||||
trick, but makes it more resistant to LCG prediction.
|
||||
|
||||
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 2000 David E. O'Brien, John D. Polstra.
|
||||
All rights reserved.
|
||||
|
||||
|
@@ -101,7 +101,7 @@ int munmap(void*, size_t) all
|
||||
void* mremap(void*, size_t, size_t, unsigned long) all
|
||||
int msync(const void*, size_t, int) all
|
||||
int mprotect(const void*, size_t, int) all
|
||||
int madvise(void*, size_t, int) all
|
||||
int madvise(const void*, size_t, int) all
|
||||
int mlock(const void* addr, size_t len) all
|
||||
int munlock(const void* addr, size_t len) all
|
||||
int mlockall(int flags) all
|
||||
@@ -202,9 +202,9 @@ int swapoff(const char*) all
|
||||
int settimeofday(const struct timeval*, const struct timezone*) all
|
||||
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_settime(clockid_t clk_id, const struct timespec* tp) all
|
||||
int clock_getres(clockid_t clk_id, struct timespec* res) all
|
||||
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec* req, struct timespec* rem) 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
|
||||
@@ -223,7 +223,6 @@ 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 __signalfd4:signalfd4(int, const sigset_t*, size_t, int) all
|
||||
|
||||
# sockets
|
||||
@@ -314,8 +313,6 @@ int __set_tid_address:set_tid_address(int*) all
|
||||
int setfsgid(gid_t) all
|
||||
int setfsuid(uid_t) all
|
||||
|
||||
int sethostname(const char*, size_t) all
|
||||
|
||||
pid_t wait4(pid_t, int*, int, struct rusage*) all
|
||||
int __waitid:waitid(int, pid_t, struct siginfo_t*, int, void*) all
|
||||
|
||||
@@ -324,7 +321,7 @@ int __set_tls:__ARM_NR_set_tls(void*) arm
|
||||
int cacheflush:__ARM_NR_cacheflush(long start, long end, long flags) arm
|
||||
|
||||
# MIPS-specific
|
||||
int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips
|
||||
int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips,mips64
|
||||
int __set_tls:set_thread_area(void*) mips,mips64
|
||||
|
||||
# x86-specific
|
||||
|
@@ -1,35 +1,22 @@
|
||||
# 32-bit arm.
|
||||
# arm specific configs
|
||||
|
||||
#
|
||||
# Various kinds of LP32 cruft.
|
||||
#
|
||||
|
||||
libc_bionic_src_files_arm += \
|
||||
bionic/mmap.cpp \
|
||||
|
||||
libc_common_src_files_arm += \
|
||||
# These are used by the 32-bit targets, but not the 64-bit ones.
|
||||
libc_common_src_files_arm := \
|
||||
bionic/legacy_32_bit_support.cpp \
|
||||
bionic/ndk_cruft.cpp \
|
||||
bionic/time64.c \
|
||||
|
||||
libc_netbsd_src_files_arm += \
|
||||
upstream-netbsd/common/lib/libc/hash/sha1/sha1.c \
|
||||
|
||||
libc_openbsd_src_files_arm += \
|
||||
upstream-openbsd/lib/libc/stdio/putw.c \
|
||||
|
||||
#
|
||||
# Default implementations of functions that are commonly optimized.
|
||||
#
|
||||
# These are shared by all the 32-bit targets, but not the 64-bit ones.
|
||||
libc_bionic_src_files_arm := \
|
||||
bionic/mmap.cpp
|
||||
|
||||
libc_bionic_src_files_arm += \
|
||||
libc_common_src_files_arm += \
|
||||
bionic/memchr.c \
|
||||
bionic/memrchr.c \
|
||||
bionic/strchr.cpp \
|
||||
bionic/strnlen.c \
|
||||
bionic/strrchr.cpp \
|
||||
|
||||
libc_freebsd_src_files_arm += \
|
||||
upstream-freebsd/lib/libc/string/wcscat.c \
|
||||
upstream-freebsd/lib/libc/string/wcschr.c \
|
||||
upstream-freebsd/lib/libc/string/wcscmp.c \
|
||||
@@ -38,9 +25,8 @@ libc_freebsd_src_files_arm += \
|
||||
upstream-freebsd/lib/libc/string/wcsrchr.c \
|
||||
upstream-freebsd/lib/libc/string/wmemcmp.c \
|
||||
upstream-freebsd/lib/libc/string/wmemmove.c \
|
||||
|
||||
libc_openbsd_src_files_arm += \
|
||||
upstream-openbsd/lib/libc/string/bcopy.c \
|
||||
upstream-openbsd/lib/libc/string/stpcpy.c \
|
||||
upstream-openbsd/lib/libc/string/stpncpy.c \
|
||||
upstream-openbsd/lib/libc/string/strlcat.c \
|
||||
upstream-openbsd/lib/libc/string/strlcpy.c \
|
||||
@@ -48,10 +34,20 @@ libc_openbsd_src_files_arm += \
|
||||
upstream-openbsd/lib/libc/string/strncmp.c \
|
||||
upstream-openbsd/lib/libc/string/strncpy.c \
|
||||
|
||||
# The C++ fortify function implementations for which there is an
|
||||
# arm assembler version.
|
||||
#
|
||||
# Inherently architecture-specific code.
|
||||
#
|
||||
# Fortify implementations of libc functions.
|
||||
# libc_common_src_files_arm +=
|
||||
# bionic/__memcpy_chk.cpp \
|
||||
# bionic/__memset_chk.cpp \
|
||||
# bionic/__strcpy_chk.cpp \
|
||||
# bionic/__strcat_chk.cpp \
|
||||
|
||||
libc_common_cflags_arm := -DSOFTFLOAT
|
||||
|
||||
##########################################
|
||||
### CPU specific source files
|
||||
libc_bionic_src_files_arm += \
|
||||
arch-arm/bionic/abort_arm.S \
|
||||
arch-arm/bionic/atomics_arm.c \
|
||||
@@ -59,13 +55,17 @@ libc_bionic_src_files_arm += \
|
||||
arch-arm/bionic/_exit_with_stack_teardown.S \
|
||||
arch-arm/bionic/libgcc_compat.c \
|
||||
arch-arm/bionic/memcmp.S \
|
||||
arch-arm/bionic/__restore.S \
|
||||
arch-arm/bionic/_setjmp.S \
|
||||
arch-arm/bionic/setjmp.S \
|
||||
arch-arm/bionic/sigsetjmp.S \
|
||||
arch-arm/bionic/syscall.S \
|
||||
|
||||
libc_arch_static_src_files_arm := arch-arm/bionic/exidx_static.c
|
||||
libc_arch_dynamic_src_files_arm := arch-arm/bionic/exidx_dynamic.c
|
||||
|
||||
libc_netbsd_src_files_arm := \
|
||||
upstream-netbsd/common/lib/libc/hash/sha1/sha1.c \
|
||||
|
||||
## CPU variant specific source files
|
||||
ifeq ($(strip $(TARGET_$(my_2nd_arch_prefix)CPU_VARIANT)),)
|
||||
$(warning TARGET_$(my_2nd_arch_prefix)ARCH is arm, but TARGET_$(my_2nd_arch_prefix)CPU_VARIANT is not defined)
|
||||
|
@@ -39,9 +39,6 @@
|
||||
|
||||
extern int __cxa_atexit(void (*)(void*), void*, void*);
|
||||
|
||||
// All of these are weak symbols to avoid multiple definition errors when
|
||||
// linking with libstdc++-v3 or compiler-rt.
|
||||
|
||||
/* The "C++ ABI for ARM" document states that static C++ constructors,
|
||||
* which are called from the .init_array, should manually call
|
||||
* __aeabi_atexit() to register static destructors explicitly.
|
||||
@@ -50,35 +47,35 @@ extern int __cxa_atexit(void (*)(void*), void*, void*);
|
||||
* variable from the shared object that contains the constructor/destructor
|
||||
*/
|
||||
|
||||
// Make this a weak symbol to avoid a multiple definition error when linking with libstdc++-v3.
|
||||
int __attribute__((weak))
|
||||
__aeabi_atexit(void *object, void (*destructor) (void *), void *dso_handle) {
|
||||
return __cxa_atexit(destructor, object, dso_handle);
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((weak))
|
||||
__aeabi_memcpy8(void *dest, const void *src, size_t n) {
|
||||
void __aeabi_memcpy8(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memcpy4(void *dest, const void *src, size_t n) {
|
||||
void __aeabi_memcpy4(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memcpy(void *dest, const void *src, size_t n) {
|
||||
void __aeabi_memcpy(void *dest, const void *src, size_t n) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove8(void *dest, const void *src, size_t n) {
|
||||
void __aeabi_memmove8(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove4(void *dest, const void *src, size_t n) {
|
||||
void __aeabi_memmove4(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memmove(void *dest, const void *src, size_t n) {
|
||||
void __aeabi_memmove(void *dest, const void *src, size_t n) {
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
@@ -87,27 +84,27 @@ void __attribute__((weak)) __aeabi_memmove(void *dest, const void *src, size_t n
|
||||
* This allows __aeabi_memclr to tail-call __aeabi_memset
|
||||
*/
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset8(void *dest, size_t n, int c) {
|
||||
void __aeabi_memset8(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset4(void *dest, size_t n, int c) {
|
||||
void __aeabi_memset4(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memset(void *dest, size_t n, int c) {
|
||||
void __aeabi_memset(void *dest, size_t n, int c) {
|
||||
memset(dest, c, n);
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr8(void *dest, size_t n) {
|
||||
void __aeabi_memclr8(void *dest, size_t n) {
|
||||
__aeabi_memset8(dest, n, 0);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr4(void *dest, size_t n) {
|
||||
void __aeabi_memclr4(void *dest, size_t n) {
|
||||
__aeabi_memset4(dest, n, 0);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) __aeabi_memclr(void *dest, size_t n) {
|
||||
void __aeabi_memclr(void *dest, size_t n) {
|
||||
__aeabi_memset(dest, n, 0);
|
||||
}
|
||||
|
@@ -42,14 +42,13 @@ ENTRY(__bionic_clone)
|
||||
# load extra parameters
|
||||
ldmfd ip, {r4, r5, r6}
|
||||
|
||||
# Push 'fn' and 'arg' onto the child stack.
|
||||
stmdb r1!, {r5, r6}
|
||||
# store 'fn' and 'arg' to the child stack
|
||||
str r5, [r1, #-4]
|
||||
str r6, [r1, #-8]
|
||||
|
||||
# Make the system call.
|
||||
# System call
|
||||
ldr r7, =__NR_clone
|
||||
swi #0
|
||||
|
||||
# Are we the child?
|
||||
movs r0, r0
|
||||
beq 1f
|
||||
|
||||
@@ -63,8 +62,8 @@ ENTRY(__bionic_clone)
|
||||
1: # The child.
|
||||
# Setting lr to 0 will make the unwinder stop at __start_thread
|
||||
mov lr, #0
|
||||
# Call __start_thread with the 'fn' and 'arg' we stored on the child stack.
|
||||
pop {r0, r1}
|
||||
ldr r0, [sp, #-4]
|
||||
ldr r1, [sp, #-8]
|
||||
b __start_thread
|
||||
END(__bionic_clone)
|
||||
.hidden __bionic_clone
|
||||
|
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 <private/bionic_asm.h>
|
||||
|
||||
// gdb is smart enough to unwind through signal frames with just the regular
|
||||
// CFI information but libgcc and libunwind both need extra help. We do this
|
||||
// by using .fnstart/.fnend and inserting a nop before both __restore and
|
||||
// __restore_rt (but covered by the .fnstart/.fnend) so that although they're
|
||||
// not inside the functions from objdump's point of view, an unwinder that
|
||||
// blindly looks at the previous instruction (but is then smart enough to check
|
||||
// the DWARF information to find out where it landed) gets the right answer.
|
||||
|
||||
// We need to place .fnstart ourselves (but we may as well keep the free .fnend).
|
||||
#undef __bionic_asm_custom_entry
|
||||
#define __bionic_asm_custom_entry(f)
|
||||
|
||||
.fnstart
|
||||
.save {r0-r15}
|
||||
.pad #32
|
||||
nop
|
||||
ENTRY_PRIVATE(__restore)
|
||||
// This function must have exactly this instruction sequence.
|
||||
mov r7, #__NR_sigreturn
|
||||
swi #0
|
||||
END(__restore)
|
||||
|
||||
.fnstart
|
||||
.save {r0-r15}
|
||||
.pad #160
|
||||
nop
|
||||
ENTRY_PRIVATE(__restore_rt)
|
||||
// This function must have exactly this instruction sequence.
|
||||
mov r7, #__NR_rt_sigreturn
|
||||
swi #0
|
||||
END(__restore_rt)
|
113
libc/arch-arm/bionic/_setjmp.S
Normal file
113
libc/arch-arm/bionic/_setjmp.S
Normal file
@@ -0,0 +1,113 @@
|
||||
/* $OpenBSD: _setjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $ */
|
||||
/* $NetBSD: _setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Mark Brinicombe
|
||||
* Copyright (c) 2010 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:
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Mark Brinicombe
|
||||
* 4. 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 AUTHOR 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 AUTHOR 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 <private/bionic_asm.h>
|
||||
#include <machine/setjmp.h>
|
||||
#include <machine/cpu-features.h>
|
||||
|
||||
/*
|
||||
* C library -- _setjmp, _longjmp
|
||||
*
|
||||
* _longjmp(a,v)
|
||||
* will generate a "return(v)" from the last call to
|
||||
* _setjmp(a)
|
||||
* by restoring registers from the stack.
|
||||
* The previous signal state is NOT restored.
|
||||
*
|
||||
* Note: r0 is the return value
|
||||
* r1-r3 are scratch registers in functions
|
||||
*/
|
||||
|
||||
ENTRY(_setjmp)
|
||||
ldr r1, .L_setjmp_magic
|
||||
str r1, [r0, #(_JB_MAGIC * 4)]
|
||||
|
||||
/* Store core registers */
|
||||
add r1, r0, #(_JB_CORE_BASE * 4)
|
||||
stmia r1, {r4-r14}
|
||||
|
||||
#ifdef __ARM_HAVE_VFP
|
||||
/* Store floating-point registers */
|
||||
add r1, r0, #(_JB_FLOAT_BASE * 4)
|
||||
vstmia r1, {d8-d15}
|
||||
/* Store floating-point state */
|
||||
fmrx r1, fpscr
|
||||
str r1, [r0, #(_JB_FLOAT_STATE * 4)]
|
||||
#endif /* __ARM_HAVE_VFP */
|
||||
|
||||
mov r0, #0x00000000
|
||||
bx lr
|
||||
END(_setjmp)
|
||||
|
||||
.L_setjmp_magic:
|
||||
.word _JB_MAGIC__SETJMP
|
||||
|
||||
ENTRY(_longjmp)
|
||||
ldr r2, .L_setjmp_magic
|
||||
ldr r3, [r0, #(_JB_MAGIC * 4)]
|
||||
teq r2, r3
|
||||
bne botch
|
||||
|
||||
#ifdef __ARM_HAVE_VFP
|
||||
/* Restore floating-point registers */
|
||||
add r2, r0, #(_JB_FLOAT_BASE * 4)
|
||||
vldmia r2, {d8-d15}
|
||||
/* Restore floating-point state */
|
||||
ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
|
||||
fmxr fpscr, r2
|
||||
#endif /* __ARM_HAVE_VFP */
|
||||
|
||||
/* Restore core registers */
|
||||
add r2, r0, #(_JB_CORE_BASE * 4)
|
||||
ldmia r2, {r4-r14}
|
||||
|
||||
/* Validate sp and r14 */
|
||||
teq sp, #0
|
||||
teqne r14, #0
|
||||
beq botch
|
||||
|
||||
/* Set return value */
|
||||
mov r0, r1
|
||||
teq r0, #0x00000000
|
||||
moveq r0, #0x00000001
|
||||
bx lr
|
||||
|
||||
/* validation failed, die die die. */
|
||||
botch:
|
||||
bl PIC_SYM(longjmperror, PLT)
|
||||
bl PIC_SYM(abort, PLT)
|
||||
b . - 8 /* Cannot get here */
|
||||
END(_longjmp)
|
@@ -40,5 +40,5 @@ ENTRY(abort)
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r3, 0
|
||||
.cfi_rel_offset r14, 4
|
||||
bl __libc_android_abort
|
||||
bl PIC_SYM(__libc_android_abort, PLT)
|
||||
END(abort)
|
||||
|
@@ -1,3 +1,6 @@
|
||||
/* $OpenBSD: setjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $ */
|
||||
/* $NetBSD: setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Mark Brinicombe
|
||||
* Copyright (c) 2010 Android Open Source Project.
|
||||
@@ -32,144 +35,119 @@
|
||||
*/
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/setjmp.h>
|
||||
#include <machine/cpu-features.h>
|
||||
|
||||
// According to the ARM AAPCS document, we only need to save
|
||||
// the following registers:
|
||||
//
|
||||
// Core r4-r14
|
||||
//
|
||||
// VFP d8-d15 (see section 5.1.2.1)
|
||||
//
|
||||
// Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
|
||||
// calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
|
||||
// (and can be used for passing arguments or returning results in standard
|
||||
// procedure-call variants). Registers d16-d31 (q8-q15), if present, do
|
||||
// not need to be preserved.
|
||||
//
|
||||
// FPSCR saved because glibc does.
|
||||
|
||||
// The internal structure of a jmp_buf is totally private.
|
||||
// Current layout (may change in the future):
|
||||
//
|
||||
// word name description
|
||||
// 0 magic magic number
|
||||
// 1 sigmask signal mask (not used with _setjmp / _longjmp)
|
||||
// 2 float_base base of float registers (d8 to d15)
|
||||
// 18 float_state floating-point status and control register
|
||||
// 19 core_base base of core registers (r4 to r14)
|
||||
// 30 reserved reserved entries (room to grow)
|
||||
// 64
|
||||
//
|
||||
// NOTE: float_base must be at an even word index, since the
|
||||
// FP registers will be loaded/stored with instructions
|
||||
// that expect 8-byte alignment.
|
||||
|
||||
#define _JB_SIGFLAG 0
|
||||
#define _JB_SIGMASK (_JB_SIGFLAG+1)
|
||||
#define _JB_FLOAT_BASE (_JB_SIGMASK+1)
|
||||
#define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
|
||||
#define _JB_CORE_BASE (_JB_FLOAT_STATE+1)
|
||||
/*
|
||||
* C library -- setjmp, longjmp
|
||||
*
|
||||
* longjmp(a,v)
|
||||
* will generate a "return(v)" from the last call to
|
||||
* setjmp(a)
|
||||
* by restoring registers from the stack.
|
||||
* The previous signal state is restored.
|
||||
*/
|
||||
|
||||
ENTRY(setjmp)
|
||||
mov r1, #1
|
||||
b sigsetjmp
|
||||
/* Block all signals and retrieve the old signal mask */
|
||||
stmfd sp!, {r0, r14}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r14, 4
|
||||
mov r0, #0x00000000
|
||||
|
||||
bl PIC_SYM(sigblock, PLT)
|
||||
mov r1, r0
|
||||
|
||||
ldmfd sp!, {r0, r14}
|
||||
.cfi_def_cfa_offset 0
|
||||
|
||||
/* Store signal mask */
|
||||
str r1, [r0, #(_JB_SIGMASK * 4)]
|
||||
|
||||
ldr r1, .Lsetjmp_magic
|
||||
str r1, [r0, #(_JB_MAGIC * 4)]
|
||||
|
||||
/* Store core registers */
|
||||
add r1, r0, #(_JB_CORE_BASE * 4)
|
||||
stmia r1, {r4-r14}
|
||||
|
||||
#ifdef __ARM_HAVE_VFP
|
||||
/* Store floating-point registers */
|
||||
add r1, r0, #(_JB_FLOAT_BASE * 4)
|
||||
vstmia r1, {d8-d15}
|
||||
/* Store floating-point state */
|
||||
fmrx r1, fpscr
|
||||
str r1, [r0, #(_JB_FLOAT_STATE * 4)]
|
||||
#endif /* __ARM_HAVE_VFP */
|
||||
|
||||
mov r0, #0x00000000
|
||||
bx lr
|
||||
END(setjmp)
|
||||
|
||||
ENTRY(_setjmp)
|
||||
mov r1, #0
|
||||
b sigsetjmp
|
||||
END(_setjmp)
|
||||
.Lsetjmp_magic:
|
||||
.word _JB_MAGIC_SETJMP
|
||||
|
||||
// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
|
||||
ENTRY(sigsetjmp)
|
||||
// Record whether or not we're saving the signal mask.
|
||||
str r1, [r0, #(_JB_SIGFLAG * 4)]
|
||||
|
||||
// Do we need to save the signal mask?
|
||||
teq r1, #0
|
||||
beq 1f
|
||||
ENTRY(longjmp)
|
||||
ldr r2, .Lsetjmp_magic
|
||||
ldr r3, [r0, #(_JB_MAGIC * 4)]
|
||||
teq r2, r3
|
||||
bne botch
|
||||
|
||||
// Get current signal mask.
|
||||
stmfd sp!, {r0, r14}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r14, 4
|
||||
mov r0, #0
|
||||
bl sigblock
|
||||
mov r1, r0
|
||||
ldmfd sp!, {r0, r14}
|
||||
.cfi_def_cfa_offset 0
|
||||
/* Fetch signal mask */
|
||||
ldr r2, [r0, #(_JB_SIGMASK * 4)]
|
||||
|
||||
// Save the signal mask.
|
||||
str r1, [r0, #(_JB_SIGMASK * 4)]
|
||||
/* Set signal mask */
|
||||
stmfd sp!, {r0, r1, r14}
|
||||
.cfi_def_cfa_offset 12
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r1, 4
|
||||
.cfi_rel_offset r14, 8
|
||||
sub sp, sp, #4 /* align the stack */
|
||||
.cfi_adjust_cfa_offset 4
|
||||
|
||||
1:
|
||||
// Save core registers.
|
||||
add r1, r0, #(_JB_CORE_BASE * 4)
|
||||
stmia r1, {r4-r14}
|
||||
mov r0, r2
|
||||
bl PIC_SYM(sigsetmask, PLT)
|
||||
|
||||
// Save floating-point registers.
|
||||
add r1, r0, #(_JB_FLOAT_BASE * 4)
|
||||
vstmia r1, {d8-d15}
|
||||
add sp, sp, #4 /* unalign the stack */
|
||||
.cfi_adjust_cfa_offset -4
|
||||
ldmfd sp!, {r0, r1, r14}
|
||||
.cfi_def_cfa_offset 0
|
||||
|
||||
// Save floating-point state.
|
||||
fmrx r1, fpscr
|
||||
str r1, [r0, #(_JB_FLOAT_STATE * 4)]
|
||||
#ifdef __ARM_HAVE_VFP
|
||||
/* Restore floating-point registers */
|
||||
add r2, r0, #(_JB_FLOAT_BASE * 4)
|
||||
vldmia r2, {d8-d15}
|
||||
/* Restore floating-point state */
|
||||
ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
|
||||
fmxr fpscr, r2
|
||||
#endif /* __ARM_HAVE_VFP */
|
||||
|
||||
mov r0, #0
|
||||
bx lr
|
||||
END(sigsetjmp)
|
||||
/* Restore core registers */
|
||||
add r2, r0, #(_JB_CORE_BASE * 4)
|
||||
ldmia r2, {r4-r14}
|
||||
|
||||
// void siglongjmp(sigjmp_buf env, int value);
|
||||
ENTRY(siglongjmp)
|
||||
// Do we need to restore the signal mask?
|
||||
ldr r2, [r0, #(_JB_SIGFLAG * 4)]
|
||||
teq r2, #0
|
||||
beq 1f
|
||||
/* Validate sp and r14 */
|
||||
teq sp, #0
|
||||
teqne r14, #0
|
||||
beq botch
|
||||
|
||||
// Restore the signal mask.
|
||||
stmfd sp!, {r0, r1, r14}
|
||||
.cfi_def_cfa_offset 12
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r1, 4
|
||||
.cfi_rel_offset r14, 8
|
||||
sub sp, sp, #4 // Align the stack.
|
||||
.cfi_adjust_cfa_offset 4
|
||||
/* Set return value */
|
||||
|
||||
ldr r0, [r0, #(_JB_SIGMASK * 4)]
|
||||
bl sigsetmask
|
||||
mov r0, r1
|
||||
teq r0, #0x00000000
|
||||
moveq r0, #0x00000001
|
||||
bx lr
|
||||
#ifdef __ARM_26__
|
||||
mov r15, r14
|
||||
#else
|
||||
mov r15, r14
|
||||
#endif
|
||||
|
||||
add sp, sp, #4 // Unalign the stack.
|
||||
.cfi_adjust_cfa_offset -4
|
||||
ldmfd sp!, {r0, r1, r14}
|
||||
.cfi_def_cfa_offset 0
|
||||
|
||||
1:
|
||||
// Restore floating-point registers.
|
||||
add r2, r0, #(_JB_FLOAT_BASE * 4)
|
||||
vldmia r2, {d8-d15}
|
||||
|
||||
// Restore floating-point state.
|
||||
ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
|
||||
fmxr fpscr, r2
|
||||
|
||||
// Restore core registers.
|
||||
add r2, r0, #(_JB_CORE_BASE * 4)
|
||||
ldmia r2, {r4-r14}
|
||||
|
||||
// Validate sp and r14.
|
||||
teq sp, #0
|
||||
teqne r14, #0
|
||||
bleq longjmperror
|
||||
|
||||
// Set return value.
|
||||
mov r0, r1
|
||||
teq r0, #0
|
||||
moveq r0, #1
|
||||
bx lr
|
||||
END(siglongjmp)
|
||||
|
||||
.globl longjmp
|
||||
.equ longjmp, siglongjmp
|
||||
.globl _longjmp
|
||||
.equ _longjmp, siglongjmp
|
||||
/* validation failed, die die die. */
|
||||
botch:
|
||||
bl PIC_SYM(longjmperror, PLT)
|
||||
bl PIC_SYM(abort, PLT)
|
||||
b . - 8 /* Cannot get here */
|
||||
END(longjmp)
|
||||
|
66
libc/arch-arm/bionic/sigsetjmp.S
Normal file
66
libc/arch-arm/bionic/sigsetjmp.S
Normal file
@@ -0,0 +1,66 @@
|
||||
/* $OpenBSD: sigsetjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $ */
|
||||
/* $NetBSD: sigsetjmp.S,v 1.3 2002/08/17 19:54:30 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Mark Brinicombe
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Mark Brinicombe
|
||||
* 4. 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#define _ALIGN_TEXT .align 0
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
/*
|
||||
* C library -- sigsetjmp, siglongjmp
|
||||
*
|
||||
* longjmp(a,v)
|
||||
* will generate a "return(v)" from the last call to
|
||||
* setjmp(a, m)
|
||||
* by restoring registers from the stack.
|
||||
* The previous signal state is restored.
|
||||
*/
|
||||
|
||||
ENTRY(sigsetjmp)
|
||||
teq r1, #0
|
||||
beq PIC_SYM(_setjmp, PLT)
|
||||
b PIC_SYM(setjmp, PLT)
|
||||
END(sigsetjmp)
|
||||
|
||||
.L_setjmp_magic:
|
||||
.word _JB_MAGIC__SETJMP
|
||||
|
||||
ENTRY(siglongjmp)
|
||||
ldr r2, .L_setjmp_magic
|
||||
ldr r3, [r0]
|
||||
teq r2, r3
|
||||
beq PIC_SYM(_longjmp, PLT)
|
||||
b PIC_SYM(longjmp, PLT)
|
||||
END(siglongjmp)
|
@@ -40,10 +40,12 @@
|
||||
ENTRY(__strcat_chk)
|
||||
pld [r0, #0]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
push {r4, r5}
|
||||
.save {r4, r5}
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
@@ -193,6 +195,9 @@ END(__strcat_chk)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
ENTRY_PRIVATE(__strcat_chk_failed)
|
||||
.save {r0, lr}
|
||||
.save {r4, r5}
|
||||
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -39,6 +39,7 @@
|
||||
ENTRY(__strcpy_chk)
|
||||
pld [r0, #0]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -160,6 +161,7 @@ END(__strcpy_chk)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
ENTRY_PRIVATE(__strcpy_chk_failed)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -72,6 +72,7 @@ END(__memcpy_chk)
|
||||
ENTRY(memcpy)
|
||||
pld [r1, #64]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -84,6 +85,7 @@ END(memcpy)
|
||||
ENTRY_PRIVATE(__memcpy_chk_fail)
|
||||
// Preserve lr for backtrace.
|
||||
push {lr}
|
||||
.save {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
|
||||
|
@@ -54,6 +54,7 @@
|
||||
*/
|
||||
|
||||
ENTRY_PRIVATE(MEMCPY_BASE)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -171,6 +172,7 @@ ENTRY_PRIVATE(MEMCPY_BASE)
|
||||
END(MEMCPY_BASE)
|
||||
|
||||
ENTRY_PRIVATE(MEMCPY_BASE_ALIGNED)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -179,14 +181,17 @@ ENTRY_PRIVATE(MEMCPY_BASE_ALIGNED)
|
||||
// i.e., not keeping the stack looking like users expect
|
||||
// (highest numbered register at highest address).
|
||||
strd r4, r5, [sp, #-8]!
|
||||
.save {r4, r5}
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
strd r6, r7, [sp, #-8]!
|
||||
.save {r6, r7}
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_rel_offset r6, 0
|
||||
.cfi_rel_offset r7, 0
|
||||
strd r8, r9, [sp, #-8]!
|
||||
.save {r8, r9}
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_rel_offset r8, 0
|
||||
.cfi_rel_offset r9, 4
|
||||
|
@@ -44,6 +44,7 @@ ENTRY(__memset_chk)
|
||||
bls .L_done
|
||||
|
||||
// Preserve lr for backtrace.
|
||||
.save {lr}
|
||||
push {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
@@ -67,6 +68,7 @@ ENTRY(bzero)
|
||||
END(bzero)
|
||||
|
||||
ENTRY(memset)
|
||||
.save {r0}
|
||||
stmfd sp!, {r0}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset r0, 0
|
||||
|
@@ -168,6 +168,7 @@ ENTRY(strcmp)
|
||||
bne .L_do_align
|
||||
|
||||
/* Fast path. */
|
||||
.save {r4-r7}
|
||||
init
|
||||
|
||||
.L_doubleword_aligned:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -25,6 +25,427 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013 ARM Ltd
|
||||
* 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.
|
||||
* 3. The name of the company may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
|
||||
*/
|
||||
|
||||
#define STRCPY
|
||||
#include "string_copy.S"
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
.syntax unified
|
||||
|
||||
.thumb
|
||||
.thumb_func
|
||||
|
||||
.macro m_push
|
||||
push {r0, r4, r5, lr}
|
||||
.endm // m_push
|
||||
|
||||
.macro m_pop
|
||||
pop {r0, r4, r5, pc}
|
||||
.endm // m_pop
|
||||
|
||||
.macro m_copy_byte reg, cmd, label
|
||||
ldrb \reg, [r1], #1
|
||||
strb \reg, [r0], #1
|
||||
\cmd \reg, \label
|
||||
.endm // m_copy_byte
|
||||
|
||||
ENTRY(strcpy)
|
||||
// For short copies, hard-code checking the first 8 bytes since this
|
||||
// new code doesn't win until after about 8 bytes.
|
||||
m_push
|
||||
m_copy_byte reg=r2, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r3, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r4, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r5, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r2, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r3, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r4, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r5, cmd=cbnz, label=strcpy_continue
|
||||
|
||||
strcpy_finish:
|
||||
m_pop
|
||||
|
||||
strcpy_continue:
|
||||
pld [r1, #0]
|
||||
ands r3, r0, #7
|
||||
beq strcpy_check_src_align
|
||||
|
||||
// Align to a double word (64 bits).
|
||||
rsb r3, r3, #8
|
||||
lsls ip, r3, #31
|
||||
beq strcpy_align_to_32
|
||||
|
||||
ldrb r2, [r1], #1
|
||||
strb r2, [r0], #1
|
||||
cbz r2, strcpy_complete
|
||||
|
||||
strcpy_align_to_32:
|
||||
bcc strcpy_align_to_64
|
||||
|
||||
ldrb r2, [r1], #1
|
||||
strb r2, [r0], #1
|
||||
cbz r2, strcpy_complete
|
||||
ldrb r2, [r1], #1
|
||||
strb r2, [r0], #1
|
||||
cbz r2, strcpy_complete
|
||||
|
||||
strcpy_align_to_64:
|
||||
tst r3, #4
|
||||
beq strcpy_check_src_align
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
str r2, [r0], #4
|
||||
|
||||
strcpy_check_src_align:
|
||||
// At this point dst is aligned to a double word, check if src
|
||||
// is also aligned to a double word.
|
||||
ands r3, r1, #7
|
||||
bne strcpy_unaligned_copy
|
||||
|
||||
.p2align 2
|
||||
strcpy_mainloop:
|
||||
ldrd r2, r3, [r1], #8
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b strcpy_mainloop
|
||||
|
||||
strcpy_complete:
|
||||
m_pop
|
||||
|
||||
strcpy_zero_in_first_register:
|
||||
lsls lr, ip, #17
|
||||
bne strcpy_copy1byte
|
||||
bcs strcpy_copy2bytes
|
||||
lsls ip, ip, #1
|
||||
bne strcpy_copy3bytes
|
||||
|
||||
strcpy_copy4bytes:
|
||||
// Copy 4 bytes to the destiniation.
|
||||
str r2, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_copy2bytes:
|
||||
strh r2, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_copy3bytes:
|
||||
strh r2, [r0], #2
|
||||
lsr r2, #16
|
||||
strb r2, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_zero_in_second_register:
|
||||
lsls lr, ip, #17
|
||||
bne strcpy_copy5bytes
|
||||
bcs strcpy_copy6bytes
|
||||
lsls ip, ip, #1
|
||||
bne strcpy_copy7bytes
|
||||
|
||||
// Copy 8 bytes to the destination.
|
||||
strd r2, r3, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_copy5bytes:
|
||||
str r2, [r0], #4
|
||||
strb r3, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_copy6bytes:
|
||||
str r2, [r0], #4
|
||||
strh r3, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_copy7bytes:
|
||||
str r2, [r0], #4
|
||||
strh r3, [r0], #2
|
||||
lsr r3, #16
|
||||
strb r3, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_unaligned_copy:
|
||||
// Dst is aligned to a double word, while src is at an unknown alignment.
|
||||
// There are 7 different versions of the unaligned copy code
|
||||
// to prevent overreading the src. The mainloop of every single version
|
||||
// will store 64 bits per loop. The difference is how much of src can
|
||||
// be read without potentially crossing a page boundary.
|
||||
tbb [pc, r3]
|
||||
strcpy_unaligned_branchtable:
|
||||
.byte 0
|
||||
.byte ((strcpy_unalign7 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign6 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign5 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign4 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign3 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign2 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign1 - strcpy_unaligned_branchtable)/2)
|
||||
|
||||
.p2align 2
|
||||
// Can read 7 bytes before possibly crossing a page.
|
||||
strcpy_unalign7:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
ldrb r3, [r1]
|
||||
cbz r3, strcpy_unalign7_copy5bytes
|
||||
ldrb r4, [r1, #1]
|
||||
cbz r4, strcpy_unalign7_copy6bytes
|
||||
ldrb r5, [r1, #2]
|
||||
cbz r5, strcpy_unalign7_copy7bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
lsrs ip, r3, #24
|
||||
strd r2, r3, [r0], #8
|
||||
beq strcpy_unalign_return
|
||||
b strcpy_unalign7
|
||||
|
||||
strcpy_unalign7_copy5bytes:
|
||||
str r2, [r0], #4
|
||||
strb r3, [r0]
|
||||
strcpy_unalign_return:
|
||||
m_pop
|
||||
|
||||
strcpy_unalign7_copy6bytes:
|
||||
str r2, [r0], #4
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0], #1
|
||||
m_pop
|
||||
|
||||
strcpy_unalign7_copy7bytes:
|
||||
str r2, [r0], #4
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0], #1
|
||||
strb r5, [r0], #1
|
||||
m_pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 6 bytes before possibly crossing a page.
|
||||
strcpy_unalign6:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
ldrb r4, [r1]
|
||||
cbz r4, strcpy_unalign_copy5bytes
|
||||
ldrb r5, [r1, #1]
|
||||
cbz r5, strcpy_unalign_copy6bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
tst r3, #0xff0000
|
||||
beq strcpy_copy7bytes
|
||||
lsrs ip, r3, #24
|
||||
strd r2, r3, [r0], #8
|
||||
beq strcpy_unalign_return
|
||||
b strcpy_unalign6
|
||||
|
||||
.p2align 2
|
||||
// Can read 5 bytes before possibly crossing a page.
|
||||
strcpy_unalign5:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
ldrb r4, [r1]
|
||||
cbz r4, strcpy_unalign_copy5bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b strcpy_unalign5
|
||||
|
||||
strcpy_unalign_copy5bytes:
|
||||
str r2, [r0], #4
|
||||
strb r4, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_unalign_copy6bytes:
|
||||
str r2, [r0], #4
|
||||
strb r4, [r0], #1
|
||||
strb r5, [r0]
|
||||
m_pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 4 bytes before possibly crossing a page.
|
||||
strcpy_unalign4:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b strcpy_unalign4
|
||||
|
||||
.p2align 2
|
||||
// Can read 3 bytes before possibly crossing a page.
|
||||
strcpy_unalign3:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, strcpy_unalign3_copy1byte
|
||||
ldrb r3, [r1, #1]
|
||||
cbz r3, strcpy_unalign3_copy2bytes
|
||||
ldrb r4, [r1, #2]
|
||||
cbz r4, strcpy_unalign3_copy3bytes
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
lsrs lr, r2, #24
|
||||
beq strcpy_copy4bytes
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b strcpy_unalign3
|
||||
|
||||
strcpy_unalign3_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_unalign3_copy2bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_unalign3_copy3bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0]
|
||||
m_pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 2 bytes before possibly crossing a page.
|
||||
strcpy_unalign2:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, strcpy_unalign_copy1byte
|
||||
ldrb r4, [r1, #1]
|
||||
cbz r4, strcpy_unalign_copy2bytes
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
tst r2, #0xff0000
|
||||
beq strcpy_copy3bytes
|
||||
lsrs ip, r2, #24
|
||||
beq strcpy_copy4bytes
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b strcpy_unalign2
|
||||
|
||||
.p2align 2
|
||||
// Can read 1 byte before possibly crossing a page.
|
||||
strcpy_unalign1:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, strcpy_unalign_copy1byte
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b strcpy_unalign1
|
||||
|
||||
strcpy_unalign_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_pop
|
||||
|
||||
strcpy_unalign_copy2bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r4, [r0]
|
||||
m_pop
|
||||
END(strcpy)
|
||||
|
@@ -1,513 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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) 2013 ARM Ltd
|
||||
* 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.
|
||||
* 3. The name of the company may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
|
||||
*/
|
||||
|
||||
#if !defined(STPCPY) && !defined(STRCPY)
|
||||
#error "Either STPCPY or STRCPY must be defined."
|
||||
#endif
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
.syntax unified
|
||||
|
||||
.thumb
|
||||
.thumb_func
|
||||
|
||||
#if defined(STPCPY)
|
||||
.macro m_push
|
||||
push {r4, r5, lr}
|
||||
.cfi_def_cfa_offset 12
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
.cfi_rel_offset lr, 8
|
||||
.endm // m_push
|
||||
#else
|
||||
.macro m_push
|
||||
push {r0, r4, r5, lr}
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r4, 4
|
||||
.cfi_rel_offset r5, 8
|
||||
.cfi_rel_offset lr, 12
|
||||
.endm // m_push
|
||||
#endif
|
||||
|
||||
#if defined(STPCPY)
|
||||
.macro m_pop
|
||||
pop {r4, r5, pc}
|
||||
.endm // m_pop
|
||||
#else
|
||||
.macro m_pop
|
||||
pop {r0, r4, r5, pc}
|
||||
.endm // m_pop
|
||||
#endif
|
||||
|
||||
.macro m_copy_byte reg, cmd, label
|
||||
ldrb \reg, [r1], #1
|
||||
strb \reg, [r0], #1
|
||||
\cmd \reg, \label
|
||||
.endm // m_copy_byte
|
||||
|
||||
#if defined(STPCPY)
|
||||
ENTRY(stpcpy)
|
||||
#else
|
||||
ENTRY(strcpy)
|
||||
#endif
|
||||
// For short copies, hard-code checking the first 8 bytes since this
|
||||
// new code doesn't win until after about 8 bytes.
|
||||
m_push
|
||||
m_copy_byte reg=r2, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r3, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r4, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r5, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r2, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r3, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r4, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r5, cmd=cbnz, label=.Lstringcopy_continue
|
||||
|
||||
.Lstringcopy_finish:
|
||||
#if defined(STPCPY)
|
||||
sub r0, r0, #1
|
||||
#endif
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_continue:
|
||||
pld [r1, #0]
|
||||
ands r3, r0, #7
|
||||
beq .Lstringcopy_check_src_align
|
||||
|
||||
// Align to a double word (64 bits).
|
||||
rsb r3, r3, #8
|
||||
lsls ip, r3, #31
|
||||
beq .Lstringcopy_align_to_32
|
||||
|
||||
ldrb r2, [r1], #1
|
||||
strb r2, [r0], #1
|
||||
cbz r2, .Lstringcopy_complete
|
||||
|
||||
.Lstringcopy_align_to_32:
|
||||
bcc .Lstringcopy_align_to_64
|
||||
|
||||
ldrb r2, [r1], #1
|
||||
strb r2, [r0], #1
|
||||
cbz r2, .Lstringcopy_complete
|
||||
ldrb r2, [r1], #1
|
||||
strb r2, [r0], #1
|
||||
cbz r2, .Lstringcopy_complete
|
||||
|
||||
.Lstringcopy_align_to_64:
|
||||
tst r3, #4
|
||||
beq .Lstringcopy_check_src_align
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
str r2, [r0], #4
|
||||
|
||||
.Lstringcopy_check_src_align:
|
||||
// At this point dst is aligned to a double word, check if src
|
||||
// is also aligned to a double word.
|
||||
ands r3, r1, #7
|
||||
bne .Lstringcopy_unaligned_copy
|
||||
|
||||
.p2align 2
|
||||
.Lstringcopy_mainloop:
|
||||
ldrd r2, r3, [r1], #8
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b .Lstringcopy_mainloop
|
||||
|
||||
.Lstringcopy_complete:
|
||||
#if defined(STPCPY)
|
||||
sub r0, r0, #1
|
||||
#endif
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_zero_in_first_register:
|
||||
lsls lr, ip, #17
|
||||
bne .Lstringcopy_copy1byte
|
||||
bcs .Lstringcopy_copy2bytes
|
||||
lsls ip, ip, #1
|
||||
bne .Lstringcopy_copy3bytes
|
||||
|
||||
.Lstringcopy_copy4bytes:
|
||||
// Copy 4 bytes to the destiniation.
|
||||
#if defined(STPCPY)
|
||||
str r2, [r0], #3
|
||||
#else
|
||||
str r2, [r0]
|
||||
#endif
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_copy2bytes:
|
||||
#if defined(STPCPY)
|
||||
strh r2, [r0], #1
|
||||
#else
|
||||
strh r2, [r0]
|
||||
#endif
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_copy3bytes:
|
||||
strh r2, [r0], #2
|
||||
lsr r2, #16
|
||||
strb r2, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_zero_in_second_register:
|
||||
lsls lr, ip, #17
|
||||
bne .Lstringcopy_copy5bytes
|
||||
bcs .Lstringcopy_copy6bytes
|
||||
lsls ip, ip, #1
|
||||
bne .Lstringcopy_copy7bytes
|
||||
|
||||
// Copy 8 bytes to the destination.
|
||||
strd r2, r3, [r0]
|
||||
#if defined(STPCPY)
|
||||
add r0, r0, #7
|
||||
#endif
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_copy5bytes:
|
||||
str r2, [r0], #4
|
||||
strb r3, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_copy6bytes:
|
||||
str r2, [r0], #4
|
||||
#if defined(STPCPY)
|
||||
strh r3, [r0], #1
|
||||
#else
|
||||
strh r3, [r0]
|
||||
#endif
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_copy7bytes:
|
||||
str r2, [r0], #4
|
||||
strh r3, [r0], #2
|
||||
lsr r3, #16
|
||||
strb r3, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_unaligned_copy:
|
||||
// Dst is aligned to a double word, while src is at an unknown alignment.
|
||||
// There are 7 different versions of the unaligned copy code
|
||||
// to prevent overreading the src. The mainloop of every single version
|
||||
// will store 64 bits per loop. The difference is how much of src can
|
||||
// be read without potentially crossing a page boundary.
|
||||
tbb [pc, r3]
|
||||
.Lstringcopy_unaligned_branchtable:
|
||||
.byte 0
|
||||
.byte ((.Lstringcopy_unalign7 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign6 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign5 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign4 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign3 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign2 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign1 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
|
||||
.p2align 2
|
||||
// Can read 7 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign7:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
ldrb r3, [r1]
|
||||
cbz r3, .Lstringcopy_unalign7_copy5bytes
|
||||
ldrb r4, [r1, #1]
|
||||
cbz r4, .Lstringcopy_unalign7_copy6bytes
|
||||
ldrb r5, [r1, #2]
|
||||
cbz r5, .Lstringcopy_unalign7_copy7bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
lsrs ip, r3, #24
|
||||
strd r2, r3, [r0], #8
|
||||
#if defined(STPCPY)
|
||||
beq .Lstringcopy_finish
|
||||
#else
|
||||
beq .Lstringcopy_unalign_return
|
||||
#endif
|
||||
b .Lstringcopy_unalign7
|
||||
|
||||
.Lstringcopy_unalign7_copy5bytes:
|
||||
str r2, [r0], #4
|
||||
strb r3, [r0]
|
||||
.Lstringcopy_unalign_return:
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_unalign7_copy6bytes:
|
||||
str r2, [r0], #4
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_unalign7_copy7bytes:
|
||||
str r2, [r0], #4
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0], #1
|
||||
strb r5, [r0]
|
||||
m_pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 6 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign6:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
ldrb r4, [r1]
|
||||
cbz r4, .Lstringcopy_unalign_copy5bytes
|
||||
ldrb r5, [r1, #1]
|
||||
cbz r5, .Lstringcopy_unalign_copy6bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
tst r3, #0xff0000
|
||||
beq .Lstringcopy_copy7bytes
|
||||
lsrs ip, r3, #24
|
||||
strd r2, r3, [r0], #8
|
||||
#if defined(STPCPY)
|
||||
beq .Lstringcopy_finish
|
||||
#else
|
||||
beq .Lstringcopy_unalign_return
|
||||
#endif
|
||||
b .Lstringcopy_unalign6
|
||||
|
||||
.p2align 2
|
||||
// Can read 5 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign5:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
ldrb r4, [r1]
|
||||
cbz r4, .Lstringcopy_unalign_copy5bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b .Lstringcopy_unalign5
|
||||
|
||||
.Lstringcopy_unalign_copy5bytes:
|
||||
str r2, [r0], #4
|
||||
strb r4, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_unalign_copy6bytes:
|
||||
str r2, [r0], #4
|
||||
strb r4, [r0], #1
|
||||
strb r5, [r0]
|
||||
m_pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 4 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign4:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b .Lstringcopy_unalign4
|
||||
|
||||
.p2align 2
|
||||
// Can read 3 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign3:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, .Lstringcopy_unalign3_copy1byte
|
||||
ldrb r3, [r1, #1]
|
||||
cbz r3, .Lstringcopy_unalign3_copy2bytes
|
||||
ldrb r4, [r1, #2]
|
||||
cbz r4, .Lstringcopy_unalign3_copy3bytes
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
lsrs lr, r2, #24
|
||||
beq .Lstringcopy_copy4bytes
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b .Lstringcopy_unalign3
|
||||
|
||||
.Lstringcopy_unalign3_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_unalign3_copy2bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_unalign3_copy3bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0]
|
||||
m_pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 2 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign2:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, .Lstringcopy_unalign_copy1byte
|
||||
ldrb r4, [r1, #1]
|
||||
cbz r4, .Lstringcopy_unalign_copy2bytes
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
tst r2, #0xff0000
|
||||
beq .Lstringcopy_copy3bytes
|
||||
lsrs ip, r2, #24
|
||||
beq .Lstringcopy_copy4bytes
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b .Lstringcopy_unalign2
|
||||
|
||||
.p2align 2
|
||||
// Can read 1 byte before possibly crossing a page.
|
||||
.Lstringcopy_unalign1:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, .Lstringcopy_unalign_copy1byte
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
strd r2, r3, [r0], #8
|
||||
b .Lstringcopy_unalign1
|
||||
|
||||
.Lstringcopy_unalign_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_pop
|
||||
|
||||
.Lstringcopy_unalign_copy2bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r4, [r0]
|
||||
m_pop
|
||||
#if defined(STPCPY)
|
||||
END(stpcpy)
|
||||
#else
|
||||
END(strcpy)
|
||||
#endif
|
@@ -1,11 +1,10 @@
|
||||
libc_bionic_src_files_arm += \
|
||||
arch-arm/cortex-a15/bionic/memcpy.S \
|
||||
arch-arm/cortex-a15/bionic/memset.S \
|
||||
arch-arm/cortex-a15/bionic/stpcpy.S \
|
||||
arch-arm/cortex-a15/bionic/strcat.S \
|
||||
arch-arm/cortex-a15/bionic/__strcat_chk.S \
|
||||
arch-arm/cortex-a15/bionic/strcmp.S \
|
||||
arch-arm/cortex-a15/bionic/strcpy.S \
|
||||
arch-arm/cortex-a15/bionic/__strcpy_chk.S \
|
||||
arch-arm/cortex-a15/bionic/strlen.S \
|
||||
arch-arm/cortex-a15/bionic/__strcat_chk.S \
|
||||
arch-arm/cortex-a15/bionic/__strcpy_chk.S \
|
||||
bionic/memmove.c \
|
||||
|
@@ -40,10 +40,12 @@
|
||||
ENTRY(__strcat_chk)
|
||||
pld [r0, #0]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
push {r4, r5}
|
||||
.save {r4, r5}
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
@@ -197,6 +199,8 @@ END(__strcat_chk)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
ENTRY_PRIVATE(__strcat_chk_fail)
|
||||
.save {r0, lr}
|
||||
.save {r4, r5}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -39,6 +39,7 @@
|
||||
ENTRY(__strcpy_chk)
|
||||
pld [r0, #0]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -164,6 +165,7 @@ END(__strcpy_chk)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
ENTRY_PRIVATE(__strcpy_chk_fail)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -50,6 +50,7 @@ END(__memcpy_chk)
|
||||
ENTRY(memcpy)
|
||||
pld [r1, #0]
|
||||
stmfd sp!, {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -63,6 +64,7 @@ END(memcpy)
|
||||
ENTRY_PRIVATE(__memcpy_chk_fail)
|
||||
// Preserve lr for backtrace.
|
||||
push {lr}
|
||||
.save {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
|
||||
|
@@ -33,6 +33,7 @@
|
||||
*/
|
||||
|
||||
ENTRY_PRIVATE(MEMCPY_BASE)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -138,12 +139,14 @@ ENTRY_PRIVATE(MEMCPY_BASE)
|
||||
END(MEMCPY_BASE)
|
||||
|
||||
ENTRY_PRIVATE(MEMCPY_BASE_ALIGNED)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
||||
/* Simple arm-only copy loop to handle aligned copy operations */
|
||||
stmfd sp!, {r4-r8}
|
||||
.save {r4-r8}
|
||||
.cfi_adjust_cfa_offset 20
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
|
@@ -42,6 +42,7 @@ ENTRY(__memset_chk)
|
||||
|
||||
// Preserve lr for backtrace.
|
||||
push {lr}
|
||||
.save {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
|
||||
@@ -71,6 +72,7 @@ ENTRY(memset)
|
||||
bhi __memset_large_copy
|
||||
|
||||
stmfd sp!, {r0}
|
||||
.save {r0}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset r0, 0
|
||||
|
||||
@@ -112,6 +114,7 @@ ENTRY_PRIVATE(__memset_large_copy)
|
||||
* offset = (4-(src&3))&3 = -src & 3
|
||||
*/
|
||||
stmfd sp!, {r0, r4-r7, lr}
|
||||
.save {r0, r4-r7, lr}
|
||||
.cfi_def_cfa_offset 24
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r4, 4
|
||||
|
@@ -168,6 +168,7 @@ ENTRY(strcmp)
|
||||
bne .L_do_align
|
||||
|
||||
/* Fast path. */
|
||||
.save {r4-r7}
|
||||
init
|
||||
|
||||
.L_doubleword_aligned:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -25,6 +25,432 @@
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013 ARM Ltd
|
||||
* 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.
|
||||
* 3. The name of the company may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
|
||||
*/
|
||||
|
||||
#define STRCPY
|
||||
#include "string_copy.S"
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
.syntax unified
|
||||
|
||||
.thumb
|
||||
.thumb_func
|
||||
|
||||
.macro m_push
|
||||
push {r0, r4, r5, lr}
|
||||
.endm // m_push
|
||||
|
||||
.macro m_ret inst
|
||||
\inst {r0, r4, r5, pc}
|
||||
.endm // m_ret
|
||||
|
||||
.macro m_copy_byte reg, cmd, label
|
||||
ldrb \reg, [r1], #1
|
||||
strb \reg, [r0], #1
|
||||
\cmd \reg, \label
|
||||
.endm // m_copy_byte
|
||||
|
||||
ENTRY(strcpy)
|
||||
// Unroll the first 8 bytes that will be copied.
|
||||
m_push
|
||||
m_copy_byte reg=r2, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r3, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r4, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r5, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r2, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r3, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r4, cmd=cbz, label=strcpy_finish
|
||||
m_copy_byte reg=r5, cmd=cbnz, label=strcpy_continue
|
||||
|
||||
strcpy_finish:
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_continue:
|
||||
pld [r1, #0]
|
||||
ands r3, r0, #7
|
||||
bne strcpy_align_dst
|
||||
|
||||
strcpy_check_src_align:
|
||||
// At this point dst is aligned to a double word, check if src
|
||||
// is also aligned to a double word.
|
||||
ands r3, r1, #7
|
||||
bne strcpy_unaligned_copy
|
||||
|
||||
.p2align 2
|
||||
strcpy_mainloop:
|
||||
ldmia r1!, {r2, r3}
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b strcpy_mainloop
|
||||
|
||||
strcpy_zero_in_first_register:
|
||||
lsls lr, ip, #17
|
||||
itt ne
|
||||
strbne r2, [r0]
|
||||
m_ret inst=popne
|
||||
itt cs
|
||||
strhcs r2, [r0]
|
||||
m_ret inst=popcs
|
||||
lsls ip, ip, #1
|
||||
itt eq
|
||||
streq r2, [r0]
|
||||
m_ret inst=popeq
|
||||
strh r2, [r0], #2
|
||||
lsr r3, r2, #16
|
||||
strb r3, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_zero_in_second_register:
|
||||
lsls lr, ip, #17
|
||||
ittt ne
|
||||
stmiane r0!, {r2}
|
||||
strbne r3, [r0]
|
||||
m_ret inst=popne
|
||||
ittt cs
|
||||
strcs r2, [r0], #4
|
||||
strhcs r3, [r0]
|
||||
m_ret inst=popcs
|
||||
lsls ip, ip, #1
|
||||
itt eq
|
||||
stmiaeq r0, {r2, r3}
|
||||
m_ret inst=popeq
|
||||
stmia r0!, {r2}
|
||||
strh r3, [r0], #2
|
||||
lsr r4, r3, #16
|
||||
strb r4, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_align_dst:
|
||||
// Align to a double word (64 bits).
|
||||
rsb r3, r3, #8
|
||||
lsls ip, r3, #31
|
||||
beq strcpy_align_to_32
|
||||
|
||||
ldrb r2, [r1], #1
|
||||
strb r2, [r0], #1
|
||||
cbz r2, strcpy_complete
|
||||
|
||||
strcpy_align_to_32:
|
||||
bcc strcpy_align_to_64
|
||||
|
||||
ldrb r4, [r1], #1
|
||||
strb r4, [r0], #1
|
||||
cmp r4, #0
|
||||
it eq
|
||||
m_ret inst=popeq
|
||||
ldrb r5, [r1], #1
|
||||
strb r5, [r0], #1
|
||||
cmp r5, #0
|
||||
it eq
|
||||
m_ret inst=popeq
|
||||
|
||||
strcpy_align_to_64:
|
||||
tst r3, #4
|
||||
beq strcpy_check_src_align
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
stmia r0!, {r2}
|
||||
b strcpy_check_src_align
|
||||
|
||||
strcpy_complete:
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unaligned_copy:
|
||||
// Dst is aligned to a double word, while src is at an unknown alignment.
|
||||
// There are 7 different versions of the unaligned copy code
|
||||
// to prevent overreading the src. The mainloop of every single version
|
||||
// will store 64 bits per loop. The difference is how much of src can
|
||||
// be read without potentially crossing a page boundary.
|
||||
tbb [pc, r3]
|
||||
strcpy_unaligned_branchtable:
|
||||
.byte 0
|
||||
.byte ((strcpy_unalign7 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign6 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign5 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign4 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign3 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign2 - strcpy_unaligned_branchtable)/2)
|
||||
.byte ((strcpy_unalign1 - strcpy_unaligned_branchtable)/2)
|
||||
|
||||
.p2align 2
|
||||
// Can read 7 bytes before possibly crossing a page.
|
||||
strcpy_unalign7:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
ldrb r3, [r1]
|
||||
cbz r3, strcpy_unalign7_copy5bytes
|
||||
ldrb r4, [r1, #1]
|
||||
cbz r4, strcpy_unalign7_copy6bytes
|
||||
ldrb r5, [r1, #2]
|
||||
cbz r5, strcpy_unalign7_copy7bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
lsrs ip, r3, #24
|
||||
stmia r0!, {r2, r3}
|
||||
beq strcpy_unalign_return
|
||||
b strcpy_unalign7
|
||||
|
||||
strcpy_unalign7_copy5bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r3, [r0]
|
||||
strcpy_unalign_return:
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unalign7_copy6bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0], #1
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unalign7_copy7bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0], #1
|
||||
strb r5, [r0], #1
|
||||
m_ret inst=pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 6 bytes before possibly crossing a page.
|
||||
strcpy_unalign6:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
ldrb r4, [r1]
|
||||
cbz r4, strcpy_unalign_copy5bytes
|
||||
ldrb r5, [r1, #1]
|
||||
cbz r5, strcpy_unalign_copy6bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
tst r3, #0xff0000
|
||||
beq strcpy_unalign6_copy7bytes
|
||||
lsrs ip, r3, #24
|
||||
stmia r0!, {r2, r3}
|
||||
beq strcpy_unalign_return
|
||||
b strcpy_unalign6
|
||||
|
||||
strcpy_unalign6_copy7bytes:
|
||||
stmia r0!, {r2}
|
||||
strh r3, [r0], #2
|
||||
lsr r3, #16
|
||||
strb r3, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 5 bytes before possibly crossing a page.
|
||||
strcpy_unalign5:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
ldrb r4, [r1]
|
||||
cbz r4, strcpy_unalign_copy5bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b strcpy_unalign5
|
||||
|
||||
strcpy_unalign_copy5bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r4, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unalign_copy6bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r4, [r0], #1
|
||||
strb r5, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 4 bytes before possibly crossing a page.
|
||||
strcpy_unalign4:
|
||||
ldmia r1!, {r2}
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
ldmia r1!, {r3}
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b strcpy_unalign4
|
||||
|
||||
.p2align 2
|
||||
// Can read 3 bytes before possibly crossing a page.
|
||||
strcpy_unalign3:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, strcpy_unalign3_copy1byte
|
||||
ldrb r3, [r1, #1]
|
||||
cbz r3, strcpy_unalign3_copy2bytes
|
||||
ldrb r4, [r1, #2]
|
||||
cbz r4, strcpy_unalign3_copy3bytes
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
lsrs lr, r2, #24
|
||||
beq strcpy_unalign_copy4bytes
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b strcpy_unalign3
|
||||
|
||||
strcpy_unalign3_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unalign3_copy2bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unalign3_copy3bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 2 bytes before possibly crossing a page.
|
||||
strcpy_unalign2:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, strcpy_unalign_copy1byte
|
||||
ldrb r3, [r1, #1]
|
||||
cbz r3, strcpy_unalign_copy2bytes
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
tst r2, #0xff0000
|
||||
beq strcpy_unalign_copy3bytes
|
||||
lsrs ip, r2, #24
|
||||
beq strcpy_unalign_copy4bytes
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b strcpy_unalign2
|
||||
|
||||
.p2align 2
|
||||
// Can read 1 byte before possibly crossing a page.
|
||||
strcpy_unalign1:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, strcpy_unalign_copy1byte
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_first_register
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne strcpy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b strcpy_unalign1
|
||||
|
||||
strcpy_unalign_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unalign_copy2bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unalign_copy3bytes:
|
||||
strh r2, [r0], #2
|
||||
lsr r2, #16
|
||||
strb r2, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
strcpy_unalign_copy4bytes:
|
||||
stmia r0, {r2}
|
||||
m_ret inst=pop
|
||||
END(strcpy)
|
||||
|
@@ -1,535 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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) 2013 ARM Ltd
|
||||
* 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.
|
||||
* 3. The name of the company may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
|
||||
*/
|
||||
|
||||
#if !defined(STPCPY) && !defined(STRCPY)
|
||||
#error "Either STPCPY or STRCPY must be defined."
|
||||
#endif
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
.syntax unified
|
||||
|
||||
.thumb
|
||||
.thumb_func
|
||||
|
||||
#if defined(STPCPY)
|
||||
.macro m_push
|
||||
push {r4, r5, lr}
|
||||
.cfi_def_cfa_offset 12
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
.cfi_rel_offset lr, 8
|
||||
.endm // m_push
|
||||
#else
|
||||
.macro m_push
|
||||
push {r0, r4, r5, lr}
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r4, 4
|
||||
.cfi_rel_offset r5, 8
|
||||
.cfi_rel_offset lr, 12
|
||||
.endm // m_push
|
||||
#endif
|
||||
|
||||
#if defined(STPCPY)
|
||||
.macro m_ret inst
|
||||
\inst {r4, r5, pc}
|
||||
.endm // m_ret
|
||||
#else
|
||||
.macro m_ret inst
|
||||
\inst {r0, r4, r5, pc}
|
||||
.endm // m_ret
|
||||
#endif
|
||||
|
||||
.macro m_copy_byte reg, cmd, label
|
||||
ldrb \reg, [r1], #1
|
||||
strb \reg, [r0], #1
|
||||
\cmd \reg, \label
|
||||
.endm // m_copy_byte
|
||||
|
||||
#if defined(STPCPY)
|
||||
ENTRY(stpcpy)
|
||||
#else
|
||||
ENTRY(strcpy)
|
||||
#endif
|
||||
// Unroll the first 8 bytes that will be copied.
|
||||
m_push
|
||||
m_copy_byte reg=r2, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r3, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r4, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r5, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r2, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r3, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r4, cmd=cbz, label=.Lstringcopy_finish
|
||||
m_copy_byte reg=r5, cmd=cbnz, label=.Lstringcopy_continue
|
||||
|
||||
.Lstringcopy_finish:
|
||||
#if defined(STPCPY)
|
||||
sub r0, r0, #1
|
||||
#endif
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_continue:
|
||||
pld [r1, #0]
|
||||
ands r3, r0, #7
|
||||
bne .Lstringcopy_align_dst
|
||||
|
||||
.Lstringcopy_check_src_align:
|
||||
// At this point dst is aligned to a double word, check if src
|
||||
// is also aligned to a double word.
|
||||
ands r3, r1, #7
|
||||
bne .Lstringcopy_unaligned_copy
|
||||
|
||||
.p2align 2
|
||||
.Lstringcopy_mainloop:
|
||||
ldmia r1!, {r2, r3}
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b .Lstringcopy_mainloop
|
||||
|
||||
.Lstringcopy_zero_in_first_register:
|
||||
lsls lr, ip, #17
|
||||
itt ne
|
||||
strbne r2, [r0]
|
||||
m_ret inst=popne
|
||||
itt cs
|
||||
#if defined(STPCPY)
|
||||
strhcs r2, [r0], #1
|
||||
#else
|
||||
strhcs r2, [r0]
|
||||
#endif
|
||||
m_ret inst=popcs
|
||||
lsls ip, ip, #1
|
||||
itt eq
|
||||
#if defined(STPCPY)
|
||||
streq r2, [r0], #3
|
||||
#else
|
||||
streq r2, [r0]
|
||||
#endif
|
||||
m_ret inst=popeq
|
||||
strh r2, [r0], #2
|
||||
lsr r3, r2, #16
|
||||
strb r3, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_zero_in_second_register:
|
||||
lsls lr, ip, #17
|
||||
ittt ne
|
||||
stmiane r0!, {r2}
|
||||
strbne r3, [r0]
|
||||
m_ret inst=popne
|
||||
ittt cs
|
||||
strcs r2, [r0], #4
|
||||
#if defined(STPCPY)
|
||||
strhcs r3, [r0], #1
|
||||
#else
|
||||
strhcs r3, [r0]
|
||||
#endif
|
||||
m_ret inst=popcs
|
||||
lsls ip, ip, #1
|
||||
#if defined(STPCPY)
|
||||
ittt eq
|
||||
#else
|
||||
itt eq
|
||||
#endif
|
||||
stmiaeq r0, {r2, r3}
|
||||
#if defined(STPCPY)
|
||||
addeq r0, r0, #7
|
||||
#endif
|
||||
m_ret inst=popeq
|
||||
stmia r0!, {r2}
|
||||
strh r3, [r0], #2
|
||||
lsr r4, r3, #16
|
||||
strb r4, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_align_dst:
|
||||
// Align to a double word (64 bits).
|
||||
rsb r3, r3, #8
|
||||
lsls ip, r3, #31
|
||||
beq .Lstringcopy_align_to_32
|
||||
|
||||
ldrb r2, [r1], #1
|
||||
strb r2, [r0], #1
|
||||
cbz r2, .Lstringcopy_complete
|
||||
|
||||
.Lstringcopy_align_to_32:
|
||||
bcc .Lstringcopy_align_to_64
|
||||
|
||||
ldrb r4, [r1], #1
|
||||
strb r4, [r0], #1
|
||||
cmp r4, #0
|
||||
#if defined(STPCPY)
|
||||
itt eq
|
||||
subeq r0, r0, #1
|
||||
#else
|
||||
it eq
|
||||
#endif
|
||||
m_ret inst=popeq
|
||||
ldrb r5, [r1], #1
|
||||
strb r5, [r0], #1
|
||||
cmp r5, #0
|
||||
#if defined(STPCPY)
|
||||
itt eq
|
||||
subeq r0, r0, #1
|
||||
#else
|
||||
it eq
|
||||
#endif
|
||||
m_ret inst=popeq
|
||||
|
||||
.Lstringcopy_align_to_64:
|
||||
tst r3, #4
|
||||
beq .Lstringcopy_check_src_align
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
stmia r0!, {r2}
|
||||
b .Lstringcopy_check_src_align
|
||||
|
||||
.Lstringcopy_complete:
|
||||
#if defined(STPCPY)
|
||||
sub r0, r0, #1
|
||||
#endif
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unaligned_copy:
|
||||
// Dst is aligned to a double word, while src is at an unknown alignment.
|
||||
// There are 7 different versions of the unaligned copy code
|
||||
// to prevent overreading the src. The mainloop of every single version
|
||||
// will store 64 bits per loop. The difference is how much of src can
|
||||
// be read without potentially crossing a page boundary.
|
||||
tbb [pc, r3]
|
||||
.Lstringcopy_unaligned_branchtable:
|
||||
.byte 0
|
||||
.byte ((.Lstringcopy_unalign7 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign6 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign5 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign4 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign3 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign2 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
.byte ((.Lstringcopy_unalign1 - .Lstringcopy_unaligned_branchtable)/2)
|
||||
|
||||
.p2align 2
|
||||
// Can read 7 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign7:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
ldrb r3, [r1]
|
||||
cbz r3, .Lstringcopy_unalign7_copy5bytes
|
||||
ldrb r4, [r1, #1]
|
||||
cbz r4, .Lstringcopy_unalign7_copy6bytes
|
||||
ldrb r5, [r1, #2]
|
||||
cbz r5, .Lstringcopy_unalign7_copy7bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
lsrs ip, r3, #24
|
||||
stmia r0!, {r2, r3}
|
||||
#if defined(STPCPY)
|
||||
beq .Lstringcopy_finish
|
||||
#else
|
||||
beq .Lstringcopy_unalign_return
|
||||
#endif
|
||||
b .Lstringcopy_unalign7
|
||||
|
||||
.Lstringcopy_unalign7_copy5bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r3, [r0]
|
||||
.Lstringcopy_unalign_return:
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unalign7_copy6bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unalign7_copy7bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0], #1
|
||||
strb r5, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 6 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign6:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
ldrb r4, [r1]
|
||||
cbz r4, .Lstringcopy_unalign_copy5bytes
|
||||
ldrb r5, [r1, #1]
|
||||
cbz r5, .Lstringcopy_unalign_copy6bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
tst r3, #0xff0000
|
||||
beq .Lstringcopy_unalign6_copy7bytes
|
||||
lsrs ip, r3, #24
|
||||
stmia r0!, {r2, r3}
|
||||
#if defined(STPCPY)
|
||||
beq .Lstringcopy_finish
|
||||
#else
|
||||
beq .Lstringcopy_unalign_return
|
||||
#endif
|
||||
b .Lstringcopy_unalign6
|
||||
|
||||
.Lstringcopy_unalign6_copy7bytes:
|
||||
stmia r0!, {r2}
|
||||
strh r3, [r0], #2
|
||||
lsr r3, #16
|
||||
strb r3, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 5 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign5:
|
||||
ldr r2, [r1], #4
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
ldrb r4, [r1]
|
||||
cbz r4, .Lstringcopy_unalign_copy5bytes
|
||||
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b .Lstringcopy_unalign5
|
||||
|
||||
.Lstringcopy_unalign_copy5bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r4, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unalign_copy6bytes:
|
||||
stmia r0!, {r2}
|
||||
strb r4, [r0], #1
|
||||
strb r5, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 4 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign4:
|
||||
ldmia r1!, {r2}
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
ldmia r1!, {r3}
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b .Lstringcopy_unalign4
|
||||
|
||||
.p2align 2
|
||||
// Can read 3 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign3:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, .Lstringcopy_unalign3_copy1byte
|
||||
ldrb r3, [r1, #1]
|
||||
cbz r3, .Lstringcopy_unalign3_copy2bytes
|
||||
ldrb r4, [r1, #2]
|
||||
cbz r4, .Lstringcopy_unalign3_copy3bytes
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
lsrs lr, r2, #24
|
||||
beq .Lstringcopy_unalign_copy4bytes
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b .Lstringcopy_unalign3
|
||||
|
||||
.Lstringcopy_unalign3_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unalign3_copy2bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unalign3_copy3bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0], #1
|
||||
strb r4, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.p2align 2
|
||||
// Can read 2 bytes before possibly crossing a page.
|
||||
.Lstringcopy_unalign2:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, .Lstringcopy_unalign_copy1byte
|
||||
ldrb r3, [r1, #1]
|
||||
cbz r3, .Lstringcopy_unalign_copy2bytes
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
pld [r1, #64]
|
||||
|
||||
tst r2, #0xff0000
|
||||
beq .Lstringcopy_unalign_copy3bytes
|
||||
lsrs ip, r2, #24
|
||||
beq .Lstringcopy_unalign_copy4bytes
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b .Lstringcopy_unalign2
|
||||
|
||||
.p2align 2
|
||||
// Can read 1 byte before possibly crossing a page.
|
||||
.Lstringcopy_unalign1:
|
||||
ldrb r2, [r1]
|
||||
cbz r2, .Lstringcopy_unalign_copy1byte
|
||||
|
||||
ldr r2, [r1], #4
|
||||
ldr r3, [r1], #4
|
||||
|
||||
pld [r1, #64]
|
||||
|
||||
sub ip, r2, #0x01010101
|
||||
bic ip, ip, r2
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_first_register
|
||||
|
||||
sub ip, r3, #0x01010101
|
||||
bic ip, ip, r3
|
||||
ands ip, ip, #0x80808080
|
||||
bne .Lstringcopy_zero_in_second_register
|
||||
|
||||
stmia r0!, {r2, r3}
|
||||
b .Lstringcopy_unalign1
|
||||
|
||||
.Lstringcopy_unalign_copy1byte:
|
||||
strb r2, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unalign_copy2bytes:
|
||||
strb r2, [r0], #1
|
||||
strb r3, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unalign_copy3bytes:
|
||||
strh r2, [r0], #2
|
||||
lsr r2, #16
|
||||
strb r2, [r0]
|
||||
m_ret inst=pop
|
||||
|
||||
.Lstringcopy_unalign_copy4bytes:
|
||||
stmia r0, {r2}
|
||||
#if defined(STPCPY)
|
||||
add r0, r0, #3
|
||||
#endif
|
||||
m_ret inst=pop
|
||||
#if defined(STPCPY)
|
||||
END(stpcpy)
|
||||
#else
|
||||
END(strcpy)
|
||||
#endif
|
@@ -1,11 +1,10 @@
|
||||
libc_bionic_src_files_arm += \
|
||||
arch-arm/cortex-a9/bionic/memcpy.S \
|
||||
arch-arm/cortex-a9/bionic/memset.S \
|
||||
arch-arm/cortex-a9/bionic/stpcpy.S \
|
||||
arch-arm/cortex-a9/bionic/strcat.S \
|
||||
arch-arm/cortex-a9/bionic/__strcat_chk.S \
|
||||
arch-arm/cortex-a9/bionic/strcmp.S \
|
||||
arch-arm/cortex-a9/bionic/strcpy.S \
|
||||
arch-arm/cortex-a9/bionic/__strcpy_chk.S \
|
||||
arch-arm/cortex-a9/bionic/strlen.S \
|
||||
arch-arm/cortex-a9/bionic/__strcat_chk.S \
|
||||
arch-arm/cortex-a9/bionic/__strcpy_chk.S \
|
||||
bionic/memmove.c \
|
||||
|
@@ -40,10 +40,12 @@
|
||||
ENTRY(__strcat_chk)
|
||||
pld [r0, #0]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
push {r4, r5}
|
||||
.save {r4, r5}
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
@@ -193,6 +195,9 @@ END(__strcat_chk)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
ENTRY_PRIVATE(__strcat_chk_failed)
|
||||
.save {r0, lr}
|
||||
.save {r4, r5}
|
||||
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -39,6 +39,7 @@
|
||||
ENTRY(__strcpy_chk)
|
||||
pld [r0, #0]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -160,6 +161,7 @@ END(__strcpy_chk)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
ENTRY_PRIVATE(__strcpy_chk_failed)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -72,6 +72,7 @@ END(__memcpy_chk)
|
||||
ENTRY(memcpy)
|
||||
pld [r1, #64]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -84,6 +85,7 @@ END(memcpy)
|
||||
ENTRY_PRIVATE(__memcpy_chk_fail)
|
||||
// Preserve lr for backtrace.
|
||||
push {lr}
|
||||
.save {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
|
||||
|
@@ -37,7 +37,6 @@
|
||||
* memset() returns its first argument.
|
||||
*/
|
||||
|
||||
.cpu cortex-a15
|
||||
.fpu neon
|
||||
.syntax unified
|
||||
|
||||
|
@@ -7,8 +7,7 @@ libc_bionic_src_files_arm += \
|
||||
|
||||
# Use cortex-a15 versions of strcat/strcpy/strlen.
|
||||
libc_bionic_src_files_arm += \
|
||||
arch-arm/cortex-a15/bionic/stpcpy.S \
|
||||
arch-arm/cortex-a15/bionic/strcat.S \
|
||||
arch-arm/cortex-a15/bionic/strcmp.S \
|
||||
arch-arm/cortex-a15/bionic/strcpy.S \
|
||||
arch-arm/cortex-a15/bionic/strlen.S \
|
||||
arch-arm/cortex-a15/bionic/strcmp.S \
|
||||
|
@@ -39,7 +39,7 @@
|
||||
|
||||
ENTRY(__memcpy_chk)
|
||||
cmp r2, r3
|
||||
bhi __memcpy_chk_fail
|
||||
bgt fortify_check_failed
|
||||
|
||||
// Fall through to memcpy...
|
||||
END(__memcpy_chk)
|
||||
@@ -49,14 +49,11 @@ ENTRY(memcpy)
|
||||
* ARM ABI. Since we have to save R0, we might as well save R4
|
||||
* which we can use for better pipelining of the reads below
|
||||
*/
|
||||
.save {r0, r4, lr}
|
||||
stmfd sp!, {r0, r4, lr}
|
||||
.cfi_def_cfa_offset 12
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset r4, 4
|
||||
.cfi_rel_offset lr, 8
|
||||
/* Making room for r5-r11 which will be spilled later */
|
||||
.pad #28
|
||||
sub sp, sp, #28
|
||||
.cfi_adjust_cfa_offset 28
|
||||
|
||||
// preload the destination because we'll align it to a cache line
|
||||
// with small writes. Also start the source "pump".
|
||||
@@ -66,14 +63,14 @@ ENTRY(memcpy)
|
||||
|
||||
/* it simplifies things to take care of len<4 early */
|
||||
cmp r2, #4
|
||||
blo .Lcopy_last_3_and_return
|
||||
blo copy_last_3_and_return
|
||||
|
||||
/* compute the offset to align the source
|
||||
* offset = (4-(src&3))&3 = -src & 3
|
||||
*/
|
||||
rsb r3, r1, #0
|
||||
ands r3, r3, #3
|
||||
beq .Lsrc_aligned
|
||||
beq src_aligned
|
||||
|
||||
/* align source to 32 bits. We need to insert 2 instructions between
|
||||
* a ldr[b|h] and str[b|h] because byte and half-word instructions
|
||||
@@ -88,12 +85,12 @@ ENTRY(memcpy)
|
||||
strcsb r4, [r0], #1
|
||||
strcsb r12,[r0], #1
|
||||
|
||||
.Lsrc_aligned:
|
||||
src_aligned:
|
||||
|
||||
/* see if src and dst are aligned together (congruent) */
|
||||
eor r12, r0, r1
|
||||
tst r12, #3
|
||||
bne .Lnon_congruent
|
||||
bne non_congruent
|
||||
|
||||
/* Use post-incriment mode for stm to spill r5-r11 to reserved stack
|
||||
* frame. Don't update sp.
|
||||
@@ -103,7 +100,7 @@ ENTRY(memcpy)
|
||||
/* align the destination to a cache-line */
|
||||
rsb r3, r0, #0
|
||||
ands r3, r3, #0x1C
|
||||
beq .Lcongruent_aligned32
|
||||
beq congruent_aligned32
|
||||
cmp r3, r2
|
||||
andhi r3, r2, #0x1C
|
||||
|
||||
@@ -118,14 +115,14 @@ ENTRY(memcpy)
|
||||
strne r10,[r0], #4
|
||||
sub r2, r2, r3
|
||||
|
||||
.Lcongruent_aligned32:
|
||||
congruent_aligned32:
|
||||
/*
|
||||
* here source is aligned to 32 bytes.
|
||||
*/
|
||||
|
||||
.Lcached_aligned32:
|
||||
cached_aligned32:
|
||||
subs r2, r2, #32
|
||||
blo .Lless_than_32_left
|
||||
blo less_than_32_left
|
||||
|
||||
/*
|
||||
* We preload a cache-line up to 64 bytes ahead. On the 926, this will
|
||||
@@ -163,7 +160,10 @@ ENTRY(memcpy)
|
||||
|
||||
add r2, r2, #32
|
||||
|
||||
.Lless_than_32_left:
|
||||
|
||||
|
||||
|
||||
less_than_32_left:
|
||||
/*
|
||||
* less than 32 bytes left at this point (length in r2)
|
||||
*/
|
||||
@@ -197,7 +197,7 @@ ENTRY(memcpy)
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
.Lnon_congruent:
|
||||
non_congruent:
|
||||
/*
|
||||
* here source is aligned to 4 bytes
|
||||
* but destination is not.
|
||||
@@ -207,9 +207,9 @@ ENTRY(memcpy)
|
||||
* partial words in the shift queue)
|
||||
*/
|
||||
cmp r2, #4
|
||||
blo .Lcopy_last_3_and_return
|
||||
blo copy_last_3_and_return
|
||||
|
||||
/* Use post-increment mode for stm to spill r5-r11 to reserved stack
|
||||
/* Use post-incriment mode for stm to spill r5-r11 to reserved stack
|
||||
* frame. Don't update sp.
|
||||
*/
|
||||
stmea sp, {r5-r11}
|
||||
@@ -236,7 +236,7 @@ ENTRY(memcpy)
|
||||
movcs r3, r3, lsr #8
|
||||
|
||||
cmp r2, #4
|
||||
blo .Lpartial_word_tail
|
||||
blo partial_word_tail
|
||||
|
||||
/* Align destination to 32 bytes (cache line boundary) */
|
||||
1: tst r0, #0x1c
|
||||
@@ -248,11 +248,11 @@ ENTRY(memcpy)
|
||||
str r4, [r0], #4
|
||||
cmp r2, #4
|
||||
bhs 1b
|
||||
blo .Lpartial_word_tail
|
||||
blo partial_word_tail
|
||||
|
||||
/* copy 32 bytes at a time */
|
||||
2: subs r2, r2, #32
|
||||
blo .Lless_than_thirtytwo
|
||||
blo less_than_thirtytwo
|
||||
|
||||
/* Use immediate mode for the shifts, because there is an extra cycle
|
||||
* for register shifts, which could account for up to 50% of
|
||||
@@ -260,11 +260,11 @@ ENTRY(memcpy)
|
||||
*/
|
||||
|
||||
cmp r12, #24
|
||||
beq .Lloop24
|
||||
beq loop24
|
||||
cmp r12, #8
|
||||
beq .Lloop8
|
||||
beq loop8
|
||||
|
||||
.Lloop16:
|
||||
loop16:
|
||||
ldr r12, [r1], #4
|
||||
1: mov r4, r12
|
||||
ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
||||
@@ -289,9 +289,9 @@ ENTRY(memcpy)
|
||||
stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
||||
mov r3, r11, lsr #16
|
||||
bhs 1b
|
||||
b .Lless_than_thirtytwo
|
||||
b less_than_thirtytwo
|
||||
|
||||
.Lloop8:
|
||||
loop8:
|
||||
ldr r12, [r1], #4
|
||||
1: mov r4, r12
|
||||
ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
||||
@@ -316,9 +316,9 @@ ENTRY(memcpy)
|
||||
stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
||||
mov r3, r11, lsr #8
|
||||
bhs 1b
|
||||
b .Lless_than_thirtytwo
|
||||
b less_than_thirtytwo
|
||||
|
||||
.Lloop24:
|
||||
loop24:
|
||||
ldr r12, [r1], #4
|
||||
1: mov r4, r12
|
||||
ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
||||
@@ -345,12 +345,12 @@ ENTRY(memcpy)
|
||||
bhs 1b
|
||||
|
||||
|
||||
.Lless_than_thirtytwo:
|
||||
less_than_thirtytwo:
|
||||
/* copy the last 0 to 31 bytes of the source */
|
||||
rsb r12, lr, #32 /* we corrupted r12, recompute it */
|
||||
add r2, r2, #32
|
||||
cmp r2, #4
|
||||
blo .Lpartial_word_tail
|
||||
blo partial_word_tail
|
||||
|
||||
1: ldr r5, [r1], #4
|
||||
sub r2, r2, #4
|
||||
@@ -360,7 +360,7 @@ ENTRY(memcpy)
|
||||
cmp r2, #4
|
||||
bhs 1b
|
||||
|
||||
.Lpartial_word_tail:
|
||||
partial_word_tail:
|
||||
/* we have a partial word in the input buffer */
|
||||
movs r5, lr, lsl #(31-3)
|
||||
strmib r3, [r0], #1
|
||||
@@ -372,7 +372,7 @@ ENTRY(memcpy)
|
||||
/* Refill spilled registers from the stack. Don't update sp. */
|
||||
ldmfd sp, {r5-r11}
|
||||
|
||||
.Lcopy_last_3_and_return:
|
||||
copy_last_3_and_return:
|
||||
movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
|
||||
ldrmib r2, [r1], #1
|
||||
ldrcsb r3, [r1], #1
|
||||
@@ -385,15 +385,9 @@ ENTRY(memcpy)
|
||||
add sp, sp, #28
|
||||
ldmfd sp!, {r0, r4, lr}
|
||||
bx lr
|
||||
END(memcpy)
|
||||
|
||||
// Only reached when the __memcpy_chk check fails.
|
||||
ENTRY_PRIVATE(__memcpy_chk_fail)
|
||||
// Preserve lr for backtrace.
|
||||
push {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
|
||||
fortify_check_failed:
|
||||
ldr r0, error_message
|
||||
ldr r1, error_code
|
||||
1:
|
||||
@@ -403,7 +397,7 @@ error_code:
|
||||
.word BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW
|
||||
error_message:
|
||||
.word error_string-(1b+8)
|
||||
END(__memcpy_chk_fail)
|
||||
END(memcpy)
|
||||
|
||||
.data
|
||||
error_string:
|
||||
|
@@ -7,5 +7,4 @@ libc_bionic_src_files_arm += \
|
||||
bionic/memmove.c \
|
||||
bionic/__strcat_chk.cpp \
|
||||
bionic/__strcpy_chk.cpp \
|
||||
upstream-openbsd/lib/libc/string/stpcpy.c \
|
||||
upstream-openbsd/lib/libc/string/strcat.c \
|
||||
|
@@ -38,7 +38,9 @@
|
||||
#ifndef _ARM32_ASM_H_
|
||||
#define _ARM32_ASM_H_
|
||||
|
||||
#define __bionic_asm_align 0
|
||||
#ifndef _ALIGN_TEXT
|
||||
# define _ALIGN_TEXT .align 0
|
||||
#endif
|
||||
|
||||
#undef __bionic_asm_custom_entry
|
||||
#undef __bionic_asm_custom_end
|
||||
@@ -48,4 +50,10 @@
|
||||
#undef __bionic_asm_function_type
|
||||
#define __bionic_asm_function_type #function
|
||||
|
||||
#if defined(__ELF__) && defined(PIC)
|
||||
#define PIC_SYM(x,y) x ## ( ## y ## )
|
||||
#else
|
||||
#define PIC_SYM(x,y) x
|
||||
#endif
|
||||
|
||||
#endif /* !_ARM_ASM_H_ */
|
||||
|
@@ -28,6 +28,14 @@
|
||||
#ifndef _ARM_MACHINE_CPU_FEATURES_H
|
||||
#define _ARM_MACHINE_CPU_FEATURES_H
|
||||
|
||||
/* The purpose of this file is to define several macros corresponding
|
||||
* to CPU features that may or may not be available at build time on
|
||||
* on the target CPU.
|
||||
*
|
||||
* This is done to abstract us from the various ARM Architecture
|
||||
* quirks and alphabet soup.
|
||||
*/
|
||||
|
||||
/* __ARM_ARCH__ is a number corresponding to the ARM revision
|
||||
* we're going to support. Our toolchain doesn't define __ARM_ARCH__
|
||||
* so try to guess it.
|
||||
@@ -45,4 +53,31 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* define __ARM_HAVE_HALFWORD_MULTIPLY when half-word multiply instructions
|
||||
* this means variants of: smul, smulw, smla, smlaw, smlal
|
||||
*/
|
||||
#define __ARM_HAVE_HALFWORD_MULTIPLY 1
|
||||
|
||||
/* define __ARM_HAVE_LDREXD for ARMv7 architecture
|
||||
* (also present in ARMv6K, but not implemented in ARMv7-M, neither of which
|
||||
* we care about)
|
||||
*/
|
||||
#if __ARM_ARCH__ >= 7
|
||||
# define __ARM_HAVE_LDREXD
|
||||
#endif
|
||||
|
||||
/* define _ARM_HAVE_VFP if we have VFPv3
|
||||
*/
|
||||
#if __ARM_ARCH__ >= 7 && defined __VFP_FP__
|
||||
# define __ARM_HAVE_VFP
|
||||
#endif
|
||||
|
||||
/* define _ARM_HAVE_NEON for ARMv7 architecture if we support the
|
||||
* Neon SIMD instruction set extensions. This also implies
|
||||
* that VFPv3-D32 is supported.
|
||||
*/
|
||||
#if __ARM_ARCH__ >= 7 && defined __ARM_NEON__
|
||||
# define __ARM_HAVE_NEON
|
||||
#endif
|
||||
|
||||
#endif /* _ARM_MACHINE_CPU_FEATURES_H */
|
||||
|
79
libc/arch-arm/include/machine/endian.h
Normal file
79
libc/arch-arm/include/machine/endian.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* $OpenBSD: endian.h,v 1.3 2005/12/13 00:35:23 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 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.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_ENDIAN_H_
|
||||
#define _ARM_ENDIAN_H_
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
/* According to RealView Assembler User's Guide, REV and REV16 are available
|
||||
* in Thumb code and 16-bit instructions when used in Thumb-2 code.
|
||||
*
|
||||
* REV Rd, Rm
|
||||
* Rd and Rm must both be Lo registers.
|
||||
*
|
||||
* REV16 Rd, Rm
|
||||
* Rd and Rm must both be Lo registers.
|
||||
*
|
||||
* The +l constraint takes care of this without constraining us in ARM mode.
|
||||
*/
|
||||
#define __swap16md(x) ({ \
|
||||
register u_int16_t _x = (x); \
|
||||
__asm__ __volatile__("rev16 %0, %0" : "+l" (_x)); \
|
||||
_x; \
|
||||
})
|
||||
|
||||
#define __swap32md(x) ({ \
|
||||
register u_int32_t _x = (x); \
|
||||
__asm__ __volatile__("rev %0, %0" : "+l" (_x)); \
|
||||
_x; \
|
||||
})
|
||||
|
||||
#define __swap64md(x) ({ \
|
||||
u_int64_t _swap64md_x = (x); \
|
||||
(u_int64_t) __swap32md(_swap64md_x >> 32) | \
|
||||
(u_int64_t) __swap32md(_swap64md_x & 0xffffffff) << 32; \
|
||||
})
|
||||
|
||||
/* Tell sys/endian.h we have MD variants of the swap macros. */
|
||||
#define MD_SWAP
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined(__ARMEB__)
|
||||
#define _BYTE_ORDER _BIG_ENDIAN
|
||||
#else
|
||||
#define _BYTE_ORDER _LITTLE_ENDIAN
|
||||
#endif
|
||||
#define __STRICT_ALIGNMENT
|
||||
#include <sys/types.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
#endif /* !_ARM_ENDIAN_H_ */
|
50
libc/arch-arm/include/machine/exec.h
Normal file
50
libc/arch-arm/include/machine/exec.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* $OpenBSD: exec.h,v 1.9 2003/04/17 03:42:14 drahn Exp $ */
|
||||
/* $NetBSD: exec.h,v 1.6 1994/10/27 04:16:05 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993 Christopher G. Demetriou
|
||||
* 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_EXEC_H_
|
||||
#define _ARM_EXEC_H_
|
||||
|
||||
#define __LDPGSZ 4096
|
||||
|
||||
#define NATIVE_EXEC_ELF
|
||||
|
||||
#define ARCH_ELFSIZE 32
|
||||
|
||||
#define ELF_TARG_CLASS ELFCLASS32
|
||||
#define ELF_TARG_DATA ELFDATA2LSB
|
||||
#define ELF_TARG_MACH EM_ARM
|
||||
|
||||
#define _NLIST_DO_AOUT
|
||||
#define _NLIST_DO_ELF
|
||||
|
||||
#define _KERN_DO_AOUT
|
||||
#define _KERN_DO_ELF
|
||||
|
||||
#endif /* _ARM_EXEC_H_ */
|
@@ -26,6 +26,10 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* machine/setjmp.h: machine dependent setjmp-related information.
|
||||
*/
|
||||
|
||||
/* _JBLEN is the size of a jmp_buf in longs.
|
||||
* Do not modify this value or you will break the ABI !
|
||||
*
|
||||
@@ -33,3 +37,46 @@
|
||||
* that was replaced by this one.
|
||||
*/
|
||||
#define _JBLEN 64
|
||||
|
||||
/* According to the ARM AAPCS document, we only need to save
|
||||
* the following registers:
|
||||
*
|
||||
* Core r4-r14
|
||||
*
|
||||
* VFP d8-d15 (see section 5.1.2.1)
|
||||
*
|
||||
* Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
|
||||
* calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
|
||||
* (and can be used for passing arguments or returning results in standard
|
||||
* procedure-call variants). Registers d16-d31 (q8-q15), if present, do
|
||||
* not need to be preserved.
|
||||
*
|
||||
* FPSCR saved because GLibc does saves it too.
|
||||
*
|
||||
*/
|
||||
|
||||
/* The internal structure of a jmp_buf is totally private.
|
||||
* Current layout (may change in the future):
|
||||
*
|
||||
* word name description
|
||||
* 0 magic magic number
|
||||
* 1 sigmask signal mask (not used with _setjmp / _longjmp)
|
||||
* 2 float_base base of float registers (d8 to d15)
|
||||
* 18 float_state floating-point status and control register
|
||||
* 19 core_base base of core registers (r4 to r14)
|
||||
* 30 reserved reserved entries (room to grow)
|
||||
* 64
|
||||
*
|
||||
* NOTE: float_base must be at an even word index, since the
|
||||
* FP registers will be loaded/stored with instructions
|
||||
* that expect 8-byte alignment.
|
||||
*/
|
||||
|
||||
#define _JB_MAGIC 0
|
||||
#define _JB_SIGMASK (_JB_MAGIC+1)
|
||||
#define _JB_FLOAT_BASE (_JB_SIGMASK+1)
|
||||
#define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
|
||||
#define _JB_CORE_BASE (_JB_FLOAT_STATE+1)
|
||||
|
||||
#define _JB_MAGIC__SETJMP 0x4278f500
|
||||
#define _JB_MAGIC_SETJMP 0x4278f501
|
||||
|
@@ -40,10 +40,12 @@
|
||||
ENTRY(__strcat_chk)
|
||||
pld [r0, #0]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
push {r4, r5}
|
||||
.save {r4, r5}
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
@@ -192,6 +194,8 @@ END(__strcat_chk)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
ENTRY_PRIVATE(__strcat_chk_failed)
|
||||
.save {r0, lr}
|
||||
.save {r4, r5}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -39,6 +39,7 @@
|
||||
ENTRY(__strcpy_chk)
|
||||
pld [r0, #0]
|
||||
push {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -160,6 +161,7 @@ END(__strcpy_chk)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
ENTRY_PRIVATE(__strcpy_chk_failed)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -53,6 +53,7 @@ END(__memcpy_chk)
|
||||
ENTRY(memcpy)
|
||||
pld [r1, #64]
|
||||
stmfd sp!, {r0, lr}
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
@@ -65,6 +66,7 @@ END(memcpy)
|
||||
ENTRY_PRIVATE(__memcpy_chk_fail)
|
||||
// Preserve lr for backtrace.
|
||||
push {lr}
|
||||
.save {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
|
||||
|
@@ -36,6 +36,7 @@
|
||||
// Assumes neon instructions and a cache line size of 32 bytes.
|
||||
|
||||
ENTRY_PRIVATE(MEMCPY_BASE)
|
||||
.save {r0, lr}
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_rel_offset r0, 0
|
||||
.cfi_rel_offset lr, 4
|
||||
|
@@ -43,6 +43,7 @@ ENTRY(__memset_chk)
|
||||
bls .L_done
|
||||
|
||||
// Preserve lr for backtrace.
|
||||
.save {lr}
|
||||
push {lr}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset lr, 0
|
||||
@@ -68,6 +69,7 @@ END(bzero)
|
||||
|
||||
/* memset() returns its first argument. */
|
||||
ENTRY(memset)
|
||||
.save {r0}
|
||||
stmfd sp!, {r0}
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_rel_offset r0, 0
|
||||
|
@@ -168,6 +168,7 @@ ENTRY(strcmp)
|
||||
bne .L_do_align
|
||||
|
||||
/* Fast path. */
|
||||
.save {r4-r7}
|
||||
init
|
||||
|
||||
.L_doubleword_aligned:
|
||||
|
@@ -7,7 +7,6 @@ libc_bionic_src_files_arm += \
|
||||
|
||||
# Use cortex-a15 versions of strcat/strcpy/strlen and standard memmove
|
||||
libc_bionic_src_files_arm += \
|
||||
arch-arm/cortex-a15/bionic/stpcpy.S \
|
||||
arch-arm/cortex-a15/bionic/strcat.S \
|
||||
arch-arm/cortex-a15/bionic/strcpy.S \
|
||||
arch-arm/cortex-a15/bionic/strlen.S \
|
||||
|
@@ -1,14 +0,0 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(__rt_sigqueueinfo)
|
||||
mov ip, r7
|
||||
ldr r7, =__NR_rt_sigqueueinfo
|
||||
swi #0
|
||||
mov r7, ip
|
||||
cmn r0, #(MAX_ERRNO + 1)
|
||||
bxls lr
|
||||
neg r0, r0
|
||||
b __set_errno_internal
|
||||
END(__rt_sigqueueinfo)
|
@@ -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,4 +11,4 @@ ENTRY(__clock_nanosleep)
|
||||
bxls lr
|
||||
neg r0, r0
|
||||
b __set_errno_internal
|
||||
END(__clock_nanosleep)
|
||||
END(clock_nanosleep)
|
@@ -1,14 +0,0 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(sethostname)
|
||||
mov ip, r7
|
||||
ldr r7, =__NR_sethostname
|
||||
swi #0
|
||||
mov r7, ip
|
||||
cmn r0, #(MAX_ERRNO + 1)
|
||||
bxls lr
|
||||
neg r0, r0
|
||||
b __set_errno_internal
|
||||
END(sethostname)
|
@@ -1,17 +1,8 @@
|
||||
# 64-bit arm.
|
||||
# arm64 specific configs
|
||||
|
||||
#
|
||||
# Default implementations of functions that are commonly optimized.
|
||||
#
|
||||
|
||||
libc_bionic_src_files_arm64 += \
|
||||
bionic/__memset_chk.cpp \
|
||||
bionic/__strcpy_chk.cpp \
|
||||
bionic/__strcat_chk.cpp \
|
||||
libc_common_src_files_arm64 := \
|
||||
bionic/memrchr.c \
|
||||
bionic/strrchr.cpp \
|
||||
|
||||
libc_freebsd_src_files_arm64 += \
|
||||
upstream-freebsd/lib/libc/string/wcscat.c \
|
||||
upstream-freebsd/lib/libc/string/wcschr.c \
|
||||
upstream-freebsd/lib/libc/string/wcscmp.c \
|
||||
@@ -19,8 +10,6 @@ libc_freebsd_src_files_arm64 += \
|
||||
upstream-freebsd/lib/libc/string/wcslen.c \
|
||||
upstream-freebsd/lib/libc/string/wcsrchr.c \
|
||||
upstream-freebsd/lib/libc/string/wmemcmp.c \
|
||||
|
||||
libc_openbsd_src_files_arm64 += \
|
||||
upstream-openbsd/lib/libc/string/stpncpy.c \
|
||||
upstream-openbsd/lib/libc/string/strcat.c \
|
||||
upstream-openbsd/lib/libc/string/strlcat.c \
|
||||
@@ -28,15 +17,23 @@ libc_openbsd_src_files_arm64 += \
|
||||
upstream-openbsd/lib/libc/string/strncat.c \
|
||||
upstream-openbsd/lib/libc/string/strncpy.c \
|
||||
|
||||
#
|
||||
# Inherently architecture-specific code.
|
||||
#
|
||||
# Fortify implementations of libc functions.
|
||||
libc_common_src_files_arm64 += \
|
||||
bionic/__memcpy_chk.cpp \
|
||||
bionic/__memset_chk.cpp \
|
||||
bionic/__strcpy_chk.cpp \
|
||||
bionic/__strcat_chk.cpp \
|
||||
|
||||
libc_bionic_src_files_arm64 += \
|
||||
##########################################
|
||||
### CPU specific source files
|
||||
libc_bionic_src_files_arm64 := \
|
||||
arch-arm64/bionic/__bionic_clone.S \
|
||||
arch-arm64/bionic/_exit_with_stack_teardown.S \
|
||||
arch-arm64/bionic/__rt_sigreturn.S \
|
||||
arch-arm64/bionic/_setjmp.S \
|
||||
arch-arm64/bionic/setjmp.S \
|
||||
arch-arm64/bionic/__set_tls.c \
|
||||
arch-arm64/bionic/sigsetjmp.S \
|
||||
arch-arm64/bionic/syscall.S \
|
||||
arch-arm64/bionic/vfork.S \
|
||||
|
||||
@@ -56,7 +53,7 @@ ifeq ($(strip $(TARGET_CPU_VARIANT)),)
|
||||
endif
|
||||
cpu_variant_mk := $(LOCAL_PATH)/arch-arm64/$(TARGET_CPU_VARIANT)/$(TARGET_CPU_VARIANT).mk
|
||||
ifeq ($(wildcard $(cpu_variant_mk)),)
|
||||
$(error "TARGET_CPU_VARIANT not set or set to an unknown value. Possible values are generic, denver64. Use generic for devices that do not have a CPU similar to any of the supported cpu variants.")
|
||||
$(error "TARGET_CPU_VARIANT not set or set to an unknown value. Possible values are generic, generic-neon, denver64. Use generic for devices that do not have a CPU similar to any of the supported cpu variants.")
|
||||
endif
|
||||
include $(cpu_variant_mk)
|
||||
libc_common_additional_dependencies += $(cpu_variank_mk)
|
||||
|
@@ -31,8 +31,8 @@
|
||||
// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
|
||||
|
||||
ENTRY(__bionic_clone)
|
||||
# Push 'fn' and 'arg' onto the child stack.
|
||||
stp x5, x6, [x1, #-16]!
|
||||
# Copy 'fn' and 'arg' onto the child stack.
|
||||
stp x5, x6, [x1, #-16]
|
||||
|
||||
# Make the system call.
|
||||
mov x8, __NR_clone
|
||||
@@ -49,12 +49,12 @@ ENTRY(__bionic_clone)
|
||||
ret
|
||||
|
||||
.L_bc_child:
|
||||
# We're in the child now. Set the end of the frame record chain.
|
||||
mov x29, #0
|
||||
# Setting x30 to 0 will make the unwinder stop at __start_thread.
|
||||
mov x30, #0
|
||||
# Call __start_thread with the 'fn' and 'arg' we stored on the child stack.
|
||||
ldp x0, x1, [sp], #16
|
||||
# We're in the child now. Set the end of the frame record chain...
|
||||
mov x29, xzr
|
||||
# Setting x30 to 0 will make the unwinder stop at __start_thread
|
||||
mov x30, xzr
|
||||
# ...and call __start_thread with the 'fn' and 'arg' we stored on the child stack.
|
||||
ldp x0, x1, [sp, #-16]
|
||||
b __start_thread
|
||||
END(__bionic_clone)
|
||||
.hidden __bionic_clone
|
||||
|
34
libc/arch-arm64/bionic/__rt_sigreturn.S
Normal file
34
libc/arch-arm64/bionic/__rt_sigreturn.S
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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 <private/bionic_asm.h>
|
||||
|
||||
ENTRY_PRIVATE(__rt_sigreturn)
|
||||
mov x8, __NR_rt_sigreturn
|
||||
svc #0
|
||||
END(__rt_sigreturn)
|
111
libc/arch-arm64/bionic/_setjmp.S
Normal file
111
libc/arch-arm64/bionic/_setjmp.S
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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 <private/bionic_asm.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
/*
|
||||
* C library - _setjmp, _longjmp
|
||||
*
|
||||
* _longjmp(jmp_buf state, int value)
|
||||
* will generate a "return(v)" from the last call to _setjmp(state) by restoring
|
||||
* registers from the stack. The previous signal state is NOT restored.
|
||||
*
|
||||
* NOTE: x0 return value
|
||||
* x9-x15 temporary registers
|
||||
*/
|
||||
|
||||
ENTRY(_setjmp)
|
||||
/* store magic number */
|
||||
ldr w9, .L_setjmp_magic
|
||||
str w9, [x0, #(_JB_MAGIC * 4)]
|
||||
|
||||
/* store core registers */
|
||||
mov x10, sp
|
||||
stp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
|
||||
stp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
|
||||
stp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)]
|
||||
stp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)]
|
||||
stp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)]
|
||||
stp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
|
||||
str x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
|
||||
|
||||
/* store floating point registers */
|
||||
stp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
|
||||
stp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
|
||||
stp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
|
||||
stp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
|
||||
|
||||
mov w0, wzr
|
||||
ret
|
||||
END(_setjmp)
|
||||
|
||||
.L_setjmp_magic:
|
||||
.word _JB_MAGIC__SETJMP
|
||||
|
||||
ENTRY(_longjmp)
|
||||
/* check magic */
|
||||
ldr w9, .L_setjmp_magic
|
||||
ldr w10, [x0, #(_JB_MAGIC * 4)]
|
||||
cmp w9, w10
|
||||
b.ne .L_fail
|
||||
|
||||
/* restore core registers */
|
||||
ldp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
|
||||
mov sp, x10
|
||||
ldp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
|
||||
ldp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)]
|
||||
ldp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)]
|
||||
ldp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)]
|
||||
ldp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
|
||||
ldr x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
|
||||
|
||||
/* restore floating point registers */
|
||||
ldp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
|
||||
ldp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
|
||||
ldp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
|
||||
ldp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
|
||||
|
||||
/* validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0) */
|
||||
tst x30, #3
|
||||
b.ne .L_fail
|
||||
mov x10, sp
|
||||
tst x10, #15
|
||||
b.ne .L_fail
|
||||
|
||||
/* set return value */
|
||||
cmp w1, wzr
|
||||
csinc w0, w1, wzr, ne
|
||||
ret
|
||||
|
||||
/* validation failed, die die die */
|
||||
.L_fail:
|
||||
bl PIC_SYM(longjmperror, PLT)
|
||||
bl PIC_SYM(abort, PLT)
|
||||
b . - 8 /* Cannot get here */
|
||||
END(_longjmp)
|
@@ -27,126 +27,97 @@
|
||||
*/
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
// According to AARCH64 PCS document we need to save the following
|
||||
// registers:
|
||||
//
|
||||
// Core x19 - x30, sp (see section 5.1.1)
|
||||
// VFP d8 - d15 (see section 5.1.2)
|
||||
//
|
||||
// NOTE: All the registers saved here will have 64 bit vales.
|
||||
// AAPCS mandates that the higher part of q registers do not need to
|
||||
// be saved by the callee.
|
||||
|
||||
#define _JB_SIGFLAG 0
|
||||
#define _JB_SIGMASK (_JB_SIGFLAG + 1)
|
||||
#define _JB_X30_SP (_JB_SIGMASK + 1)
|
||||
#define _JB_X28_X29 (_JB_X30_SP + 2)
|
||||
#define _JB_X26_X27 (_JB_X28_X29 + 2)
|
||||
#define _JB_X24_X25 (_JB_X26_X27 + 2)
|
||||
#define _JB_X22_X23 (_JB_X24_X25 + 2)
|
||||
#define _JB_X20_X21 (_JB_X22_X23 + 2)
|
||||
#define _JB_X19 (_JB_X20_X21 + 2)
|
||||
#define _JB_D14_D15 (_JB_X19 + 1)
|
||||
#define _JB_D12_D13 (_JB_D14_D15 + 2)
|
||||
#define _JB_D10_D11 (_JB_D12_D13 + 1)
|
||||
#define _JB_D8_D9 (_JB_D10_D11 + 1)
|
||||
/*
|
||||
* C library - _setjmp, _longjmp
|
||||
*
|
||||
* _longjmp(jmp_buf state, int value)
|
||||
* will generate a "return(v)" from the last call to _setjmp(state) by restoring
|
||||
* registers from the stack. The previous signal state is NOT restored.
|
||||
*
|
||||
* NOTE: x0 return value
|
||||
* x9-x15 temporary registers
|
||||
*/
|
||||
|
||||
ENTRY(setjmp)
|
||||
mov w1, #1
|
||||
b sigsetjmp
|
||||
/* block all signals an retrieve signal mask */
|
||||
stp x0, x30, [sp, #-16]!
|
||||
|
||||
mov x0, xzr
|
||||
bl PIC_SYM(sigblock, PLT)
|
||||
mov w1, w0
|
||||
|
||||
ldp x0, x30, [sp], #16
|
||||
|
||||
/* store signal mask */
|
||||
str w1, [x0, #(_JB_SIGMASK *4)]
|
||||
|
||||
/* store magic number */
|
||||
ldr w9, .L_setjmp_magic
|
||||
str w9, [x0, #(_JB_MAGIC * 4)]
|
||||
|
||||
/* store core registers */
|
||||
mov x10, sp
|
||||
stp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
|
||||
stp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
|
||||
stp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)]
|
||||
stp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)]
|
||||
stp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)]
|
||||
stp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
|
||||
str x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
|
||||
|
||||
/* store floating point registers */
|
||||
stp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
|
||||
stp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
|
||||
stp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
|
||||
stp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
|
||||
|
||||
mov w0, wzr
|
||||
ret
|
||||
END(setjmp)
|
||||
|
||||
ENTRY(_setjmp)
|
||||
mov w1, #0
|
||||
b sigsetjmp
|
||||
END(_setjmp)
|
||||
.L_setjmp_magic:
|
||||
.word _JB_MAGIC__SETJMP
|
||||
|
||||
// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
|
||||
ENTRY(sigsetjmp)
|
||||
// Record whether or not we're saving the signal mask.
|
||||
str w1, [x0, #(_JB_SIGFLAG * 8)]
|
||||
ENTRY(longjmp)
|
||||
/* check magic */
|
||||
ldr w9, .L_setjmp_magic
|
||||
ldr w10, [x0, #(_JB_MAGIC * 4)]
|
||||
cmp w9, w10
|
||||
b.ne .L_fail
|
||||
|
||||
// Do we need to save the signal mask?
|
||||
cbz w1, 1f
|
||||
/* restore core registers */
|
||||
ldp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
|
||||
mov sp, x10
|
||||
ldp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
|
||||
ldp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)]
|
||||
ldp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)]
|
||||
ldp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)]
|
||||
ldp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
|
||||
ldr x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
|
||||
|
||||
// Save current signal mask.
|
||||
stp x0, x30, [sp, #-16]!
|
||||
// The 'how' argument is ignored if new_mask is NULL.
|
||||
mov x1, #0 // NULL.
|
||||
add x2, x0, #(_JB_SIGMASK * 8) // old_mask.
|
||||
bl sigprocmask
|
||||
ldp x0, x30, [sp], #16
|
||||
/* restore floating point registers */
|
||||
ldp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
|
||||
ldp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
|
||||
ldp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
|
||||
ldp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
|
||||
|
||||
1:
|
||||
// Save core registers.
|
||||
mov x10, sp
|
||||
stp x30, x10, [x0, #(_JB_X30_SP * 8)]
|
||||
stp x28, x29, [x0, #(_JB_X28_X29 * 8)]
|
||||
stp x26, x27, [x0, #(_JB_X26_X27 * 8)]
|
||||
stp x24, x25, [x0, #(_JB_X24_X25 * 8)]
|
||||
stp x22, x23, [x0, #(_JB_X22_X23 * 8)]
|
||||
stp x20, x21, [x0, #(_JB_X20_X21 * 8)]
|
||||
str x19, [x0, #(_JB_X19 * 8)]
|
||||
/* validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0) */
|
||||
tst x30, #3
|
||||
b.ne .L_fail
|
||||
mov x10, sp
|
||||
tst x10, #15
|
||||
b.ne .L_fail
|
||||
|
||||
// Save floating point registers.
|
||||
stp d14, d15, [x0, #(_JB_D14_D15 * 8)]
|
||||
stp d12, d13, [x0, #(_JB_D12_D13 * 8)]
|
||||
stp d10, d11, [x0, #(_JB_D10_D11 * 8)]
|
||||
stp d8, d9, [x0, #(_JB_D8_D9 * 8)]
|
||||
/* set return value */
|
||||
cmp w1, wzr
|
||||
csinc w0, w1, wzr, ne
|
||||
ret
|
||||
|
||||
mov w0, #0
|
||||
ret
|
||||
END(sigsetjmp)
|
||||
|
||||
// void siglongjmp(sigjmp_buf env, int value);
|
||||
ENTRY(siglongjmp)
|
||||
// Do we need to restore the signal mask?
|
||||
ldr w9, [x0, #(_JB_SIGFLAG * 8)]
|
||||
cbz w9, 1f
|
||||
|
||||
// Restore signal mask.
|
||||
stp x0, x30, [sp, #-16]!
|
||||
mov x19, x1 // Save 'value'.
|
||||
mov x2, x0
|
||||
mov x0, #2 // SIG_SETMASK
|
||||
add x1, x2, #(_JB_SIGMASK * 8) // new_mask.
|
||||
mov x2, #0 // NULL.
|
||||
bl sigprocmask
|
||||
mov x1, x19 // Restore 'value'.
|
||||
ldp x0, x30, [sp], #16
|
||||
|
||||
1:
|
||||
// Restore core registers.
|
||||
ldp x30, x10, [x0, #(_JB_X30_SP * 8)]
|
||||
mov sp, x10
|
||||
ldp x28, x29, [x0, #(_JB_X28_X29 * 8)]
|
||||
ldp x26, x27, [x0, #(_JB_X26_X27 * 8)]
|
||||
ldp x24, x25, [x0, #(_JB_X24_X25 * 8)]
|
||||
ldp x22, x23, [x0, #(_JB_X22_X23 * 8)]
|
||||
ldp x20, x21, [x0, #(_JB_X20_X21 * 8)]
|
||||
ldr x19, [x0, #(_JB_X19 * 8)]
|
||||
|
||||
// Restore floating point registers.
|
||||
ldp d14, d15, [x0, #(_JB_D14_D15 * 8)]
|
||||
ldp d12, d13, [x0, #(_JB_D12_D13 * 8)]
|
||||
ldp d10, d11, [x0, #(_JB_D10_D11 * 8)]
|
||||
ldp d8, d9, [x0, #(_JB_D8_D9 * 8)]
|
||||
|
||||
// Validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0).
|
||||
tst x30, #3
|
||||
b.ne longjmperror
|
||||
mov x10, sp
|
||||
tst x10, #15
|
||||
b.ne longjmperror
|
||||
|
||||
// Set return value.
|
||||
cmp w1, wzr
|
||||
csinc w0, w1, wzr, ne
|
||||
ret
|
||||
END(siglongjmp)
|
||||
|
||||
.globl longjmp
|
||||
.equ longjmp, siglongjmp
|
||||
.globl _longjmp
|
||||
.equ _longjmp, siglongjmp
|
||||
/* validation failed, die die die */
|
||||
.L_fail:
|
||||
bl PIC_SYM(longjmperror, PLT)
|
||||
bl PIC_SYM(abort, PLT)
|
||||
b . - 8 /* Cannot get here */
|
||||
END(longjmp)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -26,21 +26,26 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_TIMESPEC_H_
|
||||
#define _MACHINE_TIMESPEC_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
/*
|
||||
* This file is used to include timespec definition without introducing the whole
|
||||
* <linux/time.h>, <sys/time.h> or <time.h>.
|
||||
* int sigsetjmp(sigjmp_buf env, int savesigs);
|
||||
* void siglongjmp(sigjmp_buf env, int val);
|
||||
*/
|
||||
#ifndef _STRUCT_TIMESPEC
|
||||
#define _STRUCT_TIMESPEC
|
||||
struct timespec {
|
||||
time_t tv_sec;
|
||||
long tv_nsec;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* _MACHINE_TIMESPEC_H_ */
|
||||
ENTRY(sigsetjmp)
|
||||
cbz w1, PIC_SYM(_setjmp, PLT)
|
||||
b PIC_SYM(setjmp, PLT)
|
||||
END(sigsetjmp)
|
||||
|
||||
.L_setjmp_magic:
|
||||
.word _JB_MAGIC__SETJMP
|
||||
|
||||
ENTRY(siglongjmp)
|
||||
ldr w2, .L_setjmp_magic
|
||||
ldr w3, [x0]
|
||||
cmp w2, w3
|
||||
b.eq PIC_SYM(_longjmp, PLT)
|
||||
b PIC_SYM(longjmp, PLT)
|
||||
END(siglongjmp)
|
@@ -1,63 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
/* Copyright (c) 2012, Linaro Limited
|
||||
All rights reserved.
|
||||
Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Linaro 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
|
||||
HOLDER 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.
|
||||
*/
|
||||
|
||||
/* Assumptions:
|
||||
*
|
||||
* 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.
|
||||
* denver, ARMv8-a, AArch64
|
||||
* Unaligned accesses
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Prototype: void *memcpy (void *dst, const void *src, size_t count).
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <private/libc_events.h>
|
||||
|
||||
ENTRY(__memcpy_chk)
|
||||
cmp x2, x3
|
||||
b.hi __memcpy_chk_fail
|
||||
#define dstin x0
|
||||
#define src x1
|
||||
#define count x2
|
||||
#define tmp1 x3
|
||||
#define tmp1w w3
|
||||
#define tmp2 x4
|
||||
#define tmp2w w4
|
||||
#define tmp3 x5
|
||||
#define tmp3w w5
|
||||
#define dst x6
|
||||
|
||||
// Fall through to memcpy...
|
||||
END(__memcpy_chk)
|
||||
#define A_l x7
|
||||
#define A_h x8
|
||||
#define B_l x9
|
||||
#define B_h x10
|
||||
#define C_l x11
|
||||
#define C_h x12
|
||||
#define D_l x13
|
||||
#define D_h x14
|
||||
|
||||
#define QA_l q0
|
||||
#define QA_h q1
|
||||
#define QB_l q2
|
||||
#define QB_h q3
|
||||
|
||||
ENTRY(memcpy)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
mov dst, dstin
|
||||
cmp count, #64
|
||||
b.ge .Lcpy_not_short
|
||||
cmp count, #15
|
||||
b.le .Ltail15tiny
|
||||
|
||||
/* Deal with small copies quickly by dropping straight into the
|
||||
* exit block. */
|
||||
.Ltail63:
|
||||
/* Copy up to 48 bytes of data. At this point we only need the
|
||||
* bottom 6 bits of count to be accurate. */
|
||||
ands tmp1, count, #0x30
|
||||
b.eq .Ltail15
|
||||
add dst, dst, tmp1
|
||||
add src, src, tmp1
|
||||
cmp tmp1w, #0x20
|
||||
b.eq 1f
|
||||
b.lt 2f
|
||||
ldp A_l, A_h, [src, #-48]
|
||||
stp A_l, A_h, [dst, #-48]
|
||||
1:
|
||||
ldp A_l, A_h, [src, #-32]
|
||||
stp A_l, A_h, [dst, #-32]
|
||||
2:
|
||||
ldp A_l, A_h, [src, #-16]
|
||||
stp A_l, A_h, [dst, #-16]
|
||||
|
||||
.Ltail15:
|
||||
ands count, count, #15
|
||||
beq 1f
|
||||
add src, src, count
|
||||
ldp A_l, A_h, [src, #-16]
|
||||
add dst, dst, count
|
||||
stp A_l, A_h, [dst, #-16]
|
||||
1:
|
||||
ret
|
||||
|
||||
.Ltail15tiny:
|
||||
/* Copy up to 15 bytes of data. Does not assume additional data
|
||||
being copied. */
|
||||
tbz count, #3, 1f
|
||||
ldr tmp1, [src], #8
|
||||
str tmp1, [dst], #8
|
||||
1:
|
||||
tbz count, #2, 1f
|
||||
ldr tmp1w, [src], #4
|
||||
str tmp1w, [dst], #4
|
||||
1:
|
||||
tbz count, #1, 1f
|
||||
ldrh tmp1w, [src], #2
|
||||
strh tmp1w, [dst], #2
|
||||
1:
|
||||
tbz count, #0, 1f
|
||||
ldrb tmp1w, [src]
|
||||
strb tmp1w, [dst]
|
||||
1:
|
||||
ret
|
||||
|
||||
.Lcpy_not_short:
|
||||
/* We don't much care about the alignment of DST, but we want SRC
|
||||
* to be 128-bit (16 byte) aligned so that we don't cross cache line
|
||||
* boundaries on both loads and stores. */
|
||||
neg tmp2, src
|
||||
ands tmp2, tmp2, #15 /* Bytes to reach alignment. */
|
||||
b.eq 2f
|
||||
sub count, count, tmp2
|
||||
/* Copy more data than needed; it's faster than jumping
|
||||
* around copying sub-Quadword quantities. We know that
|
||||
* it can't overrun. */
|
||||
ldp A_l, A_h, [src]
|
||||
add src, src, tmp2
|
||||
stp A_l, A_h, [dst]
|
||||
add dst, dst, tmp2
|
||||
/* There may be less than 63 bytes to go now. */
|
||||
cmp count, #63
|
||||
b.le .Ltail63
|
||||
2:
|
||||
subs count, count, #128
|
||||
b.ge .Lcpy_body_large
|
||||
/* Less than 128 bytes to copy, so handle 64 here and then jump
|
||||
* to the tail. */
|
||||
ldp QA_l, QA_h, [src]
|
||||
ldp QB_l, QB_h, [src, #32]
|
||||
stp QA_l, QA_h, [dst]
|
||||
stp QB_l, QB_h, [dst, #32]
|
||||
tst count, #0x3f
|
||||
add src, src, #64
|
||||
add dst, dst, #64
|
||||
b.ne .Ltail63
|
||||
ret
|
||||
|
||||
/* Critical loop. Start at a new cache line boundary. Assuming
|
||||
* 64 bytes per line this ensures the entire loop is in one line. */
|
||||
.p2align 6
|
||||
.Lcpy_body_large:
|
||||
cmp count, 65536
|
||||
bhi .Lcpy_body_huge
|
||||
/* There are at least 128 bytes to copy. */
|
||||
ldp QA_l, QA_h, [src, #0]
|
||||
sub dst, dst, #32 /* Pre-bias. */
|
||||
ldp QB_l, QB_h, [src, #32]! /* src += 64 - Pre-bias. */
|
||||
1:
|
||||
stp QA_l, QA_h, [dst, #32]
|
||||
ldp QA_l, QA_h, [src, #32]
|
||||
stp QB_l, QB_h, [dst, #64]!
|
||||
ldp QB_l, QB_h, [src, #64]!
|
||||
|
||||
subs count, count, #64
|
||||
b.ge 1b
|
||||
|
||||
stp QA_l, QA_h, [dst, #32]
|
||||
stp QB_l, QB_h, [dst, #64]
|
||||
add src, src, #32
|
||||
add dst, dst, #64 + 32
|
||||
tst count, #0x3f
|
||||
b.ne .Ltail63
|
||||
ret
|
||||
.Lcpy_body_huge:
|
||||
/* There are at least 128 bytes to copy. */
|
||||
ldp QA_l, QA_h, [src, #0]
|
||||
sub dst, dst, #32 /* Pre-bias. */
|
||||
ldp QB_l, QB_h, [src, #32]!
|
||||
1:
|
||||
stnp QA_l, QA_h, [dst, #32]
|
||||
stnp QB_l, QB_h, [dst, #64]
|
||||
ldp QA_l, QA_h, [src, #32]
|
||||
ldp QB_l, QB_h, [src, #64]!
|
||||
add dst, dst, #64
|
||||
|
||||
subs count, count, #64
|
||||
b.ge 1b
|
||||
|
||||
stnp QA_l, QA_h, [dst, #32]
|
||||
stnp QB_l, QB_h, [dst, #64]
|
||||
add src, src, #32
|
||||
add dst, dst, #64 + 32
|
||||
tst count, #0x3f
|
||||
b.ne .Ltail63
|
||||
ret
|
||||
|
||||
END(memcpy)
|
||||
|
||||
ENTRY_PRIVATE(__memcpy_chk_fail)
|
||||
// Preserve for accurate backtrace.
|
||||
stp x29, x30, [sp, -16]!
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_rel_offset x29, 0
|
||||
.cfi_rel_offset x30, 8
|
||||
|
||||
adrp x0, error_string
|
||||
add x0, x0, :lo12:error_string
|
||||
ldr x1, error_code
|
||||
bl __fortify_chk_fail
|
||||
error_code:
|
||||
.word BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW
|
||||
END(__memcpy_chk_fail)
|
||||
|
||||
.data
|
||||
.align 2
|
||||
error_string:
|
||||
.string "memcpy: prevented write past end of buffer"
|
||||
|
@@ -1,199 +0,0 @@
|
||||
/* Copyright (c) 2012, Linaro Limited
|
||||
All rights reserved.
|
||||
Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Linaro 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
|
||||
HOLDER 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.
|
||||
*/
|
||||
|
||||
/* Assumptions:
|
||||
*
|
||||
* denver, ARMv8-a, AArch64
|
||||
* Unaligned accesses
|
||||
*
|
||||
*/
|
||||
|
||||
#define dstin x0
|
||||
#define src x1
|
||||
#define count x2
|
||||
#define tmp1 x3
|
||||
#define tmp1w w3
|
||||
#define tmp2 x4
|
||||
#define tmp2w w4
|
||||
#define tmp3 x5
|
||||
#define tmp3w w5
|
||||
#define dst x6
|
||||
|
||||
#define A_l x7
|
||||
#define A_h x8
|
||||
#define B_l x9
|
||||
#define B_h x10
|
||||
#define C_l x11
|
||||
#define C_h x12
|
||||
#define D_l x13
|
||||
#define D_h x14
|
||||
|
||||
#define QA_l q0
|
||||
#define QA_h q1
|
||||
#define QB_l q2
|
||||
#define QB_h q3
|
||||
|
||||
mov dst, dstin
|
||||
cmp count, #64
|
||||
b.ge .Lcpy_not_short
|
||||
cmp count, #15
|
||||
b.le .Ltail15tiny
|
||||
|
||||
/* Deal with small copies quickly by dropping straight into the
|
||||
* exit block. */
|
||||
.Ltail63:
|
||||
/* Copy up to 48 bytes of data. At this point we only need the
|
||||
* bottom 6 bits of count to be accurate. */
|
||||
ands tmp1, count, #0x30
|
||||
b.eq .Ltail15
|
||||
add dst, dst, tmp1
|
||||
add src, src, tmp1
|
||||
cmp tmp1w, #0x20
|
||||
b.eq 1f
|
||||
b.lt 2f
|
||||
ldp A_l, A_h, [src, #-48]
|
||||
stp A_l, A_h, [dst, #-48]
|
||||
1:
|
||||
ldp A_l, A_h, [src, #-32]
|
||||
stp A_l, A_h, [dst, #-32]
|
||||
2:
|
||||
ldp A_l, A_h, [src, #-16]
|
||||
stp A_l, A_h, [dst, #-16]
|
||||
|
||||
.Ltail15:
|
||||
ands count, count, #15
|
||||
beq 1f
|
||||
add src, src, count
|
||||
ldp A_l, A_h, [src, #-16]
|
||||
add dst, dst, count
|
||||
stp A_l, A_h, [dst, #-16]
|
||||
1:
|
||||
ret
|
||||
|
||||
.Ltail15tiny:
|
||||
/* Copy up to 15 bytes of data. Does not assume additional data
|
||||
being copied. */
|
||||
tbz count, #3, 1f
|
||||
ldr tmp1, [src], #8
|
||||
str tmp1, [dst], #8
|
||||
1:
|
||||
tbz count, #2, 1f
|
||||
ldr tmp1w, [src], #4
|
||||
str tmp1w, [dst], #4
|
||||
1:
|
||||
tbz count, #1, 1f
|
||||
ldrh tmp1w, [src], #2
|
||||
strh tmp1w, [dst], #2
|
||||
1:
|
||||
tbz count, #0, 1f
|
||||
ldrb tmp1w, [src]
|
||||
strb tmp1w, [dst]
|
||||
1:
|
||||
ret
|
||||
|
||||
.Lcpy_not_short:
|
||||
/* We don't much care about the alignment of DST, but we want SRC
|
||||
* to be 128-bit (16 byte) aligned so that we don't cross cache line
|
||||
* boundaries on both loads and stores. */
|
||||
neg tmp2, src
|
||||
ands tmp2, tmp2, #15 /* Bytes to reach alignment. */
|
||||
b.eq 2f
|
||||
sub count, count, tmp2
|
||||
/* Copy more data than needed; it's faster than jumping
|
||||
* around copying sub-Quadword quantities. We know that
|
||||
* it can't overrun. */
|
||||
ldp A_l, A_h, [src]
|
||||
add src, src, tmp2
|
||||
stp A_l, A_h, [dst]
|
||||
add dst, dst, tmp2
|
||||
/* There may be less than 63 bytes to go now. */
|
||||
cmp count, #63
|
||||
b.le .Ltail63
|
||||
2:
|
||||
subs count, count, #128
|
||||
b.ge .Lcpy_body_large
|
||||
/* Less than 128 bytes to copy, so handle 64 here and then jump
|
||||
* to the tail. */
|
||||
ldp QA_l, QA_h, [src]
|
||||
ldp QB_l, QB_h, [src, #32]
|
||||
stp QA_l, QA_h, [dst]
|
||||
stp QB_l, QB_h, [dst, #32]
|
||||
tst count, #0x3f
|
||||
add src, src, #64
|
||||
add dst, dst, #64
|
||||
b.ne .Ltail63
|
||||
ret
|
||||
|
||||
/* Critical loop. Start at a new cache line boundary. Assuming
|
||||
* 64 bytes per line this ensures the entire loop is in one line. */
|
||||
.p2align 6
|
||||
.Lcpy_body_large:
|
||||
cmp count, 65536
|
||||
bhi .Lcpy_body_huge
|
||||
/* There are at least 128 bytes to copy. */
|
||||
ldp QA_l, QA_h, [src, #0]
|
||||
sub dst, dst, #32 /* Pre-bias. */
|
||||
ldp QB_l, QB_h, [src, #32]! /* src += 64 - Pre-bias. */
|
||||
1:
|
||||
stp QA_l, QA_h, [dst, #32]
|
||||
ldp QA_l, QA_h, [src, #32]
|
||||
stp QB_l, QB_h, [dst, #64]!
|
||||
ldp QB_l, QB_h, [src, #64]!
|
||||
|
||||
subs count, count, #64
|
||||
b.ge 1b
|
||||
|
||||
stp QA_l, QA_h, [dst, #32]
|
||||
stp QB_l, QB_h, [dst, #64]
|
||||
add src, src, #32
|
||||
add dst, dst, #64 + 32
|
||||
tst count, #0x3f
|
||||
b.ne .Ltail63
|
||||
ret
|
||||
.Lcpy_body_huge:
|
||||
/* There are at least 128 bytes to copy. */
|
||||
ldp QA_l, QA_h, [src, #0]
|
||||
sub dst, dst, #32 /* Pre-bias. */
|
||||
ldp QB_l, QB_h, [src, #32]!
|
||||
1:
|
||||
stnp QA_l, QA_h, [dst, #32]
|
||||
stnp QB_l, QB_h, [dst, #64]
|
||||
ldp QA_l, QA_h, [src, #32]
|
||||
ldp QB_l, QB_h, [src, #64]!
|
||||
add dst, dst, #64
|
||||
|
||||
subs count, count, #64
|
||||
b.ge 1b
|
||||
|
||||
stnp QA_l, QA_h, [dst, #32]
|
||||
stnp QB_l, QB_h, [dst, #64]
|
||||
add src, src, #32
|
||||
add dst, dst, #64 + 32
|
||||
tst count, #0x3f
|
||||
b.ne .Ltail63
|
||||
ret
|
@@ -32,6 +32,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
#define dstin x0
|
||||
#define src x1
|
||||
#define count x2
|
||||
@@ -52,6 +54,13 @@
|
||||
#define D_l x13
|
||||
#define D_h x14
|
||||
|
||||
#define QA_l q0
|
||||
#define QA_h q1
|
||||
#define QB_l q2
|
||||
#define QB_h q3
|
||||
|
||||
ENTRY(memcpy)
|
||||
|
||||
mov dst, dstin
|
||||
cmp count, #64
|
||||
b.ge .Lcpy_not_short
|
||||
@@ -133,14 +142,10 @@
|
||||
b.ge .Lcpy_body_large
|
||||
/* Less than 128 bytes to copy, so handle 64 here and then jump
|
||||
* to the tail. */
|
||||
ldp A_l, A_h, [src]
|
||||
ldp B_l, B_h, [src, #16]
|
||||
ldp C_l, C_h, [src, #32]
|
||||
ldp D_l, D_h, [src, #48]
|
||||
stp A_l, A_h, [dst]
|
||||
stp B_l, B_h, [dst, #16]
|
||||
stp C_l, C_h, [dst, #32]
|
||||
stp D_l, D_h, [dst, #48]
|
||||
ldp QA_l, QA_h, [src]
|
||||
ldp QB_l, QB_h, [src, #32]
|
||||
stp QA_l, QA_h, [dst]
|
||||
stp QB_l, QB_h, [dst, #32]
|
||||
tst count, #0x3f
|
||||
add src, src, #64
|
||||
add dst, dst, #64
|
||||
@@ -152,28 +157,23 @@
|
||||
.p2align 6
|
||||
.Lcpy_body_large:
|
||||
/* There are at least 128 bytes to copy. */
|
||||
ldp A_l, A_h, [src, #0]
|
||||
sub dst, dst, #16 /* Pre-bias. */
|
||||
ldp B_l, B_h, [src, #16]
|
||||
ldp C_l, C_h, [src, #32]
|
||||
ldp D_l, D_h, [src, #48]! /* src += 64 - Pre-bias. */
|
||||
ldp QA_l, QA_h, [src, #0]
|
||||
sub dst, dst, #32 /* Pre-bias. */
|
||||
ldp QB_l, QB_h, [src, #32]! /* src += 64 - Pre-bias. */
|
||||
1:
|
||||
stp A_l, A_h, [dst, #16]
|
||||
ldp A_l, A_h, [src, #16]
|
||||
stp B_l, B_h, [dst, #32]
|
||||
ldp B_l, B_h, [src, #32]
|
||||
stp C_l, C_h, [dst, #48]
|
||||
ldp C_l, C_h, [src, #48]
|
||||
stp D_l, D_h, [dst, #64]!
|
||||
ldp D_l, D_h, [src, #64]!
|
||||
stp QA_l, QA_h, [dst, #32]
|
||||
ldp QA_l, QA_h, [src, #32]
|
||||
stp QB_l, QB_h, [dst, #64]!
|
||||
ldp QB_l, QB_h, [src, #64]!
|
||||
|
||||
subs count, count, #64
|
||||
b.ge 1b
|
||||
stp A_l, A_h, [dst, #16]
|
||||
stp B_l, B_h, [dst, #32]
|
||||
stp C_l, C_h, [dst, #48]
|
||||
stp D_l, D_h, [dst, #64]
|
||||
add src, src, #16
|
||||
add dst, dst, #64 + 16
|
||||
|
||||
stp QA_l, QA_h, [dst, #32]
|
||||
stp QB_l, QB_h, [dst, #64]
|
||||
add src, src, #32
|
||||
add dst, dst, #64 + 32
|
||||
tst count, #0x3f
|
||||
b.ne .Ltail63
|
||||
ret
|
||||
END(memcpy)
|
13
libc/arch-arm64/generic-neon/generic-neon.mk
Normal file
13
libc/arch-arm64/generic-neon/generic-neon.mk
Normal file
@@ -0,0 +1,13 @@
|
||||
libc_bionic_src_files_arm64 += \
|
||||
arch-arm64/generic/bionic/memchr.S \
|
||||
arch-arm64/generic/bionic/memcmp.S \
|
||||
arch-arm64/generic/bionic/memmove.S \
|
||||
arch-arm64/generic/bionic/memset.S \
|
||||
arch-arm64/generic/bionic/stpcpy.S \
|
||||
arch-arm64/generic/bionic/strchr.S \
|
||||
arch-arm64/generic/bionic/strcmp.S \
|
||||
arch-arm64/generic/bionic/strcpy.S \
|
||||
arch-arm64/generic/bionic/strlen.S \
|
||||
arch-arm64/generic/bionic/strncmp.S \
|
||||
arch-arm64/generic/bionic/strnlen.S \
|
||||
arch-arm64/generic-neon/bionic/memcpy.S \
|
@@ -1,63 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
/* Copyright (c) 2012, Linaro Limited
|
||||
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 the Linaro 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
|
||||
HOLDER 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.
|
||||
*/
|
||||
|
||||
/* Assumptions:
|
||||
*
|
||||
* 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.
|
||||
* ARMv8-a, AArch64
|
||||
* Unaligned accesses
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Prototype: void *memcpy (void *dst, const void *src, size_t count).
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <private/libc_events.h>
|
||||
|
||||
ENTRY(__memcpy_chk)
|
||||
cmp x2, x3
|
||||
b.hi __memcpy_chk_fail
|
||||
#define dstin x0
|
||||
#define src x1
|
||||
#define count x2
|
||||
#define tmp1 x3
|
||||
#define tmp1w w3
|
||||
#define tmp2 x4
|
||||
#define tmp2w w4
|
||||
#define tmp3 x5
|
||||
#define tmp3w w5
|
||||
#define dst x6
|
||||
|
||||
// Fall through to memcpy...
|
||||
END(__memcpy_chk)
|
||||
#define A_l x7
|
||||
#define A_h x8
|
||||
#define B_l x9
|
||||
#define B_h x10
|
||||
#define C_l x11
|
||||
#define C_h x12
|
||||
#define D_l x13
|
||||
#define D_h x14
|
||||
|
||||
ENTRY(memcpy)
|
||||
#include "memcpy_base.S"
|
||||
|
||||
mov dst, dstin
|
||||
cmp count, #64
|
||||
b.ge .Lcpy_not_short
|
||||
cmp count, #15
|
||||
b.le .Ltail15tiny
|
||||
|
||||
/* Deal with small copies quickly by dropping straight into the
|
||||
* exit block. */
|
||||
.Ltail63:
|
||||
/* Copy up to 48 bytes of data. At this point we only need the
|
||||
* bottom 6 bits of count to be accurate. */
|
||||
ands tmp1, count, #0x30
|
||||
b.eq .Ltail15
|
||||
add dst, dst, tmp1
|
||||
add src, src, tmp1
|
||||
cmp tmp1w, #0x20
|
||||
b.eq 1f
|
||||
b.lt 2f
|
||||
ldp A_l, A_h, [src, #-48]
|
||||
stp A_l, A_h, [dst, #-48]
|
||||
1:
|
||||
ldp A_l, A_h, [src, #-32]
|
||||
stp A_l, A_h, [dst, #-32]
|
||||
2:
|
||||
ldp A_l, A_h, [src, #-16]
|
||||
stp A_l, A_h, [dst, #-16]
|
||||
|
||||
.Ltail15:
|
||||
ands count, count, #15
|
||||
beq 1f
|
||||
add src, src, count
|
||||
ldp A_l, A_h, [src, #-16]
|
||||
add dst, dst, count
|
||||
stp A_l, A_h, [dst, #-16]
|
||||
1:
|
||||
ret
|
||||
|
||||
.Ltail15tiny:
|
||||
/* Copy up to 15 bytes of data. Does not assume additional data
|
||||
being copied. */
|
||||
tbz count, #3, 1f
|
||||
ldr tmp1, [src], #8
|
||||
str tmp1, [dst], #8
|
||||
1:
|
||||
tbz count, #2, 1f
|
||||
ldr tmp1w, [src], #4
|
||||
str tmp1w, [dst], #4
|
||||
1:
|
||||
tbz count, #1, 1f
|
||||
ldrh tmp1w, [src], #2
|
||||
strh tmp1w, [dst], #2
|
||||
1:
|
||||
tbz count, #0, 1f
|
||||
ldrb tmp1w, [src]
|
||||
strb tmp1w, [dst]
|
||||
1:
|
||||
ret
|
||||
|
||||
.Lcpy_not_short:
|
||||
/* We don't much care about the alignment of DST, but we want SRC
|
||||
* to be 128-bit (16 byte) aligned so that we don't cross cache line
|
||||
* boundaries on both loads and stores. */
|
||||
neg tmp2, src
|
||||
ands tmp2, tmp2, #15 /* Bytes to reach alignment. */
|
||||
b.eq 2f
|
||||
sub count, count, tmp2
|
||||
/* Copy more data than needed; it's faster than jumping
|
||||
* around copying sub-Quadword quantities. We know that
|
||||
* it can't overrun. */
|
||||
ldp A_l, A_h, [src]
|
||||
add src, src, tmp2
|
||||
stp A_l, A_h, [dst]
|
||||
add dst, dst, tmp2
|
||||
/* There may be less than 63 bytes to go now. */
|
||||
cmp count, #63
|
||||
b.le .Ltail63
|
||||
2:
|
||||
subs count, count, #128
|
||||
b.ge .Lcpy_body_large
|
||||
/* Less than 128 bytes to copy, so handle 64 here and then jump
|
||||
* to the tail. */
|
||||
ldp A_l, A_h, [src]
|
||||
ldp B_l, B_h, [src, #16]
|
||||
ldp C_l, C_h, [src, #32]
|
||||
ldp D_l, D_h, [src, #48]
|
||||
stp A_l, A_h, [dst]
|
||||
stp B_l, B_h, [dst, #16]
|
||||
stp C_l, C_h, [dst, #32]
|
||||
stp D_l, D_h, [dst, #48]
|
||||
tst count, #0x3f
|
||||
add src, src, #64
|
||||
add dst, dst, #64
|
||||
b.ne .Ltail63
|
||||
ret
|
||||
|
||||
/* Critical loop. Start at a new cache line boundary. Assuming
|
||||
* 64 bytes per line this ensures the entire loop is in one line. */
|
||||
.p2align 6
|
||||
.Lcpy_body_large:
|
||||
/* There are at least 128 bytes to copy. */
|
||||
ldp A_l, A_h, [src, #0]
|
||||
sub dst, dst, #16 /* Pre-bias. */
|
||||
ldp B_l, B_h, [src, #16]
|
||||
ldp C_l, C_h, [src, #32]
|
||||
ldp D_l, D_h, [src, #48]! /* src += 64 - Pre-bias. */
|
||||
1:
|
||||
stp A_l, A_h, [dst, #16]
|
||||
ldp A_l, A_h, [src, #16]
|
||||
stp B_l, B_h, [dst, #32]
|
||||
ldp B_l, B_h, [src, #32]
|
||||
stp C_l, C_h, [dst, #48]
|
||||
ldp C_l, C_h, [src, #48]
|
||||
stp D_l, D_h, [dst, #64]!
|
||||
ldp D_l, D_h, [src, #64]!
|
||||
subs count, count, #64
|
||||
b.ge 1b
|
||||
stp A_l, A_h, [dst, #16]
|
||||
stp B_l, B_h, [dst, #32]
|
||||
stp C_l, C_h, [dst, #48]
|
||||
stp D_l, D_h, [dst, #64]
|
||||
add src, src, #16
|
||||
add dst, dst, #64 + 16
|
||||
tst count, #0x3f
|
||||
b.ne .Ltail63
|
||||
ret
|
||||
END(memcpy)
|
||||
|
||||
ENTRY_PRIVATE(__memcpy_chk_fail)
|
||||
// Preserve for accurate backtrace.
|
||||
stp x29, x30, [sp, -16]!
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_rel_offset x29, 0
|
||||
.cfi_rel_offset x30, 8
|
||||
|
||||
adrp x0, error_string
|
||||
add x0, x0, :lo12:error_string
|
||||
ldr x1, error_code
|
||||
bl __fortify_chk_fail
|
||||
error_code:
|
||||
.word BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW
|
||||
END(__memcpy_chk_fail)
|
||||
|
||||
.data
|
||||
.align 2
|
||||
error_string:
|
||||
.string "memcpy: prevented write past end of buffer"
|
||||
|
@@ -38,9 +38,17 @@
|
||||
#ifndef _AARCH64_ASM_H_
|
||||
#define _AARCH64_ASM_H_
|
||||
|
||||
#define __bionic_asm_align 0
|
||||
#ifndef _ALIGN_TEXT
|
||||
# define _ALIGN_TEXT .align 0
|
||||
#endif
|
||||
|
||||
#undef __bionic_asm_function_type
|
||||
#define __bionic_asm_function_type %function
|
||||
|
||||
#if defined(__ELF__) && defined(PIC)
|
||||
#define PIC_SYM(x,y) x ## ( ## y ## )
|
||||
#else
|
||||
#define PIC_SYM(x,y) x
|
||||
#endif
|
||||
|
||||
#endif /* _AARCH64_ASM_H_ */
|
||||
|
@@ -99,7 +99,6 @@
|
||||
#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
|
||||
#define R_AARCH64_TLS_TPREL64 1030
|
||||
#define R_AARCH64_TLS_DTPREL32 1031
|
||||
#define R_AARCH64_IRELATIVE 1032
|
||||
|
||||
#define R_TYPE(name) __CONCAT(R_AARCH64_,name)
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -26,21 +26,33 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#ifndef _AARCH64_ENDIAN_H_
|
||||
#define _AARCH64_ENDIAN_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
extern "C" int __rt_sigqueueinfo(pid_t, int, siginfo_t*);
|
||||
#ifdef __GNUC__
|
||||
|
||||
int sigqueue(pid_t pid, int signo, const sigval value) {
|
||||
siginfo_t info;
|
||||
memset(&info, 0, sizeof(siginfo_t));
|
||||
info.si_signo = signo;
|
||||
info.si_code = SI_QUEUE;
|
||||
info.si_pid = getpid();
|
||||
info.si_uid = getuid();
|
||||
info.si_value = value;
|
||||
#define __swap16md(x) ({ \
|
||||
register u_int16_t _x = (x); \
|
||||
__asm volatile ("rev16 %0, %0" : "+r" (_x)); \
|
||||
_x; \
|
||||
})
|
||||
|
||||
return __rt_sigqueueinfo(pid, signo, &info);
|
||||
}
|
||||
/* Use GCC builtins */
|
||||
#define __swap32md(x) __builtin_bswap32(x)
|
||||
#define __swap64md(x) __builtin_bswap64(x)
|
||||
|
||||
/* Tell sys/endian.h we have MD variants of the swap macros. */
|
||||
#define MD_SWAP
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined(__AARCH64EB__)
|
||||
#define _BYTE_ORDER _BIG_ENDIAN
|
||||
#else
|
||||
#define _BYTE_ORDER _LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#endif /* _AARCH64_ENDIAN_H_ */
|
50
libc/arch-arm64/include/machine/exec.h
Normal file
50
libc/arch-arm64/include/machine/exec.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* $OpenBSD: exec.h,v 1.9 2003/04/17 03:42:14 drahn Exp $ */
|
||||
/* $NetBSD: exec.h,v 1.6 1994/10/27 04:16:05 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993 Christopher G. Demetriou
|
||||
* 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _AARCH64_EXEC_H_
|
||||
#define _AARCH64_EXEC_H_
|
||||
|
||||
#define __LDPGSZ 4096
|
||||
|
||||
#define NATIVE_EXEC_ELF
|
||||
|
||||
#define ARCH_ELFSIZE 64
|
||||
|
||||
#define ELF_TARG_CLASS ELFCLASS64 /* 64-bit objects */
|
||||
#define ELF_TARG_DATA ELFDATA2LSB
|
||||
#define ELF_TARG_MACH EM_AARCH64
|
||||
|
||||
#define _NLIST_DO_AOUT
|
||||
#define _NLIST_DO_ELF
|
||||
|
||||
#define _KERN_DO_AOUT
|
||||
#define _KERN_DO_ELF64
|
||||
|
||||
#endif /* _AARCH64_EXEC_H_ */
|
@@ -26,5 +26,48 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* _JBLEN is the size of a jmp_buf in longs (64bit on AArch64) */
|
||||
/*
|
||||
* machine/setjmp.h: machine dependent setjmp-related information.
|
||||
*/
|
||||
|
||||
/* _JBLEN is the size of a jmp_buf in longs(64bit on AArch64) */
|
||||
#define _JBLEN 32
|
||||
|
||||
/* According to AARCH64 PCS document we need to save the following
|
||||
* registers:
|
||||
*
|
||||
* Core x19 - x30, sp (see section 5.1.1)
|
||||
* VFP d8 - d15 (see section 5.1.2)
|
||||
*
|
||||
* NOTE: All the registers saved here will have 64bit vales (except FPSR).
|
||||
* AAPCS mandates that the higher part of q registers does not need to
|
||||
* be saveved by the callee.
|
||||
*/
|
||||
|
||||
/* The structure of jmp_buf for AArch64:
|
||||
*
|
||||
* NOTE: _JBLEN is the size of jmp_buf in longs(64bit on AArch64)! The table
|
||||
* below computes the offsets in words(32bit).
|
||||
*
|
||||
* word name description
|
||||
* 0 magic magic number
|
||||
* 1 sigmask signal mask (not used with _setjmp / _longjmp)
|
||||
* 2 core_base base of core registers (x19-x30, sp)
|
||||
* 28 float_base base of float registers (d8-d15)
|
||||
* 44 reserved reserved entries (room to grow)
|
||||
* 64
|
||||
*
|
||||
*
|
||||
* NOTE: The instructions that load/store core/vfp registers expect 8-byte
|
||||
* alignment. Contrary to the previous setjmp header for ARM we do not
|
||||
* need to save status/control registers for VFP (it is not a
|
||||
* requirement for setjmp).
|
||||
*/
|
||||
|
||||
#define _JB_MAGIC 0
|
||||
#define _JB_SIGMASK (_JB_MAGIC+1)
|
||||
#define _JB_CORE_BASE (_JB_SIGMASK+1)
|
||||
#define _JB_FLOAT_BASE (_JB_CORE_BASE + (31-19+1)*2)
|
||||
|
||||
#define _JB_MAGIC__SETJMP 0x53657200
|
||||
#define _JB_MAGIC_SETJMP 0x53657201
|
||||
|
@@ -1,15 +0,0 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(__rt_sigqueueinfo)
|
||||
mov x8, __NR_rt_sigqueueinfo
|
||||
svc #0
|
||||
|
||||
cmn x0, #(MAX_ERRNO + 1)
|
||||
cneg x0, x0, hi
|
||||
b.hi __set_errno_internal
|
||||
|
||||
ret
|
||||
END(__rt_sigqueueinfo)
|
||||
.hidden __rt_sigqueueinfo
|
@@ -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,4 @@ ENTRY(__clock_nanosleep)
|
||||
b.hi __set_errno_internal
|
||||
|
||||
ret
|
||||
END(__clock_nanosleep)
|
||||
.hidden __clock_nanosleep
|
||||
END(clock_nanosleep)
|
@@ -1,14 +0,0 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(sethostname)
|
||||
mov x8, __NR_sethostname
|
||||
svc #0
|
||||
|
||||
cmn x0, #(MAX_ERRNO + 1)
|
||||
cneg x0, x0, hi
|
||||
b.hi __set_errno_internal
|
||||
|
||||
ret
|
||||
END(sethostname)
|
150
libc/arch-mips/bionic/_setjmp.S
Normal file
150
libc/arch-mips/bionic/_setjmp.S
Normal file
@@ -0,0 +1,150 @@
|
||||
/* $OpenBSD: _setjmp.S,v 1.4 2005/08/07 16:40:15 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
|
||||
*
|
||||
* 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 Opsycon AB 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 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/regnum.h>
|
||||
#include <machine/signal.h>
|
||||
|
||||
/*
|
||||
* _setjmp, _longjmp (not restoring signal state)
|
||||
*
|
||||
* XXX FPSET should probably be taken from SR setting. hmmm...
|
||||
* GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
|
||||
*
|
||||
*/
|
||||
|
||||
FRAMESZ= MKFSIZ(0,4)
|
||||
GPOFF= FRAMESZ-2*REGSZ
|
||||
|
||||
LEAF(_setjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, _setjmp)
|
||||
SAVE_GP(GPOFF)
|
||||
.set noreorder
|
||||
#if defined(__mips64)
|
||||
dli v0, 0xACEDBADE # sigcontext magic number
|
||||
#else
|
||||
li v0, 0xACEDBADE # sigcontext magic number
|
||||
#endif
|
||||
REG_S v0, SC_REGS+ZERO*REGSZ(a0)
|
||||
REG_S s0, SC_REGS+S0*REGSZ(a0)
|
||||
REG_S s1, SC_REGS+S1*REGSZ(a0)
|
||||
REG_S s2, SC_REGS+S2*REGSZ(a0)
|
||||
REG_S s3, SC_REGS+S3*REGSZ(a0)
|
||||
REG_S s4, SC_REGS+S4*REGSZ(a0)
|
||||
REG_S s5, SC_REGS+S5*REGSZ(a0)
|
||||
REG_S s6, SC_REGS+S6*REGSZ(a0)
|
||||
REG_S s7, SC_REGS+S7*REGSZ(a0)
|
||||
REG_S s8, SC_REGS+S8*REGSZ(a0)
|
||||
REG_L v0, GPOFF(sp)
|
||||
REG_S v0, SC_REGS+GP*REGSZ(a0)
|
||||
PTR_ADDU v0, sp, FRAMESZ
|
||||
REG_S v0, SC_REGS+SP*REGSZ(a0)
|
||||
REG_S ra, SC_PC(a0)
|
||||
|
||||
#if !defined(SOFTFLOAT)
|
||||
li v0, 1 # be nice if we could tell
|
||||
REG_S v0, SC_FPUSED(a0) # sc_fpused = 1
|
||||
cfc1 v0, $31
|
||||
s.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
|
||||
s.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
|
||||
s.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
|
||||
s.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
|
||||
s.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
|
||||
s.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
|
||||
#if _MIPS_FPSET == 32
|
||||
s.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
|
||||
s.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
|
||||
s.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
|
||||
s.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
|
||||
s.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
|
||||
s.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
|
||||
#endif
|
||||
REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
|
||||
#endif /* !SOFTFLOAT */
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
j ra
|
||||
move v0, zero
|
||||
END(_setjmp)
|
||||
|
||||
LEAF(_longjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, _longjmp)
|
||||
SAVE_GP(GPOFF)
|
||||
.set noreorder
|
||||
REG_L v0, SC_REGS+ZERO*REGSZ(a0)
|
||||
bne v0, 0xACEDBADE, botch # jump if error
|
||||
REG_L ra, SC_PC(a0)
|
||||
REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
|
||||
REG_L s0, SC_REGS+S0*REGSZ(a0)
|
||||
REG_L s1, SC_REGS+S1*REGSZ(a0)
|
||||
REG_L s2, SC_REGS+S2*REGSZ(a0)
|
||||
REG_L s3, SC_REGS+S3*REGSZ(a0)
|
||||
REG_L s4, SC_REGS+S4*REGSZ(a0)
|
||||
REG_L s5, SC_REGS+S5*REGSZ(a0)
|
||||
REG_L s6, SC_REGS+S6*REGSZ(a0)
|
||||
REG_L s7, SC_REGS+S7*REGSZ(a0)
|
||||
REG_L s8, SC_REGS+S8*REGSZ(a0)
|
||||
REG_L gp, SC_REGS+GP*REGSZ(a0)
|
||||
REG_L sp, SC_REGS+SP*REGSZ(a0)
|
||||
#if !defined(SOFTFLOAT)
|
||||
ctc1 v0, $31
|
||||
l.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
|
||||
l.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
|
||||
l.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
|
||||
l.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
|
||||
l.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
|
||||
l.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
|
||||
#if _MIPS_FPSET == 32
|
||||
l.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
|
||||
l.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
|
||||
l.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
|
||||
l.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
|
||||
l.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
|
||||
l.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
|
||||
#endif
|
||||
#endif /* !SOFTFLOAT */
|
||||
bne a1, zero, 1f
|
||||
nop
|
||||
li a1, 1 # never return 0!
|
||||
1:
|
||||
j ra
|
||||
move v0, a1
|
||||
|
||||
botch:
|
||||
jal longjmperror
|
||||
nop
|
||||
jal abort
|
||||
nop
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
END(_longjmp)
|
36
libc/arch-mips/bionic/atexit.h
Normal file
36
libc/arch-mips/bionic/atexit.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
extern void *__dso_handle;
|
||||
extern int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
|
||||
|
||||
__attribute__ ((visibility ("hidden")))
|
||||
int atexit(void (*func)(void))
|
||||
{
|
||||
return (__cxa_atexit((void (*)(void *))func, (void *)0, &__dso_handle));
|
||||
}
|
@@ -91,4 +91,4 @@ __asm__ (
|
||||
);
|
||||
|
||||
#include "../../arch-common/bionic/__dso_handle.h"
|
||||
#include "../../arch-common/bionic/atexit.h"
|
||||
#include "atexit.h"
|
||||
|
38
libc/arch-mips/bionic/crtbegin_so.c
Normal file
38
libc/arch-mips/bionic/crtbegin_so.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
extern void __cxa_finalize(void *);
|
||||
extern void *__dso_handle;
|
||||
|
||||
__attribute__((visibility("hidden"),destructor))
|
||||
void __on_dlclose() {
|
||||
__cxa_finalize(&__dso_handle);
|
||||
}
|
||||
|
||||
#include "../../arch-common/bionic/__dso_handle_so.h"
|
||||
#include "atexit.h"
|
@@ -1,3 +1,5 @@
|
||||
/* $OpenBSD: setjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
|
||||
*
|
||||
@@ -26,116 +28,14 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1995,
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Havard Eidnes.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @(#)signal.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
/* On Mips32, jmpbuf begins with optional 4-byte filler so that
|
||||
* all saved FP regs are aligned on 8-byte boundary, despite this whole
|
||||
* struct being mis-declared to users as an array of (4-byte) longs.
|
||||
* All the following offsets are then from the rounded-up base addr
|
||||
*/
|
||||
|
||||
/* Fields of same size on all MIPS abis: */
|
||||
#define SC_MAGIC (0*4) /* 4 bytes, identify jmpbuf */
|
||||
#define SC_MASK (1*4) /* 4 bytes, saved signal mask */
|
||||
#define SC_FPSR (2*4) /* 4 bytes, floating point control/status reg */
|
||||
/* filler2 (3*4) 4 bytes, pad to 8-byte boundary */
|
||||
|
||||
/* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */
|
||||
#define SC_REGS_SAVED 12 /* ra,gp,sp,s0-s8 */
|
||||
#define SC_REGS (4*4) /* SC_REGS_SAVED*REGSZ bytes */
|
||||
|
||||
/* Floating pt registers are 8-bytes on all abis,
|
||||
* but the number of saved fp regs varies for o32/n32 versus n64 abis:
|
||||
*/
|
||||
|
||||
#ifdef __LP64__
|
||||
#define SC_FPREGS_SAVED 8 /* all fp regs f24,f25,f26,f27,f28,f29,f30,f31 */
|
||||
#else
|
||||
#define SC_FPREGS_SAVED 6 /* even fp regs f20,f22,f24,f26,f28,f30 */
|
||||
#endif
|
||||
|
||||
#define SC_FPREGS (SC_REGS + SC_REGS_SAVED*REGSZ) /* SC_FPREGS_SAVED*REGSZ_FP bytes */
|
||||
|
||||
#define SC_BYTES (SC_FPREGS + SC_FPREGS_SAVED*REGSZ_FP)
|
||||
#define SC_LONGS (SC_BYTES/REGSZ)
|
||||
|
||||
#ifdef __LP64__
|
||||
/* SC_LONGS is 22, so _JBLEN should be 22 or larger */
|
||||
#else
|
||||
/* SC_LONGS is 28, but must also allocate dynamic-roundup filler.
|
||||
so _JBLEN should be 29 or larger */
|
||||
#endif
|
||||
#include <machine/regnum.h>
|
||||
#include <machine/signal.h>
|
||||
|
||||
/*
|
||||
* _setjmp, _longjmp (restoring signal state)
|
||||
*
|
||||
* GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
|
||||
* setjmp, longjmp implementation for libc. this code depends
|
||||
* on the layout of the struct sigcontext in machine/signal.h.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -151,319 +51,124 @@ NON_LEAF(setjmp, FRAMESZ, ra)
|
||||
SETUP_GP64(GPOFF, setjmp)
|
||||
SAVE_GP(GPOFF)
|
||||
.set reorder
|
||||
|
||||
#ifndef __LP64__
|
||||
addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary
|
||||
li t0, ~7
|
||||
and a0, t0
|
||||
#endif
|
||||
|
||||
REG_S ra, RAOFF(sp) # save state
|
||||
REG_S a0, A0OFF(sp)
|
||||
|
||||
move a0, zero # get current signal mask
|
||||
jal sigblock
|
||||
REG_L a0, A0OFF(sp)
|
||||
|
||||
REG_L v1, A0OFF(sp) # v1 = jmpbuf
|
||||
REG_S v0, SC_MASK(v1) # save sc_mask = sigblock(0)
|
||||
|
||||
REG_L a0, A0OFF(sp) # restore jmpbuf
|
||||
REG_L ra, RAOFF(sp)
|
||||
|
||||
REG_S v0, SC_MASK(a0) # save sc_mask = sigblock(0)
|
||||
|
||||
li v0, 0xACEDBADE # sigcontext magic number
|
||||
sw v0, SC_MAGIC(a0)
|
||||
# callee-saved long-sized regs:
|
||||
REG_S ra, SC_REGS+0*REGSZ(a0)
|
||||
REG_S s0, SC_REGS+1*REGSZ(a0)
|
||||
REG_S s1, SC_REGS+2*REGSZ(a0)
|
||||
REG_S s2, SC_REGS+3*REGSZ(a0)
|
||||
REG_S s3, SC_REGS+4*REGSZ(a0)
|
||||
REG_S s4, SC_REGS+5*REGSZ(a0)
|
||||
REG_S s5, SC_REGS+6*REGSZ(a0)
|
||||
REG_S s6, SC_REGS+7*REGSZ(a0)
|
||||
REG_S s7, SC_REGS+8*REGSZ(a0)
|
||||
REG_S s8, SC_REGS+9*REGSZ(a0)
|
||||
REG_L v0, GPOFF(sp)
|
||||
REG_S v0, SC_REGS+10*REGSZ(a0)
|
||||
PTR_ADDU v0, sp, FRAMESZ
|
||||
REG_S v0, SC_REGS+11*REGSZ(a0)
|
||||
|
||||
cfc1 v0, $31
|
||||
|
||||
#ifdef __LP64__
|
||||
# callee-saved fp regs on mips n64 ABI are $f24..$f31
|
||||
s.d $f24, SC_FPREGS+0*REGSZ_FP(a0)
|
||||
s.d $f25, SC_FPREGS+1*REGSZ_FP(a0)
|
||||
s.d $f26, SC_FPREGS+2*REGSZ_FP(a0)
|
||||
s.d $f27, SC_FPREGS+3*REGSZ_FP(a0)
|
||||
s.d $f28, SC_FPREGS+4*REGSZ_FP(a0)
|
||||
s.d $f29, SC_FPREGS+5*REGSZ_FP(a0)
|
||||
s.d $f30, SC_FPREGS+6*REGSZ_FP(a0)
|
||||
s.d $f31, SC_FPREGS+7*REGSZ_FP(a0)
|
||||
REG_S ra, SC_PC(a0) # sc_pc = return address
|
||||
#if defined(__mips64)
|
||||
dli v0, 0xACEDBADE # sigcontext magic number
|
||||
#else
|
||||
# callee-saved fp regs on mips o32 ABI are
|
||||
# the even-numbered fp regs $f20,$f22,...$f30
|
||||
s.d $f20, SC_FPREGS+0*REGSZ_FP(a0)
|
||||
s.d $f22, SC_FPREGS+1*REGSZ_FP(a0)
|
||||
s.d $f24, SC_FPREGS+2*REGSZ_FP(a0)
|
||||
s.d $f26, SC_FPREGS+3*REGSZ_FP(a0)
|
||||
s.d $f28, SC_FPREGS+4*REGSZ_FP(a0)
|
||||
s.d $f30, SC_FPREGS+5*REGSZ_FP(a0)
|
||||
li v0, 0xACEDBADE # sigcontext magic number
|
||||
#endif
|
||||
sw v0, SC_FPSR(a0)
|
||||
REG_S v0, SC_REGS+ZERO*REGSZ(a0)
|
||||
REG_S s0, SC_REGS+S0*REGSZ(a0)
|
||||
REG_S s1, SC_REGS+S1*REGSZ(a0)
|
||||
REG_S s2, SC_REGS+S2*REGSZ(a0)
|
||||
REG_S s3, SC_REGS+S3*REGSZ(a0)
|
||||
REG_S s4, SC_REGS+S4*REGSZ(a0)
|
||||
REG_S s5, SC_REGS+S5*REGSZ(a0)
|
||||
REG_S s6, SC_REGS+S6*REGSZ(a0)
|
||||
REG_S s7, SC_REGS+S7*REGSZ(a0)
|
||||
REG_S s8, SC_REGS+S8*REGSZ(a0)
|
||||
REG_L v0, GPOFF(sp)
|
||||
REG_S v0, SC_REGS+GP*REGSZ(a0)
|
||||
PTR_ADDU v0, sp, FRAMESZ
|
||||
REG_S v0, SC_REGS+SP*REGSZ(a0)
|
||||
|
||||
#if !defined(SOFTFLOAT)
|
||||
li v0, 1 # be nice if we could tell
|
||||
REG_S v0, SC_FPUSED(a0) # sc_fpused = 1
|
||||
cfc1 v0, $31
|
||||
s.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
|
||||
s.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
|
||||
s.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
|
||||
s.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
|
||||
s.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
|
||||
s.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
|
||||
#if _MIPS_FPSET == 32
|
||||
s.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
|
||||
s.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
|
||||
s.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
|
||||
s.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
|
||||
s.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
|
||||
s.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
|
||||
#endif
|
||||
REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
|
||||
#endif /* !SOFTFLOAT */
|
||||
move v0, zero
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
j ra
|
||||
|
||||
botch:
|
||||
jal longjmperror
|
||||
jal abort
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
END(setjmp)
|
||||
|
||||
NON_LEAF(longjmp, FRAMESZ, ra)
|
||||
.mask 0x80000000, RAOFF
|
||||
|
||||
LEAF(longjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, longjmp)
|
||||
SAVE_GP(GPOFF)
|
||||
.set reorder
|
||||
sw a1, A1OFF(sp)
|
||||
sw a0, A0OFF(sp)
|
||||
|
||||
#ifndef __LP64__
|
||||
addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary
|
||||
li t0, ~7
|
||||
and a0, t0
|
||||
#endif
|
||||
|
||||
REG_S a1, A1OFF(sp)
|
||||
REG_S a0, A0OFF(sp)
|
||||
lw a0, SC_MASK(a0)
|
||||
jal sigsetmask
|
||||
REG_L a0, A0OFF(sp)
|
||||
REG_L a1, A1OFF(sp)
|
||||
|
||||
lw v0, SC_MAGIC(a0)
|
||||
li t0, 0xACEDBADE
|
||||
bne v0, t0, longjmp_botch # jump if error
|
||||
lw a0, A0OFF(sp)
|
||||
lw a1, A1OFF(sp)
|
||||
|
||||
# callee-saved long-sized regs:
|
||||
REG_L ra, SC_REGS+0*REGSZ(a0)
|
||||
REG_L s0, SC_REGS+1*REGSZ(a0)
|
||||
REG_L s1, SC_REGS+2*REGSZ(a0)
|
||||
REG_L s2, SC_REGS+3*REGSZ(a0)
|
||||
REG_L s3, SC_REGS+4*REGSZ(a0)
|
||||
REG_L s4, SC_REGS+5*REGSZ(a0)
|
||||
REG_L s5, SC_REGS+6*REGSZ(a0)
|
||||
REG_L s6, SC_REGS+7*REGSZ(a0)
|
||||
REG_L s7, SC_REGS+8*REGSZ(a0)
|
||||
REG_L s8, SC_REGS+9*REGSZ(a0)
|
||||
REG_L gp, SC_REGS+10*REGSZ(a0)
|
||||
REG_L sp, SC_REGS+11*REGSZ(a0)
|
||||
.set noreorder
|
||||
REG_L v0, SC_REGS+ZERO*REGSZ(a0)
|
||||
bne v0, 0xACEDBADE, botch # jump if error
|
||||
REG_L ra, SC_PC(a0)
|
||||
REG_L s0, SC_REGS+S0*REGSZ(a0)
|
||||
REG_L s1, SC_REGS+S1*REGSZ(a0)
|
||||
REG_L s2, SC_REGS+S2*REGSZ(a0)
|
||||
REG_L s3, SC_REGS+S3*REGSZ(a0)
|
||||
REG_L s4, SC_REGS+S4*REGSZ(a0)
|
||||
REG_L s5, SC_REGS+S5*REGSZ(a0)
|
||||
REG_L s6, SC_REGS+S6*REGSZ(a0)
|
||||
REG_L s7, SC_REGS+S7*REGSZ(a0)
|
||||
REG_L s8, SC_REGS+S8*REGSZ(a0)
|
||||
REG_L gp, SC_REGS+GP*REGSZ(a0)
|
||||
REG_L sp, SC_REGS+SP*REGSZ(a0)
|
||||
|
||||
lw v0, SC_FPSR(a0)
|
||||
#if !defined(SOFTFLOAT)
|
||||
REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
|
||||
ctc1 v0, $31
|
||||
#ifdef __LP64__
|
||||
# callee-saved fp regs on mips n64 ABI are $f24..$f31
|
||||
l.d $f24, SC_FPREGS+0*REGSZ_FP(a0)
|
||||
l.d $f25, SC_FPREGS+1*REGSZ_FP(a0)
|
||||
l.d $f26, SC_FPREGS+2*REGSZ_FP(a0)
|
||||
l.d $f27, SC_FPREGS+3*REGSZ_FP(a0)
|
||||
l.d $f28, SC_FPREGS+4*REGSZ_FP(a0)
|
||||
l.d $f29, SC_FPREGS+5*REGSZ_FP(a0)
|
||||
l.d $f30, SC_FPREGS+6*REGSZ_FP(a0)
|
||||
l.d $f31, SC_FPREGS+7*REGSZ_FP(a0)
|
||||
#else
|
||||
# callee-saved fp regs on mips o32 ABI are
|
||||
# the even-numbered fp regs $f20,$f22,...$f30
|
||||
l.d $f20, SC_FPREGS+0*REGSZ_FP(a0)
|
||||
l.d $f22, SC_FPREGS+1*REGSZ_FP(a0)
|
||||
l.d $f24, SC_FPREGS+2*REGSZ_FP(a0)
|
||||
l.d $f26, SC_FPREGS+3*REGSZ_FP(a0)
|
||||
l.d $f28, SC_FPREGS+4*REGSZ_FP(a0)
|
||||
l.d $f30, SC_FPREGS+5*REGSZ_FP(a0)
|
||||
l.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
|
||||
l.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
|
||||
l.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
|
||||
l.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
|
||||
l.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
|
||||
l.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
|
||||
#if _MIPS_FPSET == 32
|
||||
l.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
|
||||
l.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
|
||||
l.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
|
||||
l.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
|
||||
l.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
|
||||
l.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
|
||||
#endif
|
||||
#endif /* !SOFTFLOAT */
|
||||
bne a1, zero, 1f
|
||||
nop
|
||||
li a1, 1 # never return 0!
|
||||
1:
|
||||
move v0, a1
|
||||
j ra
|
||||
move v0, a1
|
||||
|
||||
longjmp_botch:
|
||||
jal longjmperror
|
||||
jal abort
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
END(longjmp)
|
||||
|
||||
|
||||
/*
|
||||
* _setjmp, _longjmp (not restoring signal state)
|
||||
*
|
||||
* GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
|
||||
*
|
||||
*/
|
||||
|
||||
FRAMESZ= MKFSIZ(0,4)
|
||||
GPOFF= FRAMESZ-2*REGSZ
|
||||
|
||||
LEAF(_setjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, _setjmp)
|
||||
SAVE_GP(GPOFF)
|
||||
.set reorder
|
||||
|
||||
#ifndef __LP64__
|
||||
addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary
|
||||
li t0, ~7
|
||||
and a0, t0
|
||||
#endif
|
||||
|
||||
# SC_MASK is unused here
|
||||
|
||||
li v0, 0xACEDBADE # sigcontext magic number
|
||||
sw v0, SC_MAGIC(a0)
|
||||
# callee-saved long-sized regs:
|
||||
REG_S ra, SC_REGS+0*REGSZ(a0)
|
||||
REG_S s0, SC_REGS+1*REGSZ(a0)
|
||||
REG_S s1, SC_REGS+2*REGSZ(a0)
|
||||
REG_S s2, SC_REGS+3*REGSZ(a0)
|
||||
REG_S s3, SC_REGS+4*REGSZ(a0)
|
||||
REG_S s4, SC_REGS+5*REGSZ(a0)
|
||||
REG_S s5, SC_REGS+6*REGSZ(a0)
|
||||
REG_S s6, SC_REGS+7*REGSZ(a0)
|
||||
REG_S s7, SC_REGS+8*REGSZ(a0)
|
||||
REG_S s8, SC_REGS+9*REGSZ(a0)
|
||||
REG_L v0, GPOFF(sp)
|
||||
REG_S v0, SC_REGS+10*REGSZ(a0)
|
||||
PTR_ADDU v0, sp, FRAMESZ
|
||||
REG_S v0, SC_REGS+11*REGSZ(a0)
|
||||
|
||||
cfc1 v0, $31
|
||||
|
||||
#ifdef __LP64__
|
||||
# callee-saved fp regs on mips n64 ABI are $f24..$f31
|
||||
s.d $f24, SC_FPREGS+0*REGSZ_FP(a0)
|
||||
s.d $f25, SC_FPREGS+1*REGSZ_FP(a0)
|
||||
s.d $f26, SC_FPREGS+2*REGSZ_FP(a0)
|
||||
s.d $f27, SC_FPREGS+3*REGSZ_FP(a0)
|
||||
s.d $f28, SC_FPREGS+4*REGSZ_FP(a0)
|
||||
s.d $f29, SC_FPREGS+5*REGSZ_FP(a0)
|
||||
s.d $f30, SC_FPREGS+6*REGSZ_FP(a0)
|
||||
s.d $f31, SC_FPREGS+7*REGSZ_FP(a0)
|
||||
#else
|
||||
# callee-saved fp regs on mips o32 ABI are
|
||||
# the even-numbered fp regs $f20,$f22,...$f30
|
||||
s.d $f20, SC_FPREGS+0*REGSZ_FP(a0)
|
||||
s.d $f22, SC_FPREGS+1*REGSZ_FP(a0)
|
||||
s.d $f24, SC_FPREGS+2*REGSZ_FP(a0)
|
||||
s.d $f26, SC_FPREGS+3*REGSZ_FP(a0)
|
||||
s.d $f28, SC_FPREGS+4*REGSZ_FP(a0)
|
||||
s.d $f30, SC_FPREGS+5*REGSZ_FP(a0)
|
||||
#endif
|
||||
sw v0, SC_FPSR(a0)
|
||||
move v0, zero
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
j ra
|
||||
END(_setjmp)
|
||||
|
||||
|
||||
LEAF(_longjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, _longjmp)
|
||||
SAVE_GP(GPOFF)
|
||||
.set reorder
|
||||
|
||||
#ifndef __LP64__
|
||||
addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary
|
||||
li t0, ~7
|
||||
and a0, t0
|
||||
#endif
|
||||
|
||||
# SC_MASK is unused here
|
||||
|
||||
lw v0, SC_MAGIC(a0)
|
||||
li t0, 0xACEDBADE
|
||||
bne v0, t0, _longjmp_botch # jump if error
|
||||
|
||||
# callee-saved long-sized regs:
|
||||
REG_L ra, SC_REGS+0*REGSZ(a0)
|
||||
REG_L s0, SC_REGS+1*REGSZ(a0)
|
||||
REG_L s1, SC_REGS+2*REGSZ(a0)
|
||||
REG_L s2, SC_REGS+3*REGSZ(a0)
|
||||
REG_L s3, SC_REGS+4*REGSZ(a0)
|
||||
REG_L s4, SC_REGS+5*REGSZ(a0)
|
||||
REG_L s5, SC_REGS+6*REGSZ(a0)
|
||||
REG_L s6, SC_REGS+7*REGSZ(a0)
|
||||
REG_L s7, SC_REGS+8*REGSZ(a0)
|
||||
REG_L s8, SC_REGS+9*REGSZ(a0)
|
||||
REG_L gp, SC_REGS+10*REGSZ(a0)
|
||||
REG_L sp, SC_REGS+11*REGSZ(a0)
|
||||
|
||||
lw v0, SC_FPSR(a0)
|
||||
ctc1 v0, $31
|
||||
#ifdef __LP64__
|
||||
# callee-saved fp regs on mips n64 ABI are $f24..$f31
|
||||
l.d $f24, SC_FPREGS+0*REGSZ_FP(a0)
|
||||
l.d $f25, SC_FPREGS+1*REGSZ_FP(a0)
|
||||
l.d $f26, SC_FPREGS+2*REGSZ_FP(a0)
|
||||
l.d $f27, SC_FPREGS+3*REGSZ_FP(a0)
|
||||
l.d $f28, SC_FPREGS+4*REGSZ_FP(a0)
|
||||
l.d $f29, SC_FPREGS+5*REGSZ_FP(a0)
|
||||
l.d $f30, SC_FPREGS+6*REGSZ_FP(a0)
|
||||
l.d $f31, SC_FPREGS+7*REGSZ_FP(a0)
|
||||
#else
|
||||
# callee-saved fp regs on mips o32 ABI are
|
||||
# the even-numbered fp regs $f20,$f22,...$f30
|
||||
l.d $f20, SC_FPREGS+0*REGSZ_FP(a0)
|
||||
l.d $f22, SC_FPREGS+1*REGSZ_FP(a0)
|
||||
l.d $f24, SC_FPREGS+2*REGSZ_FP(a0)
|
||||
l.d $f26, SC_FPREGS+3*REGSZ_FP(a0)
|
||||
l.d $f28, SC_FPREGS+4*REGSZ_FP(a0)
|
||||
l.d $f30, SC_FPREGS+5*REGSZ_FP(a0)
|
||||
#endif
|
||||
bne a1, zero, 1f
|
||||
li a1, 1 # never return 0!
|
||||
1:
|
||||
move v0, a1
|
||||
j ra
|
||||
|
||||
_longjmp_botch:
|
||||
jal longjmperror
|
||||
jal abort
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
END(_longjmp)
|
||||
|
||||
/*
|
||||
* trampolines for sigsetjmp and siglongjmp save and restore mask.
|
||||
*
|
||||
*/
|
||||
FRAMESZ= MKFSIZ(1,1)
|
||||
GPOFF= FRAMESZ-2*REGSZ
|
||||
|
||||
LEAF(sigsetjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, sigsetjmp)
|
||||
.set reorder
|
||||
sw a1, _JBLEN*REGSZ(a0) # save "savemask"
|
||||
bne a1, 0x0, 1f # do saving of signal mask?
|
||||
LA t9, _setjmp
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
jr t9
|
||||
|
||||
1: LA t9, setjmp
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
jr t9
|
||||
END(sigsetjmp)
|
||||
|
||||
LEAF(siglongjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, siglongjmp)
|
||||
.set reorder
|
||||
lw t0, _JBLEN*REGSZ(a0) # get "savemask"
|
||||
bne t0, 0x0, 1f # restore signal mask?
|
||||
LA t9, _longjmp
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
jr t9
|
||||
1:
|
||||
LA t9, longjmp
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
jr t9
|
||||
END(siglongjmp)
|
||||
|
@@ -1,8 +1,11 @@
|
||||
/* $OpenBSD: verr.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */
|
||||
/* $OpenBSD: sigsetjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
* Copyright (c) 1991, 1993, 1995,
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Havard Eidnes.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -28,29 +31,47 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/regnum.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
extern char *__progname; /* Program name, from crt0. */
|
||||
/*
|
||||
* trampolines for sigsetjmp and siglongjmp save and restore mask.
|
||||
*
|
||||
*/
|
||||
FRAMESZ= MKFSIZ(1,1)
|
||||
GPOFF= FRAMESZ-2*REGSZ
|
||||
|
||||
__dead void
|
||||
_verr(int eval, const char *fmt, va_list ap)
|
||||
{
|
||||
int sverrno;
|
||||
LEAF(sigsetjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, sigsetjmp)
|
||||
.set reorder
|
||||
REG_S a1, (_JBLEN*REGSZ)(a0) # save "savemask"
|
||||
bne a1, 0x0, 1f # do saving of signal mask?
|
||||
LA t9, _setjmp
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
jr t9
|
||||
|
||||
sverrno = errno;
|
||||
(void)fprintf(stderr, "%s: ", __progname);
|
||||
if (fmt != NULL) {
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
(void)fprintf(stderr, ": ");
|
||||
}
|
||||
(void)fprintf(stderr, "%s\n", strerror(sverrno));
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
__weak_alias(verr, _verr);
|
||||
1: LA t9, setjmp
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
jr t9
|
||||
END(sigsetjmp)
|
||||
|
||||
LEAF(siglongjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, siglongjmp)
|
||||
.set reorder
|
||||
REG_L t0, (_JBLEN*REGSZ)(a0) # get "savemask"
|
||||
bne t0, 0x0, 1f # restore signal mask?
|
||||
LA t9, _longjmp
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
jr t9
|
||||
1:
|
||||
LA t9, longjmp
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
jr t9
|
||||
END(siglongjmp)
|
@@ -28,7 +28,9 @@
|
||||
#ifndef _MIPS64_ASM_H
|
||||
#define _MIPS64_ASM_H
|
||||
|
||||
#define __bionic_asm_align 4
|
||||
#ifndef _ALIGN_TEXT
|
||||
# define _ALIGN_TEXT .align 4
|
||||
#endif
|
||||
|
||||
#undef __bionic_asm_custom_entry
|
||||
#undef __bionic_asm_custom_end
|
||||
|
70
libc/arch-mips/include/machine/endian.h
Normal file
70
libc/arch-mips/include/machine/endian.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* $OpenBSD: endian.h,v 1.5 2006/02/27 23:35:59 miod Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MIPS64_ENDIAN_H_
|
||||
#define _MIPS64_ENDIAN_H_
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
|
||||
#define __swap16md(x) ({ \
|
||||
register uint16_t _x = (x); \
|
||||
register uint16_t _r; \
|
||||
__asm volatile ("wsbh %0, %1" : "=r" (_r) : "r" (_x)); \
|
||||
_r; \
|
||||
})
|
||||
|
||||
#define __swap32md(x) ({ \
|
||||
register uint32_t _x = (x); \
|
||||
register uint32_t _r; \
|
||||
__asm volatile ("wsbh %0, %1; rotr %0, %0, 16" : "=r" (_r) : "r" (_x)); \
|
||||
_r; \
|
||||
})
|
||||
|
||||
#define __swap64md(x) ({ \
|
||||
uint64_t _swap64md_x = (x); \
|
||||
(uint64_t) __swap32md(_swap64md_x >> 32) | \
|
||||
(uint64_t) __swap32md(_swap64md_x & 0xffffffff) << 32; \
|
||||
})
|
||||
|
||||
/* Tell sys/endian.h we have MD variants of the swap macros. */
|
||||
#define MD_SWAP
|
||||
|
||||
#endif /* __mips32r2__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined(__MIPSEB__)
|
||||
#define _BYTE_ORDER _BIG_ENDIAN
|
||||
#else
|
||||
#define _BYTE_ORDER _LITTLE_ENDIAN
|
||||
#endif
|
||||
#define __STRICT_ALIGNMENT
|
||||
#include <sys/types.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
#endif /* _MIPS64_ENDIAN_H_ */
|
188
libc/arch-mips/include/machine/exec.h
Normal file
188
libc/arch-mips/include/machine/exec.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/* $OpenBSD: exec.h,v 1.1 2004/10/18 19:05:36 grange Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2004 Per Fogelstrom, Opsycon AB
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MIPS64_EXEC_H_
|
||||
#define _MIPS64_EXEC_H_
|
||||
|
||||
#define __LDPGSZ 4096
|
||||
|
||||
/*
|
||||
* Define what exec "formats" we should handle.
|
||||
*/
|
||||
#define NATIVE_EXEC_ELF
|
||||
#define NATIVE_ELFSIZE 64
|
||||
#define EXEC_SCRIPT
|
||||
|
||||
/*
|
||||
* If included from sys/exec.h define kernels ELF format.
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
#define ARCH_ELFSIZE 64
|
||||
#define DB_ELFSIZE 64
|
||||
#define ELF_TARG_CLASS ELFCLASS64
|
||||
#else
|
||||
#define ARCH_ELFSIZE 32
|
||||
#define DB_ELFSIZE 32
|
||||
#define ELF_TARG_CLASS ELFCLASS32
|
||||
#endif
|
||||
|
||||
#if defined(__MIPSEB__)
|
||||
#define ELF_TARG_DATA ELFDATA2MSB
|
||||
#else
|
||||
#define ELF_TARG_DATA ELFDATA2LSB
|
||||
#endif
|
||||
#define ELF_TARG_MACH EM_MIPS
|
||||
|
||||
#define _NLIST_DO_ELF
|
||||
|
||||
#if defined(_LP64)
|
||||
#define _KERN_DO_ELF64
|
||||
#if defined(COMPAT_O32)
|
||||
#define _KERN_DO_ELF
|
||||
#endif
|
||||
#else
|
||||
#define _KERN_DO_ELF
|
||||
#endif
|
||||
|
||||
/* Information taken from MIPS ABI supplemental */
|
||||
|
||||
/* Architecture dependent Segment types - p_type */
|
||||
#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
|
||||
|
||||
/* Architecture dependent d_tag field for Elf32_Dyn. */
|
||||
#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime Linker Interface ID */
|
||||
#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */
|
||||
#define DT_MIPS_ICHECKSUM 0x70000003 /* Cksum of ext. str. and com. sizes */
|
||||
#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */
|
||||
#define DT_MIPS_FLAGS 0x70000005 /* Flags */
|
||||
#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Segment base address */
|
||||
#define DT_MIPS_CONFLICT 0x70000008 /* Adr of .conflict section */
|
||||
#define DT_MIPS_LIBLIST 0x70000009 /* Address of .liblist section */
|
||||
#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local .GOT entries */
|
||||
#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of .conflict entries */
|
||||
#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of .liblist entries */
|
||||
#define DT_MIPS_SYMTABNO 0x70000011 /* Number of .dynsym entries */
|
||||
#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
|
||||
#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in .dynsym */
|
||||
#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
|
||||
#define DT_MIPS_RLD_MAP 0x70000016 /* Address of debug map pointer */
|
||||
|
||||
#define DT_PROCNUM (DT_MIPS_RLD_MAP - DT_LOPROC + 1)
|
||||
|
||||
/*
|
||||
* Legal values for e_flags field of Elf32_Ehdr.
|
||||
*/
|
||||
#define EF_MIPS_NOREORDER 0x00000001 /* .noreorder was used */
|
||||
#define EF_MIPS_PIC 0x00000002 /* Contains PIC code */
|
||||
#define EF_MIPS_CPIC 0x00000004 /* Uses PIC calling sequence */
|
||||
#define EF_MIPS_ABI2 0x00000020 /* -n32 on Irix 6 */
|
||||
#define EF_MIPS_32BITMODE 0x00000100 /* 64 bit in 32 bit mode... */
|
||||
#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */
|
||||
#define E_MIPS_ARCH_1 0x00000000
|
||||
#define E_MIPS_ARCH_2 0x10000000
|
||||
#define E_MIPS_ARCH_3 0x20000000
|
||||
#define E_MIPS_ARCH_4 0x30000000
|
||||
#define EF_MIPS_ABI 0x0000f000 /* ABI level */
|
||||
#define E_MIPS_ABI_NONE 0x00000000 /* ABI level not set */
|
||||
#define E_MIPS_ABI_O32 0x00001000
|
||||
#define E_MIPS_ABI_O64 0x00002000
|
||||
#define E_MIPS_ABI_EABI32 0x00004000
|
||||
#define E_MIPS_ABI_EABI64 0x00004000
|
||||
|
||||
/*
|
||||
* Mips special sections.
|
||||
*/
|
||||
#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */
|
||||
#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
|
||||
#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
|
||||
|
||||
/*
|
||||
* Legal values for sh_type field of Elf32_Shdr.
|
||||
*/
|
||||
#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */
|
||||
#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */
|
||||
#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */
|
||||
#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */
|
||||
#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information */
|
||||
#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */
|
||||
|
||||
/*
|
||||
* Legal values for sh_flags field of Elf32_Shdr.
|
||||
*/
|
||||
#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Entries found in sections of type SHT_MIPS_GPTAB.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
Elf32_Word gt_current_g_value; /* -G val used in compilation */
|
||||
Elf32_Word gt_unused; /* Not used */
|
||||
} gt_header; /* First entry in section */
|
||||
struct {
|
||||
Elf32_Word gt_g_value; /* If this val were used for -G */
|
||||
Elf32_Word gt_bytes; /* This many bytes would be used */
|
||||
} gt_entry; /* Subsequent entries in section */
|
||||
} Elf32_gptab;
|
||||
|
||||
/*
|
||||
* Entry found in sections of type SHT_MIPS_REGINFO.
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word ri_gprmask; /* General registers used */
|
||||
Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */
|
||||
Elf32_Sword ri_gp_value; /* $gp register value */
|
||||
} Elf32_RegInfo;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Mips relocations.
|
||||
*/
|
||||
|
||||
#define R_MIPS_NONE 0 /* No reloc */
|
||||
#define R_MIPS_16 1 /* Direct 16 bit */
|
||||
#define R_MIPS_32 2 /* Direct 32 bit */
|
||||
#define R_MIPS_REL32 3 /* PC relative 32 bit */
|
||||
#define R_MIPS_26 4 /* Direct 26 bit shifted */
|
||||
#define R_MIPS_HI16 5 /* High 16 bit */
|
||||
#define R_MIPS_LO16 6 /* Low 16 bit */
|
||||
#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
|
||||
#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
|
||||
#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
|
||||
#define R_MIPS_PC16 10 /* PC relative 16 bit */
|
||||
#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
|
||||
#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
|
||||
|
||||
#define R_MIPS_64 18
|
||||
|
||||
#define R_MIPS_REL32_64 ((R_MIPS_64 << 8) | R_MIPS_REL32)
|
||||
|
||||
|
||||
#endif /* !_MIPS64_EXEC_H_ */
|
@@ -37,13 +37,6 @@
|
||||
#ifndef _MIPS_REGDEF_H_
|
||||
#define _MIPS_REGDEF_H_
|
||||
|
||||
#if (_MIPS_SIM == _ABI64) && !defined(__mips_n64)
|
||||
#define __mips_n64 1
|
||||
#endif
|
||||
#if (_MIPS_SIM == _ABIN32) && !defined(__mips_n32)
|
||||
#define __mips_n32 1
|
||||
#endif
|
||||
|
||||
#define zero $0 /* always zero */
|
||||
#define AT $at /* assembler temp */
|
||||
#define v0 $2 /* return value */
|
||||
|
119
libc/arch-mips/include/machine/regnum.h
Normal file
119
libc/arch-mips/include/machine/regnum.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/* $OpenBSD: regnum.h,v 1.3 2004/08/10 20:28:13 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MIPS64_REGNUM_H_
|
||||
#define _MIPS64_REGNUM_H_
|
||||
|
||||
/*
|
||||
* Location of the saved registers relative to ZERO.
|
||||
* Usage is p->p_regs[XX].
|
||||
*/
|
||||
#define ZERO 0
|
||||
#define AST 1
|
||||
#define V0 2
|
||||
#define V1 3
|
||||
#define A0 4
|
||||
#define A1 5
|
||||
#define A2 6
|
||||
#define A3 7
|
||||
#define T0 8
|
||||
#define T1 9
|
||||
#define T2 10
|
||||
#define T3 11
|
||||
#define T4 12
|
||||
#define T5 13
|
||||
#define T6 14
|
||||
#define T7 15
|
||||
#define S0 16
|
||||
#define S1 17
|
||||
#define S2 18
|
||||
#define S3 19
|
||||
#define S4 20
|
||||
#define S5 21
|
||||
#define S6 22
|
||||
#define S7 23
|
||||
#define T8 24
|
||||
#define T9 25
|
||||
#define K0 26
|
||||
#define K1 27
|
||||
#define GP 28
|
||||
#define SP 29
|
||||
#define S8 30
|
||||
#define RA 31
|
||||
#define SR 32
|
||||
#define PS SR /* alias for SR */
|
||||
#define MULLO 33
|
||||
#define MULHI 34
|
||||
#define BADVADDR 35
|
||||
#define CAUSE 36
|
||||
#define PC 37
|
||||
#define IC 38
|
||||
#define CPL 39
|
||||
|
||||
#define NUMSAVEREGS 40 /* Number of registers saved in trap */
|
||||
|
||||
#define FPBASE NUMSAVEREGS
|
||||
#define F0 (FPBASE+0)
|
||||
#define F1 (FPBASE+1)
|
||||
#define F2 (FPBASE+2)
|
||||
#define F3 (FPBASE+3)
|
||||
#define F4 (FPBASE+4)
|
||||
#define F5 (FPBASE+5)
|
||||
#define F6 (FPBASE+6)
|
||||
#define F7 (FPBASE+7)
|
||||
#define F8 (FPBASE+8)
|
||||
#define F9 (FPBASE+9)
|
||||
#define F10 (FPBASE+10)
|
||||
#define F11 (FPBASE+11)
|
||||
#define F12 (FPBASE+12)
|
||||
#define F13 (FPBASE+13)
|
||||
#define F14 (FPBASE+14)
|
||||
#define F15 (FPBASE+15)
|
||||
#define F16 (FPBASE+16)
|
||||
#define F17 (FPBASE+17)
|
||||
#define F18 (FPBASE+18)
|
||||
#define F19 (FPBASE+19)
|
||||
#define F20 (FPBASE+20)
|
||||
#define F21 (FPBASE+21)
|
||||
#define F22 (FPBASE+22)
|
||||
#define F23 (FPBASE+23)
|
||||
#define F24 (FPBASE+24)
|
||||
#define F25 (FPBASE+25)
|
||||
#define F26 (FPBASE+26)
|
||||
#define F27 (FPBASE+27)
|
||||
#define F28 (FPBASE+28)
|
||||
#define F29 (FPBASE+29)
|
||||
#define F30 (FPBASE+30)
|
||||
#define F31 (FPBASE+31)
|
||||
#define FSR (FPBASE+32)
|
||||
|
||||
#define NUMFPREGS 33
|
||||
|
||||
#define NREGS (NUMSAVEREGS + NUMFPREGS)
|
||||
|
||||
#endif /* !_MIPS64_REGNUM_H_ */
|
@@ -5,10 +5,6 @@
|
||||
#ifndef _MIPS_SETJMP_H_
|
||||
#define _MIPS_SETJMP_H_
|
||||
|
||||
#ifdef __LP64__
|
||||
#define _JBLEN 22 /* size, in 8-byte longs, of a mips64 jmp_buf */
|
||||
#else
|
||||
#define _JBLEN 29 /* size, in 4-byte longs, of a mips32 jmp_buf */
|
||||
#endif
|
||||
#define _JBLEN 157 /* size, in longs, of a jmp_buf */
|
||||
|
||||
#endif /* !_MIPS_SETJMP_H_ */
|
||||
|
@@ -1,8 +1,12 @@
|
||||
/* $OpenBSD: daemon.c,v 1.7 2010/07/27 22:29:09 marco Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
/* $OpenBSD: signal.h,v 1.8 2006/01/09 18:18:37 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@@ -26,39 +30,22 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#)signal.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _MIPS_SIGNAL_H_
|
||||
#define _MIPS_SIGNAL_H_
|
||||
|
||||
int
|
||||
daemon(int nochdir, int noclose)
|
||||
{
|
||||
int fd;
|
||||
#define SC_REGMASK (0*REGSZ)
|
||||
#define SC_STATUS (1*REGSZ)
|
||||
#define SC_PC (2*REGSZ)
|
||||
#define SC_REGS (SC_PC+8)
|
||||
#define SC_FPREGS (SC_REGS+32*8)
|
||||
#define SC_ACX (SC_FPREGS+32*REGSZ_FP)
|
||||
#define SC_USED_MATH (SC_ACX+3*REGSZ)
|
||||
/* OpenBSD compatibility */
|
||||
#define SC_MASK SC_REGMASK
|
||||
#define SC_FPUSED SC_USED_MATH
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
return (-1);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
if (setsid() == -1)
|
||||
return (-1);
|
||||
|
||||
if (!nochdir)
|
||||
(void)chdir("/");
|
||||
|
||||
if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
|
||||
(void)dup2(fd, STDIN_FILENO);
|
||||
(void)dup2(fd, STDOUT_FILENO);
|
||||
(void)dup2(fd, STDERR_FILENO);
|
||||
if (fd > 2)
|
||||
(void)close(fd);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif /* !_MIPS_SIGNAL_H_ */
|
@@ -1,32 +1,17 @@
|
||||
# 32-bit mips.
|
||||
# mips specific configs
|
||||
|
||||
#
|
||||
# Various kinds of LP32 cruft.
|
||||
#
|
||||
|
||||
libc_bionic_src_files_mips += \
|
||||
bionic/mmap.cpp \
|
||||
|
||||
libc_common_src_files_mips += \
|
||||
# These are shared by all the 32-bit targets, but not the 64-bit ones.
|
||||
libc_common_src_files_mips := \
|
||||
bionic/legacy_32_bit_support.cpp \
|
||||
bionic/ndk_cruft.cpp \
|
||||
bionic/time64.c \
|
||||
|
||||
libc_netbsd_src_files_mips += \
|
||||
upstream-netbsd/common/lib/libc/hash/sha1/sha1.c \
|
||||
|
||||
libc_openbsd_src_files_mips += \
|
||||
upstream-openbsd/lib/libc/stdio/putw.c \
|
||||
|
||||
#
|
||||
# Default implementations of functions that are commonly optimized.
|
||||
#
|
||||
|
||||
# These are shared by all the 32-bit targets, but not the 64-bit ones.
|
||||
libc_bionic_src_files_mips += \
|
||||
bionic/__memcpy_chk.cpp \
|
||||
bionic/__memset_chk.cpp \
|
||||
bionic/__strcpy_chk.cpp \
|
||||
bionic/__strcat_chk.cpp \
|
||||
bionic/mmap.cpp
|
||||
|
||||
libc_common_src_files_mips += \
|
||||
bionic/memchr.c \
|
||||
bionic/memcmp.c \
|
||||
bionic/memmove.c \
|
||||
@@ -34,8 +19,6 @@ libc_bionic_src_files_mips += \
|
||||
bionic/strchr.cpp \
|
||||
bionic/strnlen.c \
|
||||
bionic/strrchr.cpp \
|
||||
|
||||
libc_freebsd_src_files_mips += \
|
||||
upstream-freebsd/lib/libc/string/wcscat.c \
|
||||
upstream-freebsd/lib/libc/string/wcschr.c \
|
||||
upstream-freebsd/lib/libc/string/wcscmp.c \
|
||||
@@ -44,8 +27,6 @@ libc_freebsd_src_files_mips += \
|
||||
upstream-freebsd/lib/libc/string/wcsrchr.c \
|
||||
upstream-freebsd/lib/libc/string/wmemcmp.c \
|
||||
upstream-freebsd/lib/libc/string/wmemmove.c \
|
||||
|
||||
libc_openbsd_src_files_mips += \
|
||||
upstream-openbsd/lib/libc/string/bcopy.c \
|
||||
upstream-openbsd/lib/libc/string/stpcpy.c \
|
||||
upstream-openbsd/lib/libc/string/stpncpy.c \
|
||||
@@ -58,16 +39,24 @@ libc_openbsd_src_files_mips += \
|
||||
upstream-openbsd/lib/libc/string/strncmp.c \
|
||||
upstream-openbsd/lib/libc/string/strncpy.c \
|
||||
|
||||
#
|
||||
# Inherently architecture-specific code.
|
||||
#
|
||||
# Fortify implementations of libc functions.
|
||||
libc_common_src_files_mips += \
|
||||
bionic/__memcpy_chk.cpp \
|
||||
bionic/__memset_chk.cpp \
|
||||
bionic/__strcpy_chk.cpp \
|
||||
bionic/__strcat_chk.cpp \
|
||||
|
||||
|
||||
##########################################
|
||||
### CPU specific source files
|
||||
libc_bionic_src_files_mips += \
|
||||
arch-mips/bionic/__bionic_clone.S \
|
||||
arch-mips/bionic/bzero.S \
|
||||
arch-mips/bionic/cacheflush.cpp \
|
||||
arch-mips/bionic/_exit_with_stack_teardown.S \
|
||||
arch-mips/bionic/_setjmp.S \
|
||||
arch-mips/bionic/setjmp.S \
|
||||
arch-mips/bionic/sigsetjmp.S \
|
||||
arch-mips/bionic/syscall.S \
|
||||
arch-mips/bionic/vfork.S \
|
||||
|
||||
@@ -80,13 +69,14 @@ libc_bionic_src_files_mips += \
|
||||
else
|
||||
libc_bionic_src_files_mips += \
|
||||
bionic/memcpy.cpp \
|
||||
bionic/memset.c \
|
||||
|
||||
libc_openbsd_src_files_mips += \
|
||||
upstream-openbsd/lib/libc/string/strlen.c \
|
||||
|
||||
bionic/memset.c
|
||||
libc_common_src_files_mips += \
|
||||
upstream-openbsd/lib/libc/string/strlen.c
|
||||
endif
|
||||
|
||||
libc_netbsd_src_files_mips := \
|
||||
upstream-netbsd/common/lib/libc/hash/sha1/sha1.c \
|
||||
|
||||
libc_crt_target_cflags_mips := \
|
||||
$($(my_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) \
|
||||
-I$(LOCAL_PATH)/arch-mips/include
|
||||
|
@@ -30,7 +30,6 @@
|
||||
* 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) {\
|
||||
@@ -48,8 +47,8 @@
|
||||
#define strlen my_strlen
|
||||
#endif
|
||||
|
||||
size_t
|
||||
strlen (const char *_a)
|
||||
int
|
||||
strlen (const void *_a)
|
||||
{
|
||||
int cnt = 0;
|
||||
unsigned x;
|
||||
|
@@ -1,19 +0,0 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(__rt_sigqueueinfo)
|
||||
.set noreorder
|
||||
.cpload t9
|
||||
li v0, __NR_rt_sigqueueinfo
|
||||
syscall
|
||||
bnez a3, 1f
|
||||
move a0, v0
|
||||
j ra
|
||||
nop
|
||||
1:
|
||||
la t9,__set_errno_internal
|
||||
j t9
|
||||
nop
|
||||
.set reorder
|
||||
END(__rt_sigqueueinfo)
|
@@ -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,4 +16,4 @@ ENTRY(__clock_nanosleep)
|
||||
j t9
|
||||
nop
|
||||
.set reorder
|
||||
END(__clock_nanosleep)
|
||||
END(clock_nanosleep)
|
@@ -1,19 +0,0 @@
|
||||
/* Generated by gensyscalls.py. Do not edit. */
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
|
||||
ENTRY(sethostname)
|
||||
.set noreorder
|
||||
.cpload t9
|
||||
li v0, __NR_sethostname
|
||||
syscall
|
||||
bnez a3, 1f
|
||||
move a0, v0
|
||||
j ra
|
||||
nop
|
||||
1:
|
||||
la t9,__set_errno_internal
|
||||
j t9
|
||||
nop
|
||||
.set reorder
|
||||
END(sethostname)
|
150
libc/arch-mips64/bionic/_setjmp.S
Normal file
150
libc/arch-mips64/bionic/_setjmp.S
Normal file
@@ -0,0 +1,150 @@
|
||||
/* $OpenBSD: _setjmp.S,v 1.4 2005/08/07 16:40:15 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
|
||||
*
|
||||
* 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 Opsycon AB 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 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <private/bionic_asm.h>
|
||||
#include <machine/regnum.h>
|
||||
#include <machine/signal.h>
|
||||
|
||||
/*
|
||||
* _setjmp, _longjmp (not restoring signal state)
|
||||
*
|
||||
* XXX FPSET should probably be taken from SR setting. hmmm...
|
||||
* GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
|
||||
*
|
||||
*/
|
||||
|
||||
FRAMESZ= MKFSIZ(0,4)
|
||||
GPOFF= FRAMESZ-2*REGSZ
|
||||
|
||||
LEAF(_setjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, _setjmp)
|
||||
SAVE_GP(GPOFF)
|
||||
.set noreorder
|
||||
#if defined(__mips64)
|
||||
dli v0, 0xACEDBADE # sigcontext magic number
|
||||
#else
|
||||
li v0, 0xACEDBADE # sigcontext magic number
|
||||
#endif
|
||||
REG_S v0, SC_REGS+ZERO*REGSZ(a0)
|
||||
REG_S s0, SC_REGS+S0*REGSZ(a0)
|
||||
REG_S s1, SC_REGS+S1*REGSZ(a0)
|
||||
REG_S s2, SC_REGS+S2*REGSZ(a0)
|
||||
REG_S s3, SC_REGS+S3*REGSZ(a0)
|
||||
REG_S s4, SC_REGS+S4*REGSZ(a0)
|
||||
REG_S s5, SC_REGS+S5*REGSZ(a0)
|
||||
REG_S s6, SC_REGS+S6*REGSZ(a0)
|
||||
REG_S s7, SC_REGS+S7*REGSZ(a0)
|
||||
REG_S s8, SC_REGS+S8*REGSZ(a0)
|
||||
REG_L v0, GPOFF(sp)
|
||||
REG_S v0, SC_REGS+GP*REGSZ(a0)
|
||||
PTR_ADDU v0, sp, FRAMESZ
|
||||
REG_S v0, SC_REGS+SP*REGSZ(a0)
|
||||
REG_S ra, SC_PC(a0)
|
||||
|
||||
#if !defined(SOFTFLOAT)
|
||||
li v0, 1 # be nice if we could tell
|
||||
REG_S v0, SC_FPUSED(a0) # sc_fpused = 1
|
||||
cfc1 v0, $31
|
||||
s.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
|
||||
s.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
|
||||
s.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
|
||||
s.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
|
||||
s.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
|
||||
s.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
|
||||
#if _MIPS_FPSET == 32
|
||||
s.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
|
||||
s.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
|
||||
s.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
|
||||
s.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
|
||||
s.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
|
||||
s.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
|
||||
#endif
|
||||
REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
|
||||
#endif /* !SOFTFLOAT */
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
j ra
|
||||
move v0, zero
|
||||
END(_setjmp)
|
||||
|
||||
LEAF(_longjmp, FRAMESZ)
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
SETUP_GP64(GPOFF, _longjmp)
|
||||
SAVE_GP(GPOFF)
|
||||
.set noreorder
|
||||
REG_L v0, SC_REGS+ZERO*REGSZ(a0)
|
||||
bne v0, 0xACEDBADE, botch # jump if error
|
||||
REG_L ra, SC_PC(a0)
|
||||
REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
|
||||
REG_L s0, SC_REGS+S0*REGSZ(a0)
|
||||
REG_L s1, SC_REGS+S1*REGSZ(a0)
|
||||
REG_L s2, SC_REGS+S2*REGSZ(a0)
|
||||
REG_L s3, SC_REGS+S3*REGSZ(a0)
|
||||
REG_L s4, SC_REGS+S4*REGSZ(a0)
|
||||
REG_L s5, SC_REGS+S5*REGSZ(a0)
|
||||
REG_L s6, SC_REGS+S6*REGSZ(a0)
|
||||
REG_L s7, SC_REGS+S7*REGSZ(a0)
|
||||
REG_L s8, SC_REGS+S8*REGSZ(a0)
|
||||
REG_L gp, SC_REGS+GP*REGSZ(a0)
|
||||
REG_L sp, SC_REGS+SP*REGSZ(a0)
|
||||
#if !defined(SOFTFLOAT)
|
||||
ctc1 v0, $31
|
||||
l.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
|
||||
l.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
|
||||
l.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
|
||||
l.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
|
||||
l.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
|
||||
l.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
|
||||
#if _MIPS_FPSET == 32
|
||||
l.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
|
||||
l.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
|
||||
l.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
|
||||
l.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
|
||||
l.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
|
||||
l.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
|
||||
#endif
|
||||
#endif /* !SOFTFLOAT */
|
||||
bne a1, zero, 1f
|
||||
nop
|
||||
li a1, 1 # never return 0!
|
||||
1:
|
||||
j ra
|
||||
move v0, a1
|
||||
|
||||
botch:
|
||||
jal longjmperror
|
||||
nop
|
||||
jal abort
|
||||
nop
|
||||
RESTORE_GP64
|
||||
PTR_ADDU sp, FRAMESZ
|
||||
END(_longjmp)
|
36
libc/arch-mips64/bionic/atexit.h
Normal file
36
libc/arch-mips64/bionic/atexit.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
extern void *__dso_handle;
|
||||
extern int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
|
||||
|
||||
__attribute__ ((visibility ("hidden")))
|
||||
int atexit(void (*func)(void))
|
||||
{
|
||||
return (__cxa_atexit((void (*)(void *))func, (void *)0, &__dso_handle));
|
||||
}
|
@@ -91,4 +91,4 @@ __asm__ (
|
||||
);
|
||||
|
||||
#include "../../arch-common/bionic/__dso_handle.h"
|
||||
#include "../../arch-common/bionic/atexit.h"
|
||||
#include "atexit.h"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user