1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker *
4*8d67ca89SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8d67ca89SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8d67ca89SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8d67ca89SAndroid Build Coastguard Worker *
8*8d67ca89SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8d67ca89SAndroid Build Coastguard Worker *
10*8d67ca89SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8d67ca89SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8d67ca89SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8d67ca89SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8d67ca89SAndroid Build Coastguard Worker * limitations under the License.
15*8d67ca89SAndroid Build Coastguard Worker */
16*8d67ca89SAndroid Build Coastguard Worker
17*8d67ca89SAndroid Build Coastguard Worker #pragma once
18*8d67ca89SAndroid Build Coastguard Worker
19*8d67ca89SAndroid Build Coastguard Worker #include <dirent.h>
20*8d67ca89SAndroid Build Coastguard Worker #include <dlfcn.h>
21*8d67ca89SAndroid Build Coastguard Worker #include <fcntl.h>
22*8d67ca89SAndroid Build Coastguard Worker #include <gtest/gtest.h>
23*8d67ca89SAndroid Build Coastguard Worker #include <inttypes.h>
24*8d67ca89SAndroid Build Coastguard Worker #include <sys/mman.h>
25*8d67ca89SAndroid Build Coastguard Worker #include <sys/prctl.h>
26*8d67ca89SAndroid Build Coastguard Worker #include <sys/types.h>
27*8d67ca89SAndroid Build Coastguard Worker #include <sys/wait.h>
28*8d67ca89SAndroid Build Coastguard Worker #include <unistd.h>
29*8d67ca89SAndroid Build Coastguard Worker
30*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
31*8d67ca89SAndroid Build Coastguard Worker #include <sys/system_properties.h>
32*8d67ca89SAndroid Build Coastguard Worker #endif
33*8d67ca89SAndroid Build Coastguard Worker
34*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
35*8d67ca89SAndroid Build Coastguard Worker #include <bionic/macros.h>
36*8d67ca89SAndroid Build Coastguard Worker #else
37*8d67ca89SAndroid Build Coastguard Worker #define untag_address(p) p
38*8d67ca89SAndroid Build Coastguard Worker #endif
39*8d67ca89SAndroid Build Coastguard Worker
40*8d67ca89SAndroid Build Coastguard Worker #include <atomic>
41*8d67ca89SAndroid Build Coastguard Worker #include <iomanip>
42*8d67ca89SAndroid Build Coastguard Worker #include <string>
43*8d67ca89SAndroid Build Coastguard Worker #include <regex>
44*8d67ca89SAndroid Build Coastguard Worker
45*8d67ca89SAndroid Build Coastguard Worker #include <android-base/file.h>
46*8d67ca89SAndroid Build Coastguard Worker #include <android-base/macros.h>
47*8d67ca89SAndroid Build Coastguard Worker #include <android-base/scopeguard.h>
48*8d67ca89SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
49*8d67ca89SAndroid Build Coastguard Worker
50*8d67ca89SAndroid Build Coastguard Worker #if defined(__LP64__)
51*8d67ca89SAndroid Build Coastguard Worker #define PATH_TO_SYSTEM_LIB "/system/lib64/"
52*8d67ca89SAndroid Build Coastguard Worker #else
53*8d67ca89SAndroid Build Coastguard Worker #define PATH_TO_SYSTEM_LIB "/system/lib/"
54*8d67ca89SAndroid Build Coastguard Worker #endif
55*8d67ca89SAndroid Build Coastguard Worker
56*8d67ca89SAndroid Build Coastguard Worker #if defined(__GLIBC__)
57*8d67ca89SAndroid Build Coastguard Worker #define BIN_DIR "/bin/"
58*8d67ca89SAndroid Build Coastguard Worker #else
59*8d67ca89SAndroid Build Coastguard Worker #define BIN_DIR "/system/bin/"
60*8d67ca89SAndroid Build Coastguard Worker #endif
61*8d67ca89SAndroid Build Coastguard Worker
62*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
63*8d67ca89SAndroid Build Coastguard Worker #define KNOWN_FAILURE_ON_BIONIC(x) xfail_ ## x
64*8d67ca89SAndroid Build Coastguard Worker #else
65*8d67ca89SAndroid Build Coastguard Worker #define KNOWN_FAILURE_ON_BIONIC(x) x
66*8d67ca89SAndroid Build Coastguard Worker #endif
67*8d67ca89SAndroid Build Coastguard Worker
68*8d67ca89SAndroid Build Coastguard Worker // bionic's dlsym doesn't work in static binaries, so we can't access icu,
69*8d67ca89SAndroid Build Coastguard Worker // so any unicode test case will fail.
have_dl()70*8d67ca89SAndroid Build Coastguard Worker static inline bool have_dl() {
71*8d67ca89SAndroid Build Coastguard Worker return (dlopen("libc.so", 0) != nullptr);
72*8d67ca89SAndroid Build Coastguard Worker }
73*8d67ca89SAndroid Build Coastguard Worker
running_with_native_bridge()74*8d67ca89SAndroid Build Coastguard Worker static inline bool running_with_native_bridge() {
75*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
76*8d67ca89SAndroid Build Coastguard Worker static const prop_info* pi = __system_property_find("ro.dalvik.vm.isa." ABI_STRING);
77*8d67ca89SAndroid Build Coastguard Worker return pi != nullptr;
78*8d67ca89SAndroid Build Coastguard Worker #endif
79*8d67ca89SAndroid Build Coastguard Worker return false;
80*8d67ca89SAndroid Build Coastguard Worker }
81*8d67ca89SAndroid Build Coastguard Worker
82*8d67ca89SAndroid Build Coastguard Worker #define SKIP_WITH_NATIVE_BRIDGE if (running_with_native_bridge()) GTEST_SKIP()
83*8d67ca89SAndroid Build Coastguard Worker
84*8d67ca89SAndroid Build Coastguard Worker #if defined(__linux__)
85*8d67ca89SAndroid Build Coastguard Worker
86*8d67ca89SAndroid Build Coastguard Worker #include <sys/sysmacros.h>
87*8d67ca89SAndroid Build Coastguard Worker
88*8d67ca89SAndroid Build Coastguard Worker struct map_record {
89*8d67ca89SAndroid Build Coastguard Worker uintptr_t addr_start;
90*8d67ca89SAndroid Build Coastguard Worker uintptr_t addr_end;
91*8d67ca89SAndroid Build Coastguard Worker
92*8d67ca89SAndroid Build Coastguard Worker int perms;
93*8d67ca89SAndroid Build Coastguard Worker
94*8d67ca89SAndroid Build Coastguard Worker size_t offset;
95*8d67ca89SAndroid Build Coastguard Worker
96*8d67ca89SAndroid Build Coastguard Worker dev_t device;
97*8d67ca89SAndroid Build Coastguard Worker ino_t inode;
98*8d67ca89SAndroid Build Coastguard Worker
99*8d67ca89SAndroid Build Coastguard Worker std::string pathname;
100*8d67ca89SAndroid Build Coastguard Worker };
101*8d67ca89SAndroid Build Coastguard Worker
102*8d67ca89SAndroid Build Coastguard Worker class Maps {
103*8d67ca89SAndroid Build Coastguard Worker public:
parse_maps(std::vector<map_record> * maps)104*8d67ca89SAndroid Build Coastguard Worker static bool parse_maps(std::vector<map_record>* maps) {
105*8d67ca89SAndroid Build Coastguard Worker maps->clear();
106*8d67ca89SAndroid Build Coastguard Worker
107*8d67ca89SAndroid Build Coastguard Worker std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("/proc/self/maps", "re"), fclose);
108*8d67ca89SAndroid Build Coastguard Worker if (!fp) return false;
109*8d67ca89SAndroid Build Coastguard Worker
110*8d67ca89SAndroid Build Coastguard Worker char line[BUFSIZ];
111*8d67ca89SAndroid Build Coastguard Worker while (fgets(line, sizeof(line), fp.get()) != nullptr) {
112*8d67ca89SAndroid Build Coastguard Worker map_record record;
113*8d67ca89SAndroid Build Coastguard Worker uint32_t dev_major, dev_minor;
114*8d67ca89SAndroid Build Coastguard Worker int path_offset;
115*8d67ca89SAndroid Build Coastguard Worker char prot[5]; // sizeof("rwxp")
116*8d67ca89SAndroid Build Coastguard Worker if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %x:%x %lu %n",
117*8d67ca89SAndroid Build Coastguard Worker &record.addr_start, &record.addr_end, prot, &record.offset,
118*8d67ca89SAndroid Build Coastguard Worker &dev_major, &dev_minor, &record.inode, &path_offset) == 7) {
119*8d67ca89SAndroid Build Coastguard Worker record.perms = 0;
120*8d67ca89SAndroid Build Coastguard Worker if (prot[0] == 'r') {
121*8d67ca89SAndroid Build Coastguard Worker record.perms |= PROT_READ;
122*8d67ca89SAndroid Build Coastguard Worker }
123*8d67ca89SAndroid Build Coastguard Worker if (prot[1] == 'w') {
124*8d67ca89SAndroid Build Coastguard Worker record.perms |= PROT_WRITE;
125*8d67ca89SAndroid Build Coastguard Worker }
126*8d67ca89SAndroid Build Coastguard Worker if (prot[2] == 'x') {
127*8d67ca89SAndroid Build Coastguard Worker record.perms |= PROT_EXEC;
128*8d67ca89SAndroid Build Coastguard Worker }
129*8d67ca89SAndroid Build Coastguard Worker
130*8d67ca89SAndroid Build Coastguard Worker // TODO: parse shared/private?
131*8d67ca89SAndroid Build Coastguard Worker
132*8d67ca89SAndroid Build Coastguard Worker record.device = makedev(dev_major, dev_minor);
133*8d67ca89SAndroid Build Coastguard Worker record.pathname = line + path_offset;
134*8d67ca89SAndroid Build Coastguard Worker if (!record.pathname.empty() && record.pathname.back() == '\n') {
135*8d67ca89SAndroid Build Coastguard Worker record.pathname.pop_back();
136*8d67ca89SAndroid Build Coastguard Worker }
137*8d67ca89SAndroid Build Coastguard Worker maps->push_back(record);
138*8d67ca89SAndroid Build Coastguard Worker }
139*8d67ca89SAndroid Build Coastguard Worker }
140*8d67ca89SAndroid Build Coastguard Worker
141*8d67ca89SAndroid Build Coastguard Worker return true;
142*8d67ca89SAndroid Build Coastguard Worker }
143*8d67ca89SAndroid Build Coastguard Worker };
144*8d67ca89SAndroid Build Coastguard Worker
145*8d67ca89SAndroid Build Coastguard Worker extern "C" pid_t gettid();
146*8d67ca89SAndroid Build Coastguard Worker
147*8d67ca89SAndroid Build Coastguard Worker #endif
148*8d67ca89SAndroid Build Coastguard Worker
WaitUntilThreadSleep(std::atomic<pid_t> & tid)149*8d67ca89SAndroid Build Coastguard Worker static inline void WaitUntilThreadSleep(std::atomic<pid_t>& tid) {
150*8d67ca89SAndroid Build Coastguard Worker while (tid == 0) {
151*8d67ca89SAndroid Build Coastguard Worker usleep(1000);
152*8d67ca89SAndroid Build Coastguard Worker }
153*8d67ca89SAndroid Build Coastguard Worker std::string filename = android::base::StringPrintf("/proc/%d/stat", tid.load());
154*8d67ca89SAndroid Build Coastguard Worker std::regex regex {R"(\s+S\s+)"};
155*8d67ca89SAndroid Build Coastguard Worker
156*8d67ca89SAndroid Build Coastguard Worker while (true) {
157*8d67ca89SAndroid Build Coastguard Worker std::string content;
158*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(filename, &content));
159*8d67ca89SAndroid Build Coastguard Worker if (std::regex_search(content, regex)) {
160*8d67ca89SAndroid Build Coastguard Worker break;
161*8d67ca89SAndroid Build Coastguard Worker }
162*8d67ca89SAndroid Build Coastguard Worker usleep(1000);
163*8d67ca89SAndroid Build Coastguard Worker }
164*8d67ca89SAndroid Build Coastguard Worker }
165*8d67ca89SAndroid Build Coastguard Worker
166*8d67ca89SAndroid Build Coastguard Worker static inline void AssertChildExited(int pid, int expected_exit_status,
167*8d67ca89SAndroid Build Coastguard Worker const std::string* error_msg = nullptr) {
168*8d67ca89SAndroid Build Coastguard Worker int status;
169*8d67ca89SAndroid Build Coastguard Worker std::string error;
170*8d67ca89SAndroid Build Coastguard Worker if (error_msg == nullptr) {
171*8d67ca89SAndroid Build Coastguard Worker error_msg = &error;
172*8d67ca89SAndroid Build Coastguard Worker }
173*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, &status, 0))) << *error_msg;
174*8d67ca89SAndroid Build Coastguard Worker if (expected_exit_status >= 0) {
175*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(WIFEXITED(status)) << *error_msg;
176*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(expected_exit_status, WEXITSTATUS(status)) << *error_msg;
177*8d67ca89SAndroid Build Coastguard Worker } else {
178*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(WIFSIGNALED(status)) << *error_msg;
179*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(-expected_exit_status, WTERMSIG(status)) << *error_msg;
180*8d67ca89SAndroid Build Coastguard Worker }
181*8d67ca89SAndroid Build Coastguard Worker }
182*8d67ca89SAndroid Build Coastguard Worker
CloseOnExec(int fd)183*8d67ca89SAndroid Build Coastguard Worker static inline bool CloseOnExec(int fd) {
184*8d67ca89SAndroid Build Coastguard Worker int flags = fcntl(fd, F_GETFD);
185*8d67ca89SAndroid Build Coastguard Worker // This isn't ideal, but the alternatives are worse:
186*8d67ca89SAndroid Build Coastguard Worker // * If we return void and use ASSERT_NE here, we get failures at utils.h:191
187*8d67ca89SAndroid Build Coastguard Worker // rather than in the relevant test.
188*8d67ca89SAndroid Build Coastguard Worker // * If we ignore failures of fcntl(), well, that's obviously a bad idea.
189*8d67ca89SAndroid Build Coastguard Worker if (flags == -1) abort();
190*8d67ca89SAndroid Build Coastguard Worker return flags & FD_CLOEXEC;
191*8d67ca89SAndroid Build Coastguard Worker }
192*8d67ca89SAndroid Build Coastguard Worker
193*8d67ca89SAndroid Build Coastguard Worker // The absolute path to the executable
194*8d67ca89SAndroid Build Coastguard Worker const std::string& get_executable_path();
195*8d67ca89SAndroid Build Coastguard Worker
196*8d67ca89SAndroid Build Coastguard Worker // Access to argc/argv/envp
197*8d67ca89SAndroid Build Coastguard Worker int get_argc();
198*8d67ca89SAndroid Build Coastguard Worker char** get_argv();
199*8d67ca89SAndroid Build Coastguard Worker char** get_envp();
200*8d67ca89SAndroid Build Coastguard Worker
201*8d67ca89SAndroid Build Coastguard Worker // ExecTestHelper is only used in bionic and glibc tests.
202*8d67ca89SAndroid Build Coastguard Worker #ifndef __APPLE__
203*8d67ca89SAndroid Build Coastguard Worker class ExecTestHelper {
204*8d67ca89SAndroid Build Coastguard Worker public:
GetArgs()205*8d67ca89SAndroid Build Coastguard Worker char** GetArgs() {
206*8d67ca89SAndroid Build Coastguard Worker return const_cast<char**>(args_.data());
207*8d67ca89SAndroid Build Coastguard Worker }
GetArg0()208*8d67ca89SAndroid Build Coastguard Worker const char* GetArg0() {
209*8d67ca89SAndroid Build Coastguard Worker return args_[0];
210*8d67ca89SAndroid Build Coastguard Worker }
GetEnv()211*8d67ca89SAndroid Build Coastguard Worker char** GetEnv() {
212*8d67ca89SAndroid Build Coastguard Worker return const_cast<char**>(env_.data());
213*8d67ca89SAndroid Build Coastguard Worker }
GetOutput()214*8d67ca89SAndroid Build Coastguard Worker const std::string& GetOutput() {
215*8d67ca89SAndroid Build Coastguard Worker return output_;
216*8d67ca89SAndroid Build Coastguard Worker }
217*8d67ca89SAndroid Build Coastguard Worker
SetArgs(const std::vector<const char * > & args)218*8d67ca89SAndroid Build Coastguard Worker void SetArgs(const std::vector<const char*>& args) {
219*8d67ca89SAndroid Build Coastguard Worker args_ = args;
220*8d67ca89SAndroid Build Coastguard Worker }
SetEnv(const std::vector<const char * > & env)221*8d67ca89SAndroid Build Coastguard Worker void SetEnv(const std::vector<const char*>& env) {
222*8d67ca89SAndroid Build Coastguard Worker env_ = env;
223*8d67ca89SAndroid Build Coastguard Worker }
224*8d67ca89SAndroid Build Coastguard Worker
Run(const std::function<void ()> & child_fn,int expected_exit_status,const char * expected_output_regex)225*8d67ca89SAndroid Build Coastguard Worker void Run(const std::function<void()>& child_fn, int expected_exit_status,
226*8d67ca89SAndroid Build Coastguard Worker const char* expected_output_regex) {
227*8d67ca89SAndroid Build Coastguard Worker int fds[2];
228*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(pipe(fds), -1);
229*8d67ca89SAndroid Build Coastguard Worker
230*8d67ca89SAndroid Build Coastguard Worker pid_t pid = fork();
231*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(pid, -1);
232*8d67ca89SAndroid Build Coastguard Worker
233*8d67ca89SAndroid Build Coastguard Worker if (pid == 0) {
234*8d67ca89SAndroid Build Coastguard Worker // Child.
235*8d67ca89SAndroid Build Coastguard Worker close(fds[0]);
236*8d67ca89SAndroid Build Coastguard Worker dup2(fds[1], STDOUT_FILENO);
237*8d67ca89SAndroid Build Coastguard Worker dup2(fds[1], STDERR_FILENO);
238*8d67ca89SAndroid Build Coastguard Worker if (fds[1] != STDOUT_FILENO && fds[1] != STDERR_FILENO) close(fds[1]);
239*8d67ca89SAndroid Build Coastguard Worker child_fn();
240*8d67ca89SAndroid Build Coastguard Worker FAIL();
241*8d67ca89SAndroid Build Coastguard Worker }
242*8d67ca89SAndroid Build Coastguard Worker
243*8d67ca89SAndroid Build Coastguard Worker // Parent.
244*8d67ca89SAndroid Build Coastguard Worker close(fds[1]);
245*8d67ca89SAndroid Build Coastguard Worker output_.clear();
246*8d67ca89SAndroid Build Coastguard Worker char buf[BUFSIZ];
247*8d67ca89SAndroid Build Coastguard Worker ssize_t bytes_read;
248*8d67ca89SAndroid Build Coastguard Worker while ((bytes_read = TEMP_FAILURE_RETRY(read(fds[0], buf, sizeof(buf)))) > 0) {
249*8d67ca89SAndroid Build Coastguard Worker output_.append(buf, bytes_read);
250*8d67ca89SAndroid Build Coastguard Worker }
251*8d67ca89SAndroid Build Coastguard Worker close(fds[0]);
252*8d67ca89SAndroid Build Coastguard Worker
253*8d67ca89SAndroid Build Coastguard Worker std::string error_msg("Test output:\n" + output_);
254*8d67ca89SAndroid Build Coastguard Worker AssertChildExited(pid, expected_exit_status, &error_msg);
255*8d67ca89SAndroid Build Coastguard Worker if (expected_output_regex != nullptr) {
256*8d67ca89SAndroid Build Coastguard Worker if (!std::regex_search(output_, std::regex(expected_output_regex))) {
257*8d67ca89SAndroid Build Coastguard Worker FAIL() << "regex " << std::quoted(expected_output_regex) << " didn't match " << std::quoted(output_);
258*8d67ca89SAndroid Build Coastguard Worker }
259*8d67ca89SAndroid Build Coastguard Worker }
260*8d67ca89SAndroid Build Coastguard Worker }
261*8d67ca89SAndroid Build Coastguard Worker
262*8d67ca89SAndroid Build Coastguard Worker private:
263*8d67ca89SAndroid Build Coastguard Worker std::vector<const char*> args_;
264*8d67ca89SAndroid Build Coastguard Worker std::vector<const char*> env_;
265*8d67ca89SAndroid Build Coastguard Worker std::string output_;
266*8d67ca89SAndroid Build Coastguard Worker };
267*8d67ca89SAndroid Build Coastguard Worker
268*8d67ca89SAndroid Build Coastguard Worker void RunGwpAsanTest(const char* test_name);
269*8d67ca89SAndroid Build Coastguard Worker void RunSubtestNoEnv(const char* test_name);
270*8d67ca89SAndroid Build Coastguard Worker #endif
271*8d67ca89SAndroid Build Coastguard Worker
272*8d67ca89SAndroid Build Coastguard Worker class FdLeakChecker {
273*8d67ca89SAndroid Build Coastguard Worker public:
FdLeakChecker()274*8d67ca89SAndroid Build Coastguard Worker FdLeakChecker() {
275*8d67ca89SAndroid Build Coastguard Worker }
276*8d67ca89SAndroid Build Coastguard Worker
~FdLeakChecker()277*8d67ca89SAndroid Build Coastguard Worker ~FdLeakChecker() {
278*8d67ca89SAndroid Build Coastguard Worker size_t end_count = CountOpenFds();
279*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(start_count_, end_count);
280*8d67ca89SAndroid Build Coastguard Worker }
281*8d67ca89SAndroid Build Coastguard Worker
282*8d67ca89SAndroid Build Coastguard Worker private:
CountOpenFds()283*8d67ca89SAndroid Build Coastguard Worker static size_t CountOpenFds() {
284*8d67ca89SAndroid Build Coastguard Worker auto fd_dir = std::unique_ptr<DIR, decltype(&closedir)>{ opendir("/proc/self/fd"), closedir };
285*8d67ca89SAndroid Build Coastguard Worker size_t count = 0;
286*8d67ca89SAndroid Build Coastguard Worker dirent* de = nullptr;
287*8d67ca89SAndroid Build Coastguard Worker while ((de = readdir(fd_dir.get())) != nullptr) {
288*8d67ca89SAndroid Build Coastguard Worker if (de->d_type == DT_LNK) {
289*8d67ca89SAndroid Build Coastguard Worker ++count;
290*8d67ca89SAndroid Build Coastguard Worker }
291*8d67ca89SAndroid Build Coastguard Worker }
292*8d67ca89SAndroid Build Coastguard Worker return count;
293*8d67ca89SAndroid Build Coastguard Worker }
294*8d67ca89SAndroid Build Coastguard Worker
295*8d67ca89SAndroid Build Coastguard Worker size_t start_count_ = CountOpenFds();
296*8d67ca89SAndroid Build Coastguard Worker };
297*8d67ca89SAndroid Build Coastguard Worker
running_with_mte()298*8d67ca89SAndroid Build Coastguard Worker static inline bool running_with_mte() {
299*8d67ca89SAndroid Build Coastguard Worker #ifdef __aarch64__
300*8d67ca89SAndroid Build Coastguard Worker int level = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
301*8d67ca89SAndroid Build Coastguard Worker return level >= 0 && (level & PR_TAGGED_ADDR_ENABLE) &&
302*8d67ca89SAndroid Build Coastguard Worker (level & PR_MTE_TCF_MASK) != PR_MTE_TCF_NONE;
303*8d67ca89SAndroid Build Coastguard Worker #else
304*8d67ca89SAndroid Build Coastguard Worker return false;
305*8d67ca89SAndroid Build Coastguard Worker #endif
306*8d67ca89SAndroid Build Coastguard Worker }
307*8d67ca89SAndroid Build Coastguard Worker
308*8d67ca89SAndroid Build Coastguard Worker bool IsLowRamDevice();
309*8d67ca89SAndroid Build Coastguard Worker
310*8d67ca89SAndroid Build Coastguard Worker int64_t NanoTime();
311*8d67ca89SAndroid Build Coastguard Worker
312*8d67ca89SAndroid Build Coastguard Worker class Errno {
313*8d67ca89SAndroid Build Coastguard Worker public:
Errno(int e)314*8d67ca89SAndroid Build Coastguard Worker Errno(int e) : errno_(e) {}
315*8d67ca89SAndroid Build Coastguard Worker int errno_;
316*8d67ca89SAndroid Build Coastguard Worker };
317*8d67ca89SAndroid Build Coastguard Worker void PrintTo(const Errno& e, std::ostream* os);
318*8d67ca89SAndroid Build Coastguard Worker bool operator==(const Errno& lhs, const Errno& rhs);
319*8d67ca89SAndroid Build Coastguard Worker #define ASSERT_ERRNO(expected_errno) ASSERT_EQ(Errno(expected_errno), Errno(errno))
320*8d67ca89SAndroid Build Coastguard Worker #define EXPECT_ERRNO(expected_errno) EXPECT_EQ(Errno(expected_errno), Errno(errno))
321