Compare commits
	
		
			223 Commits
		
	
	
		
			android-6.
			...
			android-m-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7a9732d663 | ||
| 
						 | 
					7ea817d39e | ||
| 
						 | 
					89bbb846b9 | ||
| 
						 | 
					dbb17b2831 | ||
| 
						 | 
					f542b30970 | ||
| 
						 | 
					eeb6b57e75 | ||
| 
						 | 
					77455f85ab | ||
| 
						 | 
					86061f39c2 | ||
| 
						 | 
					416695a75c | ||
| 
						 | 
					c2247478d5 | ||
| 
						 | 
					b9f76dc829 | ||
| 
						 | 
					7f46cf9a5f | ||
| 
						 | 
					83474cd387 | ||
| 
						 | 
					7271caf93d | ||
| 
						 | 
					46d24d12e1 | ||
| 
						 | 
					25da2d7ca2 | ||
| 
						 | 
					59d5854d14 | ||
| 
						 | 
					71107cdd02 | ||
| 
						 | 
					a05bee544a | ||
| 
						 | 
					01e37c9665 | ||
| 
						 | 
					eeb9f5e416 | ||
| 
						 | 
					3f987f5b3e | ||
| 
						 | 
					56f40fbb82 | ||
| 
						 | 
					d19c271599 | ||
| 
						 | 
					6589febec2 | ||
| 
						 | 
					fef58353f4 | ||
| 
						 | 
					bc425c73e0 | ||
| 
						 | 
					c666838ad6 | ||
| 
						 | 
					cc83890464 | ||
| 
						 | 
					d807b9a12d | ||
| 
						 | 
					e79d06b0e8 | ||
| 
						 | 
					af6ee5b5bc | ||
| 
						 | 
					aff18fd608 | ||
| 
						 | 
					7d09a8cd11 | ||
| 
						 | 
					a8993c994e | ||
| 
						 | 
					e4ad91f86a | ||
| 
						 | 
					13cee57dee | ||
| 
						 | 
					de4e27e231 | ||
| 
						 | 
					6a5ead6990 | ||
| 
						 | 
					d02ec08427 | ||
| 
						 | 
					6cc98af72b | ||
| 
						 | 
					d1ade7ce02 | ||
| 
						 | 
					547fa54e6d | ||
| 
						 | 
					a9703332f6 | ||
| 
						 | 
					bfa601a999 | ||
| 
						 | 
					9ae6f794ca | ||
| 
						 | 
					d2c81ed000 | ||
| 
						 | 
					f448ef491c | ||
| 
						 | 
					61cbd02f10 | ||
| 
						 | 
					455c145e3c | ||
| 
						 | 
					3b5a4b0c33 | ||
| 
						 | 
					dee130f598 | ||
| 
						 | 
					38f2eaa07b | ||
| 
						 | 
					81b2382df6 | ||
| 
						 | 
					895241efbb | ||
| 
						 | 
					b628b7db39 | ||
| 
						 | 
					11ea08c5cb | ||
| 
						 | 
					9876aa273d | ||
| 
						 | 
					48fa28bacd | ||
| 
						 | 
					cd1be3b69e | ||
| 
						 | 
					665607a6b7 | ||
| 
						 | 
					a73b2c961f | ||
| 
						 | 
					b1304935b6 | ||
| 
						 | 
					636f5ddddc | ||
| 
						 | 
					df11f340ca | ||
| 
						 | 
					0577733c2e | ||
| 
						 | 
					27f5c37b12 | ||
| 
						 | 
					333bdad361 | ||
| 
						 | 
					469b418784 | ||
| 
						 | 
					bf18c61798 | ||
| 
						 | 
					713ae464ab | ||
| 
						 | 
					402a75060d | ||
| 
						 | 
					9ef26a3c4c | ||
| 
						 | 
					173ad0a53e | ||
| 
						 | 
					b90e9b7183 | ||
| 
						 | 
					175dae92d7 | ||
| 
						 | 
					c910de9d5e | ||
| 
						 | 
					be57a40d29 | ||
| 
						 | 
					db68b4600d | ||
| 
						 | 
					bd3b961186 | ||
| 
						 | 
					72af1235e4 | ||
| 
						 | 
					6865082ca6 | ||
| 
						 | 
					ba1d40a3f1 | ||
| 
						 | 
					f3463db7eb | ||
| 
						 | 
					6a494915d7 | ||
| 
						 | 
					60907c7f4e | ||
| 
						 | 
					1801db3d3f | ||
| 
						 | 
					1cfbd94a2f | ||
| 
						 | 
					8a11628355 | ||
| 
						 | 
					866d6fb090 | ||
| 
						 | 
					4900f1c4cd | ||
| 
						 | 
					624b8f17a1 | ||
| 
						 | 
					12fb28bbd8 | ||
| 
						 | 
					d9dc13d417 | ||
| 
						 | 
					e1d0810cd7 | ||
| 
						 | 
					f9554a1776 | ||
| 
						 | 
					966f84b11d | ||
| 
						 | 
					19fee2ca8b | ||
| 
						 | 
					12ca831b0e | ||
| 
						 | 
					9cf6fc304b | ||
| 
						 | 
					b68b8b4b95 | ||
| 
						 | 
					c062218a9b | ||
| 
						 | 
					5cce2e7205 | ||
| 
						 | 
					6cda074289 | ||
| 
						 | 
					3931b6d9b3 | ||
| 
						 | 
					1913352c6b | ||
| 
						 | 
					11b15b23aa | ||
| 
						 | 
					75108f4f83 | ||
| 
						 | 
					ef55f96723 | ||
| 
						 | 
					e7deb145c6 | ||
| 
						 | 
					2825f10b7f | ||
| 
						 | 
					f439b5a318 | ||
| 
						 | 
					ef607cdae2 | ||
| 
						 | 
					9d476a02e9 | ||
| 
						 | 
					d70891687d | ||
| 
						 | 
					5511551009 | ||
| 
						 | 
					6c2dba8651 | ||
| 
						 | 
					d974e88046 | ||
| 
						 | 
					087005f37e | ||
| 
						 | 
					d717b1a3e5 | ||
| 
						 | 
					79fd668bb4 | ||
| 
						 | 
					560aacee84 | ||
| 
						 | 
					1011e1a402 | ||
| 
						 | 
					fad15145f8 | ||
| 
						 | 
					41c99cdbb9 | ||
| 
						 | 
					3cec6eca92 | ||
| 
						 | 
					aaafbe128f | ||
| 
						 | 
					b96ac41b32 | ||
| 
						 | 
					ffe01a3de6 | ||
| 
						 | 
					4fc106d34b | ||
| 
						 | 
					b0c6f2dba2 | ||
| 
						 | 
					c05554ec5c | ||
| 
						 | 
					c02bdc76a2 | ||
| 
						 | 
					40a8f214a5 | ||
| 
						 | 
					a42b5bcd89 | ||
| 
						 | 
					9185e04f72 | ||
| 
						 | 
					882283e9e2 | ||
| 
						 | 
					4e8ef698d0 | ||
| 
						 | 
					1d52b8b07c | ||
| 
						 | 
					b00c23a8db | ||
| 
						 | 
					e77e335b54 | ||
| 
						 | 
					933332462d | ||
| 
						 | 
					0378d8f651 | ||
| 
						 | 
					706eafc9b0 | ||
| 
						 | 
					0346ad7a4f | ||
| 
						 | 
					c217373bd6 | ||
| 
						 | 
					fe77d2d003 | ||
| 
						 | 
					697bd9fd38 | ||
| 
						 | 
					d0763ba076 | ||
| 
						 | 
					f58ac87182 | ||
| 
						 | 
					3ff027e550 | ||
| 
						 | 
					7e54c762fc | ||
| 
						 | 
					8a330cad8d | ||
| 
						 | 
					c69ace87ec | ||
| 
						 | 
					972d7fe63a | ||
| 
						 | 
					33f33515b5 | ||
| 
						 | 
					c9310266dc | ||
| 
						 | 
					ec738d9494 | ||
| 
						 | 
					75f2dfca65 | ||
| 
						 | 
					4e8cda641a | ||
| 
						 | 
					267f39bf63 | ||
| 
						 | 
					88e777d6f4 | ||
| 
						 | 
					11fc3f47af | ||
| 
						 | 
					a924d4ba26 | ||
| 
						 | 
					7d6b8db28e | ||
| 
						 | 
					ce16a53d39 | ||
| 
						 | 
					f9eeea6d65 | ||
| 
						 | 
					2957cc5f10 | ||
| 
						 | 
					ded34ce94f | ||
| 
						 | 
					7c2c01d681 | ||
| 
						 | 
					6f0d7005f9 | ||
| 
						 | 
					f920f821e2 | ||
| 
						 | 
					dc10b077ea | ||
| 
						 | 
					e543c7612e | ||
| 
						 | 
					9c1894186c | ||
| 
						 | 
					3edb9182ff | ||
| 
						 | 
					fff06e624d | ||
| 
						 | 
					5624a6a1e5 | ||
| 
						 | 
					c95a9e9dad | ||
| 
						 | 
					406d99665c | ||
| 
						 | 
					f3392791bc | ||
| 
						 | 
					dbe26fdcc7 | ||
| 
						 | 
					2c3d8d8b2c | ||
| 
						 | 
					4637f3d66d | ||
| 
						 | 
					64a8698809 | ||
| 
						 | 
					7fbd6355ae | ||
| 
						 | 
					f39cb63603 | ||
| 
						 | 
					7e4bbbae4a | ||
| 
						 | 
					788ea593ec | ||
| 
						 | 
					31b408d2c2 | ||
| 
						 | 
					033a68f1ac | ||
| 
						 | 
					6a4c9d9bf9 | ||
| 
						 | 
					df877d7b28 | ||
| 
						 | 
					18c935ceab | ||
| 
						 | 
					f29640c2d8 | ||
| 
						 | 
					c6b9b254dc | ||
| 
						 | 
					0373d4f473 | ||
| 
						 | 
					c3f4c964a3 | ||
| 
						 | 
					fa6f649607 | ||
| 
						 | 
					e1a61f5e93 | ||
| 
						 | 
					0bf650373e | ||
| 
						 | 
					11331f60dd | ||
| 
						 | 
					f8093a9485 | ||
| 
						 | 
					b4e5067cab | ||
| 
						 | 
					b904afa16e | ||
| 
						 | 
					9f0d99d298 | ||
| 
						 | 
					62d6533c1a | ||
| 
						 | 
					bed7a7e5eb | ||
| 
						 | 
					a85bcc2e99 | ||
| 
						 | 
					6fa65e7cd5 | ||
| 
						 | 
					e0905c94d3 | ||
| 
						 | 
					520cbf51b1 | ||
| 
						 | 
					42d7468f99 | ||
| 
						 | 
					b293969c6d | ||
| 
						 | 
					032907d8c7 | ||
| 
						 | 
					2ea504fed1 | ||
| 
						 | 
					59bce688c7 | ||
| 
						 | 
					bfd65279a5 | ||
| 
						 | 
					682a240c5d | ||
| 
						 | 
					6f88821e5d | ||
| 
						 | 
					d2177404e2 | ||
| 
						 | 
					0a93df369c | ||
| 
						 | 
					3da136aa47 | 
@@ -16,6 +16,7 @@
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdio_ext.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include <benchmark/Benchmark.h>
 | 
			
		||||
 | 
			
		||||
@@ -73,7 +74,7 @@ static void FopenFgetsFclose(int iters, bool no_locking) {
 | 
			
		||||
  for (int i = 0; i < iters; ++i) {
 | 
			
		||||
    FILE* fp = fopen("/proc/version", "re");
 | 
			
		||||
    if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
 | 
			
		||||
    fgets(buf, sizeof(buf), fp);
 | 
			
		||||
    if (fgets(buf, sizeof(buf), fp) == nullptr) abort();
 | 
			
		||||
    fclose(fp);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,8 @@
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
@@ -21,7 +23,7 @@
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#include <base/stringprintf.h>
 | 
			
		||||
 | 
			
		||||
int Round(int n) {
 | 
			
		||||
  int base = 1;
 | 
			
		||||
@@ -72,10 +74,7 @@ std::string PrettyInt(long value, size_t base) {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  char* s = NULL;
 | 
			
		||||
  asprintf(&s, "%s%" PRId64 "%s", (negative_number ? "-" : ""),
 | 
			
		||||
           count / kAmountPerUnit[i], kUnitStrings[i]);
 | 
			
		||||
  std::string result(s);
 | 
			
		||||
  free(s);
 | 
			
		||||
  return result;
 | 
			
		||||
  return android::base::StringPrintf("%s%" PRId64 "%s",
 | 
			
		||||
                                     negative_number ? "-" : "",
 | 
			
		||||
                                     count / kAmountPerUnit[i], kUnitStrings[i]);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										109
									
								
								libc/Android.mk
									
									
									
									
									
								
							
							
						
						
									
										109
									
								
								libc/Android.mk
									
									
									
									
									
								
							@@ -129,8 +129,12 @@ libc_bionic_ndk_src_files := \
 | 
			
		||||
    bionic/fchmod.cpp \
 | 
			
		||||
    bionic/fchmodat.cpp \
 | 
			
		||||
    bionic/ffs.cpp \
 | 
			
		||||
    bionic/fgetxattr.cpp \
 | 
			
		||||
    bionic/flistxattr.cpp \
 | 
			
		||||
    bionic/flockfile.cpp \
 | 
			
		||||
    bionic/fpclassify.cpp \
 | 
			
		||||
    bionic/fsetxattr.cpp \
 | 
			
		||||
    bionic/ftruncate.cpp \
 | 
			
		||||
    bionic/futimens.cpp \
 | 
			
		||||
    bionic/getcwd.cpp \
 | 
			
		||||
    bionic/gethostname.cpp \
 | 
			
		||||
@@ -546,14 +550,16 @@ libc_thread_atexit_impl_src_files := \
 | 
			
		||||
libc_arch_static_src_files := \
 | 
			
		||||
    bionic/dl_iterate_phdr_static.cpp \
 | 
			
		||||
 | 
			
		||||
# Various kinds of LP32 cruft.
 | 
			
		||||
# Various kinds of cruft.
 | 
			
		||||
# ========================================================
 | 
			
		||||
libc_bionic_src_files_32 += \
 | 
			
		||||
libc_common_src_files += \
 | 
			
		||||
    bionic/ndk_cruft.cpp \
 | 
			
		||||
 | 
			
		||||
libc_bionic_ndk_src_files_32 += \
 | 
			
		||||
    bionic/mmap.cpp \
 | 
			
		||||
 | 
			
		||||
libc_common_src_files_32 += \
 | 
			
		||||
    bionic/legacy_32_bit_support.cpp \
 | 
			
		||||
    bionic/ndk_cruft.cpp \
 | 
			
		||||
    bionic/time64.c \
 | 
			
		||||
 | 
			
		||||
libc_netbsd_src_files_32 += \
 | 
			
		||||
@@ -574,6 +580,13 @@ libc_common_cflags += -DTARGET_USES_LOGD
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
use_clang := $(USE_CLANG_PLATFORM_BUILD)
 | 
			
		||||
 | 
			
		||||
# Clang/llvm has incompatible long double (fp128) for x86_64.
 | 
			
		||||
# https://llvm.org/bugs/show_bug.cgi?id=23897
 | 
			
		||||
ifeq ($(TARGET_ARCH),x86_64)
 | 
			
		||||
  use_clang := false
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(use_clang),)
 | 
			
		||||
  use_clang := false
 | 
			
		||||
endif
 | 
			
		||||
@@ -652,7 +665,7 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -693,7 +706,7 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -739,7 +752,7 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -772,7 +785,7 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -807,7 +820,7 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -848,7 +861,7 @@ LOCAL_MODULE := libc_openbsd_ndk
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -886,7 +899,7 @@ LOCAL_MODULE := libc_openbsd
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -924,7 +937,7 @@ LOCAL_MODULE := libc_gdtoa
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -941,13 +954,6 @@ 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) -Wold-style-cast
 | 
			
		||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
 | 
			
		||||
@@ -956,10 +962,11 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_src_files))
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -975,13 +982,6 @@ LOCAL_SRC_FILES := $(libc_bionic_ndk_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) -Wold-style-cast
 | 
			
		||||
LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
 | 
			
		||||
@@ -990,11 +990,11 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
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))
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_ndk_src_files))
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
 | 
			
		||||
include $(CLEAR_VARS)
 | 
			
		||||
@@ -1011,7 +1011,7 @@ LOCAL_CLANG := false
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
@@ -1030,13 +1030,6 @@ LOCAL_SRC_FILES := $(libc_pthread_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) -Wold-style-cast
 | 
			
		||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
 | 
			
		||||
@@ -1045,7 +1038,7 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
@@ -1069,7 +1062,7 @@ LOCAL_CLANG := true # GCC refuses to hide new/delete
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
# b/17574078: Need to disable coverage until we have a prebuilt libprofile_rt.
 | 
			
		||||
# Since this is a static library built with clang, it needs to link
 | 
			
		||||
# libprofile_rt when it is linked into the final binary. Since the final binary
 | 
			
		||||
@@ -1097,7 +1090,7 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
@@ -1119,7 +1112,7 @@ 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_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
@@ -1145,7 +1138,7 @@ LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 | 
			
		||||
LOCAL_CFLAGS := $(libc_common_cflags) -fvisibility=hidden -O0
 | 
			
		||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
 | 
			
		||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
 | 
			
		||||
@@ -1229,7 +1222,7 @@ LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
 | 
			
		||||
# TODO: split out the asflags.
 | 
			
		||||
LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -1267,7 +1260,7 @@ 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_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -1290,7 +1283,7 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
 | 
			
		||||
LOCAL_MODULE := libc_malloc
 | 
			
		||||
LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
@@ -1323,7 +1316,7 @@ endif
 | 
			
		||||
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -1355,12 +1348,15 @@ LOCAL_CLANG := $(use_clang)
 | 
			
		||||
LOCAL_REQUIRED_MODULES := tzdata
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := \
 | 
			
		||||
    $(libc_common_additional_dependencies) \
 | 
			
		||||
    $(LOCAL_PATH)/version_script.txt \
 | 
			
		||||
    $(LOCAL_PATH)/libc.map \
 | 
			
		||||
 | 
			
		||||
# Leave the symbols in the shared library so that stack unwinders can produce
 | 
			
		||||
# meaningful name resolution.
 | 
			
		||||
LOCAL_STRIP_MODULE := keep_symbols
 | 
			
		||||
 | 
			
		||||
# Do not pack libc.so relocations; see http://b/20645321 for details.
 | 
			
		||||
LOCAL_PACK_MODULE_RELOCATIONS := false
 | 
			
		||||
 | 
			
		||||
# WARNING: The only library libc.so should depend on is libdl.so!  If you add other libraries,
 | 
			
		||||
# make sure to add -Wl,--exclude-libs=libgcc.a to the LOCAL_LDFLAGS for those libraries.  This
 | 
			
		||||
# ensures that symbols that are pulled into those new libraries from libgcc.a are not declared
 | 
			
		||||
@@ -1380,16 +1376,16 @@ LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES :=
 | 
			
		||||
 | 
			
		||||
# Don't re-export new/delete and friends, even if the compiler really wants to.
 | 
			
		||||
LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/version_script.txt
 | 
			
		||||
LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/libc.map
 | 
			
		||||
 | 
			
		||||
# We'd really like to do this for all architectures, but since this wasn't done
 | 
			
		||||
# before, these symbols must continue to be exported on LP32 for binary
 | 
			
		||||
# compatibility.
 | 
			
		||||
# TODO: disabled for http://b/20065774.
 | 
			
		||||
#LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
 | 
			
		||||
LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
 | 
			
		||||
 | 
			
		||||
# TODO: This is to work around b/19059885. Remove after root cause is fixed
 | 
			
		||||
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
 | 
			
		||||
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 | 
			
		||||
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_dynamic_src_files))
 | 
			
		||||
@@ -1402,7 +1398,7 @@ LOCAL_CFLAGS_arm += -DCRT_LEGACY_WORKAROUND
 | 
			
		||||
LOCAL_SRC_FILES_arm += \
 | 
			
		||||
    arch-arm/bionic/atexit_legacy.c
 | 
			
		||||
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
include $(BUILD_SHARED_LIBRARY)
 | 
			
		||||
@@ -1456,7 +1452,7 @@ LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/version_script.txt
 | 
			
		||||
 | 
			
		||||
# Don't install on release build
 | 
			
		||||
LOCAL_MODULE_TAGS := eng debug
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -1496,7 +1492,7 @@ LOCAL_LDFLAGS := -Wl,--version-script,$(LOCAL_PATH)/version_script.txt
 | 
			
		||||
 | 
			
		||||
# Don't install on release build
 | 
			
		||||
LOCAL_MODULE_TAGS := eng debug
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
 | 
			
		||||
$(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 | 
			
		||||
@@ -1519,14 +1515,15 @@ LOCAL_CFLAGS := $(libc_common_cflags)
 | 
			
		||||
LOCAL_CPPFLAGS := $(libc_common_cppflags)
 | 
			
		||||
 | 
			
		||||
# TODO: This is to work around b/19059885. Remove after root cause is fixed
 | 
			
		||||
LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
 | 
			
		||||
LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 | 
			
		||||
LOCAL_LDFLAGS_x86 := -Wl,--hash-style=both
 | 
			
		||||
 | 
			
		||||
LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
 | 
			
		||||
LOCAL_MODULE:= libstdc++
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
include $(BUILD_SHARED_LIBRARY)
 | 
			
		||||
 | 
			
		||||
@@ -1542,7 +1539,7 @@ LOCAL_MODULE:= libstdc++
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 | 
			
		||||
LOCAL_CXX_STL := none
 | 
			
		||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
 | 
			
		||||
LOCAL_ADDRESS_SANITIZER := false
 | 
			
		||||
LOCAL_SANITIZE := never
 | 
			
		||||
LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 | 
			
		||||
include $(BUILD_STATIC_LIBRARY)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										156
									
								
								libc/NOTICE
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								libc/NOTICE
									
									
									
									
									
								
							@@ -307,34 +307,6 @@ SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2008-2010 The Android Open Source Project
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions
 | 
			
		||||
are met:
 | 
			
		||||
 * Redistributions of source code must retain the above copyright
 | 
			
		||||
   notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
   notice, this list of conditions and the following disclaimer in
 | 
			
		||||
   the documentation and/or other materials provided with the
 | 
			
		||||
   distribution.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | 
			
		||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 | 
			
		||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 | 
			
		||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2009 The Android Open Source Project
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
@@ -454,22 +426,6 @@ Android adaptation and tweak by Jim Huang <jserv@0xlab.org>.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2011 The Android Open Source Project
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2011 The Android Open Source Project
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
@@ -688,6 +644,50 @@ SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015 The Android Open Source Project
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015 The Android Open Source Project
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions
 | 
			
		||||
are met:
 | 
			
		||||
 * Redistributions of source code must retain the above copyright
 | 
			
		||||
   notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
   notice, this list of conditions and the following disclaimer in
 | 
			
		||||
   the documentation and/or other materials provided with the
 | 
			
		||||
   distribution.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | 
			
		||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 | 
			
		||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 | 
			
		||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 1980, 1983, 1988, 1993
 | 
			
		||||
   The Regents of the University of California.  All rights reserved.
 | 
			
		||||
 | 
			
		||||
@@ -2550,33 +2550,6 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 1995, 1996 Carnegie-Mellon University.
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Author: Chris G. Demetriou
 | 
			
		||||
 | 
			
		||||
Permission to use, copy, modify and distribute this software and
 | 
			
		||||
its documentation is hereby granted, provided that both the copyright
 | 
			
		||||
notice and this permission notice appear in all copies of the
 | 
			
		||||
software, derivative works or modified versions, and any portions
 | 
			
		||||
thereof, and that both notices appear in supporting documentation.
 | 
			
		||||
 | 
			
		||||
CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 | 
			
		||||
CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
 | 
			
		||||
FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 | 
			
		||||
 | 
			
		||||
Carnegie Mellon requests users of this software to return to
 | 
			
		||||
 | 
			
		||||
 Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 | 
			
		||||
 School of Computer Science
 | 
			
		||||
 Carnegie Mellon University
 | 
			
		||||
 Pittsburgh PA 15213-3890
 | 
			
		||||
 | 
			
		||||
any improvements or extensions that they make and grant Carnegie the
 | 
			
		||||
rights to redistribute these changes.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 1996 by Internet Software Consortium.
 | 
			
		||||
 | 
			
		||||
Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
@@ -3795,6 +3768,22 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
 | 
			
		||||
 | 
			
		||||
Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2007-2008  Michael G Schwern
 | 
			
		||||
 | 
			
		||||
This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
 | 
			
		||||
@@ -4733,31 +4722,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright 2000 David E. O'Brien, John D. Polstra.
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions
 | 
			
		||||
are met:
 | 
			
		||||
1. Redistributions of source code must retain the above copyright
 | 
			
		||||
   notice, this list of conditions and the following disclaimer.
 | 
			
		||||
2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
   notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
   documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 | 
			
		||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
			
		||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
			
		||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
			
		||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
			
		||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright 2008  Android Open Source Project (source port randomization)
 | 
			
		||||
Copyright (c) 1985, 1989, 1993
 | 
			
		||||
   The Regents of the University of California.  All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
@@ -122,9 +122,9 @@ int         fdatasync(int) all
 | 
			
		||||
int         fchown:fchown32(int, uid_t, gid_t)  arm,x86
 | 
			
		||||
int         fchown:fchown(int, uid_t, gid_t)    arm64,mips,mips64,x86_64
 | 
			
		||||
void        sync(void)  all
 | 
			
		||||
int         fsetxattr(int, const char*, const void*, size_t, int) all
 | 
			
		||||
ssize_t     fgetxattr(int, const char*, void*, size_t) all
 | 
			
		||||
ssize_t     flistxattr(int, char*, size_t) all
 | 
			
		||||
int         ___fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all
 | 
			
		||||
ssize_t     ___fgetxattr:fgetxattr(int, const char*, void*, size_t) all
 | 
			
		||||
ssize_t     ___flistxattr:flistxattr(int, char*, size_t) all
 | 
			
		||||
int         fremovexattr(int, const char*) all
 | 
			
		||||
 | 
			
		||||
int __getdents64:getdents64(unsigned int, struct dirent*, unsigned int)   arm,arm64,mips,mips64,x86,x86_64
 | 
			
		||||
@@ -151,7 +151,6 @@ int utimensat(int, const char*, const struct timespec times[2], int)  all
 | 
			
		||||
off_t lseek(int, off_t, int) arm,mips,x86
 | 
			
		||||
int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86
 | 
			
		||||
off_t lseek|lseek64(int, off_t, int) arm64,mips64,x86_64
 | 
			
		||||
int ftruncate(int, off_t) arm,mips,x86
 | 
			
		||||
int ftruncate64(int, off64_t) arm,mips,x86
 | 
			
		||||
int ftruncate|ftruncate64(int, off_t) arm64,mips64,x86_64
 | 
			
		||||
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) arm,mips,x86
 | 
			
		||||
@@ -204,7 +203,7 @@ clock_t       times(struct tms*)       all
 | 
			
		||||
int           nanosleep(const struct timespec*, struct timespec*)   all
 | 
			
		||||
int           clock_settime(clockid_t, const struct timespec*)  all
 | 
			
		||||
int           clock_getres(clockid_t, struct timespec*)   all
 | 
			
		||||
int           __clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*)  all
 | 
			
		||||
int           ___clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*)  all
 | 
			
		||||
int           getitimer(int, const struct itimerval*)   all
 | 
			
		||||
int           setitimer(int, const struct itimerval*, struct itimerval*)  all
 | 
			
		||||
int           __timer_create:timer_create(clockid_t clockid, struct sigevent* evp, __kernel_timer_t* timerid)    all
 | 
			
		||||
@@ -223,7 +222,7 @@ int     __rt_sigpending:rt_sigpending(sigset_t*, size_t)  all
 | 
			
		||||
int     __rt_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t)  all
 | 
			
		||||
int     __rt_sigsuspend:rt_sigsuspend(const sigset_t*, size_t)  all
 | 
			
		||||
int     __rt_sigtimedwait:rt_sigtimedwait(const sigset_t*, struct siginfo_t*, struct timespec_t*, size_t)  all
 | 
			
		||||
int     __rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*)  all
 | 
			
		||||
int     ___rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*)  all
 | 
			
		||||
int     __signalfd4:signalfd4(int, const sigset_t*, size_t, int)  all
 | 
			
		||||
 | 
			
		||||
# sockets
 | 
			
		||||
@@ -309,6 +308,9 @@ int inotify_rm_watch(int, unsigned int)  all
 | 
			
		||||
int __pselect6:pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*)  all
 | 
			
		||||
int __ppoll:ppoll(pollfd*, unsigned int, timespec*, const sigset_t*, size_t)  all
 | 
			
		||||
 | 
			
		||||
ssize_t process_vm_readv(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long)  all
 | 
			
		||||
ssize_t process_vm_writev(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long)  all
 | 
			
		||||
 | 
			
		||||
int __set_tid_address:set_tid_address(int*)  all
 | 
			
		||||
 | 
			
		||||
int setfsgid(gid_t)  all
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008-2010 The Android Open Source Project
 | 
			
		||||
 * Copyright (C) 2008 The Android Open Source Project
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								libc/arch-arm/cortex-a53/cortex-a53.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libc/arch-arm/cortex-a53/cortex-a53.mk
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
include bionic/libc/arch-arm/cortex-a7/cortex-a7.mk
 | 
			
		||||
@@ -44,7 +44,7 @@ ENTRY_PRIVATE(MEMCPY_BASE)
 | 
			
		||||
        /* check if buffers are aligned. If so, run arm-only version */
 | 
			
		||||
        eor         r3, r0, r1
 | 
			
		||||
        ands        r3, r3, #0x3
 | 
			
		||||
        beq         __memcpy_base_aligned
 | 
			
		||||
        beq         MEMCPY_BASE_ALIGNED
 | 
			
		||||
 | 
			
		||||
        /* Check the upper size limit for Neon unaligned memory access in memcpy */
 | 
			
		||||
        cmp         r2, #224
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
    .fpu    neon
 | 
			
		||||
    .syntax unified
 | 
			
		||||
 | 
			
		||||
ENTRY(__memset_chk)
 | 
			
		||||
        cmp         r2, r3
 | 
			
		||||
@@ -100,9 +101,9 @@ ENTRY(memset)
 | 
			
		||||
1:      bge         2f
 | 
			
		||||
        vst1.32     {d0[0]}, [r0]!
 | 
			
		||||
2:      movs        ip, r2, lsl #31
 | 
			
		||||
        strmib      r1, [r0], #1
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        strbmi      r1, [r0], #1
 | 
			
		||||
        strbcs      r1, [r0], #1
 | 
			
		||||
        strbcs      r1, [r0], #1
 | 
			
		||||
        ldmfd       sp!, {r0}
 | 
			
		||||
        bx          lr
 | 
			
		||||
END(memset)
 | 
			
		||||
@@ -131,11 +132,11 @@ ENTRY_PRIVATE(__memset_large_copy)
 | 
			
		||||
        orr         r1, r1, r1, lsr #16
 | 
			
		||||
 | 
			
		||||
        movs        r12, r3, lsl #31
 | 
			
		||||
        strcsb      r1, [r0], #1    /* can't use strh (alignment unknown) */
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        strmib      r1, [r0], #1
 | 
			
		||||
        strbcs      r1, [r0], #1    /* can't use strh (alignment unknown) */
 | 
			
		||||
        strbcs      r1, [r0], #1
 | 
			
		||||
        strbmi      r1, [r0], #1
 | 
			
		||||
        subs        r2, r2, r3
 | 
			
		||||
        ldmlsfd     sp!, {r0, r4-r7, lr}   /* return */
 | 
			
		||||
        popls       {r0, r4-r7, lr}   /* return */
 | 
			
		||||
        bxls        lr
 | 
			
		||||
 | 
			
		||||
        /* align the destination to a cache-line */
 | 
			
		||||
@@ -155,9 +156,9 @@ ENTRY_PRIVATE(__memset_large_copy)
 | 
			
		||||
 | 
			
		||||
        /* conditionally writes 0 to 7 words (length in r3) */
 | 
			
		||||
        movs        r3, r3, lsl #28
 | 
			
		||||
        stmcsia     r0!, {r1, lr}
 | 
			
		||||
        stmcsia     r0!, {r1, lr}
 | 
			
		||||
        stmmiia     r0!, {r1, lr}
 | 
			
		||||
        stmcs       r0!, {r1, lr}
 | 
			
		||||
        stmcs       r0!, {r1, lr}
 | 
			
		||||
        stmmi       r0!, {r1, lr}
 | 
			
		||||
        movs        r3, r3, lsl #2
 | 
			
		||||
        strcs       r1, [r0], #4
 | 
			
		||||
 | 
			
		||||
@@ -172,13 +173,13 @@ ENTRY_PRIVATE(__memset_large_copy)
 | 
			
		||||
 | 
			
		||||
        /* conditionally stores 0 to 31 bytes */
 | 
			
		||||
        movs        r2, r2, lsl #28
 | 
			
		||||
        stmcsia     r0!, {r1,r3,r12,lr}
 | 
			
		||||
        stmmiia     r0!, {r1, lr}
 | 
			
		||||
        stmcs       r0!, {r1,r3,r12,lr}
 | 
			
		||||
        stmmi       r0!, {r1, lr}
 | 
			
		||||
        movs        r2, r2, lsl #2
 | 
			
		||||
        strcs       r1, [r0], #4
 | 
			
		||||
        strmih      r1, [r0], #2
 | 
			
		||||
        strhmi      r1, [r0], #2
 | 
			
		||||
        movs        r2, r2, lsl #2
 | 
			
		||||
        strcsb      r1, [r0]
 | 
			
		||||
        strbcs      r1, [r0]
 | 
			
		||||
        ldmfd       sp!, {r0, r4-r7, lr}
 | 
			
		||||
        bx          lr
 | 
			
		||||
END(__memset_large_copy)
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,8 @@
 | 
			
		||||
 * Optimized memcmp() for Cortex-A9.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.syntax unified
 | 
			
		||||
 | 
			
		||||
ENTRY(memcmp)
 | 
			
		||||
        pld         [r0, #(CACHE_LINE_SIZE * 0)]
 | 
			
		||||
        pld         [r0, #(CACHE_LINE_SIZE * 1)]
 | 
			
		||||
@@ -161,25 +163,25 @@ ENTRY(memcmp)
 | 
			
		||||
        eors        r0, r0, ip
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        ldreq       ip, [r1, #4]!
 | 
			
		||||
        eoreqs      r0, r0, lr
 | 
			
		||||
        eorseq      r0, r0, lr
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        ldreq       lr, [r1, #4]!
 | 
			
		||||
        eoreqs      r0, r0, ip
 | 
			
		||||
        eorseq      r0, r0, ip
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        ldreq       ip, [r1, #4]!
 | 
			
		||||
        eoreqs      r0, r0, lr
 | 
			
		||||
        eorseq      r0, r0, lr
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        ldreq       lr, [r1, #4]!
 | 
			
		||||
        eoreqs      r0, r0, ip
 | 
			
		||||
        eorseq      r0, r0, ip
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        ldreq       ip, [r1, #4]!
 | 
			
		||||
        eoreqs      r0, r0, lr
 | 
			
		||||
        eorseq      r0, r0, lr
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        ldreq       lr, [r1, #4]!
 | 
			
		||||
        eoreqs      r0, r0, ip
 | 
			
		||||
        eorseq      r0, r0, ip
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        ldreq       ip, [r1, #4]!
 | 
			
		||||
        eoreqs      r0, r0, lr
 | 
			
		||||
        eorseq      r0, r0, lr
 | 
			
		||||
        bne         2f
 | 
			
		||||
        subs        r2, r2, #32
 | 
			
		||||
        bhs         0b
 | 
			
		||||
@@ -263,17 +265,17 @@ ENTRY(memcmp)
 | 
			
		||||
        ldreq       lr, [r1], #4
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        orreq       ip, ip, lr, lsl #16
 | 
			
		||||
        eoreqs      r0, r0, ip
 | 
			
		||||
        eorseq      r0, r0, ip
 | 
			
		||||
        moveq       ip, lr, lsr #16
 | 
			
		||||
        ldreq       lr, [r1], #4
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        orreq       ip, ip, lr, lsl #16
 | 
			
		||||
        eoreqs      r0, r0, ip
 | 
			
		||||
        eorseq      r0, r0, ip
 | 
			
		||||
        moveq       ip, lr, lsr #16
 | 
			
		||||
        ldreq       lr, [r1], #4
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        orreq       ip, ip, lr, lsl #16
 | 
			
		||||
        eoreqs      r0, r0, ip
 | 
			
		||||
        eorseq      r0, r0, ip
 | 
			
		||||
        bne         7f
 | 
			
		||||
        subs        r2, r2, #16
 | 
			
		||||
        bhs         6b
 | 
			
		||||
@@ -317,7 +319,7 @@ ENTRY(memcmp)
 | 
			
		||||
        ldreq       r7, [r1], #4
 | 
			
		||||
        ldreq       r0, [r4], #4
 | 
			
		||||
        orreq       ip, ip, r7, lsl r6
 | 
			
		||||
        eoreqs      r0, r0, ip
 | 
			
		||||
        eorseq      r0, r0, ip
 | 
			
		||||
        bne         7f
 | 
			
		||||
        subs        r2, r2, #8
 | 
			
		||||
        bhs         6b
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,8 @@
 | 
			
		||||
         * so we have to preserve R0.
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
         .syntax unified
 | 
			
		||||
 | 
			
		||||
ENTRY(__memcpy_chk)
 | 
			
		||||
        cmp         r2, r3
 | 
			
		||||
        bhi         __memcpy_chk_fail
 | 
			
		||||
@@ -81,12 +83,12 @@ ENTRY(memcpy)
 | 
			
		||||
         */
 | 
			
		||||
        movs        r12, r3, lsl #31
 | 
			
		||||
        sub         r2, r2, r3      /* we know that r3 <= r2 because r2 >= 4 */
 | 
			
		||||
        ldrmib      r3, [r1], #1
 | 
			
		||||
        ldrcsb      r4, [r1], #1
 | 
			
		||||
        ldrcsb      r12,[r1], #1
 | 
			
		||||
        strmib      r3, [r0], #1
 | 
			
		||||
        strcsb      r4, [r0], #1
 | 
			
		||||
        strcsb      r12,[r0], #1
 | 
			
		||||
        ldrbmi      r3, [r1], #1
 | 
			
		||||
        ldrbcs      r4, [r1], #1
 | 
			
		||||
        ldrbcs      r12,[r1], #1
 | 
			
		||||
        strbmi      r3, [r0], #1
 | 
			
		||||
        strbcs      r4, [r0], #1
 | 
			
		||||
        strbcs      r12,[r0], #1
 | 
			
		||||
 | 
			
		||||
.Lsrc_aligned:
 | 
			
		||||
 | 
			
		||||
@@ -109,10 +111,10 @@ ENTRY(memcpy)
 | 
			
		||||
 | 
			
		||||
        /* conditionally copies 0 to 7 words (length in r3) */
 | 
			
		||||
        movs        r12, r3, lsl #28
 | 
			
		||||
        ldmcsia     r1!, {r4, r5, r6, r7}   /* 16 bytes */
 | 
			
		||||
        ldmmiia     r1!, {r8, r9}           /*  8 bytes */
 | 
			
		||||
        stmcsia     r0!, {r4, r5, r6, r7}
 | 
			
		||||
        stmmiia     r0!, {r8, r9}
 | 
			
		||||
        ldmcs       r1!, {r4, r5, r6, r7}   /* 16 bytes */
 | 
			
		||||
        ldmmi       r1!, {r8, r9}           /*  8 bytes */
 | 
			
		||||
        stmcs       r0!, {r4, r5, r6, r7}
 | 
			
		||||
        stmmi       r0!, {r8, r9}
 | 
			
		||||
        tst         r3, #0x4
 | 
			
		||||
        ldrne       r10,[r1], #4            /*  4 bytes */
 | 
			
		||||
        strne       r10,[r0], #4
 | 
			
		||||
@@ -177,18 +179,18 @@ ENTRY(memcpy)
 | 
			
		||||
 | 
			
		||||
        /* conditionnaly copies 0 to 31 bytes */
 | 
			
		||||
        movs        r12, r2, lsl #28
 | 
			
		||||
        ldmcsia     r1!, {r4, r5, r6, r7}   /* 16 bytes */
 | 
			
		||||
        ldmmiia     r1!, {r8, r9}           /*  8 bytes */
 | 
			
		||||
        stmcsia     r0!, {r4, r5, r6, r7}
 | 
			
		||||
        stmmiia     r0!, {r8, r9}
 | 
			
		||||
        ldmcs       r1!, {r4, r5, r6, r7}   /* 16 bytes */
 | 
			
		||||
        ldmmi       r1!, {r8, r9}           /*  8 bytes */
 | 
			
		||||
        stmcs       r0!, {r4, r5, r6, r7}
 | 
			
		||||
        stmmi       r0!, {r8, r9}
 | 
			
		||||
        movs        r12, r2, lsl #30
 | 
			
		||||
        ldrcs       r3, [r1], #4            /*  4 bytes */
 | 
			
		||||
        ldrmih      r4, [r1], #2            /*  2 bytes */
 | 
			
		||||
        ldrhmi      r4, [r1], #2            /*  2 bytes */
 | 
			
		||||
        strcs       r3, [r0], #4
 | 
			
		||||
        strmih      r4, [r0], #2
 | 
			
		||||
        strhmi      r4, [r0], #2
 | 
			
		||||
        tst         r2, #0x1
 | 
			
		||||
        ldrneb      r3, [r1]                /*  last byte  */
 | 
			
		||||
        strneb      r3, [r0]
 | 
			
		||||
        ldrbne      r3, [r1]                /*  last byte  */
 | 
			
		||||
        strbne      r3, [r0]
 | 
			
		||||
 | 
			
		||||
        /* we're done! restore everything and return */
 | 
			
		||||
1:      ldmfd       sp!, {r5-r11}
 | 
			
		||||
@@ -228,11 +230,11 @@ ENTRY(memcpy)
 | 
			
		||||
         * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
 | 
			
		||||
         */
 | 
			
		||||
        movs        r5, r5, lsl #31
 | 
			
		||||
        strmib      r3, [r0], #1
 | 
			
		||||
        strbmi      r3, [r0], #1
 | 
			
		||||
        movmi       r3, r3, lsr #8
 | 
			
		||||
        strcsb      r3, [r0], #1
 | 
			
		||||
        strbcs      r3, [r0], #1
 | 
			
		||||
        movcs       r3, r3, lsr #8
 | 
			
		||||
        strcsb      r3, [r0], #1
 | 
			
		||||
        strbcs      r3, [r0], #1
 | 
			
		||||
        movcs       r3, r3, lsr #8
 | 
			
		||||
 | 
			
		||||
        cmp         r2, #4
 | 
			
		||||
@@ -363,23 +365,23 @@ ENTRY(memcpy)
 | 
			
		||||
.Lpartial_word_tail:
 | 
			
		||||
        /* we have a partial word in the input buffer */
 | 
			
		||||
        movs        r5, lr, lsl #(31-3)
 | 
			
		||||
        strmib      r3, [r0], #1
 | 
			
		||||
        strbmi      r3, [r0], #1
 | 
			
		||||
        movmi       r3, r3, lsr #8
 | 
			
		||||
        strcsb      r3, [r0], #1
 | 
			
		||||
        strbcs      r3, [r0], #1
 | 
			
		||||
        movcs       r3, r3, lsr #8
 | 
			
		||||
        strcsb      r3, [r0], #1
 | 
			
		||||
        strbcs      r3, [r0], #1
 | 
			
		||||
 | 
			
		||||
        /* Refill spilled registers from the stack. Don't update sp. */
 | 
			
		||||
        ldmfd       sp, {r5-r11}
 | 
			
		||||
 | 
			
		||||
.Lcopy_last_3_and_return:
 | 
			
		||||
        movs        r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
 | 
			
		||||
        ldrmib      r2, [r1], #1
 | 
			
		||||
        ldrcsb      r3, [r1], #1
 | 
			
		||||
        ldrcsb      r12,[r1]
 | 
			
		||||
        strmib      r2, [r0], #1
 | 
			
		||||
        strcsb      r3, [r0], #1
 | 
			
		||||
        strcsb      r12,[r0]
 | 
			
		||||
        ldrbmi      r2, [r1], #1
 | 
			
		||||
        ldrbcs      r3, [r1], #1
 | 
			
		||||
        ldrbcs      r12,[r1]
 | 
			
		||||
        strbmi      r2, [r0], #1
 | 
			
		||||
        strbcs      r3, [r0], #1
 | 
			
		||||
        strbcs      r12,[r0]
 | 
			
		||||
 | 
			
		||||
        /* we're done! restore sp and spilled registers and return */
 | 
			
		||||
        add         sp,  sp, #28
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,8 @@
 | 
			
		||||
         * memset() returns its first argument.
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
         .syntax unified
 | 
			
		||||
 | 
			
		||||
ENTRY(__memset_chk)
 | 
			
		||||
        cmp         r2, r3
 | 
			
		||||
        bls         done
 | 
			
		||||
@@ -76,11 +78,11 @@ ENTRY(memset)
 | 
			
		||||
        orr         r1, r1, r1, lsr #16
 | 
			
		||||
 | 
			
		||||
        movs        r12, r3, lsl #31
 | 
			
		||||
        strcsb      r1, [r0], #1    /* can't use strh (alignment unknown) */
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        strmib      r1, [r0], #1
 | 
			
		||||
        strbcs      r1, [r0], #1    /* can't use strh (alignment unknown) */
 | 
			
		||||
        strbcs      r1, [r0], #1
 | 
			
		||||
        strbmi      r1, [r0], #1
 | 
			
		||||
        subs        r2, r2, r3
 | 
			
		||||
        ldmlsfd     sp!, {r0, r4-r7, lr}    /* return */
 | 
			
		||||
        popls       {r0, r4-r7, lr}    /* return */
 | 
			
		||||
        bxls        lr
 | 
			
		||||
 | 
			
		||||
        /* align the destination to a cache-line */
 | 
			
		||||
@@ -100,9 +102,9 @@ ENTRY(memset)
 | 
			
		||||
 | 
			
		||||
        /* conditionally writes 0 to 7 words (length in r3) */
 | 
			
		||||
        movs        r3, r3, lsl #28
 | 
			
		||||
        stmcsia     r0!, {r1, lr}
 | 
			
		||||
        stmcsia     r0!, {r1, lr}
 | 
			
		||||
        stmmiia     r0!, {r1, lr}
 | 
			
		||||
        stmcs       r0!, {r1, lr}
 | 
			
		||||
        stmcs       r0!, {r1, lr}
 | 
			
		||||
        stmmi       r0!, {r1, lr}
 | 
			
		||||
        movs        r3, r3, lsl #2
 | 
			
		||||
        strcs       r1, [r0], #4
 | 
			
		||||
 | 
			
		||||
@@ -117,13 +119,13 @@ ENTRY(memset)
 | 
			
		||||
 | 
			
		||||
        /* conditionally stores 0 to 31 bytes */
 | 
			
		||||
        movs        r2, r2, lsl #28
 | 
			
		||||
        stmcsia     r0!, {r1,r3,r12,lr}
 | 
			
		||||
        stmmiia     r0!, {r1, lr}
 | 
			
		||||
        stmcs       r0!, {r1,r3,r12,lr}
 | 
			
		||||
        stmmi       r0!, {r1, lr}
 | 
			
		||||
        movs        r2, r2, lsl #2
 | 
			
		||||
        strcs       r1, [r0], #4
 | 
			
		||||
        strmih      r1, [r0], #2
 | 
			
		||||
        strhmi      r1, [r0], #2
 | 
			
		||||
        movs        r2, r2, lsl #2
 | 
			
		||||
        strcsb      r1, [r0]
 | 
			
		||||
        strbcs      r1, [r0]
 | 
			
		||||
        ldmfd       sp!, {r0, r4-r7, lr}
 | 
			
		||||
        bx          lr
 | 
			
		||||
END(memset)
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,8 @@
 | 
			
		||||
#include <machine/cpu-features.h>
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
.syntax unified
 | 
			
		||||
 | 
			
		||||
ENTRY(strcpy)
 | 
			
		||||
	pld	[r1, #0]
 | 
			
		||||
	eor	r2, r0, r1
 | 
			
		||||
@@ -108,15 +110,15 @@ ENTRY(strcpy)
 | 
			
		||||
#ifdef __ARMEB__
 | 
			
		||||
	tst	r2, #0xff00
 | 
			
		||||
	iteet	ne
 | 
			
		||||
	strneh	r2, [ip], #2
 | 
			
		||||
	strhne	r2, [ip], #2
 | 
			
		||||
	lsreq	r2, r2, #8
 | 
			
		||||
	streqb	r2, [ip]
 | 
			
		||||
	strbeq	r2, [ip]
 | 
			
		||||
	tstne	r2, #0xff
 | 
			
		||||
#else
 | 
			
		||||
	tst	r2, #0xff
 | 
			
		||||
	itet	ne
 | 
			
		||||
	strneh	r2, [ip], #2
 | 
			
		||||
	streqb	r2, [ip]
 | 
			
		||||
	strhne	r2, [ip], #2
 | 
			
		||||
	strbeq	r2, [ip]
 | 
			
		||||
	tstne	r2, #0xff00
 | 
			
		||||
#endif
 | 
			
		||||
	bne	5b
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
    .fpu    neon
 | 
			
		||||
    .syntax unified
 | 
			
		||||
 | 
			
		||||
ENTRY(__memset_chk)
 | 
			
		||||
        cmp         r2, r3
 | 
			
		||||
@@ -98,9 +99,9 @@ ENTRY(memset)
 | 
			
		||||
1:      bge         2f
 | 
			
		||||
        vst1.32     {d0[0]}, [r0]!
 | 
			
		||||
2:      movs        ip, r2, lsl #31
 | 
			
		||||
        strmib      r1, [r0], #1
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        strbmi      r1, [r0], #1
 | 
			
		||||
        strbcs      r1, [r0], #1
 | 
			
		||||
        strbcs      r1, [r0], #1
 | 
			
		||||
        ldmfd       sp!, {r0}
 | 
			
		||||
        bx          lr
 | 
			
		||||
END(memset)
 | 
			
		||||
 
 | 
			
		||||
@@ -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,5 @@ ENTRY(__clock_nanosleep)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno_internal
 | 
			
		||||
END(__clock_nanosleep)
 | 
			
		||||
END(___clock_nanosleep)
 | 
			
		||||
.hidden ___clock_nanosleep
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fgetxattr)
 | 
			
		||||
ENTRY(___fgetxattr)
 | 
			
		||||
    mov     ip, r7
 | 
			
		||||
    ldr     r7, =__NR_fgetxattr
 | 
			
		||||
    swi     #0
 | 
			
		||||
@@ -11,4 +11,5 @@ ENTRY(fgetxattr)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno_internal
 | 
			
		||||
END(fgetxattr)
 | 
			
		||||
END(___fgetxattr)
 | 
			
		||||
.hidden ___fgetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(flistxattr)
 | 
			
		||||
ENTRY(___flistxattr)
 | 
			
		||||
    mov     ip, r7
 | 
			
		||||
    ldr     r7, =__NR_flistxattr
 | 
			
		||||
    swi     #0
 | 
			
		||||
@@ -11,4 +11,5 @@ ENTRY(flistxattr)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno_internal
 | 
			
		||||
END(flistxattr)
 | 
			
		||||
END(___flistxattr)
 | 
			
		||||
.hidden ___flistxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fsetxattr)
 | 
			
		||||
ENTRY(___fsetxattr)
 | 
			
		||||
    mov     ip, sp
 | 
			
		||||
    stmfd   sp!, {r4, r5, r6, r7}
 | 
			
		||||
    .cfi_def_cfa_offset 16
 | 
			
		||||
@@ -19,4 +19,5 @@ ENTRY(fsetxattr)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno_internal
 | 
			
		||||
END(fsetxattr)
 | 
			
		||||
END(___fsetxattr)
 | 
			
		||||
.hidden ___fsetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
ENTRY(___rt_sigqueueinfo)
 | 
			
		||||
    mov     ip, r7
 | 
			
		||||
    ldr     r7, =__NR_rt_sigqueueinfo
 | 
			
		||||
    swi     #0
 | 
			
		||||
@@ -11,4 +11,5 @@ ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno_internal
 | 
			
		||||
END(__rt_sigqueueinfo)
 | 
			
		||||
END(___rt_sigqueueinfo)
 | 
			
		||||
.hidden ___rt_sigqueueinfo
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(ftruncate)
 | 
			
		||||
    mov     ip, r7
 | 
			
		||||
    ldr     r7, =__NR_ftruncate
 | 
			
		||||
    swi     #0
 | 
			
		||||
    mov     r7, ip
 | 
			
		||||
    cmn     r0, #(MAX_ERRNO + 1)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno_internal
 | 
			
		||||
END(ftruncate)
 | 
			
		||||
							
								
								
									
										22
									
								
								libc/arch-arm/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								libc/arch-arm/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_readv)
 | 
			
		||||
    mov     ip, sp
 | 
			
		||||
    stmfd   sp!, {r4, r5, r6, r7}
 | 
			
		||||
    .cfi_def_cfa_offset 16
 | 
			
		||||
    .cfi_rel_offset r4, 0
 | 
			
		||||
    .cfi_rel_offset r5, 4
 | 
			
		||||
    .cfi_rel_offset r6, 8
 | 
			
		||||
    .cfi_rel_offset r7, 12
 | 
			
		||||
    ldmfd   ip, {r4, r5, r6}
 | 
			
		||||
    ldr     r7, =__NR_process_vm_readv
 | 
			
		||||
    swi     #0
 | 
			
		||||
    ldmfd   sp!, {r4, r5, r6, r7}
 | 
			
		||||
    .cfi_def_cfa_offset 0
 | 
			
		||||
    cmn     r0, #(MAX_ERRNO + 1)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno_internal
 | 
			
		||||
END(process_vm_readv)
 | 
			
		||||
							
								
								
									
										22
									
								
								libc/arch-arm/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								libc/arch-arm/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_writev)
 | 
			
		||||
    mov     ip, sp
 | 
			
		||||
    stmfd   sp!, {r4, r5, r6, r7}
 | 
			
		||||
    .cfi_def_cfa_offset 16
 | 
			
		||||
    .cfi_rel_offset r4, 0
 | 
			
		||||
    .cfi_rel_offset r5, 4
 | 
			
		||||
    .cfi_rel_offset r6, 8
 | 
			
		||||
    .cfi_rel_offset r7, 12
 | 
			
		||||
    ldmfd   ip, {r4, r5, r6}
 | 
			
		||||
    ldr     r7, =__NR_process_vm_writev
 | 
			
		||||
    swi     #0
 | 
			
		||||
    ldmfd   sp!, {r4, r5, r6, r7}
 | 
			
		||||
    .cfi_def_cfa_offset 0
 | 
			
		||||
    cmn     r0, #(MAX_ERRNO + 1)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno_internal
 | 
			
		||||
END(process_vm_writev)
 | 
			
		||||
@@ -40,8 +40,6 @@ libc_bionic_src_files_arm64 += \
 | 
			
		||||
    arch-arm64/bionic/syscall.S \
 | 
			
		||||
    arch-arm64/bionic/vfork.S \
 | 
			
		||||
 | 
			
		||||
# Work around for http://b/20065774.
 | 
			
		||||
libc_bionic_src_files_arm64 += arch-arm64/bionic/libgcc_compat.c
 | 
			
		||||
 | 
			
		||||
libc_crt_target_cflags_arm64 := \
 | 
			
		||||
    -I$(LOCAL_PATH)/arch-arm64/include
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
/* STOPSHIP: remove this once the flounder blobs have been rebuilt (http://b/20065774). */
 | 
			
		||||
 | 
			
		||||
#if !defined(__clang__)
 | 
			
		||||
 | 
			
		||||
extern void __clear_cache(char*, char*);
 | 
			
		||||
extern char _Unwind_Backtrace;
 | 
			
		||||
extern char _Unwind_GetIP;
 | 
			
		||||
 | 
			
		||||
void* __bionic_libgcc_compat_symbols[] = {
 | 
			
		||||
    &__clear_cache,
 | 
			
		||||
    &_Unwind_Backtrace,
 | 
			
		||||
    &_Unwind_GetIP,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										1
									
								
								libc/arch-arm64/cortex-a53/cortex-a53.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libc/arch-arm64/cortex-a53/cortex-a53.mk
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
include bionic/libc/arch-arm64/generic/generic.mk
 | 
			
		||||
@@ -101,7 +101,7 @@ ENTRY(memchr)
 | 
			
		||||
	and	vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
 | 
			
		||||
	addp	vend.16b, vhas_chr1.16b, vhas_chr2.16b		/* 256->128 */
 | 
			
		||||
	addp	vend.16b, vend.16b, vend.16b			/* 128->64 */
 | 
			
		||||
	mov	synd, vend.2d[0]
 | 
			
		||||
	mov	synd, vend.d[0]
 | 
			
		||||
	/* Clear the soff*2 lower bits */
 | 
			
		||||
	lsl	tmp, soff, #1
 | 
			
		||||
	lsr	synd, synd, tmp
 | 
			
		||||
@@ -121,7 +121,7 @@ ENTRY(memchr)
 | 
			
		||||
	/* Use a fast check for the termination condition */
 | 
			
		||||
	orr	vend.16b, vhas_chr1.16b, vhas_chr2.16b
 | 
			
		||||
	addp	vend.2d, vend.2d, vend.2d
 | 
			
		||||
	mov	synd, vend.2d[0]
 | 
			
		||||
	mov	synd, vend.d[0]
 | 
			
		||||
	/* We're not out of data, loop if we haven't found the character */
 | 
			
		||||
	cbz	synd, .Lloop
 | 
			
		||||
 | 
			
		||||
@@ -131,7 +131,7 @@ ENTRY(memchr)
 | 
			
		||||
	and	vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
 | 
			
		||||
	addp	vend.16b, vhas_chr1.16b, vhas_chr2.16b		/* 256->128 */
 | 
			
		||||
	addp	vend.16b, vend.16b, vend.16b			/* 128->64 */
 | 
			
		||||
	mov	synd, vend.2d[0]
 | 
			
		||||
	mov	synd, vend.d[0]
 | 
			
		||||
	/* Only do the clear for the last possible block */
 | 
			
		||||
	b.hi	.Ltail
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -109,7 +109,7 @@ ENTRY(strchr)
 | 
			
		||||
	addp	vend1.16b, vend1.16b, vend2.16b		// 128->64
 | 
			
		||||
	lsr	tmp1, tmp3, tmp1
 | 
			
		||||
 | 
			
		||||
	mov	tmp3, vend1.2d[0]
 | 
			
		||||
	mov	tmp3, vend1.d[0]
 | 
			
		||||
	bic	tmp1, tmp3, tmp1	// Mask padding bits.
 | 
			
		||||
	cbnz	tmp1, .Ltail
 | 
			
		||||
 | 
			
		||||
@@ -124,7 +124,7 @@ ENTRY(strchr)
 | 
			
		||||
	orr	vend2.16b, vhas_nul2.16b, vhas_chr2.16b
 | 
			
		||||
	orr	vend1.16b, vend1.16b, vend2.16b
 | 
			
		||||
	addp	vend1.2d, vend1.2d, vend1.2d
 | 
			
		||||
	mov	tmp1, vend1.2d[0]
 | 
			
		||||
	mov	tmp1, vend1.d[0]
 | 
			
		||||
	cbz	tmp1, .Lloop
 | 
			
		||||
 | 
			
		||||
	/* Termination condition found.  Now need to establish exactly why
 | 
			
		||||
@@ -138,7 +138,7 @@ ENTRY(strchr)
 | 
			
		||||
	addp	vend1.16b, vend1.16b, vend2.16b		// 256->128
 | 
			
		||||
	addp	vend1.16b, vend1.16b, vend2.16b		// 128->64
 | 
			
		||||
 | 
			
		||||
	mov	tmp1, vend1.2d[0]
 | 
			
		||||
	mov	tmp1, vend1.d[0]
 | 
			
		||||
.Ltail:
 | 
			
		||||
	/* Count the trailing zeros, by bit reversing...  */
 | 
			
		||||
	rbit	tmp1, tmp1
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__clock_nanosleep)
 | 
			
		||||
ENTRY(___clock_nanosleep)
 | 
			
		||||
    mov     x8, __NR_clock_nanosleep
 | 
			
		||||
    svc     #0
 | 
			
		||||
 | 
			
		||||
@@ -11,5 +11,5 @@ ENTRY(__clock_nanosleep)
 | 
			
		||||
    b.hi    __set_errno_internal
 | 
			
		||||
 | 
			
		||||
    ret
 | 
			
		||||
END(__clock_nanosleep)
 | 
			
		||||
.hidden __clock_nanosleep
 | 
			
		||||
END(___clock_nanosleep)
 | 
			
		||||
.hidden ___clock_nanosleep
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fgetxattr)
 | 
			
		||||
ENTRY(___fgetxattr)
 | 
			
		||||
    mov     x8, __NR_fgetxattr
 | 
			
		||||
    svc     #0
 | 
			
		||||
 | 
			
		||||
@@ -11,4 +11,5 @@ ENTRY(fgetxattr)
 | 
			
		||||
    b.hi    __set_errno_internal
 | 
			
		||||
 | 
			
		||||
    ret
 | 
			
		||||
END(fgetxattr)
 | 
			
		||||
END(___fgetxattr)
 | 
			
		||||
.hidden ___fgetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(flistxattr)
 | 
			
		||||
ENTRY(___flistxattr)
 | 
			
		||||
    mov     x8, __NR_flistxattr
 | 
			
		||||
    svc     #0
 | 
			
		||||
 | 
			
		||||
@@ -11,4 +11,5 @@ ENTRY(flistxattr)
 | 
			
		||||
    b.hi    __set_errno_internal
 | 
			
		||||
 | 
			
		||||
    ret
 | 
			
		||||
END(flistxattr)
 | 
			
		||||
END(___flistxattr)
 | 
			
		||||
.hidden ___flistxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fsetxattr)
 | 
			
		||||
ENTRY(___fsetxattr)
 | 
			
		||||
    mov     x8, __NR_fsetxattr
 | 
			
		||||
    svc     #0
 | 
			
		||||
 | 
			
		||||
@@ -11,4 +11,5 @@ ENTRY(fsetxattr)
 | 
			
		||||
    b.hi    __set_errno_internal
 | 
			
		||||
 | 
			
		||||
    ret
 | 
			
		||||
END(fsetxattr)
 | 
			
		||||
END(___fsetxattr)
 | 
			
		||||
.hidden ___fsetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
ENTRY(___rt_sigqueueinfo)
 | 
			
		||||
    mov     x8, __NR_rt_sigqueueinfo
 | 
			
		||||
    svc     #0
 | 
			
		||||
 | 
			
		||||
@@ -11,5 +11,5 @@ ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
    b.hi    __set_errno_internal
 | 
			
		||||
 | 
			
		||||
    ret
 | 
			
		||||
END(__rt_sigqueueinfo)
 | 
			
		||||
.hidden __rt_sigqueueinfo
 | 
			
		||||
END(___rt_sigqueueinfo)
 | 
			
		||||
.hidden ___rt_sigqueueinfo
 | 
			
		||||
							
								
								
									
										14
									
								
								libc/arch-arm64/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								libc/arch-arm64/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_readv)
 | 
			
		||||
    mov     x8, __NR_process_vm_readv
 | 
			
		||||
    svc     #0
 | 
			
		||||
 | 
			
		||||
    cmn     x0, #(MAX_ERRNO + 1)
 | 
			
		||||
    cneg    x0, x0, hi
 | 
			
		||||
    b.hi    __set_errno_internal
 | 
			
		||||
 | 
			
		||||
    ret
 | 
			
		||||
END(process_vm_readv)
 | 
			
		||||
							
								
								
									
										14
									
								
								libc/arch-arm64/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								libc/arch-arm64/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_writev)
 | 
			
		||||
    mov     x8, __NR_process_vm_writev
 | 
			
		||||
    svc     #0
 | 
			
		||||
 | 
			
		||||
    cmn     x0, #(MAX_ERRNO + 1)
 | 
			
		||||
    cneg    x0, x0, hi
 | 
			
		||||
    b.hi    __set_errno_internal
 | 
			
		||||
 | 
			
		||||
    ret
 | 
			
		||||
END(process_vm_writev)
 | 
			
		||||
@@ -28,9 +28,9 @@
 | 
			
		||||
 | 
			
		||||
#ifdef __LP64__
 | 
			
		||||
# define ASM_PTR_SIZE(x) .quad x
 | 
			
		||||
# define ASM_ALIGN(x)
 | 
			
		||||
# define ASM_ALIGN_TO_PTR_SIZE .balign 8
 | 
			
		||||
#else
 | 
			
		||||
# define ASM_PTR_SIZE(x) .long x
 | 
			
		||||
# define ASM_ALIGN(x)    .align x
 | 
			
		||||
# define ASM_ALIGN_TO_PTR_SIZE .balign 4
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,12 +29,15 @@
 | 
			
		||||
#include "asm_multiarch.h"
 | 
			
		||||
 | 
			
		||||
	.section .preinit_array, "aw"
 | 
			
		||||
	ASM_ALIGN_TO_PTR_SIZE
 | 
			
		||||
	ASM_PTR_SIZE(0)
 | 
			
		||||
 | 
			
		||||
	.section .init_array, "aw"
 | 
			
		||||
	ASM_ALIGN_TO_PTR_SIZE
 | 
			
		||||
	ASM_PTR_SIZE(0)
 | 
			
		||||
 | 
			
		||||
	.section .fini_array, "aw"
 | 
			
		||||
	ASM_ALIGN_TO_PTR_SIZE
 | 
			
		||||
	ASM_PTR_SIZE(0)
 | 
			
		||||
 | 
			
		||||
#if defined(__linux__) && defined(__ELF__)
 | 
			
		||||
@@ -42,7 +45,9 @@
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(__i386__) || defined(__x86_64__)
 | 
			
		||||
	.section	.eh_frame,"a",@progbits
 | 
			
		||||
	ASM_ALIGN(4)
 | 
			
		||||
#if defined(__i386__)
 | 
			
		||||
	.balign 4
 | 
			
		||||
#endif
 | 
			
		||||
	.type	__FRAME_END__, @object
 | 
			
		||||
	.size	__FRAME_END__, 4
 | 
			
		||||
__FRAME_END__:
 | 
			
		||||
 
 | 
			
		||||
@@ -26,22 +26,14 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "asm_multiarch.h"
 | 
			
		||||
 | 
			
		||||
#ifndef __arm__
 | 
			
		||||
	.section .init_array, "aw"
 | 
			
		||||
	ASM_PTR_SIZE(0)
 | 
			
		||||
 | 
			
		||||
	.section .fini_array, "aw"
 | 
			
		||||
	ASM_PTR_SIZE(0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__linux__) && defined(__ELF__)
 | 
			
		||||
	.section .note.GNU-stack,"",%progbits
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(__i386__) || defined(__x86_64__)
 | 
			
		||||
	.section	.eh_frame,"a",@progbits
 | 
			
		||||
	ASM_ALIGN(4)
 | 
			
		||||
#if defined(__i386__)
 | 
			
		||||
	.balign 4
 | 
			
		||||
#endif
 | 
			
		||||
	.type	__FRAME_END__, @object
 | 
			
		||||
	.size	__FRAME_END__, 4
 | 
			
		||||
__FRAME_END__:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014-2015 The Android Open Source Project
 | 
			
		||||
 * Copyright (C) 2014 The Android Open Source Project
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,9 @@
 | 
			
		||||
 | 
			
		||||
libc_bionic_src_files_mips += \
 | 
			
		||||
    arch-mips/string/memcmp.c \
 | 
			
		||||
    arch-mips/string/memcpy.S \
 | 
			
		||||
    arch-mips/string/memset.S \
 | 
			
		||||
    arch-mips/string/strcmp.S \
 | 
			
		||||
    bionic/__memcpy_chk.cpp \
 | 
			
		||||
    bionic/__memset_chk.cpp \
 | 
			
		||||
    bionic/__strcpy_chk.cpp \
 | 
			
		||||
@@ -31,7 +34,6 @@ libc_openbsd_src_files_mips += \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/stpcpy.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/stpncpy.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strcat.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strcmp.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strcpy.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strlcat.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strlcpy.c \
 | 
			
		||||
@@ -54,14 +56,10 @@ libc_bionic_src_files_mips += \
 | 
			
		||||
 | 
			
		||||
ifndef ARCH_MIPS_REV6
 | 
			
		||||
libc_bionic_src_files_mips += \
 | 
			
		||||
    arch-mips/string/memcpy.S \
 | 
			
		||||
    arch-mips/string/memset.S \
 | 
			
		||||
    arch-mips/string/mips_strlen.c \
 | 
			
		||||
 | 
			
		||||
else
 | 
			
		||||
libc_bionic_src_files_mips += \
 | 
			
		||||
    arch-mips/string/memcpy.c \
 | 
			
		||||
    arch-mips/string/memset.c \
 | 
			
		||||
    arch-mips/string/strlen.c \
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,91 +0,0 @@
 | 
			
		||||
/*	$OpenBSD: memcpy.c,v 1.1 2014/11/30 19:43:56 deraadt Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990 The Regents of the University of California.
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This code is derived from software contributed to Berkeley by
 | 
			
		||||
 * Chris Torek.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 | 
			
		||||
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
			
		||||
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * sizeof(word) MUST BE A POWER OF TWO
 | 
			
		||||
 * SO THAT wmask BELOW IS ALL ONES
 | 
			
		||||
 */
 | 
			
		||||
typedef	long word;		/* "word" used for optimal copy speed */
 | 
			
		||||
 | 
			
		||||
#define	wsize	sizeof(word)
 | 
			
		||||
#define	wmask	(wsize - 1)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copy a block of memory, not handling overlap.
 | 
			
		||||
 */
 | 
			
		||||
void *
 | 
			
		||||
memcpy(void *dst0, const void *src0, size_t length)
 | 
			
		||||
{
 | 
			
		||||
	char *dst = dst0;
 | 
			
		||||
	const char *src = src0;
 | 
			
		||||
	size_t t;
 | 
			
		||||
 | 
			
		||||
	if (length == 0 || dst == src)		/* nothing to do */
 | 
			
		||||
		goto done;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Macros: loop-t-times; and loop-t-times, t>0
 | 
			
		||||
	 */
 | 
			
		||||
#define	TLOOP(s) if (t) TLOOP1(s)
 | 
			
		||||
#define	TLOOP1(s) do { s; } while (--t)
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Copy forward.
 | 
			
		||||
	 */
 | 
			
		||||
	t = (long)src;	/* only need low bits */
 | 
			
		||||
	if ((t | (long)dst) & wmask) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Try to align operands.  This cannot be done
 | 
			
		||||
		 * unless the low bits match.
 | 
			
		||||
		 */
 | 
			
		||||
		if ((t ^ (long)dst) & wmask || length < wsize)
 | 
			
		||||
			t = length;
 | 
			
		||||
		else
 | 
			
		||||
			t = wsize - (t & wmask);
 | 
			
		||||
		length -= t;
 | 
			
		||||
		TLOOP1(*dst++ = *src++);
 | 
			
		||||
	}
 | 
			
		||||
	/*
 | 
			
		||||
	 * Copy whole words, then mop up any trailing bytes.
 | 
			
		||||
	 */
 | 
			
		||||
	t = length / wsize;
 | 
			
		||||
	TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
 | 
			
		||||
	t = length & wmask;
 | 
			
		||||
	TLOOP(*dst++ = *src++);
 | 
			
		||||
done:
 | 
			
		||||
	return (dst0);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2009
 | 
			
		||||
 * Copyright (c) 2013
 | 
			
		||||
 *      MIPS Technologies, Inc., California.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
@@ -27,216 +27,410 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 *  memset.S, version "64h" with 1 cache line horizon for "pref 30" and 14 nops
 | 
			
		||||
 *  Version: "043009"
 | 
			
		||||
 *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *  Include files
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This routine could be optimized for MIPS64. The current code only
 | 
			
		||||
 * uses MIPS32 instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(__MIPSEB__)
 | 
			
		||||
#  define SWHI	swl		/* high part is left in big-endian	*/
 | 
			
		||||
#  define SWLO	swr		/* low part is right in big-endian	*/
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__MIPSEL__)
 | 
			
		||||
#  define SWHI	swr		/* high part is right in little-endian	*/
 | 
			
		||||
#  define SWLO	swl		/* low part is left in little-endian	*/
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !(defined(XGPROF) || defined(XPROF))
 | 
			
		||||
#undef SETUP_GP
 | 
			
		||||
#define SETUP_GP
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef NDEBUG
 | 
			
		||||
#define DBG #
 | 
			
		||||
#ifdef __ANDROID__
 | 
			
		||||
# include <private/bionic_asm.h>
 | 
			
		||||
# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
 | 
			
		||||
#elif _LIBC
 | 
			
		||||
# include <sysdep.h>
 | 
			
		||||
# include <regdef.h>
 | 
			
		||||
# include <sys/asm.h>
 | 
			
		||||
# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
 | 
			
		||||
#elif _COMPILING_NEWLIB
 | 
			
		||||
# include "machine/asm.h"
 | 
			
		||||
# include "machine/regdef.h"
 | 
			
		||||
# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
 | 
			
		||||
#else
 | 
			
		||||
#define DBG
 | 
			
		||||
# include <regdef.h>
 | 
			
		||||
# include <sys/asm.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
LEAF(memset,0)
 | 
			
		||||
/* Check to see if the MIPS architecture we are compiling for supports
 | 
			
		||||
   prefetching.  */
 | 
			
		||||
 | 
			
		||||
#if (__mips == 4) || (__mips == 5) || (__mips == 32) || (__mips == 64)
 | 
			
		||||
# ifndef DISABLE_PREFETCH
 | 
			
		||||
#  define USE_PREFETCH
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32))
 | 
			
		||||
# ifndef DISABLE_DOUBLE
 | 
			
		||||
#  define USE_DOUBLE
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef USE_DOUBLE
 | 
			
		||||
# ifndef DISABLE_DOUBLE_ALIGN
 | 
			
		||||
#  define DOUBLE_ALIGN
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Some asm.h files do not have the L macro definition.  */
 | 
			
		||||
#ifndef L
 | 
			
		||||
# if _MIPS_SIM == _ABIO32
 | 
			
		||||
#  define L(label) $L ## label
 | 
			
		||||
# else
 | 
			
		||||
#  define L(label) .L ## label
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Some asm.h files do not have the PTR_ADDIU macro definition.  */
 | 
			
		||||
#ifndef PTR_ADDIU
 | 
			
		||||
# if _MIPS_SIM == _ABIO32
 | 
			
		||||
#  define PTR_ADDIU	addiu
 | 
			
		||||
# else
 | 
			
		||||
#  define PTR_ADDIU	daddiu
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* New R6 instructions that may not be in asm.h.  */
 | 
			
		||||
#ifndef PTR_LSA
 | 
			
		||||
# if _MIPS_SIM == _ABIO32
 | 
			
		||||
#  define PTR_LSA        lsa
 | 
			
		||||
# else
 | 
			
		||||
#  define PTR_LSA        dlsa
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE
 | 
			
		||||
   or PREFETCH_STORE_STREAMED offers a large performance advantage
 | 
			
		||||
   but PREPAREFORSTORE has some special restrictions to consider.
 | 
			
		||||
 | 
			
		||||
   Prefetch with the 'prepare for store' hint does not copy a memory
 | 
			
		||||
   location into the cache, it just allocates a cache line and zeros
 | 
			
		||||
   it out.  This means that if you do not write to the entire cache
 | 
			
		||||
   line before writing it out to memory some data will get zero'ed out
 | 
			
		||||
   when the cache line is written back to memory and data will be lost.
 | 
			
		||||
 | 
			
		||||
   There are ifdef'ed sections of this memcpy to make sure that it does not
 | 
			
		||||
   do prefetches on cache lines that are not going to be completely written.
 | 
			
		||||
   This code is only needed and only used when PREFETCH_STORE_HINT is set to
 | 
			
		||||
   PREFETCH_HINT_PREPAREFORSTORE.  This code assumes that cache lines are
 | 
			
		||||
   less than MAX_PREFETCH_SIZE bytes and if the cache line is larger it will
 | 
			
		||||
   not work correctly.  */
 | 
			
		||||
 | 
			
		||||
#ifdef USE_PREFETCH
 | 
			
		||||
# define PREFETCH_HINT_STORE		1
 | 
			
		||||
# define PREFETCH_HINT_STORE_STREAMED	5
 | 
			
		||||
# define PREFETCH_HINT_STORE_RETAINED	7
 | 
			
		||||
# define PREFETCH_HINT_PREPAREFORSTORE	30
 | 
			
		||||
 | 
			
		||||
/* If we have not picked out what hints to use at this point use the
 | 
			
		||||
   standard load and store prefetch hints.  */
 | 
			
		||||
# ifndef PREFETCH_STORE_HINT
 | 
			
		||||
#  define PREFETCH_STORE_HINT PREFETCH_HINT_STORE
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
/* We double everything when USE_DOUBLE is true so we do 2 prefetches to
 | 
			
		||||
   get 64 bytes in that case.  The assumption is that each individual
 | 
			
		||||
   prefetch brings in 32 bytes.  */
 | 
			
		||||
# ifdef USE_DOUBLE
 | 
			
		||||
#  define PREFETCH_CHUNK 64
 | 
			
		||||
#  define PREFETCH_FOR_STORE(chunk, reg) \
 | 
			
		||||
    pref PREFETCH_STORE_HINT, (chunk)*64(reg); \
 | 
			
		||||
    pref PREFETCH_STORE_HINT, ((chunk)*64)+32(reg)
 | 
			
		||||
# else
 | 
			
		||||
#  define PREFETCH_CHUNK 32
 | 
			
		||||
#  define PREFETCH_FOR_STORE(chunk, reg) \
 | 
			
		||||
    pref PREFETCH_STORE_HINT, (chunk)*32(reg)
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
/* MAX_PREFETCH_SIZE is the maximum size of a prefetch, it must not be less
 | 
			
		||||
   than PREFETCH_CHUNK, the assumed size of each prefetch.  If the real size
 | 
			
		||||
   of a prefetch is greater than MAX_PREFETCH_SIZE and the PREPAREFORSTORE
 | 
			
		||||
   hint is used, the code will not work correctly.  If PREPAREFORSTORE is not
 | 
			
		||||
   used than MAX_PREFETCH_SIZE does not matter.  */
 | 
			
		||||
# define MAX_PREFETCH_SIZE 128
 | 
			
		||||
/* PREFETCH_LIMIT is set based on the fact that we never use an offset greater
 | 
			
		||||
   than 5 on a STORE prefetch and that a single prefetch can never be larger
 | 
			
		||||
   than MAX_PREFETCH_SIZE.  We add the extra 32 when USE_DOUBLE is set because
 | 
			
		||||
   we actually do two prefetches in that case, one 32 bytes after the other.  */
 | 
			
		||||
# ifdef USE_DOUBLE
 | 
			
		||||
#  define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + 32 + MAX_PREFETCH_SIZE
 | 
			
		||||
# else
 | 
			
		||||
#  define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + MAX_PREFETCH_SIZE
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) \
 | 
			
		||||
    && ((PREFETCH_CHUNK * 4) < MAX_PREFETCH_SIZE)
 | 
			
		||||
/* We cannot handle this because the initial prefetches may fetch bytes that
 | 
			
		||||
   are before the buffer being copied.  We start copies with an offset
 | 
			
		||||
   of 4 so avoid this situation when using PREPAREFORSTORE.  */
 | 
			
		||||
#  error "PREFETCH_CHUNK is too large and/or MAX_PREFETCH_SIZE is too small."
 | 
			
		||||
# endif
 | 
			
		||||
#else /* USE_PREFETCH not defined */
 | 
			
		||||
# define PREFETCH_FOR_STORE(offset, reg)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if __mips_isa_rev > 5
 | 
			
		||||
# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
 | 
			
		||||
#  undef PREFETCH_STORE_HINT
 | 
			
		||||
#  define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED
 | 
			
		||||
# endif
 | 
			
		||||
# define R6_CODE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Allow the routine to be named something else if desired.  */
 | 
			
		||||
#ifndef MEMSET_NAME
 | 
			
		||||
# define MEMSET_NAME memset
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* We load/store 64 bits at a time when USE_DOUBLE is true.
 | 
			
		||||
   The C_ prefix stands for CHUNK and is used to avoid macro name
 | 
			
		||||
   conflicts with system header files.  */
 | 
			
		||||
 | 
			
		||||
#ifdef USE_DOUBLE
 | 
			
		||||
# define C_ST	sd
 | 
			
		||||
# if __MIPSEB
 | 
			
		||||
#  define C_STHI	sdl	/* high part is left in big-endian	*/
 | 
			
		||||
# else
 | 
			
		||||
#  define C_STHI	sdr	/* high part is right in little-endian	*/
 | 
			
		||||
# endif
 | 
			
		||||
#else
 | 
			
		||||
# define C_ST	sw
 | 
			
		||||
# if __MIPSEB
 | 
			
		||||
#  define C_STHI	swl	/* high part is left in big-endian	*/
 | 
			
		||||
# else
 | 
			
		||||
#  define C_STHI	swr	/* high part is right in little-endian	*/
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Bookkeeping values for 32 vs. 64 bit mode.  */
 | 
			
		||||
#ifdef USE_DOUBLE
 | 
			
		||||
# define NSIZE 8
 | 
			
		||||
# define NSIZEMASK 0x3f
 | 
			
		||||
# define NSIZEDMASK 0x7f
 | 
			
		||||
#else
 | 
			
		||||
# define NSIZE 4
 | 
			
		||||
# define NSIZEMASK 0x1f
 | 
			
		||||
# define NSIZEDMASK 0x3f
 | 
			
		||||
#endif
 | 
			
		||||
#define UNIT(unit) ((unit)*NSIZE)
 | 
			
		||||
#define UNITM1(unit) (((unit)*NSIZE)-1)
 | 
			
		||||
 | 
			
		||||
#ifdef __ANDROID__
 | 
			
		||||
LEAF(MEMSET_NAME,0)
 | 
			
		||||
#else
 | 
			
		||||
LEAF(MEMSET_NAME)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	.set	nomips16
 | 
			
		||||
	.set	noreorder
 | 
			
		||||
	.set	noat
 | 
			
		||||
/* If the size is less than 2*NSIZE (8 or 16), go to L(lastb).  Regardless of
 | 
			
		||||
   size, copy dst pointer to v0 for the return value.  */
 | 
			
		||||
	slti	t2,a2,(2 * NSIZE)
 | 
			
		||||
	bne	t2,zero,L(lastb)
 | 
			
		||||
	move	v0,a0
 | 
			
		||||
 | 
			
		||||
	addu	t0,a0,a2		# t0 is the "past the end" address
 | 
			
		||||
	slti	AT,a2,4			# is a2 less than 4?
 | 
			
		||||
	bne	AT,zero,.Llast4		# if yes, go to last4
 | 
			
		||||
	 move	v0,a0			# memset returns the dst pointer
 | 
			
		||||
/* If memset value is not zero, we copy it to all the bytes in a 32 or 64
 | 
			
		||||
   bit word.  */
 | 
			
		||||
	beq	a1,zero,L(set0)		/* If memset value is zero no smear  */
 | 
			
		||||
	PTR_SUBU a3,zero,a0
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	beq	a1,zero,.Lset0
 | 
			
		||||
	 subu	v1,zero,a0
 | 
			
		||||
 | 
			
		||||
	# smear byte into 32 bit word
 | 
			
		||||
#if (__mips==32) && (__mips_isa_rev>=2)
 | 
			
		||||
	ins     a1, a1, 8, 8        # Replicate fill byte into half-word.
 | 
			
		||||
	ins     a1, a1, 16, 16      # Replicate fill byte into word.
 | 
			
		||||
	/* smear byte into 32 or 64 bit word */
 | 
			
		||||
#if ((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)
 | 
			
		||||
# ifdef USE_DOUBLE
 | 
			
		||||
	dins	a1, a1, 8, 8        /* Replicate fill byte into half-word.  */
 | 
			
		||||
	dins	a1, a1, 16, 16      /* Replicate fill byte into word.       */
 | 
			
		||||
	dins	a1, a1, 32, 32      /* Replicate fill byte into dbl word.   */
 | 
			
		||||
# else
 | 
			
		||||
	ins	a1, a1, 8, 8        /* Replicate fill byte into half-word.  */
 | 
			
		||||
	ins	a1, a1, 16, 16      /* Replicate fill byte into word.       */
 | 
			
		||||
# endif
 | 
			
		||||
#else
 | 
			
		||||
	and	a1,0xff
 | 
			
		||||
	sll	AT,a1,8
 | 
			
		||||
	or	a1,AT
 | 
			
		||||
	sll	AT,a1,16
 | 
			
		||||
	or	a1,AT
 | 
			
		||||
# ifdef USE_DOUBLE
 | 
			
		||||
        and     a1,0xff
 | 
			
		||||
	dsll	t2,a1,8
 | 
			
		||||
	or	a1,t2
 | 
			
		||||
	dsll	t2,a1,16
 | 
			
		||||
	or	a1,t2
 | 
			
		||||
	dsll	t2,a1,32
 | 
			
		||||
	or	a1,t2
 | 
			
		||||
# else
 | 
			
		||||
        and     a1,0xff
 | 
			
		||||
	sll	t2,a1,8
 | 
			
		||||
	or	a1,t2
 | 
			
		||||
	sll	t2,a1,16
 | 
			
		||||
	or	a1,t2
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
.Lset0:
 | 
			
		||||
	andi	v1,v1,0x3		# word-unaligned address?
 | 
			
		||||
	beq	v1,zero,.Laligned	# v1 is the unalignment count
 | 
			
		||||
	 subu	a2,a2,v1
 | 
			
		||||
	SWHI	a1,0(a0)
 | 
			
		||||
	addu	a0,a0,v1
 | 
			
		||||
/* If the destination address is not aligned do a partial store to get it
 | 
			
		||||
   aligned.  If it is already aligned just jump to L(aligned).  */
 | 
			
		||||
L(set0):
 | 
			
		||||
#ifndef R6_CODE
 | 
			
		||||
	andi	t2,a3,(NSIZE-1)		/* word-unaligned address?          */
 | 
			
		||||
	beq	t2,zero,L(aligned)	/* t2 is the unalignment count      */
 | 
			
		||||
	PTR_SUBU a2,a2,t2
 | 
			
		||||
	C_STHI	a1,0(a0)
 | 
			
		||||
	PTR_ADDU a0,a0,t2
 | 
			
		||||
#else /* R6_CODE */
 | 
			
		||||
	andi	t2,a0,(NSIZE-1)
 | 
			
		||||
	lapc	t9,L(atable)
 | 
			
		||||
	PTR_LSA	t9,t2,t9,2
 | 
			
		||||
	jrc	t9
 | 
			
		||||
L(atable):
 | 
			
		||||
	bc	L(aligned)
 | 
			
		||||
# ifdef USE_DOUBLE
 | 
			
		||||
	bc	L(lb7)
 | 
			
		||||
	bc	L(lb6)
 | 
			
		||||
	bc	L(lb5)
 | 
			
		||||
	bc	L(lb4)
 | 
			
		||||
# endif
 | 
			
		||||
	bc	L(lb3)
 | 
			
		||||
	bc	L(lb2)
 | 
			
		||||
	bc	L(lb1)
 | 
			
		||||
L(lb7):
 | 
			
		||||
	sb	a1,6(a0)
 | 
			
		||||
L(lb6):
 | 
			
		||||
	sb	a1,5(a0)
 | 
			
		||||
L(lb5):
 | 
			
		||||
	sb	a1,4(a0)
 | 
			
		||||
L(lb4):
 | 
			
		||||
	sb	a1,3(a0)
 | 
			
		||||
L(lb3):
 | 
			
		||||
	sb	a1,2(a0)
 | 
			
		||||
L(lb2):
 | 
			
		||||
	sb	a1,1(a0)
 | 
			
		||||
L(lb1):
 | 
			
		||||
	sb	a1,0(a0)
 | 
			
		||||
 | 
			
		||||
# Here we have the "word-aligned" a0 (until the "last4")
 | 
			
		||||
.Laligned:
 | 
			
		||||
	andi	t8,a2,0x3f	# any 64-byte chunks?
 | 
			
		||||
				# t8 is the byte count past 64-byte chunks
 | 
			
		||||
	beq	a2,t8,.Lchk8w	# when a2==t8, no 64-byte chunks
 | 
			
		||||
				# There will be at most 1 32-byte chunk then
 | 
			
		||||
	 subu	a3,a2,t8	# subtract from a2 the reminder
 | 
			
		||||
				# Here a3 counts bytes in 16w chunks
 | 
			
		||||
	addu	a3,a0,a3	# Now a3 is the final dst after 64-byte chunks
 | 
			
		||||
 | 
			
		||||
# Find out, if there are any 64-byte chunks after which will be still at least
 | 
			
		||||
# 96 bytes left. The value "96" is calculated as needed buffer for
 | 
			
		||||
# "pref 30,64(a0)" prefetch, which can be used as "pref 30,0(a0)" after
 | 
			
		||||
# incrementing "a0" by 64.
 | 
			
		||||
# For "a2" below 160 there will be no such "pref 30 safe" 64-byte chunk.
 | 
			
		||||
#
 | 
			
		||||
	sltiu	v1,a2,160
 | 
			
		||||
	bgtz	v1,.Lloop16w_nopref30	# skip "pref 30,0(a0)"
 | 
			
		||||
	 subu	t7,a2,96	# subtract "pref 30 unsafe" region
 | 
			
		||||
		# below we have at least 1 64-byte chunk which is "pref 30 safe"
 | 
			
		||||
	andi	t6,t7,0x3f	# t6 is past "64-byte safe chunks" reminder
 | 
			
		||||
	subu	t5,t7,t6	# subtract from t7 the reminder
 | 
			
		||||
				# Here t5 counts bytes in 16w "safe" chunks
 | 
			
		||||
	addu	t4,a0,t5	# Now t4 is the dst after 64-byte "safe" chunks
 | 
			
		||||
 | 
			
		||||
# Don't use "pref 30,0(a0)" for a0 in a "middle" of a cache line
 | 
			
		||||
#	pref	30,0(a0)
 | 
			
		||||
# Here we are in the region, where it is safe to use "pref 30,64(a0)"
 | 
			
		||||
.Lloop16w:
 | 
			
		||||
	addiu	a0,a0,64
 | 
			
		||||
	pref	30,-32(a0)	# continue setting up the dest, addr 64-32
 | 
			
		||||
	sw	a1,-64(a0)
 | 
			
		||||
	sw	a1,-60(a0)
 | 
			
		||||
	sw	a1,-56(a0)
 | 
			
		||||
	sw	a1,-52(a0)
 | 
			
		||||
	sw	a1,-48(a0)
 | 
			
		||||
	sw	a1,-44(a0)
 | 
			
		||||
	sw	a1,-40(a0)
 | 
			
		||||
	sw	a1,-36(a0)
 | 
			
		||||
	nop
 | 
			
		||||
	nop			# the extra nop instructions help to balance
 | 
			
		||||
	nop			# cycles needed for "store" + "fill" + "evict"
 | 
			
		||||
	nop			# For 64byte store there are needed 8 fill
 | 
			
		||||
	nop			# and 8 evict cycles, i.e. at least 32 instr.
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	pref	30,0(a0)	# continue setting up the dest, addr 64-0
 | 
			
		||||
	sw	a1,-32(a0)
 | 
			
		||||
	sw	a1,-28(a0)
 | 
			
		||||
	sw	a1,-24(a0)
 | 
			
		||||
	sw	a1,-20(a0)
 | 
			
		||||
	sw	a1,-16(a0)
 | 
			
		||||
	sw	a1,-12(a0)
 | 
			
		||||
	sw	a1,-8(a0)
 | 
			
		||||
	sw	a1,-4(a0)
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop			# NOTE: adding 14 nop-s instead of 12 nop-s
 | 
			
		||||
	nop			# gives better results for "fast" memory
 | 
			
		||||
	nop
 | 
			
		||||
	bne	a0,t4,.Lloop16w
 | 
			
		||||
	 nop
 | 
			
		||||
 | 
			
		||||
	beq	a0,a3,.Lchk8w	# maybe no more 64-byte chunks?
 | 
			
		||||
	 nop			# this "delayed slot" is useless ...
 | 
			
		||||
 | 
			
		||||
.Lloop16w_nopref30:	# there could be up to 3 "64-byte nopref30" chunks
 | 
			
		||||
	addiu	a0,a0,64
 | 
			
		||||
	sw	a1,-64(a0)
 | 
			
		||||
	sw	a1,-60(a0)
 | 
			
		||||
	sw	a1,-56(a0)
 | 
			
		||||
	sw	a1,-52(a0)
 | 
			
		||||
	sw	a1,-48(a0)
 | 
			
		||||
	sw	a1,-44(a0)
 | 
			
		||||
	sw	a1,-40(a0)
 | 
			
		||||
	sw	a1,-36(a0)
 | 
			
		||||
	sw	a1,-32(a0)
 | 
			
		||||
	sw	a1,-28(a0)
 | 
			
		||||
	sw	a1,-24(a0)
 | 
			
		||||
	sw	a1,-20(a0)
 | 
			
		||||
	sw	a1,-16(a0)
 | 
			
		||||
	sw	a1,-12(a0)
 | 
			
		||||
	sw	a1,-8(a0)
 | 
			
		||||
	bne	a0,a3,.Lloop16w_nopref30
 | 
			
		||||
	 sw	a1,-4(a0)
 | 
			
		||||
 | 
			
		||||
.Lchk8w:		# t8 here is the byte count past 64-byte chunks
 | 
			
		||||
 | 
			
		||||
	andi	t7,t8,0x1f	# is there a 32-byte chunk?
 | 
			
		||||
				# the t7 is the reminder count past 32-bytes
 | 
			
		||||
	beq	t8,t7,.Lchk1w	# when t8==t7, no 32-byte chunk
 | 
			
		||||
	 move	a2,t7
 | 
			
		||||
	li	t9,NSIZE
 | 
			
		||||
	subu	t2,t9,t2
 | 
			
		||||
	PTR_SUBU a2,a2,t2
 | 
			
		||||
	PTR_ADDU a0,a0,t2
 | 
			
		||||
#endif /* R6_CODE */
 | 
			
		||||
 | 
			
		||||
L(aligned):
 | 
			
		||||
/* If USE_DOUBLE is not set we may still want to align the data on a 16
 | 
			
		||||
   byte boundry instead of an 8 byte boundry to maximize the opportunity
 | 
			
		||||
   of proAptiv chips to do memory bonding (combining two sequential 4
 | 
			
		||||
   byte stores into one 8 byte store).  We know there are at least 4 bytes
 | 
			
		||||
   left to store or we would have jumped to L(lastb) earlier in the code.  */
 | 
			
		||||
#ifdef DOUBLE_ALIGN
 | 
			
		||||
	andi	t2,a3,4
 | 
			
		||||
	beq	t2,zero,L(double_aligned)
 | 
			
		||||
	PTR_SUBU a2,a2,t2
 | 
			
		||||
	sw	a1,0(a0)
 | 
			
		||||
	sw	a1,4(a0)
 | 
			
		||||
	sw	a1,8(a0)
 | 
			
		||||
	sw	a1,12(a0)
 | 
			
		||||
	sw	a1,16(a0)
 | 
			
		||||
	sw	a1,20(a0)
 | 
			
		||||
	sw	a1,24(a0)
 | 
			
		||||
	sw	a1,28(a0)
 | 
			
		||||
	addiu	a0,a0,32
 | 
			
		||||
	PTR_ADDU a0,a0,t2
 | 
			
		||||
L(double_aligned):
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
.Lchk1w:
 | 
			
		||||
	andi	t8,a2,0x3	# now t8 is the reminder past 1w chunks
 | 
			
		||||
	beq	a2,t8,.Llast4aligned
 | 
			
		||||
	 subu	a3,a2,t8	# a3 is the count of bytes in 1w chunks
 | 
			
		||||
	addu	a3,a0,a3	# now a3 is the dst address past the 1w chunks
 | 
			
		||||
/* Now the destination is aligned to (word or double word) aligned address
 | 
			
		||||
   Set a2 to count how many bytes we have to copy after all the 64/128 byte
 | 
			
		||||
   chunks are copied and a3 to the dest pointer after all the 64/128 byte
 | 
			
		||||
   chunks have been copied.  We will loop, incrementing a0 until it equals
 | 
			
		||||
   a3.  */
 | 
			
		||||
	andi	t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
 | 
			
		||||
	beq	a2,t8,L(chkw)	 /* if a2==t8, no 64-byte/128-byte chunks */
 | 
			
		||||
	PTR_SUBU a3,a2,t8	 /* subtract from a2 the reminder */
 | 
			
		||||
	PTR_ADDU a3,a0,a3	 /* Now a3 is the final dst after loop */
 | 
			
		||||
 | 
			
		||||
# copying in words (4-byte chunks)
 | 
			
		||||
.LwordCopy_loop:
 | 
			
		||||
	addiu	a0,a0,4
 | 
			
		||||
	bne	a0,a3,.LwordCopy_loop
 | 
			
		||||
	 sw	a1,-4(a0)
 | 
			
		||||
/* When in the loop we may prefetch with the 'prepare to store' hint,
 | 
			
		||||
   in this case the a0+x should not be past the "t0-32" address.  This
 | 
			
		||||
   means: for x=128 the last "safe" a0 address is "t0-160".  Alternatively,
 | 
			
		||||
   for x=64 the last "safe" a0 address is "t0-96" In the current version we
 | 
			
		||||
   will use "prefetch hint,128(a0)", so "t0-160" is the limit.  */
 | 
			
		||||
#if defined(USE_PREFETCH) \
 | 
			
		||||
    && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
 | 
			
		||||
	PTR_ADDU t0,a0,a2		/* t0 is the "past the end" address */
 | 
			
		||||
	PTR_SUBU t9,t0,PREFETCH_LIMIT	/* t9 is the "last safe pref" address */
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(USE_PREFETCH) \
 | 
			
		||||
    && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
 | 
			
		||||
	PREFETCH_FOR_STORE (1, a0)
 | 
			
		||||
	PREFETCH_FOR_STORE (2, a0)
 | 
			
		||||
	PREFETCH_FOR_STORE (3, a0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
# store last 0-3 bytes
 | 
			
		||||
# this will repeat the last store if the memset finishes on a word boundary
 | 
			
		||||
.Llast4aligned:
 | 
			
		||||
L(loop16w):
 | 
			
		||||
#if defined(USE_PREFETCH) \
 | 
			
		||||
    && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
 | 
			
		||||
	sltu	v1,t9,a0		/* If a0 > t9 don't use next prefetch */
 | 
			
		||||
	bgtz	v1,L(skip_pref)
 | 
			
		||||
	nop
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef R6_CODE
 | 
			
		||||
	PREFETCH_FOR_STORE (4, a0)
 | 
			
		||||
	PREFETCH_FOR_STORE (5, a0)
 | 
			
		||||
#else
 | 
			
		||||
	PREFETCH_FOR_STORE (2, a0)
 | 
			
		||||
#endif
 | 
			
		||||
L(skip_pref):
 | 
			
		||||
	C_ST	a1,UNIT(0)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(1)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(2)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(3)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(4)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(5)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(6)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(7)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(8)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(9)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(10)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(11)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(12)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(13)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(14)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(15)(a0)
 | 
			
		||||
	PTR_ADDIU a0,a0,UNIT(16)	/* adding 64/128 to dest */
 | 
			
		||||
	bne	a0,a3,L(loop16w)
 | 
			
		||||
	nop
 | 
			
		||||
	move	a2,t8
 | 
			
		||||
 | 
			
		||||
/* Here we have dest word-aligned but less than 64-bytes or 128 bytes to go.
 | 
			
		||||
   Check for a 32(64) byte chunk and copy if if there is one.  Otherwise
 | 
			
		||||
   jump down to L(chk1w) to handle the tail end of the copy.  */
 | 
			
		||||
L(chkw):
 | 
			
		||||
	andi	t8,a2,NSIZEMASK	/* is there a 32-byte/64-byte chunk.  */
 | 
			
		||||
				/* the t8 is the reminder count past 32-bytes */
 | 
			
		||||
	beq	a2,t8,L(chk1w)/* when a2==t8, no 32-byte chunk */
 | 
			
		||||
	nop
 | 
			
		||||
	C_ST	a1,UNIT(0)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(1)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(2)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(3)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(4)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(5)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(6)(a0)
 | 
			
		||||
	C_ST	a1,UNIT(7)(a0)
 | 
			
		||||
	PTR_ADDIU a0,a0,UNIT(8)
 | 
			
		||||
 | 
			
		||||
/* Here we have less than 32(64) bytes to set.  Set up for a loop to
 | 
			
		||||
   copy one word (or double word) at a time.  Set a2 to count how many
 | 
			
		||||
   bytes we have to copy after all the word (or double word) chunks are
 | 
			
		||||
   copied and a3 to the dest pointer after all the (d)word chunks have
 | 
			
		||||
   been copied.  We will loop, incrementing a0 until a0 equals a3.  */
 | 
			
		||||
L(chk1w):
 | 
			
		||||
	andi	a2,t8,(NSIZE-1)	/* a2 is the reminder past one (d)word chunks */
 | 
			
		||||
	beq	a2,t8,L(lastb)
 | 
			
		||||
	PTR_SUBU a3,t8,a2	/* a3 is count of bytes in one (d)word chunks */
 | 
			
		||||
	PTR_ADDU a3,a0,a3	/* a3 is the dst address after loop */
 | 
			
		||||
 | 
			
		||||
/* copying in words (4-byte or 8 byte chunks) */
 | 
			
		||||
L(wordCopy_loop):
 | 
			
		||||
	PTR_ADDIU a0,a0,UNIT(1)
 | 
			
		||||
	bne	a0,a3,L(wordCopy_loop)
 | 
			
		||||
	C_ST	a1,UNIT(-1)(a0)
 | 
			
		||||
 | 
			
		||||
/* Copy the last 8 (or 16) bytes */
 | 
			
		||||
L(lastb):
 | 
			
		||||
	blez	a2,L(leave)
 | 
			
		||||
	PTR_ADDU a3,a0,a2       /* a3 is the last dst address */
 | 
			
		||||
L(lastbloop):
 | 
			
		||||
	PTR_ADDIU a0,a0,1
 | 
			
		||||
	bne	a0,a3,L(lastbloop)
 | 
			
		||||
	sb	a1,-1(a0)
 | 
			
		||||
L(leave):
 | 
			
		||||
	j	ra
 | 
			
		||||
	 SWLO	a1,-1(t0)
 | 
			
		||||
 | 
			
		||||
.Llast4:
 | 
			
		||||
	beq	a0,t0,.Llast4e
 | 
			
		||||
.Llast4l:
 | 
			
		||||
	 addiu	a0,a0,1
 | 
			
		||||
	bne	a0,t0,.Llast4l
 | 
			
		||||
	 sb	a1,-1(a0)
 | 
			
		||||
.Llast4e:
 | 
			
		||||
	j	ra
 | 
			
		||||
	 nop
 | 
			
		||||
	nop
 | 
			
		||||
 | 
			
		||||
	.set	at
 | 
			
		||||
	.set	reorder
 | 
			
		||||
 | 
			
		||||
END(memset)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *  Implementation : Static functions
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
END(MEMSET_NAME)
 | 
			
		||||
#ifndef __ANDROID__
 | 
			
		||||
# ifdef _LIBC
 | 
			
		||||
libc_hidden_builtin_def (MEMSET_NAME)
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										260
									
								
								libc/arch-mips/string/strcmp.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								libc/arch-mips/string/strcmp.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,260 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014
 | 
			
		||||
 *      Imagination Technologies Limited.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from
 | 
			
		||||
 *    this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY IMAGINATION TECHNOLOGIES LIMITED ``AS IS'' AND
 | 
			
		||||
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL IMAGINATION TECHNOLOGIES LIMITED BE LIABLE
 | 
			
		||||
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
			
		||||
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef __ANDROID__
 | 
			
		||||
# include <private/bionic_asm.h>
 | 
			
		||||
#elif _LIBC
 | 
			
		||||
# include <sysdep.h>
 | 
			
		||||
# include <regdef.h>
 | 
			
		||||
# include <sys/asm.h>
 | 
			
		||||
#elif _COMPILING_NEWLIB
 | 
			
		||||
# include "machine/asm.h"
 | 
			
		||||
# include "machine/regdef.h"
 | 
			
		||||
#else
 | 
			
		||||
# include <regdef.h>
 | 
			
		||||
# include <sys/asm.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Technically strcmp should not read past the end of the strings being
 | 
			
		||||
   compared.  We will read a full word that may contain excess bits beyond
 | 
			
		||||
   the NULL string terminator but unless ENABLE_READAHEAD is set, we will not
 | 
			
		||||
   read the next word after the end of string.  Setting ENABLE_READAHEAD will
 | 
			
		||||
   improve performance but is technically illegal based on the definition of
 | 
			
		||||
   strcmp.  */
 | 
			
		||||
#ifdef ENABLE_READAHEAD
 | 
			
		||||
# define DELAY_READ
 | 
			
		||||
#else
 | 
			
		||||
# define DELAY_READ nop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Testing on a little endian machine showed using CLZ was a
 | 
			
		||||
   performance loss, so we are not turning it on by default.  */
 | 
			
		||||
#if defined(ENABLE_CLZ) && (__mips_isa_rev > 1)
 | 
			
		||||
# define USE_CLZ
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Some asm.h files do not have the L macro definition.  */
 | 
			
		||||
#ifndef L
 | 
			
		||||
# if _MIPS_SIM == _ABIO32
 | 
			
		||||
#  define L(label) $L ## label
 | 
			
		||||
# else
 | 
			
		||||
#  define L(label) .L ## label
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Some asm.h files do not have the PTR_ADDIU macro definition.  */
 | 
			
		||||
#ifndef PTR_ADDIU
 | 
			
		||||
# if _MIPS_SIM == _ABIO32
 | 
			
		||||
#  define PTR_ADDIU       addiu
 | 
			
		||||
# else
 | 
			
		||||
#  define PTR_ADDIU       daddiu
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Allow the routine to be named something else if desired.  */
 | 
			
		||||
#ifndef STRCMP_NAME
 | 
			
		||||
# define STRCMP_NAME strcmp
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __ANDROID__
 | 
			
		||||
LEAF(STRCMP_NAME, 0)
 | 
			
		||||
#else
 | 
			
		||||
LEAF(STRCMP_NAME)
 | 
			
		||||
#endif
 | 
			
		||||
	.set	nomips16
 | 
			
		||||
	.set	noreorder
 | 
			
		||||
 | 
			
		||||
	or	t0, a0, a1
 | 
			
		||||
	andi	t0,0x3
 | 
			
		||||
	bne	t0, zero, L(byteloop)
 | 
			
		||||
 | 
			
		||||
/* Both strings are 4 byte aligned at this point.  */
 | 
			
		||||
 | 
			
		||||
	lui	t8, 0x0101
 | 
			
		||||
	ori	t8, t8, 0x0101
 | 
			
		||||
	lui	t9, 0x7f7f
 | 
			
		||||
	ori	t9, 0x7f7f
 | 
			
		||||
 | 
			
		||||
#define STRCMP32(OFFSET) \
 | 
			
		||||
	lw	v0, OFFSET(a0); \
 | 
			
		||||
	lw	v1, OFFSET(a1); \
 | 
			
		||||
	subu	t0, v0, t8; \
 | 
			
		||||
	bne	v0, v1, L(worddiff); \
 | 
			
		||||
	nor	t1, v0, t9; \
 | 
			
		||||
	and	t0, t0, t1; \
 | 
			
		||||
	bne	t0, zero, L(returnzero)
 | 
			
		||||
 | 
			
		||||
L(wordloop):
 | 
			
		||||
	STRCMP32(0)
 | 
			
		||||
	DELAY_READ
 | 
			
		||||
	STRCMP32(4)
 | 
			
		||||
	DELAY_READ
 | 
			
		||||
	STRCMP32(8)
 | 
			
		||||
	DELAY_READ
 | 
			
		||||
	STRCMP32(12)
 | 
			
		||||
	DELAY_READ
 | 
			
		||||
	STRCMP32(16)
 | 
			
		||||
	DELAY_READ
 | 
			
		||||
	STRCMP32(20)
 | 
			
		||||
	DELAY_READ
 | 
			
		||||
	STRCMP32(24)
 | 
			
		||||
	DELAY_READ
 | 
			
		||||
	STRCMP32(28)
 | 
			
		||||
	PTR_ADDIU a0, a0, 32
 | 
			
		||||
	b	L(wordloop)
 | 
			
		||||
	PTR_ADDIU a1, a1, 32
 | 
			
		||||
 | 
			
		||||
L(returnzero):
 | 
			
		||||
	j	ra
 | 
			
		||||
	move	v0, zero
 | 
			
		||||
 | 
			
		||||
L(worddiff):
 | 
			
		||||
#ifdef USE_CLZ
 | 
			
		||||
	subu	t0, v0, t8
 | 
			
		||||
	nor	t1, v0, t9
 | 
			
		||||
	and	t1, t0, t1
 | 
			
		||||
	xor	t0, v0, v1
 | 
			
		||||
	or	t0, t0, t1
 | 
			
		||||
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 | 
			
		||||
	wsbh	t0, t0
 | 
			
		||||
	rotr	t0, t0, 16
 | 
			
		||||
# endif
 | 
			
		||||
	clz	t1, t0
 | 
			
		||||
	and	t1, 0xf8
 | 
			
		||||
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 | 
			
		||||
	neg	t1
 | 
			
		||||
	addu	t1, 24
 | 
			
		||||
# endif
 | 
			
		||||
	rotrv	v0, v0, t1
 | 
			
		||||
	rotrv	v1, v1, t1
 | 
			
		||||
	and	v0, v0, 0xff
 | 
			
		||||
	and	v1, v1, 0xff
 | 
			
		||||
	j	ra
 | 
			
		||||
	subu	v0, v0, v1
 | 
			
		||||
#else /* USE_CLZ */
 | 
			
		||||
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 | 
			
		||||
	andi	t0, v0, 0xff
 | 
			
		||||
	beq	t0, zero, L(wexit01)
 | 
			
		||||
	andi	t1, v1, 0xff
 | 
			
		||||
	bne	t0, t1, L(wexit01)
 | 
			
		||||
 | 
			
		||||
	srl	t8, v0, 8
 | 
			
		||||
	srl	t9, v1, 8
 | 
			
		||||
	andi	t8, t8, 0xff
 | 
			
		||||
	beq	t8, zero, L(wexit89)
 | 
			
		||||
	andi	t9, t9, 0xff
 | 
			
		||||
	bne	t8, t9, L(wexit89)
 | 
			
		||||
 | 
			
		||||
	srl	t0, v0, 16
 | 
			
		||||
	srl	t1, v1, 16
 | 
			
		||||
	andi	t0, t0, 0xff
 | 
			
		||||
	beq	t0, zero, L(wexit01)
 | 
			
		||||
	andi	t1, t1, 0xff
 | 
			
		||||
	bne	t0, t1, L(wexit01)
 | 
			
		||||
 | 
			
		||||
	srl	t8, v0, 24
 | 
			
		||||
	srl	t9, v1, 24
 | 
			
		||||
# else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
 | 
			
		||||
	srl	t0, v0, 24
 | 
			
		||||
	beq	t0, zero, L(wexit01)
 | 
			
		||||
	srl	t1, v1, 24
 | 
			
		||||
	bne	t0, t1, L(wexit01)
 | 
			
		||||
 | 
			
		||||
	srl	t8, v0, 16
 | 
			
		||||
	srl	t9, v1, 16
 | 
			
		||||
	andi	t8, t8, 0xff
 | 
			
		||||
	beq	t8, zero, L(wexit89)
 | 
			
		||||
	andi	t9, t9, 0xff
 | 
			
		||||
	bne	t8, t9, L(wexit89)
 | 
			
		||||
 | 
			
		||||
	srl	t0, v0, 8
 | 
			
		||||
	srl	t1, v1, 8
 | 
			
		||||
	andi	t0, t0, 0xff
 | 
			
		||||
	beq	t0, zero, L(wexit01)
 | 
			
		||||
	andi	t1, t1, 0xff
 | 
			
		||||
	bne	t0, t1, L(wexit01)
 | 
			
		||||
 | 
			
		||||
	andi	t8, v0, 0xff
 | 
			
		||||
	andi	t9, v1, 0xff
 | 
			
		||||
# endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
 | 
			
		||||
 | 
			
		||||
L(wexit89):
 | 
			
		||||
	j	ra
 | 
			
		||||
	subu	v0, t8, t9
 | 
			
		||||
L(wexit01):
 | 
			
		||||
	j	ra
 | 
			
		||||
	subu	v0, t0, t1
 | 
			
		||||
#endif /* USE_CLZ */
 | 
			
		||||
 | 
			
		||||
/* It might seem better to do the 'beq' instruction between the two 'lbu'
 | 
			
		||||
   instructions so that the nop is not needed but testing showed that this
 | 
			
		||||
   code is actually faster (based on glibc strcmp test).  */
 | 
			
		||||
#define BYTECMP01(OFFSET) \
 | 
			
		||||
	lbu	v0, OFFSET(a0); \
 | 
			
		||||
	lbu	v1, OFFSET(a1); \
 | 
			
		||||
	beq	v0, zero, L(bexit01); \
 | 
			
		||||
	nop; \
 | 
			
		||||
	bne	v0, v1, L(bexit01)
 | 
			
		||||
 | 
			
		||||
#define BYTECMP89(OFFSET) \
 | 
			
		||||
	lbu	t8, OFFSET(a0); \
 | 
			
		||||
	lbu	t9, OFFSET(a1); \
 | 
			
		||||
	beq	t8, zero, L(bexit89); \
 | 
			
		||||
	nop;	\
 | 
			
		||||
	bne	t8, t9, L(bexit89)
 | 
			
		||||
 | 
			
		||||
L(byteloop):
 | 
			
		||||
	BYTECMP01(0)
 | 
			
		||||
	BYTECMP89(1)
 | 
			
		||||
	BYTECMP01(2)
 | 
			
		||||
	BYTECMP89(3)
 | 
			
		||||
	BYTECMP01(4)
 | 
			
		||||
	BYTECMP89(5)
 | 
			
		||||
	BYTECMP01(6)
 | 
			
		||||
	BYTECMP89(7)
 | 
			
		||||
	PTR_ADDIU a0, a0, 8
 | 
			
		||||
	b	L(byteloop)
 | 
			
		||||
	PTR_ADDIU a1, a1, 8
 | 
			
		||||
 | 
			
		||||
L(bexit01):
 | 
			
		||||
	j	ra
 | 
			
		||||
	subu	v0, v0, v1
 | 
			
		||||
L(bexit89):
 | 
			
		||||
	j	ra
 | 
			
		||||
	subu	v0, t8, t9
 | 
			
		||||
 | 
			
		||||
	.set	at
 | 
			
		||||
	.set	reorder
 | 
			
		||||
 | 
			
		||||
END(STRCMP_NAME)
 | 
			
		||||
#ifndef __ANDROID__
 | 
			
		||||
# ifdef _LIBC
 | 
			
		||||
libc_hidden_builtin_def (STRCMP_NAME)
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
@@ -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,5 @@ ENTRY(__clock_nanosleep)
 | 
			
		||||
    j t9
 | 
			
		||||
    nop
 | 
			
		||||
    .set reorder
 | 
			
		||||
END(__clock_nanosleep)
 | 
			
		||||
END(___clock_nanosleep)
 | 
			
		||||
.hidden ___clock_nanosleep
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fgetxattr)
 | 
			
		||||
ENTRY(___fgetxattr)
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    .cpload t9
 | 
			
		||||
    li v0, __NR_fgetxattr
 | 
			
		||||
@@ -16,4 +16,5 @@ ENTRY(fgetxattr)
 | 
			
		||||
    j t9
 | 
			
		||||
    nop
 | 
			
		||||
    .set reorder
 | 
			
		||||
END(fgetxattr)
 | 
			
		||||
END(___fgetxattr)
 | 
			
		||||
.hidden ___fgetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(flistxattr)
 | 
			
		||||
ENTRY(___flistxattr)
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    .cpload t9
 | 
			
		||||
    li v0, __NR_flistxattr
 | 
			
		||||
@@ -16,4 +16,5 @@ ENTRY(flistxattr)
 | 
			
		||||
    j t9
 | 
			
		||||
    nop
 | 
			
		||||
    .set reorder
 | 
			
		||||
END(flistxattr)
 | 
			
		||||
END(___flistxattr)
 | 
			
		||||
.hidden ___flistxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fsetxattr)
 | 
			
		||||
ENTRY(___fsetxattr)
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    .cpload t9
 | 
			
		||||
    li v0, __NR_fsetxattr
 | 
			
		||||
@@ -16,4 +16,5 @@ ENTRY(fsetxattr)
 | 
			
		||||
    j t9
 | 
			
		||||
    nop
 | 
			
		||||
    .set reorder
 | 
			
		||||
END(fsetxattr)
 | 
			
		||||
END(___fsetxattr)
 | 
			
		||||
.hidden ___fsetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
ENTRY(___rt_sigqueueinfo)
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    .cpload t9
 | 
			
		||||
    li v0, __NR_rt_sigqueueinfo
 | 
			
		||||
@@ -16,4 +16,5 @@ ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
    j t9
 | 
			
		||||
    nop
 | 
			
		||||
    .set reorder
 | 
			
		||||
END(__rt_sigqueueinfo)
 | 
			
		||||
END(___rt_sigqueueinfo)
 | 
			
		||||
.hidden ___rt_sigqueueinfo
 | 
			
		||||
@@ -2,10 +2,10 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(ftruncate)
 | 
			
		||||
ENTRY(process_vm_readv)
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    .cpload t9
 | 
			
		||||
    li v0, __NR_ftruncate
 | 
			
		||||
    li v0, __NR_process_vm_readv
 | 
			
		||||
    syscall
 | 
			
		||||
    bnez a3, 1f
 | 
			
		||||
    move a0, v0
 | 
			
		||||
@@ -16,4 +16,4 @@ ENTRY(ftruncate)
 | 
			
		||||
    j t9
 | 
			
		||||
    nop
 | 
			
		||||
    .set reorder
 | 
			
		||||
END(ftruncate)
 | 
			
		||||
END(process_vm_readv)
 | 
			
		||||
							
								
								
									
										19
									
								
								libc/arch-mips/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								libc/arch-mips/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_writev)
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    .cpload t9
 | 
			
		||||
    li v0, __NR_process_vm_writev
 | 
			
		||||
    syscall
 | 
			
		||||
    bnez a3, 1f
 | 
			
		||||
    move a0, v0
 | 
			
		||||
    j ra
 | 
			
		||||
    nop
 | 
			
		||||
1:
 | 
			
		||||
    la t9,__set_errno_internal
 | 
			
		||||
    j t9
 | 
			
		||||
    nop
 | 
			
		||||
    .set reorder
 | 
			
		||||
END(process_vm_writev)
 | 
			
		||||
@@ -32,29 +32,28 @@
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
struct kernel_stat {
 | 
			
		||||
 unsigned int st_dev;
 | 
			
		||||
 unsigned int st_pad0[3];
 | 
			
		||||
 unsigned long st_ino;
 | 
			
		||||
 mode_t st_mode;
 | 
			
		||||
 __u32 st_nlink;
 | 
			
		||||
 uid_t st_uid;
 | 
			
		||||
 gid_t st_gid;
 | 
			
		||||
 unsigned int st_rdev;
 | 
			
		||||
 unsigned int st_pad1[3];
 | 
			
		||||
 __kernel_off_t st_size;
 | 
			
		||||
 unsigned int _st_atime;
 | 
			
		||||
 unsigned int st_atime_nsec;
 | 
			
		||||
 unsigned int _st_mtime;
 | 
			
		||||
 unsigned int st_mtime_nsec;
 | 
			
		||||
 unsigned int _st_ctime;
 | 
			
		||||
 unsigned int st_ctime_nsec;
 | 
			
		||||
 unsigned int st_blksize;
 | 
			
		||||
 unsigned int st_pad2;
 | 
			
		||||
 unsigned long st_blocks;
 | 
			
		||||
  unsigned int st_dev;
 | 
			
		||||
  unsigned int st_pad0[3];
 | 
			
		||||
  unsigned long st_ino;
 | 
			
		||||
  mode_t st_mode;
 | 
			
		||||
  __u32 st_nlink;
 | 
			
		||||
  uid_t st_uid;
 | 
			
		||||
  gid_t st_gid;
 | 
			
		||||
  unsigned int st_rdev;
 | 
			
		||||
  unsigned int st_pad1[3];
 | 
			
		||||
  __kernel_off_t st_size;
 | 
			
		||||
  unsigned int _st_atime;
 | 
			
		||||
  unsigned int st_atime_nsec;
 | 
			
		||||
  unsigned int _st_mtime;
 | 
			
		||||
  unsigned int st_mtime_nsec;
 | 
			
		||||
  unsigned int _st_ctime;
 | 
			
		||||
  unsigned int st_ctime_nsec;
 | 
			
		||||
  unsigned int st_blksize;
 | 
			
		||||
  unsigned int st_pad2;
 | 
			
		||||
  unsigned long st_blocks;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void copy_stat(struct stat *st, struct kernel_stat *s)
 | 
			
		||||
{
 | 
			
		||||
static void copy_stat(struct stat* st, struct kernel_stat* s) {
 | 
			
		||||
  st->st_dev = static_cast<dev_t>(s->st_dev);
 | 
			
		||||
  st->st_ino = static_cast<ino_t>(s->st_ino);
 | 
			
		||||
  st->st_mode = static_cast<mode_t>(s->st_mode);
 | 
			
		||||
@@ -73,30 +72,17 @@ void copy_stat(struct stat *st, struct kernel_stat *s)
 | 
			
		||||
  st->st_ctim.tv_nsec = static_cast<long>(s->st_ctime_nsec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fstat(int fp, struct stat *st)
 | 
			
		||||
{
 | 
			
		||||
int fstat(int fp, struct stat* st) {
 | 
			
		||||
  kernel_stat s;
 | 
			
		||||
  int ret;
 | 
			
		||||
  ret = syscall (__NR_fstat, fp, &s);
 | 
			
		||||
  copy_stat (st, &s);
 | 
			
		||||
  int ret = syscall(__NR_fstat, fp, &s);
 | 
			
		||||
  copy_stat(st, &s);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
__strong_alias(fstat64, fstat);
 | 
			
		||||
 | 
			
		||||
int newfstatat(int dirfd, const char *pathname, struct stat *buf, int flags)
 | 
			
		||||
{
 | 
			
		||||
int fstatat(int dirfd, const char* pathname, struct stat* buf, int flags) {
 | 
			
		||||
   kernel_stat s;
 | 
			
		||||
   int ret;
 | 
			
		||||
   ret = syscall(__NR_newfstatat, dirfd, pathname, &s, flags);
 | 
			
		||||
   copy_stat(buf, &s);
 | 
			
		||||
   return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags)
 | 
			
		||||
{
 | 
			
		||||
   kernel_stat s;
 | 
			
		||||
   int ret;
 | 
			
		||||
   ret = syscall(__NR_newfstatat, dirfd, pathname, &s, flags);
 | 
			
		||||
   int ret = syscall(__NR_newfstatat, dirfd, pathname, &s, flags);
 | 
			
		||||
   copy_stat(buf, &s);
 | 
			
		||||
   return ret;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,11 @@
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
libc_bionic_src_files_mips64 += \
 | 
			
		||||
    arch-mips/string/memcmp.c \
 | 
			
		||||
    arch-mips/string/memcpy.S \
 | 
			
		||||
    arch-mips/string/memset.S \
 | 
			
		||||
    arch-mips/string/strcmp.S \
 | 
			
		||||
    arch-mips/string/strlen.c \
 | 
			
		||||
    bionic/__memcpy_chk.cpp \
 | 
			
		||||
    bionic/__memset_chk.cpp \
 | 
			
		||||
    bionic/__strcpy_chk.cpp \
 | 
			
		||||
@@ -12,10 +17,6 @@ libc_bionic_src_files_mips64 += \
 | 
			
		||||
    bionic/strchr.cpp \
 | 
			
		||||
    bionic/strnlen.c \
 | 
			
		||||
    bionic/strrchr.cpp \
 | 
			
		||||
    arch-mips/string/memcmp.c \
 | 
			
		||||
    arch-mips/string/memcpy.c \
 | 
			
		||||
    arch-mips/string/memset.c \
 | 
			
		||||
    arch-mips/string/strlen.c \
 | 
			
		||||
 | 
			
		||||
libc_freebsd_src_files_mips64 += \
 | 
			
		||||
    upstream-freebsd/lib/libc/string/wcscat.c \
 | 
			
		||||
@@ -34,7 +35,6 @@ libc_openbsd_src_files_mips64 += \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/stpcpy.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/stpncpy.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strcat.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strcmp.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strcpy.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strlcat.c \
 | 
			
		||||
    upstream-openbsd/lib/libc/string/strlcpy.c \
 | 
			
		||||
 
 | 
			
		||||
@@ -1,423 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2009
 | 
			
		||||
 *      MIPS Technologies, Inc., California.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from
 | 
			
		||||
 *    this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
 | 
			
		||||
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
 | 
			
		||||
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
			
		||||
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 *  memcpy.S
 | 
			
		||||
 *  Version: "043009"
 | 
			
		||||
 *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *  Include files
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This routine could be optimized for MIPS64. The current code only
 | 
			
		||||
 * uses MIPS32 instructions.
 | 
			
		||||
 */
 | 
			
		||||
#if defined(__MIPSEB__)
 | 
			
		||||
#  define LWHI	lwl		/* high part is left in big-endian	*/
 | 
			
		||||
#  define SWHI	swl		/* high part is left in big-endian	*/
 | 
			
		||||
#  define LWLO	lwr		/* low part is right in big-endian	*/
 | 
			
		||||
#  define SWLO	swr		/* low part is right in big-endian	*/
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__MIPSEL__)
 | 
			
		||||
#  define LWHI	lwr		/* high part is right in little-endian	*/
 | 
			
		||||
#  define SWHI	swr		/* high part is right in little-endian	*/
 | 
			
		||||
#  define LWLO	lwl		/* low part is left in big-endian	*/
 | 
			
		||||
#  define SWLO	swl		/* low part is left in big-endian	*/
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
LEAF(memcpy,0)
 | 
			
		||||
 | 
			
		||||
	.set	noreorder
 | 
			
		||||
	.set	noat
 | 
			
		||||
/*
 | 
			
		||||
 * Below we handle the case where memcpy is called with overlapping src and dst.
 | 
			
		||||
 * Although memcpy is not required to handle this case, some parts of Android like Skia
 | 
			
		||||
 * rely on such usage. We call memmove to handle such cases.
 | 
			
		||||
 */
 | 
			
		||||
	subu	t0,a0,a1
 | 
			
		||||
	sra	AT,t0,31
 | 
			
		||||
	xor	t1,t0,AT
 | 
			
		||||
	subu	t0,t1,AT
 | 
			
		||||
	sltu	AT,t0,a2
 | 
			
		||||
	beq	AT,zero,.Lmemcpy
 | 
			
		||||
	 la	t9,memmove
 | 
			
		||||
	jr	t9
 | 
			
		||||
	 nop
 | 
			
		||||
.Lmemcpy:
 | 
			
		||||
	slti	AT,a2,8
 | 
			
		||||
	bne	AT,zero,.Llast8
 | 
			
		||||
	 move	v0,a0	# memcpy returns the dst pointer
 | 
			
		||||
 | 
			
		||||
# Test if the src and dst are word-aligned, or can be made word-aligned
 | 
			
		||||
	xor	t8,a1,a0
 | 
			
		||||
	andi	t8,t8,0x3		# t8 is a0/a1 word-displacement
 | 
			
		||||
 | 
			
		||||
	bne	t8,zero,.Lunaligned
 | 
			
		||||
	 negu	a3,a0
 | 
			
		||||
 | 
			
		||||
	andi	a3,a3,0x3	# we need to copy a3 bytes to make a0/a1 aligned
 | 
			
		||||
	beq	a3,zero,.Lchk16w # when a3=0 then the dst (a0) is word-aligned
 | 
			
		||||
	 subu	a2,a2,a3	# now a2 is the remining bytes count
 | 
			
		||||
 | 
			
		||||
	LWHI	t8,0(a1)
 | 
			
		||||
	addu	a1,a1,a3
 | 
			
		||||
	SWHI	t8,0(a0)
 | 
			
		||||
	addu	a0,a0,a3
 | 
			
		||||
 | 
			
		||||
# Now the dst/src are mutually word-aligned with word-aligned addresses
 | 
			
		||||
.Lchk16w:
 | 
			
		||||
	andi	t8,a2,0x3f	# any whole 64-byte chunks?
 | 
			
		||||
				# t8 is the byte count after 64-byte chunks
 | 
			
		||||
 | 
			
		||||
	beq	a2,t8,.Lchk8w	# if a2==t8, no 64-byte chunks
 | 
			
		||||
				# There will be at most 1 32-byte chunk after it
 | 
			
		||||
	 subu	a3,a2,t8	# subtract from a2 the reminder
 | 
			
		||||
                                # Here a3 counts bytes in 16w chunks
 | 
			
		||||
	addu	a3,a0,a3	# Now a3 is the final dst after 64-byte chunks
 | 
			
		||||
 | 
			
		||||
	addu	t0,a0,a2	# t0 is the "past the end" address
 | 
			
		||||
 | 
			
		||||
# When in the loop we exercise "pref 30,x(a0)", the a0+x should not be past
 | 
			
		||||
# the "t0-32" address
 | 
			
		||||
# This means: for x=128 the last "safe" a0 address is "t0-160"
 | 
			
		||||
# Alternatively, for x=64 the last "safe" a0 address is "t0-96"
 | 
			
		||||
# In the current version we will use "pref 30,128(a0)", so "t0-160" is the limit
 | 
			
		||||
	subu	t9,t0,160	# t9 is the "last safe pref 30,128(a0)" address
 | 
			
		||||
 | 
			
		||||
	pref    0,0(a1)		# bring the first line of src, addr 0
 | 
			
		||||
	pref    0,32(a1)	# bring the second line of src, addr 32
 | 
			
		||||
	pref    0,64(a1)	# bring the third line of src, addr 64
 | 
			
		||||
	pref	30,32(a0)	# safe, as we have at least 64 bytes ahead
 | 
			
		||||
# In case the a0 > t9 don't use "pref 30" at all
 | 
			
		||||
	sgtu	v1,a0,t9
 | 
			
		||||
	bgtz	v1,.Lloop16w	# skip "pref 30,64(a0)" for too short arrays
 | 
			
		||||
	 nop
 | 
			
		||||
# otherwise, start with using pref30
 | 
			
		||||
	pref	30,64(a0)
 | 
			
		||||
.Lloop16w:
 | 
			
		||||
	pref	0,96(a1)
 | 
			
		||||
	lw	t0,0(a1)
 | 
			
		||||
	bgtz	v1,.Lskip_pref30_96	# skip "pref 30,96(a0)"
 | 
			
		||||
	 lw	t1,4(a1)
 | 
			
		||||
	pref    30,96(a0)   # continue setting up the dest, addr 96
 | 
			
		||||
.Lskip_pref30_96:
 | 
			
		||||
	lw	t2,8(a1)
 | 
			
		||||
	lw	t3,12(a1)
 | 
			
		||||
	lw	t4,16(a1)
 | 
			
		||||
	lw	t5,20(a1)
 | 
			
		||||
	lw	t6,24(a1)
 | 
			
		||||
	lw	t7,28(a1)
 | 
			
		||||
        pref    0,128(a1)    # bring the next lines of src, addr 128
 | 
			
		||||
 | 
			
		||||
	sw	t0,0(a0)
 | 
			
		||||
	sw	t1,4(a0)
 | 
			
		||||
	sw	t2,8(a0)
 | 
			
		||||
	sw	t3,12(a0)
 | 
			
		||||
	sw	t4,16(a0)
 | 
			
		||||
	sw	t5,20(a0)
 | 
			
		||||
	sw	t6,24(a0)
 | 
			
		||||
	sw	t7,28(a0)
 | 
			
		||||
 | 
			
		||||
	lw	t0,32(a1)
 | 
			
		||||
	bgtz	v1,.Lskip_pref30_128	# skip "pref 30,128(a0)"
 | 
			
		||||
	 lw	t1,36(a1)
 | 
			
		||||
	pref    30,128(a0)   # continue setting up the dest, addr 128
 | 
			
		||||
.Lskip_pref30_128:
 | 
			
		||||
	lw	t2,40(a1)
 | 
			
		||||
	lw	t3,44(a1)
 | 
			
		||||
	lw	t4,48(a1)
 | 
			
		||||
	lw	t5,52(a1)
 | 
			
		||||
	lw	t6,56(a1)
 | 
			
		||||
	lw	t7,60(a1)
 | 
			
		||||
        pref    0, 160(a1)    # bring the next lines of src, addr 160
 | 
			
		||||
 | 
			
		||||
	sw	t0,32(a0)
 | 
			
		||||
	sw	t1,36(a0)
 | 
			
		||||
	sw	t2,40(a0)
 | 
			
		||||
	sw	t3,44(a0)
 | 
			
		||||
	sw	t4,48(a0)
 | 
			
		||||
	sw	t5,52(a0)
 | 
			
		||||
	sw	t6,56(a0)
 | 
			
		||||
	sw	t7,60(a0)
 | 
			
		||||
 | 
			
		||||
	addiu	a0,a0,64	# adding 64 to dest
 | 
			
		||||
	sgtu	v1,a0,t9
 | 
			
		||||
	bne	a0,a3,.Lloop16w
 | 
			
		||||
	 addiu	a1,a1,64	# adding 64 to src
 | 
			
		||||
	move	a2,t8
 | 
			
		||||
 | 
			
		||||
# Here we have src and dest word-aligned but less than 64-bytes to go
 | 
			
		||||
 | 
			
		||||
.Lchk8w:
 | 
			
		||||
	pref 0, 0x0(a1)
 | 
			
		||||
	andi	t8,a2,0x1f	# is there a 32-byte chunk?
 | 
			
		||||
				# the t8 is the reminder count past 32-bytes
 | 
			
		||||
	beq	a2,t8,.Lchk1w	# when a2=t8, no 32-byte chunk
 | 
			
		||||
	 nop
 | 
			
		||||
 | 
			
		||||
	lw	t0,0(a1)
 | 
			
		||||
	lw	t1,4(a1)
 | 
			
		||||
	lw	t2,8(a1)
 | 
			
		||||
	lw	t3,12(a1)
 | 
			
		||||
	lw	t4,16(a1)
 | 
			
		||||
	lw	t5,20(a1)
 | 
			
		||||
	lw	t6,24(a1)
 | 
			
		||||
	lw	t7,28(a1)
 | 
			
		||||
	addiu	a1,a1,32
 | 
			
		||||
 | 
			
		||||
	sw	t0,0(a0)
 | 
			
		||||
	sw	t1,4(a0)
 | 
			
		||||
	sw	t2,8(a0)
 | 
			
		||||
	sw	t3,12(a0)
 | 
			
		||||
	sw	t4,16(a0)
 | 
			
		||||
	sw	t5,20(a0)
 | 
			
		||||
	sw	t6,24(a0)
 | 
			
		||||
	sw	t7,28(a0)
 | 
			
		||||
	addiu	a0,a0,32
 | 
			
		||||
 | 
			
		||||
.Lchk1w:
 | 
			
		||||
	andi	a2,t8,0x3	# now a2 is the reminder past 1w chunks
 | 
			
		||||
	beq	a2,t8,.Llast8
 | 
			
		||||
	 subu	a3,t8,a2	# a3 is count of bytes in 1w chunks
 | 
			
		||||
	addu	a3,a0,a3	# now a3 is the dst address past the 1w chunks
 | 
			
		||||
 | 
			
		||||
# copying in words (4-byte chunks)
 | 
			
		||||
.LwordCopy_loop:
 | 
			
		||||
	lw	t3,0(a1)	# the first t3 may be equal t0 ... optimize?
 | 
			
		||||
	addiu	a1,a1,4
 | 
			
		||||
	addiu	a0,a0,4
 | 
			
		||||
	bne	a0,a3,.LwordCopy_loop
 | 
			
		||||
	 sw	t3,-4(a0)
 | 
			
		||||
 | 
			
		||||
# For the last (<8) bytes
 | 
			
		||||
.Llast8:
 | 
			
		||||
	blez	a2,.Lleave
 | 
			
		||||
	 addu	a3,a0,a2	# a3 is the last dst address
 | 
			
		||||
.Llast8loop:
 | 
			
		||||
	lb	v1,0(a1)
 | 
			
		||||
	addiu	a1,a1,1
 | 
			
		||||
	addiu	a0,a0,1
 | 
			
		||||
	bne	a0,a3,.Llast8loop
 | 
			
		||||
	 sb	v1,-1(a0)
 | 
			
		||||
 | 
			
		||||
.Lleave:
 | 
			
		||||
	j	ra
 | 
			
		||||
	 nop
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# UNALIGNED case
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
.Lunaligned:
 | 
			
		||||
	# got here with a3="negu a0"
 | 
			
		||||
	andi	a3,a3,0x3	# test if the a0 is word aligned
 | 
			
		||||
	beqz	a3,.Lua_chk16w
 | 
			
		||||
	 subu	a2,a2,a3	# bytes left after initial a3 bytes
 | 
			
		||||
 | 
			
		||||
	LWHI	v1,0(a1)
 | 
			
		||||
	LWLO	v1,3(a1)
 | 
			
		||||
	addu	a1,a1,a3	# a3 may be here 1, 2 or 3
 | 
			
		||||
	SWHI	v1,0(a0)
 | 
			
		||||
	addu	a0,a0,a3	# below the dst will be word aligned (NOTE1)
 | 
			
		||||
 | 
			
		||||
.Lua_chk16w:
 | 
			
		||||
	andi	t8,a2,0x3f	# any whole 64-byte chunks?
 | 
			
		||||
				# t8 is the byte count after 64-byte chunks
 | 
			
		||||
	beq	a2,t8,.Lua_chk8w # if a2==t8, no 64-byte chunks
 | 
			
		||||
				# There will be at most 1 32-byte chunk after it
 | 
			
		||||
	 subu	a3,a2,t8	# subtract from a2 the reminder
 | 
			
		||||
                                # Here a3 counts bytes in 16w chunks
 | 
			
		||||
	addu	a3,a0,a3	# Now a3 is the final dst after 64-byte chunks
 | 
			
		||||
 | 
			
		||||
	addu	t0,a0,a2	# t0 is the "past the end" address
 | 
			
		||||
 | 
			
		||||
	subu	t9,t0,160	# t9 is the "last safe pref 30,128(a0)" address
 | 
			
		||||
 | 
			
		||||
	pref    0,0(a1)		# bring the first line of src, addr 0
 | 
			
		||||
	pref    0,32(a1)	# bring the second line of src, addr 32
 | 
			
		||||
	pref    0,64(a1)	# bring the third line of src, addr 64
 | 
			
		||||
	pref	30,32(a0)	# safe, as we have at least 64 bytes ahead
 | 
			
		||||
# In case the a0 > t9 don't use "pref 30" at all
 | 
			
		||||
	sgtu	v1,a0,t9
 | 
			
		||||
	bgtz	v1,.Lua_loop16w	# skip "pref 30,64(a0)" for too short arrays
 | 
			
		||||
	 nop
 | 
			
		||||
# otherwise, start with using pref30
 | 
			
		||||
	pref	30,64(a0)
 | 
			
		||||
.Lua_loop16w:
 | 
			
		||||
	pref	0,96(a1)
 | 
			
		||||
	LWHI	t0,0(a1)
 | 
			
		||||
	LWLO	t0,3(a1)
 | 
			
		||||
	LWHI	t1,4(a1)
 | 
			
		||||
	bgtz	v1,.Lua_skip_pref30_96
 | 
			
		||||
	 LWLO	t1,7(a1)
 | 
			
		||||
	pref    30,96(a0)   # continue setting up the dest, addr 96
 | 
			
		||||
.Lua_skip_pref30_96:
 | 
			
		||||
	LWHI	t2,8(a1)
 | 
			
		||||
	LWLO	t2,11(a1)
 | 
			
		||||
	LWHI	t3,12(a1)
 | 
			
		||||
	LWLO	t3,15(a1)
 | 
			
		||||
	LWHI	t4,16(a1)
 | 
			
		||||
	LWLO	t4,19(a1)
 | 
			
		||||
	LWHI	t5,20(a1)
 | 
			
		||||
	LWLO	t5,23(a1)
 | 
			
		||||
	LWHI	t6,24(a1)
 | 
			
		||||
	LWLO	t6,27(a1)
 | 
			
		||||
	LWHI	t7,28(a1)
 | 
			
		||||
	LWLO	t7,31(a1)
 | 
			
		||||
        pref    0,128(a1)    # bring the next lines of src, addr 128
 | 
			
		||||
 | 
			
		||||
	sw	t0,0(a0)
 | 
			
		||||
	sw	t1,4(a0)
 | 
			
		||||
	sw	t2,8(a0)
 | 
			
		||||
	sw	t3,12(a0)
 | 
			
		||||
	sw	t4,16(a0)
 | 
			
		||||
	sw	t5,20(a0)
 | 
			
		||||
	sw	t6,24(a0)
 | 
			
		||||
	sw	t7,28(a0)
 | 
			
		||||
 | 
			
		||||
	LWHI	t0,32(a1)
 | 
			
		||||
	LWLO	t0,35(a1)
 | 
			
		||||
	LWHI	t1,36(a1)
 | 
			
		||||
	bgtz	v1,.Lua_skip_pref30_128
 | 
			
		||||
	LWLO	t1,39(a1)
 | 
			
		||||
	pref    30,128(a0)   # continue setting up the dest, addr 128
 | 
			
		||||
.Lua_skip_pref30_128:
 | 
			
		||||
	LWHI	t2,40(a1)
 | 
			
		||||
	LWLO	t2,43(a1)
 | 
			
		||||
	LWHI	t3,44(a1)
 | 
			
		||||
	LWLO	t3,47(a1)
 | 
			
		||||
	LWHI	t4,48(a1)
 | 
			
		||||
	LWLO	t4,51(a1)
 | 
			
		||||
	LWHI	t5,52(a1)
 | 
			
		||||
	LWLO	t5,55(a1)
 | 
			
		||||
	LWHI	t6,56(a1)
 | 
			
		||||
	LWLO	t6,59(a1)
 | 
			
		||||
	LWHI	t7,60(a1)
 | 
			
		||||
	LWLO	t7,63(a1)
 | 
			
		||||
        pref    0, 160(a1)    # bring the next lines of src, addr 160
 | 
			
		||||
 | 
			
		||||
	sw	t0,32(a0)
 | 
			
		||||
	sw	t1,36(a0)
 | 
			
		||||
	sw	t2,40(a0)
 | 
			
		||||
	sw	t3,44(a0)
 | 
			
		||||
	sw	t4,48(a0)
 | 
			
		||||
	sw	t5,52(a0)
 | 
			
		||||
	sw	t6,56(a0)
 | 
			
		||||
	sw	t7,60(a0)
 | 
			
		||||
 | 
			
		||||
	addiu	a0,a0,64	# adding 64 to dest
 | 
			
		||||
	sgtu	v1,a0,t9
 | 
			
		||||
	bne	a0,a3,.Lua_loop16w
 | 
			
		||||
	 addiu	a1,a1,64	# adding 64 to src
 | 
			
		||||
	move	a2,t8
 | 
			
		||||
 | 
			
		||||
# Here we have src and dest word-aligned but less than 64-bytes to go
 | 
			
		||||
 | 
			
		||||
.Lua_chk8w:
 | 
			
		||||
	pref 0, 0x0(a1)
 | 
			
		||||
	andi	t8,a2,0x1f	# is there a 32-byte chunk?
 | 
			
		||||
				# the t8 is the reminder count
 | 
			
		||||
	beq	a2,t8,.Lua_chk1w # when a2=t8, no 32-byte chunk
 | 
			
		||||
	 nop
 | 
			
		||||
 | 
			
		||||
	LWHI	t0,0(a1)
 | 
			
		||||
	LWLO	t0,3(a1)
 | 
			
		||||
	LWHI	t1,4(a1)
 | 
			
		||||
	LWLO	t1,7(a1)
 | 
			
		||||
	LWHI	t2,8(a1)
 | 
			
		||||
	LWLO	t2,11(a1)
 | 
			
		||||
	LWHI	t3,12(a1)
 | 
			
		||||
	LWLO	t3,15(a1)
 | 
			
		||||
	LWHI	t4,16(a1)
 | 
			
		||||
	LWLO	t4,19(a1)
 | 
			
		||||
	LWHI	t5,20(a1)
 | 
			
		||||
	LWLO	t5,23(a1)
 | 
			
		||||
	LWHI	t6,24(a1)
 | 
			
		||||
	LWLO	t6,27(a1)
 | 
			
		||||
	LWHI	t7,28(a1)
 | 
			
		||||
	LWLO	t7,31(a1)
 | 
			
		||||
	addiu	a1,a1,32
 | 
			
		||||
 | 
			
		||||
	sw	t0,0(a0)
 | 
			
		||||
	sw	t1,4(a0)
 | 
			
		||||
	sw	t2,8(a0)
 | 
			
		||||
	sw	t3,12(a0)
 | 
			
		||||
	sw	t4,16(a0)
 | 
			
		||||
	sw	t5,20(a0)
 | 
			
		||||
	sw	t6,24(a0)
 | 
			
		||||
	sw	t7,28(a0)
 | 
			
		||||
	addiu	a0,a0,32
 | 
			
		||||
 | 
			
		||||
.Lua_chk1w:
 | 
			
		||||
	andi	a2,t8,0x3	# now a2 is the reminder past 1w chunks
 | 
			
		||||
	beq	a2,t8,.Lua_smallCopy
 | 
			
		||||
	 subu	a3,t8,a2	# a3 is count of bytes in 1w chunks
 | 
			
		||||
	addu	a3,a0,a3	# now a3 is the dst address past the 1w chunks
 | 
			
		||||
 | 
			
		||||
# copying in words (4-byte chunks)
 | 
			
		||||
.Lua_wordCopy_loop:
 | 
			
		||||
	LWHI	v1,0(a1)
 | 
			
		||||
	LWLO	v1,3(a1)
 | 
			
		||||
	addiu	a1,a1,4
 | 
			
		||||
	addiu	a0,a0,4		# note: dst=a0 is word aligned here, see NOTE1
 | 
			
		||||
	bne	a0,a3,.Lua_wordCopy_loop
 | 
			
		||||
	 sw	v1,-4(a0)
 | 
			
		||||
 | 
			
		||||
# Now less than 4 bytes (value in a2) left to copy
 | 
			
		||||
.Lua_smallCopy:
 | 
			
		||||
	beqz	a2,.Lleave
 | 
			
		||||
	addu	a3,a0,a2	# a3 is the last dst address
 | 
			
		||||
.Lua_smallCopy_loop:
 | 
			
		||||
	lb	v1,0(a1)
 | 
			
		||||
	addiu	a1,a1,1
 | 
			
		||||
	addiu	a0,a0,1
 | 
			
		||||
	bne	a0,a3,.Lua_smallCopy_loop
 | 
			
		||||
	 sb	v1,-1(a0)
 | 
			
		||||
 | 
			
		||||
	j	ra
 | 
			
		||||
	 nop
 | 
			
		||||
 | 
			
		||||
	.set	at
 | 
			
		||||
	.set	reorder
 | 
			
		||||
 | 
			
		||||
END(memcpy)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *  Implementation : Static functions
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
@@ -1,242 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2009
 | 
			
		||||
 *      MIPS Technologies, Inc., California.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
 | 
			
		||||
 *    contributors may be used to endorse or promote products derived from
 | 
			
		||||
 *    this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
 | 
			
		||||
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
 | 
			
		||||
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
			
		||||
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 *  memset.S, version "64h" with 1 cache line horizon for "pref 30" and 14 nops
 | 
			
		||||
 *  Version: "043009"
 | 
			
		||||
 *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *  Include files
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This routine could be optimized for MIPS64. The current code only
 | 
			
		||||
 * uses MIPS32 instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(__MIPSEB__)
 | 
			
		||||
#  define SWHI	swl		/* high part is left in big-endian	*/
 | 
			
		||||
#  define SWLO	swr		/* low part is right in big-endian	*/
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__MIPSEL__)
 | 
			
		||||
#  define SWHI	swr		/* high part is right in little-endian	*/
 | 
			
		||||
#  define SWLO	swl		/* low part is left in little-endian	*/
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !(defined(XGPROF) || defined(XPROF))
 | 
			
		||||
#undef SETUP_GP
 | 
			
		||||
#define SETUP_GP
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef NDEBUG
 | 
			
		||||
#define DBG #
 | 
			
		||||
#else
 | 
			
		||||
#define DBG
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
LEAF(memset,0)
 | 
			
		||||
 | 
			
		||||
	.set	noreorder
 | 
			
		||||
	.set	noat
 | 
			
		||||
 | 
			
		||||
	addu	t0,a0,a2		# t0 is the "past the end" address
 | 
			
		||||
	slti	AT,a2,4			# is a2 less than 4?
 | 
			
		||||
	bne	AT,zero,.Llast4		# if yes, go to last4
 | 
			
		||||
	 move	v0,a0			# memset returns the dst pointer
 | 
			
		||||
 | 
			
		||||
	beq	a1,zero,.Lset0
 | 
			
		||||
	 subu	v1,zero,a0
 | 
			
		||||
 | 
			
		||||
	# smear byte into 32 bit word
 | 
			
		||||
#if (__mips==32) && (__mips_isa_rev>=2)
 | 
			
		||||
	ins     a1, a1, 8, 8        # Replicate fill byte into half-word.
 | 
			
		||||
	ins     a1, a1, 16, 16      # Replicate fill byte into word.
 | 
			
		||||
#else
 | 
			
		||||
	and	a1,0xff
 | 
			
		||||
	sll	AT,a1,8
 | 
			
		||||
	or	a1,AT
 | 
			
		||||
	sll	AT,a1,16
 | 
			
		||||
	or	a1,AT
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
.Lset0:
 | 
			
		||||
	andi	v1,v1,0x3		# word-unaligned address?
 | 
			
		||||
	beq	v1,zero,.Laligned	# v1 is the unalignment count
 | 
			
		||||
	 subu	a2,a2,v1
 | 
			
		||||
	SWHI	a1,0(a0)
 | 
			
		||||
	addu	a0,a0,v1
 | 
			
		||||
 | 
			
		||||
# Here we have the "word-aligned" a0 (until the "last4")
 | 
			
		||||
.Laligned:
 | 
			
		||||
	andi	t8,a2,0x3f	# any 64-byte chunks?
 | 
			
		||||
				# t8 is the byte count past 64-byte chunks
 | 
			
		||||
	beq	a2,t8,.Lchk8w	# when a2==t8, no 64-byte chunks
 | 
			
		||||
				# There will be at most 1 32-byte chunk then
 | 
			
		||||
	 subu	a3,a2,t8	# subtract from a2 the reminder
 | 
			
		||||
				# Here a3 counts bytes in 16w chunks
 | 
			
		||||
	addu	a3,a0,a3	# Now a3 is the final dst after 64-byte chunks
 | 
			
		||||
 | 
			
		||||
# Find out, if there are any 64-byte chunks after which will be still at least
 | 
			
		||||
# 96 bytes left. The value "96" is calculated as needed buffer for
 | 
			
		||||
# "pref 30,64(a0)" prefetch, which can be used as "pref 30,0(a0)" after
 | 
			
		||||
# incrementing "a0" by 64.
 | 
			
		||||
# For "a2" below 160 there will be no such "pref 30 safe" 64-byte chunk.
 | 
			
		||||
#
 | 
			
		||||
	sltiu	v1,a2,160
 | 
			
		||||
	bgtz	v1,.Lloop16w_nopref30	# skip "pref 30,0(a0)"
 | 
			
		||||
	 subu	t7,a2,96	# subtract "pref 30 unsafe" region
 | 
			
		||||
		# below we have at least 1 64-byte chunk which is "pref 30 safe"
 | 
			
		||||
	andi	t6,t7,0x3f	# t6 is past "64-byte safe chunks" reminder
 | 
			
		||||
	subu	t5,t7,t6	# subtract from t7 the reminder
 | 
			
		||||
				# Here t5 counts bytes in 16w "safe" chunks
 | 
			
		||||
	addu	t4,a0,t5	# Now t4 is the dst after 64-byte "safe" chunks
 | 
			
		||||
 | 
			
		||||
# Don't use "pref 30,0(a0)" for a0 in a "middle" of a cache line
 | 
			
		||||
#	pref	30,0(a0)
 | 
			
		||||
# Here we are in the region, where it is safe to use "pref 30,64(a0)"
 | 
			
		||||
.Lloop16w:
 | 
			
		||||
	addiu	a0,a0,64
 | 
			
		||||
	pref	30,-32(a0)	# continue setting up the dest, addr 64-32
 | 
			
		||||
	sw	a1,-64(a0)
 | 
			
		||||
	sw	a1,-60(a0)
 | 
			
		||||
	sw	a1,-56(a0)
 | 
			
		||||
	sw	a1,-52(a0)
 | 
			
		||||
	sw	a1,-48(a0)
 | 
			
		||||
	sw	a1,-44(a0)
 | 
			
		||||
	sw	a1,-40(a0)
 | 
			
		||||
	sw	a1,-36(a0)
 | 
			
		||||
	nop
 | 
			
		||||
	nop			# the extra nop instructions help to balance
 | 
			
		||||
	nop			# cycles needed for "store" + "fill" + "evict"
 | 
			
		||||
	nop			# For 64byte store there are needed 8 fill
 | 
			
		||||
	nop			# and 8 evict cycles, i.e. at least 32 instr.
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	pref	30,0(a0)	# continue setting up the dest, addr 64-0
 | 
			
		||||
	sw	a1,-32(a0)
 | 
			
		||||
	sw	a1,-28(a0)
 | 
			
		||||
	sw	a1,-24(a0)
 | 
			
		||||
	sw	a1,-20(a0)
 | 
			
		||||
	sw	a1,-16(a0)
 | 
			
		||||
	sw	a1,-12(a0)
 | 
			
		||||
	sw	a1,-8(a0)
 | 
			
		||||
	sw	a1,-4(a0)
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop
 | 
			
		||||
	nop			# NOTE: adding 14 nop-s instead of 12 nop-s
 | 
			
		||||
	nop			# gives better results for "fast" memory
 | 
			
		||||
	nop
 | 
			
		||||
	bne	a0,t4,.Lloop16w
 | 
			
		||||
	 nop
 | 
			
		||||
 | 
			
		||||
	beq	a0,a3,.Lchk8w	# maybe no more 64-byte chunks?
 | 
			
		||||
	 nop			# this "delayed slot" is useless ...
 | 
			
		||||
 | 
			
		||||
.Lloop16w_nopref30:	# there could be up to 3 "64-byte nopref30" chunks
 | 
			
		||||
	addiu	a0,a0,64
 | 
			
		||||
	sw	a1,-64(a0)
 | 
			
		||||
	sw	a1,-60(a0)
 | 
			
		||||
	sw	a1,-56(a0)
 | 
			
		||||
	sw	a1,-52(a0)
 | 
			
		||||
	sw	a1,-48(a0)
 | 
			
		||||
	sw	a1,-44(a0)
 | 
			
		||||
	sw	a1,-40(a0)
 | 
			
		||||
	sw	a1,-36(a0)
 | 
			
		||||
	sw	a1,-32(a0)
 | 
			
		||||
	sw	a1,-28(a0)
 | 
			
		||||
	sw	a1,-24(a0)
 | 
			
		||||
	sw	a1,-20(a0)
 | 
			
		||||
	sw	a1,-16(a0)
 | 
			
		||||
	sw	a1,-12(a0)
 | 
			
		||||
	sw	a1,-8(a0)
 | 
			
		||||
	bne	a0,a3,.Lloop16w_nopref30
 | 
			
		||||
	 sw	a1,-4(a0)
 | 
			
		||||
 | 
			
		||||
.Lchk8w:		# t8 here is the byte count past 64-byte chunks
 | 
			
		||||
 | 
			
		||||
	andi	t7,t8,0x1f	# is there a 32-byte chunk?
 | 
			
		||||
				# the t7 is the reminder count past 32-bytes
 | 
			
		||||
	beq	t8,t7,.Lchk1w	# when t8==t7, no 32-byte chunk
 | 
			
		||||
	 move	a2,t7
 | 
			
		||||
 | 
			
		||||
	sw	a1,0(a0)
 | 
			
		||||
	sw	a1,4(a0)
 | 
			
		||||
	sw	a1,8(a0)
 | 
			
		||||
	sw	a1,12(a0)
 | 
			
		||||
	sw	a1,16(a0)
 | 
			
		||||
	sw	a1,20(a0)
 | 
			
		||||
	sw	a1,24(a0)
 | 
			
		||||
	sw	a1,28(a0)
 | 
			
		||||
	addiu	a0,a0,32
 | 
			
		||||
 | 
			
		||||
.Lchk1w:
 | 
			
		||||
	andi	t8,a2,0x3	# now t8 is the reminder past 1w chunks
 | 
			
		||||
	beq	a2,t8,.Llast4aligned
 | 
			
		||||
	 subu	a3,a2,t8	# a3 is the count of bytes in 1w chunks
 | 
			
		||||
	addu	a3,a0,a3	# now a3 is the dst address past the 1w chunks
 | 
			
		||||
 | 
			
		||||
# copying in words (4-byte chunks)
 | 
			
		||||
.LwordCopy_loop:
 | 
			
		||||
	addiu	a0,a0,4
 | 
			
		||||
	bne	a0,a3,.LwordCopy_loop
 | 
			
		||||
	 sw	a1,-4(a0)
 | 
			
		||||
 | 
			
		||||
# store last 0-3 bytes
 | 
			
		||||
# this will repeat the last store if the memset finishes on a word boundary
 | 
			
		||||
.Llast4aligned:
 | 
			
		||||
	j	ra
 | 
			
		||||
	 SWLO	a1,-1(t0)
 | 
			
		||||
 | 
			
		||||
.Llast4:
 | 
			
		||||
	beq	a0,t0,.Llast4e
 | 
			
		||||
.Llast4l:
 | 
			
		||||
	 addiu	a0,a0,1
 | 
			
		||||
	bne	a0,t0,.Llast4l
 | 
			
		||||
	 sb	a1,-1(a0)
 | 
			
		||||
.Llast4e:
 | 
			
		||||
	j	ra
 | 
			
		||||
	 nop
 | 
			
		||||
 | 
			
		||||
	.set	at
 | 
			
		||||
	.set	reorder
 | 
			
		||||
 | 
			
		||||
END(memset)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 *  Implementation : Static functions
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
@@ -1,148 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2010 MIPS Technologies, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *      * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *        notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *      * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *        notice, this list of conditions and the following disclaimer
 | 
			
		||||
 *        in the documentation and/or other materials provided with
 | 
			
		||||
 *        the distribution.
 | 
			
		||||
 *      * Neither the name of MIPS Technologies Inc. nor the names of its
 | 
			
		||||
 *        contributors may be used to endorse or promote products derived
 | 
			
		||||
 *        from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __MIPS_STRING_OPS_H
 | 
			
		||||
#define __MIPS_STRING_OPS_H
 | 
			
		||||
    /* This definition of the byte bitfields uses the
 | 
			
		||||
       assumption that the layout of the bitfields is
 | 
			
		||||
       equivalent to the layout in memory.  Generally,
 | 
			
		||||
       for the MIPS ABIs, this is true. If you compile
 | 
			
		||||
       the strcmp.c file with -DSMOKE_TEST_NEW_STRCMP,
 | 
			
		||||
       this assumption will be tested.
 | 
			
		||||
 | 
			
		||||
       Also, regardless of char signedness, ANSI C dictates that
 | 
			
		||||
       strcmp() treats each character as unsigned char.  For
 | 
			
		||||
       strlen and the like, signedness doesn't matter.
 | 
			
		||||
 | 
			
		||||
       Also, this code assumes that there are 8-bits per 'char'.  */
 | 
			
		||||
 | 
			
		||||
#if __mips64
 | 
			
		||||
typedef struct bits
 | 
			
		||||
{
 | 
			
		||||
  unsigned long B0:8, B1:8, B2:8, B3:8, B4:8, B5:8, B6:8, B7:8;
 | 
			
		||||
} bits_t;
 | 
			
		||||
#else
 | 
			
		||||
typedef struct bits
 | 
			
		||||
{
 | 
			
		||||
  unsigned long B0:8, B1:8, B2:8, B3:8;
 | 
			
		||||
} bits_t;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef _ULW
 | 
			
		||||
    /* for MIPS GCC, there is no unaligned builtins - so this code forces
 | 
			
		||||
       the compiler to treat the pointer access as unaligned.  */
 | 
			
		||||
struct ulw
 | 
			
		||||
{
 | 
			
		||||
  unsigned long b;
 | 
			
		||||
} __attribute__ ((packed));
 | 
			
		||||
 | 
			
		||||
#define _ULW(__x) ((struct ulw *) ((char *)(&__x)))->b;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* This union assumes that small structures can be in registers.  If
 | 
			
		||||
   not, then memory accesses will be done - not optimal, but ok.  */
 | 
			
		||||
typedef union
 | 
			
		||||
{
 | 
			
		||||
  unsigned long v;
 | 
			
		||||
  bits_t b;
 | 
			
		||||
} bitfields_t;
 | 
			
		||||
 | 
			
		||||
#ifndef detect_zero
 | 
			
		||||
/* __mips_dsp, __mips_dspr2, and __mips64 are predefined by
 | 
			
		||||
   the compiler, based on command line options.  */
 | 
			
		||||
#if (__mips_dsp || __mips_dspr2) && !__mips64
 | 
			
		||||
#define __mips_using_dsp 1
 | 
			
		||||
 | 
			
		||||
/* DSP 4-lane (8 unsigned bits per line) subtract and saturate
 | 
			
		||||
 * Intrinsic operation. How this works:
 | 
			
		||||
 *     Given a 4-byte string of "ABC\0", subtract this as
 | 
			
		||||
 *     an unsigned integer from 0x01010101:
 | 
			
		||||
 *	   0x01010101
 | 
			
		||||
 *       - 0x41424300
 | 
			
		||||
 *        -----------
 | 
			
		||||
 (         0xbfbebe01 <-- answer without saturation
 | 
			
		||||
 *	   0x00000001 <-- answer with saturation
 | 
			
		||||
 * When this 4-lane vector is treated as an unsigned int value,
 | 
			
		||||
 * a non-zero answer indicates the presence of a zero in the
 | 
			
		||||
 * original 4-byte argument.  */
 | 
			
		||||
 | 
			
		||||
typedef signed char v4i8 __attribute__ ((vector_size (4)));
 | 
			
		||||
 | 
			
		||||
#define detect_zero(__x,__y,__01s,__80s)\
 | 
			
		||||
       ((unsigned) __builtin_mips_subu_s_qb((v4i8) __01s,(v4i8) __x))
 | 
			
		||||
 | 
			
		||||
    /* sets all 4 lanes to requested byte.  */
 | 
			
		||||
#define set_byte_lanes(__x) ((unsigned) __builtin_mips_repl_qb(__x))
 | 
			
		||||
 | 
			
		||||
    /* sets all 4 lanes to 0x01.  */
 | 
			
		||||
#define def_and_set_01(__x) unsigned long __x = (unsigned) __builtin_mips_repl_qb(0x01)
 | 
			
		||||
 | 
			
		||||
    /* sets all 4 lanes to 0x80. Not needed when subu_s.qb used. */
 | 
			
		||||
#define def_and_set_80(__x) /* do nothing */
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
    /* this version, originally published in the 80's, uses
 | 
			
		||||
       a reverse-carry-set like determination of the zero byte.
 | 
			
		||||
       The steps are, for __x = 0x31ff0001:
 | 
			
		||||
       __x - _01s = 0x30fdff00
 | 
			
		||||
       ~__x = 0xce00fffe
 | 
			
		||||
       ((__x - _01s) & ~__x) = 0x0000ff00
 | 
			
		||||
       x & _80s = 0x00008000 <- byte 3 was zero
 | 
			
		||||
       Some implementaions naively assume that characters are
 | 
			
		||||
       always 7-bit unsigned ASCII. With that assumption, the
 | 
			
		||||
       "& ~x" is usually discarded. Since character strings
 | 
			
		||||
       are 8-bit, the and is needed to catch the case of
 | 
			
		||||
       a false positive when the byte is 0x80. */
 | 
			
		||||
 | 
			
		||||
#define detect_zero(__x,__y,_01s,_80s)\
 | 
			
		||||
	((unsigned) (((__x) - _01s) & ~(__x)) & _80s)
 | 
			
		||||
 | 
			
		||||
#if __mips64
 | 
			
		||||
#define def_and_set_80(__x) unsigned long __x =  0x8080808080808080ul
 | 
			
		||||
#define def_and_set_01(__x)  unsigned long __x = 0x0101010101010101ul
 | 
			
		||||
#else
 | 
			
		||||
#define def_and_set_80(__x) unsigned long __x = 0x80808080ul
 | 
			
		||||
#define def_and_set_01(__x) unsigned long __x = 0x01010101ul
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* dealing with 'void *' conversions without using extra variables. */
 | 
			
		||||
#define get_byte(__x,__idx) (((unsigned char *) (__x))[__idx])
 | 
			
		||||
#define set_byte(__x,__idx,__fill) ((unsigned char *) (__x))[__idx] = (__fill)
 | 
			
		||||
#define get_word(__x,__idx) (((unsigned long *) (__x))[__idx])
 | 
			
		||||
#define set_word(__x,__idx,__fill) ((unsigned long *) (__x))[__idx] = (__fill)
 | 
			
		||||
#define inc_ptr_as(__type,__x,__inc) __x = (void *) (((__type) __x) + (__inc))
 | 
			
		||||
#define cvt_ptr_to(__type,__x) ((__type) (__x))
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,224 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2010 MIPS Technologies, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *      * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *        notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *      * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *        notice, this list of conditions and the following disclaimer
 | 
			
		||||
 *        in the documentation and/or other materials provided with
 | 
			
		||||
 *        the distribution.
 | 
			
		||||
 *      * Neither the name of MIPS Technologies Inc. nor the names of its
 | 
			
		||||
 *        contributors may be used to endorse or promote products derived
 | 
			
		||||
 *        from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "mips-string-ops.h"
 | 
			
		||||
 | 
			
		||||
#define do_strlen_word(__av) {\
 | 
			
		||||
    if (detect_zero(x,x,_01s,_80s)) break;\
 | 
			
		||||
    x = __av;\
 | 
			
		||||
    cnt += sizeof (unsigned);\
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define do_strlen_byte(__x) {\
 | 
			
		||||
  if ((bx.b.B##__x) == 0) break;\
 | 
			
		||||
  ++cnt;\
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if SMOKE_TEST_MIPS_STRLEN
 | 
			
		||||
#define strlen my_strlen
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
strlen (const char *_a)
 | 
			
		||||
{
 | 
			
		||||
  int cnt = 0;
 | 
			
		||||
  unsigned long x;
 | 
			
		||||
 | 
			
		||||
  /* align the string to word boundary so we can do word at a time.  */
 | 
			
		||||
  if ((cvt_ptr_to (unsigned long, _a) & (sizeof (unsigned long) - 1)) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      if ((cvt_ptr_to (unsigned long, _a) & 1) != 0)
 | 
			
		||||
	{
 | 
			
		||||
	  if (get_byte (_a, 0) == 0)
 | 
			
		||||
	    return cnt;
 | 
			
		||||
	  /* set bit 1 so 2-bytes are checked and incremented. */
 | 
			
		||||
	  inc_ptr_as (char *, _a, 1);
 | 
			
		||||
	  ++cnt;
 | 
			
		||||
	}
 | 
			
		||||
      if ((cvt_ptr_to (unsigned long, _a) & 2) != 0)
 | 
			
		||||
	{
 | 
			
		||||
	  if (get_byte (_a, 0) == 0)
 | 
			
		||||
	    return cnt + 0;
 | 
			
		||||
	  if (get_byte (_a, 1) == 0)
 | 
			
		||||
	    return cnt + 1;
 | 
			
		||||
	  inc_ptr_as (char *, _a, 2);
 | 
			
		||||
	  cnt += 2;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if __mips64
 | 
			
		||||
#error strlen: mips64 check for 4-byte alignment not implemented.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (1)
 | 
			
		||||
    {
 | 
			
		||||
      def_and_set_01 (_01s);
 | 
			
		||||
      def_and_set_80 (_80s);
 | 
			
		||||
 | 
			
		||||
      /* as advantagous as it is to performance, this code cannot pre-load
 | 
			
		||||
         the following word, nor can it prefetch the next line at the start
 | 
			
		||||
         of the loop since the string can be at the end of a page with the
 | 
			
		||||
         following page unmapped. There are tests in the suite to catch
 | 
			
		||||
         any attempt to go beyond the current word. */
 | 
			
		||||
      x = get_word (_a, 0);
 | 
			
		||||
      while (1)
 | 
			
		||||
	{
 | 
			
		||||
	  /* doing 8 words should cover most strings.  */
 | 
			
		||||
	  do_strlen_word (get_word (_a, 1));
 | 
			
		||||
	  do_strlen_word (get_word (_a, 2));
 | 
			
		||||
	  do_strlen_word (get_word (_a, 3));
 | 
			
		||||
	  do_strlen_word (get_word (_a, 4));
 | 
			
		||||
	  do_strlen_word (get_word (_a, 5));
 | 
			
		||||
	  do_strlen_word (get_word (_a, 6));
 | 
			
		||||
	  do_strlen_word (get_word (_a, 7));
 | 
			
		||||
	  do_strlen_word (get_word (_a, 8));
 | 
			
		||||
	  inc_ptr_as (unsigned long*, _a, 8);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      /* pull apart the last word processed and find the zero.  */
 | 
			
		||||
      bitfields_t bx;
 | 
			
		||||
      bx.v = x;
 | 
			
		||||
#if __mips64
 | 
			
		||||
      do_strlen_byte (0);
 | 
			
		||||
      do_strlen_byte (1);
 | 
			
		||||
      do_strlen_byte (2);
 | 
			
		||||
      do_strlen_byte (3);
 | 
			
		||||
      do_strlen_byte (4);
 | 
			
		||||
      do_strlen_byte (5);
 | 
			
		||||
      do_strlen_byte (6);
 | 
			
		||||
#else
 | 
			
		||||
      do_strlen_byte (0);
 | 
			
		||||
      do_strlen_byte (1);
 | 
			
		||||
      do_strlen_byte (2);
 | 
			
		||||
#endif
 | 
			
		||||
      /* last byte is zero */
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  return cnt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef do_strlen_byte
 | 
			
		||||
#undef do_strlen_word
 | 
			
		||||
 | 
			
		||||
#if SMOKE_TEST_MIPS_STRLEN
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
char str1[] = "DHRYSTONE PROGRAM, 1'ST STRING";
 | 
			
		||||
char str2[] = "DHRYSTONE PROGRAM, 2'ST STRING";
 | 
			
		||||
 | 
			
		||||
char str3[] = "another string";
 | 
			
		||||
char str4[] = "another";
 | 
			
		||||
 | 
			
		||||
char str5[] = "somes tring";
 | 
			
		||||
char str6[] = "somes_tring";
 | 
			
		||||
 | 
			
		||||
char str7[16], str8[16];
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
chk (unsigned long mine, unsigned long libs, int *errors)
 | 
			
		||||
{
 | 
			
		||||
  static char answer[1024];
 | 
			
		||||
  char *result = mine == libs ? "PASS" : "FAIL";
 | 
			
		||||
  sprintf (answer, "new_strlen=%d: lib_strlen=%d: %s!", mine, libs, result);
 | 
			
		||||
  if (mine != libs)
 | 
			
		||||
    (*errors)++;
 | 
			
		||||
  return answer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  int errors = 0;
 | 
			
		||||
  /* set -1 in one position */
 | 
			
		||||
  str6[5] = 0xff;
 | 
			
		||||
  /* set zero in same position with junk in following 3 */
 | 
			
		||||
  str7[0] = str8[0] = 0;
 | 
			
		||||
  str7[1] = 0xff;
 | 
			
		||||
  str7[2] = 'a';
 | 
			
		||||
  str7[3] = 2;
 | 
			
		||||
  str8[1] = 's';
 | 
			
		||||
  str8[2] = -2;
 | 
			
		||||
  str8[3] = 0;
 | 
			
		||||
 | 
			
		||||
  fprintf (stderr, "========== mips_strlen%s test...\n",
 | 
			
		||||
	   argv[0] ? argv[0] : "unknown strlen");
 | 
			
		||||
#define P(__x,__y) {\
 | 
			
		||||
    int a = my_strlen(__x + __y);\
 | 
			
		||||
    int b = (strlen)(__x + __y) /* library version */;\
 | 
			
		||||
    fprintf(stderr,"%s+%d: %s\n",#__x,__y,chk(a,b,&errors));\
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  P (str1, 0);
 | 
			
		||||
  P (str1, 1);
 | 
			
		||||
  P (str1, 2);
 | 
			
		||||
  P (str1, 3);
 | 
			
		||||
 | 
			
		||||
  P (str2, 0);
 | 
			
		||||
  P (str2, 1);
 | 
			
		||||
  P (str2, 2);
 | 
			
		||||
  P (str2, 3);
 | 
			
		||||
 | 
			
		||||
  P (str3, 0);
 | 
			
		||||
  P (str3, 1);
 | 
			
		||||
  P (str3, 2);
 | 
			
		||||
  P (str3, 3);
 | 
			
		||||
 | 
			
		||||
  P (str4, 0);
 | 
			
		||||
  P (str4, 1);
 | 
			
		||||
  P (str4, 2);
 | 
			
		||||
  P (str4, 3);
 | 
			
		||||
 | 
			
		||||
  P (str5, 0);
 | 
			
		||||
  P (str5, 1);
 | 
			
		||||
  P (str5, 2);
 | 
			
		||||
  P (str5, 3);
 | 
			
		||||
 | 
			
		||||
  P (str6, 0);
 | 
			
		||||
  P (str6, 1);
 | 
			
		||||
  P (str6, 2);
 | 
			
		||||
  P (str6, 3);
 | 
			
		||||
 | 
			
		||||
  P (str7, 0);
 | 
			
		||||
  P (str7, 1);
 | 
			
		||||
  P (str7, 2);
 | 
			
		||||
  P (str7, 3);
 | 
			
		||||
 | 
			
		||||
  P (str8, 0);
 | 
			
		||||
  P (str8, 1);
 | 
			
		||||
  P (str8, 2);
 | 
			
		||||
  P (str8, 3);
 | 
			
		||||
 | 
			
		||||
  return errors;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__clock_nanosleep)
 | 
			
		||||
ENTRY(___clock_nanosleep)
 | 
			
		||||
    .set push
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    li v0, __NR_clock_nanosleep
 | 
			
		||||
@@ -22,5 +22,5 @@ ENTRY(__clock_nanosleep)
 | 
			
		||||
    j t9
 | 
			
		||||
    move ra, t0
 | 
			
		||||
    .set pop
 | 
			
		||||
END(__clock_nanosleep)
 | 
			
		||||
.hidden __clock_nanosleep
 | 
			
		||||
END(___clock_nanosleep)
 | 
			
		||||
.hidden ___clock_nanosleep
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fgetxattr)
 | 
			
		||||
ENTRY(___fgetxattr)
 | 
			
		||||
    .set push
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    li v0, __NR_fgetxattr
 | 
			
		||||
@@ -22,4 +22,5 @@ ENTRY(fgetxattr)
 | 
			
		||||
    j t9
 | 
			
		||||
    move ra, t0
 | 
			
		||||
    .set pop
 | 
			
		||||
END(fgetxattr)
 | 
			
		||||
END(___fgetxattr)
 | 
			
		||||
.hidden ___fgetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(flistxattr)
 | 
			
		||||
ENTRY(___flistxattr)
 | 
			
		||||
    .set push
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    li v0, __NR_flistxattr
 | 
			
		||||
@@ -22,4 +22,5 @@ ENTRY(flistxattr)
 | 
			
		||||
    j t9
 | 
			
		||||
    move ra, t0
 | 
			
		||||
    .set pop
 | 
			
		||||
END(flistxattr)
 | 
			
		||||
END(___flistxattr)
 | 
			
		||||
.hidden ___flistxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fsetxattr)
 | 
			
		||||
ENTRY(___fsetxattr)
 | 
			
		||||
    .set push
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    li v0, __NR_fsetxattr
 | 
			
		||||
@@ -22,4 +22,5 @@ ENTRY(fsetxattr)
 | 
			
		||||
    j t9
 | 
			
		||||
    move ra, t0
 | 
			
		||||
    .set pop
 | 
			
		||||
END(fsetxattr)
 | 
			
		||||
END(___fsetxattr)
 | 
			
		||||
.hidden ___fsetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
ENTRY(___rt_sigqueueinfo)
 | 
			
		||||
    .set push
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    li v0, __NR_rt_sigqueueinfo
 | 
			
		||||
@@ -22,5 +22,5 @@ ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
    j t9
 | 
			
		||||
    move ra, t0
 | 
			
		||||
    .set pop
 | 
			
		||||
END(__rt_sigqueueinfo)
 | 
			
		||||
.hidden __rt_sigqueueinfo
 | 
			
		||||
END(___rt_sigqueueinfo)
 | 
			
		||||
.hidden ___rt_sigqueueinfo
 | 
			
		||||
							
								
								
									
										25
									
								
								libc/arch-mips64/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								libc/arch-mips64/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_readv)
 | 
			
		||||
    .set push
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    li v0, __NR_process_vm_readv
 | 
			
		||||
    syscall
 | 
			
		||||
    bnez a3, 1f
 | 
			
		||||
    move a0, v0
 | 
			
		||||
    j ra
 | 
			
		||||
    nop
 | 
			
		||||
1:
 | 
			
		||||
    move t0, ra
 | 
			
		||||
    bal     2f
 | 
			
		||||
    nop
 | 
			
		||||
2:
 | 
			
		||||
    .cpsetup ra, t1, 2b
 | 
			
		||||
    LA t9,__set_errno_internal
 | 
			
		||||
    .cpreturn
 | 
			
		||||
    j t9
 | 
			
		||||
    move ra, t0
 | 
			
		||||
    .set pop
 | 
			
		||||
END(process_vm_readv)
 | 
			
		||||
							
								
								
									
										25
									
								
								libc/arch-mips64/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								libc/arch-mips64/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_writev)
 | 
			
		||||
    .set push
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    li v0, __NR_process_vm_writev
 | 
			
		||||
    syscall
 | 
			
		||||
    bnez a3, 1f
 | 
			
		||||
    move a0, v0
 | 
			
		||||
    j ra
 | 
			
		||||
    nop
 | 
			
		||||
1:
 | 
			
		||||
    move t0, ra
 | 
			
		||||
    bal     2f
 | 
			
		||||
    nop
 | 
			
		||||
2:
 | 
			
		||||
    .cpsetup ra, t1, 2b
 | 
			
		||||
    LA t9,__set_errno_internal
 | 
			
		||||
    .cpreturn
 | 
			
		||||
    j t9
 | 
			
		||||
    move ra, t0
 | 
			
		||||
    .set pop
 | 
			
		||||
END(process_vm_writev)
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__clock_nanosleep)
 | 
			
		||||
ENTRY(___clock_nanosleep)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    .cfi_def_cfa_offset 8
 | 
			
		||||
    .cfi_rel_offset ebx, 0
 | 
			
		||||
@@ -33,4 +33,5 @@ ENTRY(__clock_nanosleep)
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(__clock_nanosleep)
 | 
			
		||||
END(___clock_nanosleep)
 | 
			
		||||
.hidden ___clock_nanosleep
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fgetxattr)
 | 
			
		||||
ENTRY(___fgetxattr)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    .cfi_def_cfa_offset 8
 | 
			
		||||
    .cfi_rel_offset ebx, 0
 | 
			
		||||
@@ -33,4 +33,5 @@ ENTRY(fgetxattr)
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(fgetxattr)
 | 
			
		||||
END(___fgetxattr)
 | 
			
		||||
.hidden ___fgetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(flistxattr)
 | 
			
		||||
ENTRY(___flistxattr)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    .cfi_def_cfa_offset 8
 | 
			
		||||
    .cfi_rel_offset ebx, 0
 | 
			
		||||
@@ -28,4 +28,5 @@ ENTRY(flistxattr)
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(flistxattr)
 | 
			
		||||
END(___flistxattr)
 | 
			
		||||
.hidden ___flistxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fsetxattr)
 | 
			
		||||
ENTRY(___fsetxattr)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    .cfi_def_cfa_offset 8
 | 
			
		||||
    .cfi_rel_offset ebx, 0
 | 
			
		||||
@@ -38,4 +38,5 @@ ENTRY(fsetxattr)
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(fsetxattr)
 | 
			
		||||
END(___fsetxattr)
 | 
			
		||||
.hidden ___fsetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
ENTRY(___rt_sigqueueinfo)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    .cfi_def_cfa_offset 8
 | 
			
		||||
    .cfi_rel_offset ebx, 0
 | 
			
		||||
@@ -28,4 +28,5 @@ ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(__rt_sigqueueinfo)
 | 
			
		||||
END(___rt_sigqueueinfo)
 | 
			
		||||
.hidden ___rt_sigqueueinfo
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(ftruncate)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    .cfi_def_cfa_offset 8
 | 
			
		||||
    .cfi_rel_offset ebx, 0
 | 
			
		||||
    pushl   %ecx
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset ecx, 0
 | 
			
		||||
    mov     12(%esp), %ebx
 | 
			
		||||
    mov     16(%esp), %ecx
 | 
			
		||||
    movl    $__NR_ftruncate, %eax
 | 
			
		||||
    int     $0x80
 | 
			
		||||
    cmpl    $-MAX_ERRNO, %eax
 | 
			
		||||
    jb      1f
 | 
			
		||||
    negl    %eax
 | 
			
		||||
    pushl   %eax
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
    addl    $4, %esp
 | 
			
		||||
1:
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(ftruncate)
 | 
			
		||||
							
								
								
									
										46
									
								
								libc/arch-x86/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								libc/arch-x86/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_readv)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    .cfi_def_cfa_offset 8
 | 
			
		||||
    .cfi_rel_offset ebx, 0
 | 
			
		||||
    pushl   %ecx
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset ecx, 0
 | 
			
		||||
    pushl   %edx
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset edx, 0
 | 
			
		||||
    pushl   %esi
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset esi, 0
 | 
			
		||||
    pushl   %edi
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset edi, 0
 | 
			
		||||
    pushl   %ebp
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset ebp, 0
 | 
			
		||||
    mov     28(%esp), %ebx
 | 
			
		||||
    mov     32(%esp), %ecx
 | 
			
		||||
    mov     36(%esp), %edx
 | 
			
		||||
    mov     40(%esp), %esi
 | 
			
		||||
    mov     44(%esp), %edi
 | 
			
		||||
    mov     48(%esp), %ebp
 | 
			
		||||
    movl    $__NR_process_vm_readv, %eax
 | 
			
		||||
    int     $0x80
 | 
			
		||||
    cmpl    $-MAX_ERRNO, %eax
 | 
			
		||||
    jb      1f
 | 
			
		||||
    negl    %eax
 | 
			
		||||
    pushl   %eax
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
    addl    $4, %esp
 | 
			
		||||
1:
 | 
			
		||||
    popl    %ebp
 | 
			
		||||
    popl    %edi
 | 
			
		||||
    popl    %esi
 | 
			
		||||
    popl    %edx
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(process_vm_readv)
 | 
			
		||||
							
								
								
									
										46
									
								
								libc/arch-x86/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								libc/arch-x86/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_writev)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    .cfi_def_cfa_offset 8
 | 
			
		||||
    .cfi_rel_offset ebx, 0
 | 
			
		||||
    pushl   %ecx
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset ecx, 0
 | 
			
		||||
    pushl   %edx
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset edx, 0
 | 
			
		||||
    pushl   %esi
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset esi, 0
 | 
			
		||||
    pushl   %edi
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset edi, 0
 | 
			
		||||
    pushl   %ebp
 | 
			
		||||
    .cfi_adjust_cfa_offset 4
 | 
			
		||||
    .cfi_rel_offset ebp, 0
 | 
			
		||||
    mov     28(%esp), %ebx
 | 
			
		||||
    mov     32(%esp), %ecx
 | 
			
		||||
    mov     36(%esp), %edx
 | 
			
		||||
    mov     40(%esp), %esi
 | 
			
		||||
    mov     44(%esp), %edi
 | 
			
		||||
    mov     48(%esp), %ebp
 | 
			
		||||
    movl    $__NR_process_vm_writev, %eax
 | 
			
		||||
    int     $0x80
 | 
			
		||||
    cmpl    $-MAX_ERRNO, %eax
 | 
			
		||||
    jb      1f
 | 
			
		||||
    negl    %eax
 | 
			
		||||
    pushl   %eax
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
    addl    $4, %esp
 | 
			
		||||
1:
 | 
			
		||||
    popl    %ebp
 | 
			
		||||
    popl    %edi
 | 
			
		||||
    popl    %esi
 | 
			
		||||
    popl    %edx
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(process_vm_writev)
 | 
			
		||||
@@ -1897,8 +1897,8 @@ L(strcmp_exitz):
 | 
			
		||||
 | 
			
		||||
	.p2align 4
 | 
			
		||||
L(Byte0):
 | 
			
		||||
	movzx	(%rsi), %ecx
 | 
			
		||||
	movzx	(%rdi), %eax
 | 
			
		||||
	movzbl	(%rsi), %ecx
 | 
			
		||||
	movzbl	(%rdi), %eax
 | 
			
		||||
 | 
			
		||||
	sub	%ecx, %eax
 | 
			
		||||
	ret
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__clock_nanosleep)
 | 
			
		||||
ENTRY(___clock_nanosleep)
 | 
			
		||||
    movq    %rcx, %r10
 | 
			
		||||
    movl    $__NR_clock_nanosleep, %eax
 | 
			
		||||
    syscall
 | 
			
		||||
@@ -13,5 +13,5 @@ ENTRY(__clock_nanosleep)
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
1:
 | 
			
		||||
    ret
 | 
			
		||||
END(__clock_nanosleep)
 | 
			
		||||
.hidden __clock_nanosleep
 | 
			
		||||
END(___clock_nanosleep)
 | 
			
		||||
.hidden ___clock_nanosleep
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fgetxattr)
 | 
			
		||||
ENTRY(___fgetxattr)
 | 
			
		||||
    movq    %rcx, %r10
 | 
			
		||||
    movl    $__NR_fgetxattr, %eax
 | 
			
		||||
    syscall
 | 
			
		||||
@@ -13,4 +13,5 @@ ENTRY(fgetxattr)
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
1:
 | 
			
		||||
    ret
 | 
			
		||||
END(fgetxattr)
 | 
			
		||||
END(___fgetxattr)
 | 
			
		||||
.hidden ___fgetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(flistxattr)
 | 
			
		||||
ENTRY(___flistxattr)
 | 
			
		||||
    movl    $__NR_flistxattr, %eax
 | 
			
		||||
    syscall
 | 
			
		||||
    cmpq    $-MAX_ERRNO, %rax
 | 
			
		||||
@@ -12,4 +12,5 @@ ENTRY(flistxattr)
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
1:
 | 
			
		||||
    ret
 | 
			
		||||
END(flistxattr)
 | 
			
		||||
END(___flistxattr)
 | 
			
		||||
.hidden ___flistxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(fsetxattr)
 | 
			
		||||
ENTRY(___fsetxattr)
 | 
			
		||||
    movq    %rcx, %r10
 | 
			
		||||
    movl    $__NR_fsetxattr, %eax
 | 
			
		||||
    syscall
 | 
			
		||||
@@ -13,4 +13,5 @@ ENTRY(fsetxattr)
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
1:
 | 
			
		||||
    ret
 | 
			
		||||
END(fsetxattr)
 | 
			
		||||
END(___fsetxattr)
 | 
			
		||||
.hidden ___fsetxattr
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
ENTRY(___rt_sigqueueinfo)
 | 
			
		||||
    movl    $__NR_rt_sigqueueinfo, %eax
 | 
			
		||||
    syscall
 | 
			
		||||
    cmpq    $-MAX_ERRNO, %rax
 | 
			
		||||
@@ -12,5 +12,5 @@ ENTRY(__rt_sigqueueinfo)
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
1:
 | 
			
		||||
    ret
 | 
			
		||||
END(__rt_sigqueueinfo)
 | 
			
		||||
.hidden __rt_sigqueueinfo
 | 
			
		||||
END(___rt_sigqueueinfo)
 | 
			
		||||
.hidden ___rt_sigqueueinfo
 | 
			
		||||
							
								
								
									
										16
									
								
								libc/arch-x86_64/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								libc/arch-x86_64/syscalls/process_vm_readv.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_readv)
 | 
			
		||||
    movq    %rcx, %r10
 | 
			
		||||
    movl    $__NR_process_vm_readv, %eax
 | 
			
		||||
    syscall
 | 
			
		||||
    cmpq    $-MAX_ERRNO, %rax
 | 
			
		||||
    jb      1f
 | 
			
		||||
    negl    %eax
 | 
			
		||||
    movl    %eax, %edi
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
1:
 | 
			
		||||
    ret
 | 
			
		||||
END(process_vm_readv)
 | 
			
		||||
							
								
								
									
										16
									
								
								libc/arch-x86_64/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								libc/arch-x86_64/syscalls/process_vm_writev.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(process_vm_writev)
 | 
			
		||||
    movq    %rcx, %r10
 | 
			
		||||
    movl    $__NR_process_vm_writev, %eax
 | 
			
		||||
    syscall
 | 
			
		||||
    cmpq    $-MAX_ERRNO, %rax
 | 
			
		||||
    jb      1f
 | 
			
		||||
    negl    %eax
 | 
			
		||||
    movl    %eax, %edi
 | 
			
		||||
    call    __set_errno_internal
 | 
			
		||||
1:
 | 
			
		||||
    ret
 | 
			
		||||
END(process_vm_writev)
 | 
			
		||||
@@ -30,9 +30,9 @@
 | 
			
		||||
 | 
			
		||||
#include "private/ErrnoRestorer.h"
 | 
			
		||||
 | 
			
		||||
extern "C" int __clock_nanosleep(clockid_t, int, const timespec*, timespec*);
 | 
			
		||||
extern "C" int ___clock_nanosleep(clockid_t, int, const timespec*, timespec*);
 | 
			
		||||
 | 
			
		||||
int clock_nanosleep(clockid_t clock_id, int flags, const timespec* in, timespec* out) {
 | 
			
		||||
  ErrnoRestorer errno_restorer;
 | 
			
		||||
  return (__clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
 | 
			
		||||
  return (___clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,13 +41,19 @@
 | 
			
		||||
 | 
			
		||||
extern "C" int __getdents64(unsigned int, dirent*, unsigned int);
 | 
			
		||||
 | 
			
		||||
// Apportable decided to copy the data structure from this file
 | 
			
		||||
// and use it in their own code, but they also call into readdir.
 | 
			
		||||
// In order to avoid a lockup, the structure must be maintained in
 | 
			
		||||
// the exact same order as in L and below. New structure members
 | 
			
		||||
// need to be added to the end of this structure.
 | 
			
		||||
// See b/21037208 for more details.
 | 
			
		||||
struct DIR {
 | 
			
		||||
  int fd_;
 | 
			
		||||
  size_t available_bytes_;
 | 
			
		||||
  dirent* next_;
 | 
			
		||||
  long current_pos_;
 | 
			
		||||
  pthread_mutex_t mutex_;
 | 
			
		||||
  dirent buff_[15];
 | 
			
		||||
  long current_pos_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static DIR* __allocate_DIR(int fd) {
 | 
			
		||||
 
 | 
			
		||||
@@ -44,11 +44,13 @@
 | 
			
		||||
#define dlmalloc dlmalloc_real
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Export two symbols used by the VM. */
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
int dlmalloc_trim(size_t) __LIBC_ABI_PUBLIC__;
 | 
			
		||||
void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void*) __LIBC_ABI_PUBLIC__;
 | 
			
		||||
__END_DECLS
 | 
			
		||||
/* These two symbols are exported on devices that use dlmalloc.
 | 
			
		||||
 * In order to be consistent across all devices, they will
 | 
			
		||||
 * be exported everywhere. Move the real symbols out of the way
 | 
			
		||||
 * so that ndk_cruft.cpp can export these symbols.
 | 
			
		||||
 */
 | 
			
		||||
#define dlmalloc_inspect_all dlmalloc_inspect_all_real
 | 
			
		||||
#define dlmalloc_trim dlmalloc_trim_real
 | 
			
		||||
 | 
			
		||||
/* Include the proper definitions. */
 | 
			
		||||
#include "../upstream-dlmalloc/malloc.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								libc/bionic/fgetxattr.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								libc/bionic/fgetxattr.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2015 The Android Open Source Project
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *  * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *  * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in
 | 
			
		||||
 *    the documentation and/or other materials provided with the
 | 
			
		||||
 *    distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | 
			
		||||
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 | 
			
		||||
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 | 
			
		||||
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/xattr.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
extern "C" ssize_t ___fgetxattr(int, const char*, void*, size_t);
 | 
			
		||||
 | 
			
		||||
ssize_t fgetxattr(int fd, const char *name, void *value, size_t size) {
 | 
			
		||||
  int saved_errno = errno;
 | 
			
		||||
  ssize_t result = ___fgetxattr(fd, name, value, size);
 | 
			
		||||
 | 
			
		||||
  if ((result != -1) || (errno != EBADF)) {
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // fd could be an O_PATH file descriptor, and the kernel
 | 
			
		||||
  // may not directly support fgetxattr() on such a file descriptor.
 | 
			
		||||
  // Use /proc/self/fd instead to emulate this support.
 | 
			
		||||
  int fd_flag = fcntl(fd, F_GETFL);
 | 
			
		||||
  if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
 | 
			
		||||
    errno = EBADF;
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  char buf[40];
 | 
			
		||||
  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
 | 
			
		||||
  errno = saved_errno;
 | 
			
		||||
  return getxattr(buf, name, value, size);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 The Android Open Source Project
 | 
			
		||||
 * Copyright (C) 2015 The Android Open Source Project
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
@@ -26,19 +26,34 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef LINKER_ENVIRON_H
 | 
			
		||||
#define LINKER_ENVIRON_H
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/xattr.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
class KernelArgumentBlock;
 | 
			
		||||
extern "C" ssize_t ___flistxattr(int, char*, size_t);
 | 
			
		||||
 | 
			
		||||
// Call this function before any of the other functions in this header file.
 | 
			
		||||
extern void linker_env_init(KernelArgumentBlock& args);
 | 
			
		||||
ssize_t flistxattr(int fd, char *list, size_t size) {
 | 
			
		||||
  int saved_errno = errno;
 | 
			
		||||
  ssize_t result = ___flistxattr(fd, list, size);
 | 
			
		||||
 | 
			
		||||
// Returns the value of environment variable 'name' if defined and not
 | 
			
		||||
// empty, or null otherwise.
 | 
			
		||||
extern const char* linker_env_get(const char* name);
 | 
			
		||||
  if ((result != -1) || (errno != EBADF)) {
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
// Returns the value of this program's AT_SECURE variable.
 | 
			
		||||
extern bool get_AT_SECURE();
 | 
			
		||||
  // fd could be an O_PATH file descriptor, and the kernel
 | 
			
		||||
  // may not directly support fgetxattr() on such a file descriptor.
 | 
			
		||||
  // Use /proc/self/fd instead to emulate this support.
 | 
			
		||||
  int fd_flag = fcntl(fd, F_GETFL);
 | 
			
		||||
  if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
 | 
			
		||||
    errno = EBADF;
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif // LINKER_ENVIRON_H
 | 
			
		||||
  char buf[40];
 | 
			
		||||
  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
 | 
			
		||||
  errno = saved_errno;
 | 
			
		||||
  return listxattr(buf, list, size);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								libc/bionic/fsetxattr.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								libc/bionic/fsetxattr.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2015 The Android Open Source Project
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *  * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *  * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in
 | 
			
		||||
 *    the documentation and/or other materials provided with the
 | 
			
		||||
 *    distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | 
			
		||||
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 | 
			
		||||
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 | 
			
		||||
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/xattr.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
extern "C" int ___fsetxattr(int, const char*, const void*, size_t, int);
 | 
			
		||||
 | 
			
		||||
int fsetxattr(int fd, const char* name, const void* value, size_t size, int flags) {
 | 
			
		||||
  int saved_errno = errno;
 | 
			
		||||
  int result = ___fsetxattr(fd, name, value, size, flags);
 | 
			
		||||
 | 
			
		||||
  if ((result == 0) || (errno != EBADF)) {
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // fd could be an O_PATH file descriptor, and the kernel
 | 
			
		||||
  // may not directly support fsetxattr() on such a file descriptor.
 | 
			
		||||
  // Use /proc/self/fd instead to emulate this support.
 | 
			
		||||
  int fd_flag = fcntl(fd, F_GETFL);
 | 
			
		||||
  if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
 | 
			
		||||
    errno = EBADF;
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  char buf[40];
 | 
			
		||||
  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
 | 
			
		||||
  errno = saved_errno;
 | 
			
		||||
  return setxattr(buf, name, value, size, flags);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								libc/bionic/ftruncate.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								libc/bionic/ftruncate.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2015 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#if !defined(__LP64__)
 | 
			
		||||
static_assert(sizeof(off_t) == 4,
 | 
			
		||||
              "libc can't be built with _FILE_OFFSET_BITS=64.");
 | 
			
		||||
 | 
			
		||||
// The kernel's implementation of ftruncate uses an unsigned long for the length
 | 
			
		||||
// parameter, so it will not catch negative values. On the other hand
 | 
			
		||||
// ftruncate64 does check for this, so just forward the call.
 | 
			
		||||
int ftruncate(int filedes, off_t length) {
 | 
			
		||||
  return ftruncate64(filedes, length);
 | 
			
		||||
}
 | 
			
		||||
#endif  // !defined(__LP64__)
 | 
			
		||||
@@ -30,11 +30,14 @@
 | 
			
		||||
 | 
			
		||||
#include <elf.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/auxv.h>
 | 
			
		||||
#include <sys/personality.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
@@ -42,6 +45,7 @@
 | 
			
		||||
#include "private/bionic_ssp.h"
 | 
			
		||||
#include "private/bionic_tls.h"
 | 
			
		||||
#include "private/KernelArgumentBlock.h"
 | 
			
		||||
#include "private/libc_logging.h"
 | 
			
		||||
#include "pthread_internal.h"
 | 
			
		||||
 | 
			
		||||
extern "C" abort_msg_t** __abort_message_ptr;
 | 
			
		||||
@@ -120,6 +124,213 @@ void __libc_init_common(KernelArgumentBlock& args) {
 | 
			
		||||
  __libc_init_vdso();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__noreturn static void __early_abort(int line) {
 | 
			
		||||
  // We can't write to stdout or stderr because we're aborting before we've checked that
 | 
			
		||||
  // it's safe for us to use those file descriptors. We probably can't strace either, so
 | 
			
		||||
  // we rely on the fact that if we dereference a low address, either debuggerd or the
 | 
			
		||||
  // kernel's crash dump will show the fault address.
 | 
			
		||||
  *reinterpret_cast<int*>(line) = 0;
 | 
			
		||||
  _exit(EXIT_FAILURE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Force any of the closed stdin, stdout and stderr to be associated with /dev/null.
 | 
			
		||||
static void __nullify_closed_stdio() {
 | 
			
		||||
  int dev_null = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
 | 
			
		||||
  if (dev_null == -1) {
 | 
			
		||||
    // init won't have /dev/null available, but SELinux provides an equivalent.
 | 
			
		||||
    dev_null = TEMP_FAILURE_RETRY(open("/sys/fs/selinux/null", O_RDWR));
 | 
			
		||||
  }
 | 
			
		||||
  if (dev_null == -1) {
 | 
			
		||||
    __early_abort(__LINE__);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If any of the stdio file descriptors is valid and not associated
 | 
			
		||||
  // with /dev/null, dup /dev/null to it.
 | 
			
		||||
  for (int i = 0; i < 3; i++) {
 | 
			
		||||
    // If it is /dev/null already, we are done.
 | 
			
		||||
    if (i == dev_null) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Is this fd already open?
 | 
			
		||||
    int status = TEMP_FAILURE_RETRY(fcntl(i, F_GETFL));
 | 
			
		||||
    if (status != -1) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The only error we allow is that the file descriptor does not
 | 
			
		||||
    // exist, in which case we dup /dev/null to it.
 | 
			
		||||
    if (errno == EBADF) {
 | 
			
		||||
      // Try dupping /dev/null to this stdio file descriptor and
 | 
			
		||||
      // repeat if there is a signal. Note that any errors in closing
 | 
			
		||||
      // the stdio descriptor are lost.
 | 
			
		||||
      status = TEMP_FAILURE_RETRY(dup2(dev_null, i));
 | 
			
		||||
      if (status == -1) {
 | 
			
		||||
        __early_abort(__LINE__);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      __early_abort(__LINE__);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If /dev/null is not one of the stdio file descriptors, close it.
 | 
			
		||||
  if (dev_null > 2) {
 | 
			
		||||
    if (close(dev_null) == -1) {
 | 
			
		||||
      __early_abort(__LINE__);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check if the environment variable definition at 'envstr'
 | 
			
		||||
// starts with '<name>=', and if so return the address of the
 | 
			
		||||
// first character after the equal sign. Otherwise return null.
 | 
			
		||||
static const char* env_match(const char* envstr, const char* name) {
 | 
			
		||||
  size_t i = 0;
 | 
			
		||||
 | 
			
		||||
  while (envstr[i] == name[i] && name[i] != '\0') {
 | 
			
		||||
    ++i;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (name[i] == '\0' && envstr[i] == '=') {
 | 
			
		||||
    return envstr + i + 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool __is_valid_environment_variable(const char* name) {
 | 
			
		||||
  // According to the kernel source, by default the kernel uses 32*PAGE_SIZE
 | 
			
		||||
  // as the maximum size for an environment variable definition.
 | 
			
		||||
  const int MAX_ENV_LEN = 32*4096;
 | 
			
		||||
 | 
			
		||||
  if (name == nullptr) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Parse the string, looking for the first '=' there, and its size.
 | 
			
		||||
  int pos = 0;
 | 
			
		||||
  int first_equal_pos = -1;
 | 
			
		||||
  while (pos < MAX_ENV_LEN) {
 | 
			
		||||
    if (name[pos] == '\0') {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    if (name[pos] == '=' && first_equal_pos < 0) {
 | 
			
		||||
      first_equal_pos = pos;
 | 
			
		||||
    }
 | 
			
		||||
    pos++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check that it's smaller than MAX_ENV_LEN (to detect non-zero terminated strings).
 | 
			
		||||
  if (pos >= MAX_ENV_LEN) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check that it contains at least one equal sign that is not the first character
 | 
			
		||||
  if (first_equal_pos < 1) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool __is_unsafe_environment_variable(const char* name) {
 | 
			
		||||
  // None of these should be allowed in setuid programs.
 | 
			
		||||
  static const char* const UNSAFE_VARIABLE_NAMES[] = {
 | 
			
		||||
      "GCONV_PATH",
 | 
			
		||||
      "GETCONF_DIR",
 | 
			
		||||
      "HOSTALIASES",
 | 
			
		||||
      "JE_MALLOC_CONF",
 | 
			
		||||
      "LD_AOUT_LIBRARY_PATH",
 | 
			
		||||
      "LD_AOUT_PRELOAD",
 | 
			
		||||
      "LD_AUDIT",
 | 
			
		||||
      "LD_DEBUG",
 | 
			
		||||
      "LD_DEBUG_OUTPUT",
 | 
			
		||||
      "LD_DYNAMIC_WEAK",
 | 
			
		||||
      "LD_LIBRARY_PATH",
 | 
			
		||||
      "LD_ORIGIN_PATH",
 | 
			
		||||
      "LD_PRELOAD",
 | 
			
		||||
      "LD_PROFILE",
 | 
			
		||||
      "LD_SHOW_AUXV",
 | 
			
		||||
      "LD_USE_LOAD_BIAS",
 | 
			
		||||
      "LOCALDOMAIN",
 | 
			
		||||
      "LOCPATH",
 | 
			
		||||
      "MALLOC_CHECK_",
 | 
			
		||||
      "MALLOC_CONF",
 | 
			
		||||
      "MALLOC_TRACE",
 | 
			
		||||
      "NIS_PATH",
 | 
			
		||||
      "NLSPATH",
 | 
			
		||||
      "RESOLV_HOST_CONF",
 | 
			
		||||
      "RES_OPTIONS",
 | 
			
		||||
      "TMPDIR",
 | 
			
		||||
      "TZDIR",
 | 
			
		||||
      nullptr
 | 
			
		||||
  };
 | 
			
		||||
  for (size_t i = 0; UNSAFE_VARIABLE_NAMES[i] != nullptr; ++i) {
 | 
			
		||||
    if (env_match(name, UNSAFE_VARIABLE_NAMES[i]) != nullptr) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __sanitize_environment_variables(char** env) {
 | 
			
		||||
  bool is_AT_SECURE = getauxval(AT_SECURE);
 | 
			
		||||
  char** src = env;
 | 
			
		||||
  char** dst = env;
 | 
			
		||||
  for (; src[0] != nullptr; ++src) {
 | 
			
		||||
    if (!__is_valid_environment_variable(src[0])) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    // Remove various unsafe environment variables if we're loading a setuid program.
 | 
			
		||||
    if (is_AT_SECURE && __is_unsafe_environment_variable(src[0])) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    dst[0] = src[0];
 | 
			
		||||
    ++dst;
 | 
			
		||||
  }
 | 
			
		||||
  dst[0] = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __initialize_personality() {
 | 
			
		||||
#if !defined(__LP64__)
 | 
			
		||||
  int old_value = personality(0xffffffff);
 | 
			
		||||
  if (old_value == -1) {
 | 
			
		||||
    __libc_fatal("error getting old personality value: %s", strerror(errno));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (personality((static_cast<unsigned int>(old_value) & ~PER_MASK) | PER_LINUX32) == -1) {
 | 
			
		||||
    __libc_fatal("error setting PER_LINUX32 personality: %s", strerror(errno));
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __libc_init_AT_SECURE(KernelArgumentBlock& args) {
 | 
			
		||||
  __libc_auxv = args.auxv;
 | 
			
		||||
 | 
			
		||||
  // Check that the kernel provided a value for AT_SECURE.
 | 
			
		||||
  bool found_AT_SECURE = false;
 | 
			
		||||
  for (ElfW(auxv_t)* v = __libc_auxv; v->a_type != AT_NULL; ++v) {
 | 
			
		||||
    if (v->a_type == AT_SECURE) {
 | 
			
		||||
      found_AT_SECURE = true;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (!found_AT_SECURE) __early_abort(__LINE__);
 | 
			
		||||
 | 
			
		||||
  if (getauxval(AT_SECURE)) {
 | 
			
		||||
    // If this is a setuid/setgid program, close the security hole described in
 | 
			
		||||
    // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
 | 
			
		||||
    __nullify_closed_stdio();
 | 
			
		||||
 | 
			
		||||
    __sanitize_environment_variables(args.envp);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Now the environment has been sanitized, make it available.
 | 
			
		||||
  environ = args.envp;
 | 
			
		||||
 | 
			
		||||
  __initialize_personality();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function will be called during normal program termination
 | 
			
		||||
 * to run the destructors that are listed in the .fini_array section
 | 
			
		||||
 * of the executable, if any.
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,12 @@ __LIBC_HIDDEN__ void __libc_fini(void* finit_array);
 | 
			
		||||
__END_DECLS
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
 | 
			
		||||
class KernelArgumentBlock;
 | 
			
		||||
__LIBC_HIDDEN__ void __libc_init_common(KernelArgumentBlock& args);
 | 
			
		||||
 | 
			
		||||
__LIBC_HIDDEN__ void __libc_init_AT_SECURE(KernelArgumentBlock& args);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,7 @@ __noreturn void __libc_init(void* raw_args,
 | 
			
		||||
                            structors_array_t const * const structors) {
 | 
			
		||||
  KernelArgumentBlock args(raw_args);
 | 
			
		||||
  __libc_init_tls(args);
 | 
			
		||||
  __libc_init_AT_SECURE(args);
 | 
			
		||||
  __libc_init_common(args);
 | 
			
		||||
 | 
			
		||||
  apply_gnu_relro();
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,7 @@ enum AndroidEventLogType {
 | 
			
		||||
  EVENT_TYPE_LONG     = 1,
 | 
			
		||||
  EVENT_TYPE_STRING   = 2,
 | 
			
		||||
  EVENT_TYPE_LIST     = 3,
 | 
			
		||||
  EVENT_TYPE_FLOAT    = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct BufferOutputStream {
 | 
			
		||||
 
 | 
			
		||||
@@ -340,7 +340,7 @@ extern "C" pid_t __pthread_gettid(pthread_t t) {
 | 
			
		||||
  return pthread_gettid_np(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Older versions of appportable used dlmalloc directly instead of malloc,
 | 
			
		||||
// Older versions of apportable used dlmalloc directly instead of malloc,
 | 
			
		||||
// so export this compatibility shim that simply calls malloc.
 | 
			
		||||
extern "C" void* dlmalloc(size_t size) {
 | 
			
		||||
  return malloc(size);
 | 
			
		||||
@@ -369,3 +369,26 @@ extern "C" void endusershell() { }
 | 
			
		||||
 | 
			
		||||
// This is never implemented in bionic, only needed for ABI compatibility with the NDK.
 | 
			
		||||
extern "C" void endpwent() { }
 | 
			
		||||
 | 
			
		||||
// Since dlmalloc_inspect_all and dlmalloc_trim are exported for systems
 | 
			
		||||
// that use dlmalloc, be consistent and export them everywhere.
 | 
			
		||||
#if defined(USE_JEMALLOC)
 | 
			
		||||
extern "C" void dlmalloc_inspect_all(void (*)(void*, void*, size_t, void*), void*) {
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
extern "C" void dlmalloc_inspect_all_real(void (*)(void*, void*, size_t, void*), void*);
 | 
			
		||||
extern "C" void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg) {
 | 
			
		||||
  dlmalloc_inspect_all_real(handler, arg);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(USE_JEMALLOC)
 | 
			
		||||
extern "C" int dlmalloc_trim(size_t) {
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
extern "C" int dlmalloc_trim_real(size_t);
 | 
			
		||||
extern "C" int dlmalloc_trim(size_t pad) {
 | 
			
		||||
  return dlmalloc_trim_real(pad);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -87,6 +87,7 @@ void __init_alternate_signal_stack(pthread_internal_t* thread) {
 | 
			
		||||
    // We can only use const static allocated string for mapped region name, as Android kernel
 | 
			
		||||
    // uses the string pointer directly when dumping /proc/pid/maps.
 | 
			
		||||
    prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ss.ss_sp, ss.ss_size, "thread signal stack");
 | 
			
		||||
    prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, stack_base, PAGE_SIZE, "thread signal stack guard page");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -140,6 +141,7 @@ static void* __create_thread_mapped_space(size_t mmap_size, size_t stack_guard_s
 | 
			
		||||
    munmap(space, mmap_size);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, space, stack_guard_size, "thread stack guard page");
 | 
			
		||||
 | 
			
		||||
  return space;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -501,6 +501,12 @@ static int __pthread_mutex_lock_with_timeout(pthread_mutex_internal_t* mutex,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pthread_mutex_lock(pthread_mutex_t* mutex_interface) {
 | 
			
		||||
#if !defined(__LP64__)
 | 
			
		||||
    if (mutex_interface == NULL) {
 | 
			
		||||
        return EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
 | 
			
		||||
 | 
			
		||||
    uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
 | 
			
		||||
@@ -516,6 +522,12 @@ int pthread_mutex_lock(pthread_mutex_t* mutex_interface) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pthread_mutex_unlock(pthread_mutex_t* mutex_interface) {
 | 
			
		||||
#if !defined(__LP64__)
 | 
			
		||||
    if (mutex_interface == NULL) {
 | 
			
		||||
        return EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
 | 
			
		||||
 | 
			
		||||
    uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
extern "C" int __rt_sigqueueinfo(pid_t, int, siginfo_t*);
 | 
			
		||||
extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
 | 
			
		||||
 | 
			
		||||
int sigqueue(pid_t pid, int signo, const sigval value) {
 | 
			
		||||
  siginfo_t info;
 | 
			
		||||
@@ -42,5 +42,5 @@ int sigqueue(pid_t pid, int signo, const sigval value) {
 | 
			
		||||
  info.si_uid = getuid();
 | 
			
		||||
  info.si_value = value;
 | 
			
		||||
 | 
			
		||||
  return __rt_sigqueueinfo(pid, signo, &info);
 | 
			
		||||
  return ___rt_sigqueueinfo(pid, signo, &info);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -598,6 +598,16 @@ int __system_property_area_init()
 | 
			
		||||
    return map_prop_area_rw();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int __system_property_area_serial()
 | 
			
		||||
{
 | 
			
		||||
    prop_area *pa = __system_property_area__;
 | 
			
		||||
    if (!pa) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    // Make sure this read fulfilled before __system_property_serial
 | 
			
		||||
    return atomic_load_explicit(&(pa->serial), memory_order_acquire);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const prop_info *__system_property_find(const char *name)
 | 
			
		||||
{
 | 
			
		||||
    if (__predict_false(compat_mode)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -53,10 +53,37 @@ struct addrinfo;
 | 
			
		||||
 | 
			
		||||
#define __used_in_netd __attribute__((visibility ("default")))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A struct to capture context relevant to network operations.
 | 
			
		||||
 *
 | 
			
		||||
 * Application and DNS netids/marks can differ from one another under certain
 | 
			
		||||
 * circumstances, notably when a VPN applies to the given uid's traffic but the
 | 
			
		||||
 * VPN network does not have its own DNS servers explicitly provisioned.
 | 
			
		||||
 *
 | 
			
		||||
 * The introduction of per-UID routing means the uid is also an essential part
 | 
			
		||||
 * of the evaluation context. Its proper uninitialized value is
 | 
			
		||||
 * NET_CONTEXT_INVALID_UID.
 | 
			
		||||
 */
 | 
			
		||||
struct android_net_context {
 | 
			
		||||
    unsigned app_netid;
 | 
			
		||||
    unsigned app_mark;
 | 
			
		||||
    unsigned dns_netid;
 | 
			
		||||
    unsigned dns_mark;
 | 
			
		||||
    uid_t uid;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
#define NET_CONTEXT_INVALID_UID ((uid_t)-1)
 | 
			
		||||
 | 
			
		||||
struct hostent *android_gethostbyaddrfornet(const void *, socklen_t, int, unsigned, unsigned) __used_in_netd;
 | 
			
		||||
struct hostent *android_gethostbynamefornet(const char *, int, unsigned, unsigned) __used_in_netd;
 | 
			
		||||
int android_getaddrinfofornet(const char *, const char *, const struct addrinfo *, unsigned,
 | 
			
		||||
		unsigned, struct addrinfo **) __used_in_netd;
 | 
			
		||||
    unsigned, struct addrinfo **) __used_in_netd;
 | 
			
		||||
/*
 | 
			
		||||
 * TODO: consider refactoring android_getaddrinfo_proxy() to serve as an
 | 
			
		||||
 * explore_fqdn() dispatch table method, with the below function only making DNS calls.
 | 
			
		||||
 */
 | 
			
		||||
int android_getaddrinfofornetcontext(const char *, const char *, const struct addrinfo *,
 | 
			
		||||
    const struct android_net_context *, struct addrinfo **) __used_in_netd;
 | 
			
		||||
 | 
			
		||||
/* set name servers for a network */
 | 
			
		||||
extern void _resolv_set_nameservers_for_net(unsigned netid,
 | 
			
		||||
 
 | 
			
		||||
@@ -218,7 +218,7 @@ struct res_target {
 | 
			
		||||
 | 
			
		||||
static int str2number(const char *);
 | 
			
		||||
static int explore_fqdn(const struct addrinfo *, const char *,
 | 
			
		||||
	const char *, struct addrinfo **, unsigned netid, unsigned mark);
 | 
			
		||||
	const char *, struct addrinfo **, const struct android_net_context *);
 | 
			
		||||
static int explore_null(const struct addrinfo *,
 | 
			
		||||
	const char *, struct addrinfo **);
 | 
			
		||||
static int explore_numeric(const struct addrinfo *, const char *,
 | 
			
		||||
@@ -244,6 +244,7 @@ static void _endhtent(FILE **);
 | 
			
		||||
static struct addrinfo *_gethtent(FILE **, const char *,
 | 
			
		||||
    const struct addrinfo *);
 | 
			
		||||
static int _files_getaddrinfo(void *, void *, va_list);
 | 
			
		||||
static int _find_src_addr(const struct sockaddr *, struct sockaddr *, unsigned , uid_t);
 | 
			
		||||
 | 
			
		||||
static int res_queryN(const char *, struct res_target *, res_state);
 | 
			
		||||
static int res_searchN(const char *, struct res_target *, res_state);
 | 
			
		||||
@@ -359,29 +360,6 @@ str2number(const char *p)
 | 
			
		||||
		return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Connect a UDP socket to a given unicast address. This will cause no network
 | 
			
		||||
 * traffic, but will fail fast if the system has no or limited reachability to
 | 
			
		||||
 * the destination (e.g., no IPv4 address, no IPv6 default route, ...).
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
_test_connect(int pf, struct sockaddr *addr, size_t addrlen, unsigned mark) {
 | 
			
		||||
	int s = socket(pf, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
 | 
			
		||||
	if (s < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	if (mark != MARK_UNSET && setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	int ret;
 | 
			
		||||
	do {
 | 
			
		||||
		ret = __connect(s, addr, addrlen);
 | 
			
		||||
	} while (ret < 0 && errno == EINTR);
 | 
			
		||||
	int success = (ret == 0);
 | 
			
		||||
	do {
 | 
			
		||||
		ret = close(s);
 | 
			
		||||
	} while (ret < 0 && errno == EINTR);
 | 
			
		||||
	return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The following functions determine whether IPv4 or IPv6 connectivity is
 | 
			
		||||
 * available in order to implement AI_ADDRCONFIG.
 | 
			
		||||
@@ -392,24 +370,24 @@ _test_connect(int pf, struct sockaddr *addr, size_t addrlen, unsigned mark) {
 | 
			
		||||
 * so checking for connectivity is the next best thing.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
_have_ipv6(unsigned mark) {
 | 
			
		||||
_have_ipv6(unsigned mark, uid_t uid) {
 | 
			
		||||
	static const struct sockaddr_in6 sin6_test = {
 | 
			
		||||
		.sin6_family = AF_INET6,
 | 
			
		||||
		.sin6_addr.s6_addr = {  // 2000::
 | 
			
		||||
			0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
 | 
			
		||||
		};
 | 
			
		||||
	sockaddr_union addr = { .in6 = sin6_test };
 | 
			
		||||
	return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6), mark);
 | 
			
		||||
	return _find_src_addr(&addr.generic, NULL, mark, uid) == 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
_have_ipv4(unsigned mark) {
 | 
			
		||||
_have_ipv4(unsigned mark, uid_t uid) {
 | 
			
		||||
	static const struct sockaddr_in sin_test = {
 | 
			
		||||
		.sin_family = AF_INET,
 | 
			
		||||
		.sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
 | 
			
		||||
	};
 | 
			
		||||
	sockaddr_union addr = { .in = sin_test };
 | 
			
		||||
	return _test_connect(PF_INET, &addr.generic, sizeof(addr.in), mark);
 | 
			
		||||
	return _find_src_addr(&addr.generic, NULL, mark, uid) == 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool readBE32(FILE* fp, int32_t* result) {
 | 
			
		||||
@@ -474,7 +452,7 @@ android_getaddrinfo_proxy(
 | 
			
		||||
 | 
			
		||||
	int result_code = (int)strtol(buf, NULL, 10);
 | 
			
		||||
	// verify the code itself
 | 
			
		||||
	if (result_code != DnsProxyQueryResult ) {
 | 
			
		||||
	if (result_code != DnsProxyQueryResult) {
 | 
			
		||||
		fread(buf, 1, sizeof(buf), proxy);
 | 
			
		||||
		goto exit;
 | 
			
		||||
	}
 | 
			
		||||
@@ -588,6 +566,21 @@ getaddrinfo(const char *hostname, const char *servname,
 | 
			
		||||
int
 | 
			
		||||
android_getaddrinfofornet(const char *hostname, const char *servname,
 | 
			
		||||
    const struct addrinfo *hints, unsigned netid, unsigned mark, struct addrinfo **res)
 | 
			
		||||
{
 | 
			
		||||
	struct android_net_context netcontext = {
 | 
			
		||||
		.app_netid = netid,
 | 
			
		||||
		.app_mark = mark,
 | 
			
		||||
		.dns_netid = netid,
 | 
			
		||||
		.dns_mark = mark,
 | 
			
		||||
		.uid = NET_CONTEXT_INVALID_UID,
 | 
			
		||||
        };
 | 
			
		||||
	return android_getaddrinfofornetcontext(hostname, servname, hints, &netcontext, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
android_getaddrinfofornetcontext(const char *hostname, const char *servname,
 | 
			
		||||
    const struct addrinfo *hints, const struct android_net_context *netcontext,
 | 
			
		||||
    struct addrinfo **res)
 | 
			
		||||
{
 | 
			
		||||
	struct addrinfo sentinel;
 | 
			
		||||
	struct addrinfo *cur;
 | 
			
		||||
@@ -601,6 +594,7 @@ android_getaddrinfofornet(const char *hostname, const char *servname,
 | 
			
		||||
	/* servname is allowed to be NULL */
 | 
			
		||||
	/* hints is allowed to be NULL */
 | 
			
		||||
	assert(res != NULL);
 | 
			
		||||
	assert(netcontext != NULL);
 | 
			
		||||
	memset(&sentinel, 0, sizeof(sentinel));
 | 
			
		||||
	cur = &sentinel;
 | 
			
		||||
	pai = &ai;
 | 
			
		||||
@@ -731,7 +725,8 @@ android_getaddrinfofornet(const char *hostname, const char *servname,
 | 
			
		||||
		ERR(EAI_NONAME);
 | 
			
		||||
 | 
			
		||||
#if defined(__ANDROID__)
 | 
			
		||||
	int gai_error = android_getaddrinfo_proxy(hostname, servname, hints, res, netid);
 | 
			
		||||
	int gai_error = android_getaddrinfo_proxy(
 | 
			
		||||
		hostname, servname, hints, res, netcontext->app_netid);
 | 
			
		||||
	if (gai_error != EAI_SYSTEM) {
 | 
			
		||||
		return gai_error;
 | 
			
		||||
	}
 | 
			
		||||
@@ -763,8 +758,8 @@ android_getaddrinfofornet(const char *hostname, const char *servname,
 | 
			
		||||
		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
 | 
			
		||||
			pai->ai_protocol = ex->e_protocol;
 | 
			
		||||
 | 
			
		||||
		error = explore_fqdn(pai, hostname, servname,
 | 
			
		||||
			&cur->ai_next, netid, mark);
 | 
			
		||||
		error = explore_fqdn(
 | 
			
		||||
			pai, hostname, servname, &cur->ai_next, netcontext);
 | 
			
		||||
 | 
			
		||||
		while (cur && cur->ai_next)
 | 
			
		||||
			cur = cur->ai_next;
 | 
			
		||||
@@ -797,7 +792,8 @@ android_getaddrinfofornet(const char *hostname, const char *servname,
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
explore_fqdn(const struct addrinfo *pai, const char *hostname,
 | 
			
		||||
    const char *servname, struct addrinfo **res, unsigned netid, unsigned mark)
 | 
			
		||||
    const char *servname, struct addrinfo **res,
 | 
			
		||||
    const struct android_net_context *netcontext)
 | 
			
		||||
{
 | 
			
		||||
	struct addrinfo *result;
 | 
			
		||||
	struct addrinfo *cur;
 | 
			
		||||
@@ -823,7 +819,7 @@ explore_fqdn(const struct addrinfo *pai, const char *hostname,
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
 | 
			
		||||
			default_dns_files, hostname, pai, netid, mark)) {
 | 
			
		||||
			default_dns_files, hostname, pai, netcontext)) {
 | 
			
		||||
	case NS_TRYAGAIN:
 | 
			
		||||
		error = EAI_AGAIN;
 | 
			
		||||
		goto free;
 | 
			
		||||
@@ -1763,13 +1759,13 @@ _rfc6724_compare(const void *ptr1, const void* ptr2)
 | 
			
		||||
 * address. src_addr must be large enough to hold a struct sockaddr_in6.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns 1 if a source address was found, 0 if the address is unreachable,
 | 
			
		||||
 * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
 | 
			
		||||
 * and -1 if a fatal error occurred. If 0 or -1, the contents of src_addr are
 | 
			
		||||
 * undefined.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
static int
 | 
			
		||||
_find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned mark)
 | 
			
		||||
_find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned mark, uid_t uid)
 | 
			
		||||
{
 | 
			
		||||
	int sock;
 | 
			
		||||
	int ret;
 | 
			
		||||
@@ -1797,6 +1793,8 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned
 | 
			
		||||
	}
 | 
			
		||||
	if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	if (uid > 0 && uid != NET_CONTEXT_INVALID_UID && fchown(sock, uid, (gid_t)-1) < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	do {
 | 
			
		||||
		ret = __connect(sock, addr, len);
 | 
			
		||||
	} while (ret == -1 && errno == EINTR);
 | 
			
		||||
@@ -1806,7 +1804,7 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (getsockname(sock, src_addr, &len) == -1) {
 | 
			
		||||
	if (src_addr && getsockname(sock, src_addr, &len) == -1) {
 | 
			
		||||
		close(sock);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1821,7 +1819,7 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
static void
 | 
			
		||||
_rfc6724_sort(struct addrinfo *list_sentinel, unsigned mark)
 | 
			
		||||
_rfc6724_sort(struct addrinfo *list_sentinel, unsigned mark, uid_t uid)
 | 
			
		||||
{
 | 
			
		||||
	struct addrinfo *cur;
 | 
			
		||||
	int nelem = 0, i;
 | 
			
		||||
@@ -1848,7 +1846,7 @@ _rfc6724_sort(struct addrinfo *list_sentinel, unsigned mark)
 | 
			
		||||
		elems[i].ai = cur;
 | 
			
		||||
		elems[i].original_order = i;
 | 
			
		||||
 | 
			
		||||
		has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic, mark);
 | 
			
		||||
		has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic, mark, uid);
 | 
			
		||||
		if (has_src_addr == -1) {
 | 
			
		||||
			goto error;
 | 
			
		||||
		}
 | 
			
		||||
@@ -1879,12 +1877,11 @@ _dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
 | 
			
		||||
	struct addrinfo sentinel, *cur;
 | 
			
		||||
	struct res_target q, q2;
 | 
			
		||||
	res_state res;
 | 
			
		||||
	unsigned netid, mark;
 | 
			
		||||
	const struct android_net_context *netcontext;
 | 
			
		||||
 | 
			
		||||
	name = va_arg(ap, char *);
 | 
			
		||||
	pai = va_arg(ap, const struct addrinfo *);
 | 
			
		||||
	netid = va_arg(ap, unsigned);
 | 
			
		||||
	mark = va_arg(ap, unsigned);
 | 
			
		||||
	netcontext = va_arg(ap, const struct android_net_context *);
 | 
			
		||||
	//fprintf(stderr, "_dns_getaddrinfo() name = '%s'\n", name);
 | 
			
		||||
 | 
			
		||||
	memset(&q, 0, sizeof(q));
 | 
			
		||||
@@ -1913,8 +1910,8 @@ _dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
 | 
			
		||||
		q.anslen = sizeof(buf->buf);
 | 
			
		||||
		int query_ipv6 = 1, query_ipv4 = 1;
 | 
			
		||||
		if (pai->ai_flags & AI_ADDRCONFIG) {
 | 
			
		||||
			query_ipv6 = _have_ipv6(mark);
 | 
			
		||||
			query_ipv4 = _have_ipv4(mark);
 | 
			
		||||
			query_ipv6 = _have_ipv6(netcontext->app_mark, netcontext->uid);
 | 
			
		||||
			query_ipv4 = _have_ipv4(netcontext->app_mark, netcontext->uid);
 | 
			
		||||
		}
 | 
			
		||||
		if (query_ipv6) {
 | 
			
		||||
			q.qtype = T_AAAA;
 | 
			
		||||
@@ -1966,8 +1963,8 @@ _dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
 | 
			
		||||
	 * fully populate the thread private data here, but if we get down there
 | 
			
		||||
	 * and have a cache hit that would be wasted, so we do the rest there on miss
 | 
			
		||||
	 */
 | 
			
		||||
	res_setnetid(res, netid);
 | 
			
		||||
	res_setmark(res, mark);
 | 
			
		||||
	res_setnetid(res, netcontext->dns_netid);
 | 
			
		||||
	res_setmark(res, netcontext->dns_mark);
 | 
			
		||||
	if (res_searchN(name, &q, res) < 0) {
 | 
			
		||||
		__res_put_state(res);
 | 
			
		||||
		free(buf);
 | 
			
		||||
@@ -1999,7 +1996,7 @@ _dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_rfc6724_sort(&sentinel, netid);
 | 
			
		||||
	_rfc6724_sort(&sentinel, netcontext->app_mark, netcontext->uid);
 | 
			
		||||
 | 
			
		||||
	__res_put_state(res);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -640,6 +640,9 @@ android_read_hostent(FILE* proxy, struct hostent* hp, char* hbuf, size_t hbuflen
 | 
			
		||||
		ptr += size;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fix alignment after variable-length data.
 | 
			
		||||
	ptr = (char*)ALIGN(ptr);
 | 
			
		||||
 | 
			
		||||
	int aliases_len = ((int)(aliases - aliases_ptrs) + 1) * sizeof(*hp->h_aliases);
 | 
			
		||||
	if (ptr + aliases_len > hbuf_end) {
 | 
			
		||||
		goto nospc;
 | 
			
		||||
@@ -674,6 +677,9 @@ android_read_hostent(FILE* proxy, struct hostent* hp, char* hbuf, size_t hbuflen
 | 
			
		||||
		ptr += size;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fix alignment after variable-length data.
 | 
			
		||||
	ptr = (char*)ALIGN(ptr);
 | 
			
		||||
 | 
			
		||||
	int addrs_len = ((int)(addr_p - addr_ptrs) + 1) * sizeof(*hp->h_addr_list);
 | 
			
		||||
	if (ptr + addrs_len > hbuf_end) {
 | 
			
		||||
		goto nospc;
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,13 @@ enum {
 | 
			
		||||
   */
 | 
			
		||||
  ANDROID_DLEXT_FORCE_LOAD = 0x40,
 | 
			
		||||
 | 
			
		||||
  /* When set, if the minimum p_vaddr of the ELF file's PT_LOAD segments is non-zero,
 | 
			
		||||
   * the dynamic linker will load it at that address.
 | 
			
		||||
   *
 | 
			
		||||
   * This flag is for ART internal use only.
 | 
			
		||||
   */
 | 
			
		||||
  ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80,
 | 
			
		||||
 | 
			
		||||
  /* Mask of valid bits */
 | 
			
		||||
  ANDROID_DLEXT_VALID_FLAG_BITS       = ANDROID_DLEXT_RESERVED_ADDRESS |
 | 
			
		||||
                                        ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
 | 
			
		||||
@@ -80,7 +87,8 @@ enum {
 | 
			
		||||
                                        ANDROID_DLEXT_USE_RELRO |
 | 
			
		||||
                                        ANDROID_DLEXT_USE_LIBRARY_FD |
 | 
			
		||||
                                        ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
 | 
			
		||||
                                        ANDROID_DLEXT_FORCE_LOAD,
 | 
			
		||||
                                        ANDROID_DLEXT_FORCE_LOAD |
 | 
			
		||||
                                        ANDROID_DLEXT_FORCE_FIXED_VADDR,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,11 @@
 | 
			
		||||
 | 
			
		||||
#include <machine/elf_machdep.h>
 | 
			
		||||
 | 
			
		||||
#define ELF32_R_INFO(sym, type) ((((Elf32_Word)sym) << 8) | ((type) & 0xff))
 | 
			
		||||
#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)sym) << 32) | ((type) & 0xffffffff))
 | 
			
		||||
 | 
			
		||||
typedef __s64 Elf32_Sxword;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  __u32 a_type;
 | 
			
		||||
  union {
 | 
			
		||||
@@ -187,6 +192,11 @@ typedef struct {
 | 
			
		||||
#define STT_LOPROC    13
 | 
			
		||||
#define STT_HIPROC    15
 | 
			
		||||
 | 
			
		||||
#define STV_DEFAULT   0
 | 
			
		||||
#define STV_INTERNAL  1
 | 
			
		||||
#define STV_HIDDEN    2
 | 
			
		||||
#define STV_PROTECTED 3
 | 
			
		||||
 | 
			
		||||
/* The kernel uses NT_PRFPREG but glibc also offers NT_FPREGSET */
 | 
			
		||||
#define NT_FPREGSET NT_PRFPREG
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user