1 /*
2  * Copyright (C) 2024 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 "berberis/runtime_primitives/runtime_library.h"
18 
19 #if defined(__x86_64__)
20 #include "berberis/assembler/machine_code.h"
21 #include "berberis/assembler/x86_64.h"
22 #include "berberis/runtime_primitives/code_pool.h"
23 #endif
24 
25 namespace berberis {
26 
27 HostCodeAddr kEntryInterpret;
28 HostCodeAddr kEntryExitGeneratedCode;
29 HostCodeAddr kEntryStop;
30 HostCodeAddr kEntryNoExec;
31 HostCodeAddr kEntryNotTranslated;
32 HostCodeAddr kEntryTranslating;
33 HostCodeAddr kEntryInvalidating;
34 HostCodeAddr kEntryWrapping;
35 
36 namespace {
37 // This function installs a trampoline in the CodePool address space.
38 // This needed to ensure that all entries in the translation cache
39 // are always pointing to the memory allocated via CodePool.
InstallEntryTrampoline(HostCode target_function_ptr)40 HostCodeAddr InstallEntryTrampoline(HostCode target_function_ptr) {
41 #if defined(__x86_64__)
42   MachineCode mc;
43   x86_64::Assembler as(&mc);
44   as.Jmp(target_function_ptr);
45   as.Finalize();
46   return GetDefaultCodePoolInstance()->Add(&mc);
47 #else
48   return AsHostCodeAddr(target_function_ptr);
49 #endif
50 }
51 }  // namespace
52 
InitHostEntries()53 void InitHostEntries() {
54   kEntryInterpret = InstallEntryTrampoline(AsHostCode(berberis_entry_Interpret));
55   kEntryExitGeneratedCode = InstallEntryTrampoline(AsHostCode(berberis_entry_ExitGeneratedCode));
56   kEntryStop = InstallEntryTrampoline(AsHostCode(berberis_entry_Stop));
57   kEntryNoExec = InstallEntryTrampoline(AsHostCode(berberis_entry_NoExec));
58   kEntryNotTranslated = InstallEntryTrampoline(AsHostCode(berberis_entry_NotTranslated));
59   kEntryTranslating = InstallEntryTrampoline(AsHostCode(berberis_entry_Translating));
60   kEntryInvalidating = InstallEntryTrampoline(AsHostCode(berberis_entry_Invalidating));
61   kEntryWrapping = InstallEntryTrampoline(AsHostCode(berberis_entry_Wrapping));
62 }
63 
64 }  // namespace berberis
65