1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker * All rights reserved.
4*8d67ca89SAndroid Build Coastguard Worker *
5*8d67ca89SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*8d67ca89SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
7*8d67ca89SAndroid Build Coastguard Worker * are met:
8*8d67ca89SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright
9*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
10*8d67ca89SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright
11*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in
12*8d67ca89SAndroid Build Coastguard Worker * the documentation and/or other materials provided with the
13*8d67ca89SAndroid Build Coastguard Worker * distribution.
14*8d67ca89SAndroid Build Coastguard Worker *
15*8d67ca89SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16*8d67ca89SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17*8d67ca89SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18*8d67ca89SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19*8d67ca89SAndroid Build Coastguard Worker * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20*8d67ca89SAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21*8d67ca89SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22*8d67ca89SAndroid Build Coastguard Worker * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23*8d67ca89SAndroid Build Coastguard Worker * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*8d67ca89SAndroid Build Coastguard Worker * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25*8d67ca89SAndroid Build Coastguard Worker * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*8d67ca89SAndroid Build Coastguard Worker * SUCH DAMAGE.
27*8d67ca89SAndroid Build Coastguard Worker */
28*8d67ca89SAndroid Build Coastguard Worker
29*8d67ca89SAndroid Build Coastguard Worker #include <fcntl.h>
30*8d67ca89SAndroid Build Coastguard Worker #include <private/bionic_ifuncs.h>
31*8d67ca89SAndroid Build Coastguard Worker #include <stddef.h>
32*8d67ca89SAndroid Build Coastguard Worker #include <sys/syscall.h>
33*8d67ca89SAndroid Build Coastguard Worker #include <unistd.h>
34*8d67ca89SAndroid Build Coastguard Worker
35*8d67ca89SAndroid Build Coastguard Worker extern "C" {
36*8d67ca89SAndroid Build Coastguard Worker
ifunc_faccessat(int dir_fd,const char * path,int mode)37*8d67ca89SAndroid Build Coastguard Worker static inline __always_inline int ifunc_faccessat(int dir_fd, const char* path, int mode) {
38*8d67ca89SAndroid Build Coastguard Worker register long a0 __asm__("a0") = dir_fd;
39*8d67ca89SAndroid Build Coastguard Worker register long a1 __asm__("a1") = reinterpret_cast<long>(path);
40*8d67ca89SAndroid Build Coastguard Worker register long a2 __asm__("a2") = mode;
41*8d67ca89SAndroid Build Coastguard Worker register long a7 __asm__("a7") = __NR_faccessat;
42*8d67ca89SAndroid Build Coastguard Worker __asm__("ecall" : "=r"(a0) : "r"(a0), "r"(a1), "r"(a2), "r"(a7) : "memory");
43*8d67ca89SAndroid Build Coastguard Worker return a0;
44*8d67ca89SAndroid Build Coastguard Worker }
45*8d67ca89SAndroid Build Coastguard Worker
have_fast_v()46*8d67ca89SAndroid Build Coastguard Worker static bool have_fast_v() {
47*8d67ca89SAndroid Build Coastguard Worker static bool result = []() {
48*8d67ca89SAndroid Build Coastguard Worker // We don't want to do a full "bogomips" test, so just check for the
49*8d67ca89SAndroid Build Coastguard Worker // presence of a file that would indicate that we're running in qemu.
50*8d67ca89SAndroid Build Coastguard Worker return ifunc_faccessat(AT_FDCWD, "/dev/hvc0", F_OK) != 0;
51*8d67ca89SAndroid Build Coastguard Worker }();
52*8d67ca89SAndroid Build Coastguard Worker return result;
53*8d67ca89SAndroid Build Coastguard Worker }
54*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(memchr)55*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(memchr) {
56*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(memchr_func_t, memchr_v);
57*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(memchr_func_t, memchr_gc);
58*8d67ca89SAndroid Build Coastguard Worker }
59*8d67ca89SAndroid Build Coastguard Worker MEMCHR_SHIM()
60*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(memcmp)61*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(memcmp) {
62*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(memcmp_func_t, memcmp_v);
63*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(memcmp_func_t, memcmp_gc);
64*8d67ca89SAndroid Build Coastguard Worker }
65*8d67ca89SAndroid Build Coastguard Worker MEMCMP_SHIM()
66*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(memcpy)67*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(memcpy) {
68*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(memcpy_func_t, memcpy_v);
69*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(memcpy_func_t, memcpy_gc);
70*8d67ca89SAndroid Build Coastguard Worker }
71*8d67ca89SAndroid Build Coastguard Worker MEMCPY_SHIM()
72*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(memmove)73*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(memmove) {
74*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(memmove_func_t, memmove_v);
75*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(memmove_func_t, memmove_gc);
76*8d67ca89SAndroid Build Coastguard Worker }
77*8d67ca89SAndroid Build Coastguard Worker MEMMOVE_SHIM()
78*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(memset)79*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(memset) {
80*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(memset_func_t, memset_v);
81*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(memset_func_t, memset_gc);
82*8d67ca89SAndroid Build Coastguard Worker }
83*8d67ca89SAndroid Build Coastguard Worker MEMSET_SHIM()
84*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(stpcpy)85*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(stpcpy) {
86*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(stpcpy_func_t, stpcpy_v);
87*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(stpcpy_func_t, stpcpy_gc);
88*8d67ca89SAndroid Build Coastguard Worker }
89*8d67ca89SAndroid Build Coastguard Worker STPCPY_SHIM()
90*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strcat)91*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strcat) {
92*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strcat_func_t, strcat_v);
93*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strcat_func_t, strcat_gc);
94*8d67ca89SAndroid Build Coastguard Worker }
95*8d67ca89SAndroid Build Coastguard Worker STRCAT_SHIM()
96*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strchr)97*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strchr) {
98*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strchr_func_t, strchr_v);
99*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strchr_func_t, strchr_gc);
100*8d67ca89SAndroid Build Coastguard Worker }
101*8d67ca89SAndroid Build Coastguard Worker STRCHR_SHIM()
102*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strcmp)103*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strcmp) {
104*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strcmp_func_t, strcmp_v);
105*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strcmp_func_t, strcmp_gc);
106*8d67ca89SAndroid Build Coastguard Worker }
107*8d67ca89SAndroid Build Coastguard Worker STRCMP_SHIM()
108*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strcpy)109*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strcpy) {
110*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strcpy_func_t, strcpy_v);
111*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strcpy_func_t, strcpy_gc);
112*8d67ca89SAndroid Build Coastguard Worker }
113*8d67ca89SAndroid Build Coastguard Worker STRCPY_SHIM()
114*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strlen)115*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strlen) {
116*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strlen_func_t, strlen_v);
117*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strlen_func_t, strlen_gc);
118*8d67ca89SAndroid Build Coastguard Worker }
119*8d67ca89SAndroid Build Coastguard Worker STRLEN_SHIM()
120*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strncat)121*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strncat) {
122*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strncat_func_t, strncat_v);
123*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strncat_func_t, strncat_gc);
124*8d67ca89SAndroid Build Coastguard Worker }
125*8d67ca89SAndroid Build Coastguard Worker STRNCAT_SHIM()
126*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strncmp)127*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strncmp) {
128*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strncmp_func_t, strncmp_v);
129*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strncmp_func_t, strncmp_gc);
130*8d67ca89SAndroid Build Coastguard Worker }
131*8d67ca89SAndroid Build Coastguard Worker STRNCMP_SHIM()
132*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strncpy)133*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strncpy) {
134*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strncpy_func_t, strncpy_v);
135*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strncpy_func_t, strncpy_gc);
136*8d67ca89SAndroid Build Coastguard Worker }
137*8d67ca89SAndroid Build Coastguard Worker STRNCPY_SHIM()
138*8d67ca89SAndroid Build Coastguard Worker
DEFINE_IFUNC_FOR(strnlen)139*8d67ca89SAndroid Build Coastguard Worker DEFINE_IFUNC_FOR(strnlen) {
140*8d67ca89SAndroid Build Coastguard Worker if (have_fast_v()) RETURN_FUNC(strnlen_func_t, strnlen_v);
141*8d67ca89SAndroid Build Coastguard Worker RETURN_FUNC(strnlen_func_t, strnlen_gc);
142*8d67ca89SAndroid Build Coastguard Worker }
143*8d67ca89SAndroid Build Coastguard Worker STRNLEN_SHIM()
144*8d67ca89SAndroid Build Coastguard Worker
145*8d67ca89SAndroid Build Coastguard Worker } // extern "C"
146