1 /*
2  * Copyright (C) 2023 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 "berberis/runtime/execute_guest.h"
20 
21 #include <cstdint>
22 
23 #include "berberis/guest_os_primitives/guest_map_shadow.h"
24 #include "berberis/guest_os_primitives/guest_thread_manager.h"
25 #include "berberis/guest_state/guest_addr.h"
26 #include "berberis/guest_state/guest_state.h"
27 #include "berberis/runtime/berberis.h"
28 #include "berberis/runtime_primitives/translation_cache.h"
29 
30 namespace berberis {
31 
32 namespace {
33 
TEST(ExecuteGuestRiscv64,Basic)34 TEST(ExecuteGuestRiscv64, Basic) {
35   const uint32_t code[] = {
36       0x003100b3,  // add x1, x2, x3
37       0x004090b3,  // sll x1, x1, x4
38       0x008002ef,  // jal x5, 8
39   };
40 
41   InitBerberis();
42 
43   GuestMapShadow::GetInstance()->SetExecutable(ToGuestAddr(&code[0]), sizeof(code));
44 
45   GuestThread* thread = GetCurrentGuestThread();
46   auto& cpu_state = thread->state()->cpu;
47   cpu_state.insn_addr = ToGuestAddr(&code[0]);
48   SetXReg<2>(cpu_state, 10);
49   SetXReg<3>(cpu_state, 11);
50   SetXReg<4>(cpu_state, 1);
51   GuestAddr stop_pc = ToGuestAddr(&code[0]) + 16;
52   auto cache = TranslationCache::GetInstance();
53   cache->SetStop(stop_pc);
54   ExecuteGuest(thread->state());
55   cache->TestingClearStop(stop_pc);
56   EXPECT_EQ(GetXReg<1>(cpu_state), 42u);
57 
58   GuestMapShadow::GetInstance()->ClearExecutable(ToGuestAddr(&code[0]), sizeof(code));
59 }
60 
61 }  // namespace
62 
63 }  // namespace berberis
64