• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "gtest/gtest.h"
18 
19 #include <sys/mman.h>
20 #include <sys/syscall.h>
21 
TEST(Syscall,SchedSetAffinity)22 TEST(Syscall, SchedSetAffinity) {
23   int mask = 1;
24   ASSERT_EQ(syscall(SYS_sched_setaffinity, 0, 4, &mask), 0);
25 }
26 
TEST(Syscall,CacheFlush)27 TEST(Syscall, CacheFlush) {
28   // This test work as simple JIT engine with code patching.
29   // Workflow is like this:
30   // - create code
31   // - flush cache
32   // - runs code
33   // - modify code
34   // - flush cache
35   // - run code
36   static const int kCacheFlushSyscall = 0xf0002;
37   static const uint32_t code_template[] = {
38       0xe3000001,  // movw r0, #0x1
39       0xe12fff1e,  // bx lr
40   };
41   uint8_t* start = reinterpret_cast<uint8_t*>(mmap(0,
42                                                    sizeof(code_template),
43                                                    PROT_READ | PROT_WRITE | PROT_EXEC,
44                                                    MAP_PRIVATE | MAP_ANONYMOUS,
45                                                    -1,
46                                                    0));
47   ASSERT_NE(start, MAP_FAILED);
48   memcpy(start, code_template, sizeof(code_template));
49   uint8_t* end = start + sizeof(code_template);
50   ASSERT_EQ(syscall(kCacheFlushSyscall, start, end, 0), 0);
51   using TestFunc = int (*)(void);
52   TestFunc func = reinterpret_cast<TestFunc>(start);
53   ASSERT_EQ(func(), 0x1);
54   *reinterpret_cast<uint32_t*>(start) = 0xe3000011;  // movw r0, #0x11
55   ASSERT_EQ(syscall(kCacheFlushSyscall, start, end, 0), 0);
56   ASSERT_EQ(func(), 0x11);
57   munmap(start, sizeof(code_template));
58 }
59 
TEST(Syscall,OAbiDisabled)60 TEST(Syscall, OAbiDisabled) {
61   int pipefd[2];
62   ASSERT_EQ(pipe(pipefd), 0);
63   char buf[4] = "Tst";
64   register uint32_t r0 asm("r0") = pipefd[1];
65   register uint32_t r1 asm("r1") = reinterpret_cast<uint32_t>(buf);
66   register uint32_t r2 asm("r2") = sizeof(buf);
67   register uint32_t r7 asm("r7") = SYS_write;
68   // Call "write" syscall using EABI, but instrument it to be interpreted as "read" if executed
69   // on system with OABI syscall calling convention or CONFIG_OABI_COMPAT mode enabled.
70   //
71   // On kernels with CONFIG_OABI_COMPAT immediate from "swi" instruction would be used, attempt to
72   // use "read" syscall (based on .imm value of "swi"instruction) would happen - and test would
73   // fail.
74   //
75   // On kernels without CONFIG_OABI_COMPAT value from r7 would be used and test would succeed.
76   asm("swi %1" : "=r"(r0) : "i"(SYS_read), "r"(r0), "r"(r1), "r"(r2), "r"(r7));
77   uint32_t result = r0;
78   ASSERT_EQ(result, sizeof(buf));
79   close(pipefd[0]);
80   close(pipefd[1]);
81 }
82