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 #ifndef BERBERIS_GUEST_LOADER_GUEST_LOADER_IMPL_H_
18 #define BERBERIS_GUEST_LOADER_GUEST_LOADER_IMPL_H_
19
20 #include <cstddef> // size_t
21 #include <cstdint> // uint8_t
22
23 #include "berberis/base/stringprintf.h"
24 #include "berberis/guest_abi/guest_function_wrapper.h"
25 #include "berberis/guest_abi/guest_type.h"
26 #include "berberis/guest_loader/guest_loader.h"
27 #include "berberis/guest_state/guest_addr.h"
28 #include "berberis/guest_state/guest_state_opaque.h"
29 #include "berberis/runtime_primitives/host_code.h"
30 #include "berberis/tiny_loader/loaded_elf_file.h"
31
32 namespace berberis {
33
34 // TODO(b/280544942): Consider moving these paths to native_bridge_support.
35 // Define these path constants for the target guest architecture.
36 extern const char* kAppProcessPath;
37 extern const char* kPtInterpPath;
38 extern const char* kVdsoPath;
39 extern const char* kProxyPrefix;
40
41 GuestAddr InitKernelArgs(GuestAddr guest_sp,
42 size_t argc,
43 const char* argv[],
44 char* envp[],
45 GuestAddr linker_base_addr,
46 GuestAddr main_executable_entry_point,
47 GuestAddr phdr,
48 size_t phdr_count,
49 GuestAddr ehdr_vdso,
50 const uint8_t (*random_bytes)[16]);
51
52 bool MakeElfSymbolTrampolineCallable(const LoadedElfFile& elf_file,
53 const char* elf_file_label,
54 const char* symbol_name,
55 void (*callback)(HostCode, ThreadState*),
56 HostCode arg,
57 std::string* error_msg);
58
59 void InitializeLinkerCallbacksToStubs(LinkerCallbacks* linker_callbacks);
60 // Registers architecture-agnostic linker callbacks.
61 bool InitializeLinkerCallbacks(LinkerCallbacks* linker_callbacks,
62 const LoadedElfFile& linker_elf_file,
63 std::string* error_msg);
64 // Registers guest architecture-specific callbacks.
65 bool InitializeLinkerCallbacksArch(LinkerCallbacks* linker_callbacks,
66 const LoadedElfFile& linker_elf_file,
67 std::string* error_msg);
68
69 void InitLinkerDebug(const LoadedElfFile& linker_elf_file);
70
71 // For InitializeLinkerCallbacks implementations.
72 template <typename T>
FindSymbol(const LoadedElfFile & elf_file,const char * symbol_name,T * fn,std::string * error_msg)73 bool FindSymbol(const LoadedElfFile& elf_file,
74 const char* symbol_name,
75 T* fn,
76 std::string* error_msg) {
77 T guest_fn = reinterpret_cast<T>(elf_file.FindSymbol(symbol_name));
78 if (guest_fn == nullptr) {
79 *error_msg = StringPrintf("symbol not found: %s", symbol_name);
80 return false;
81 }
82
83 *fn = WrapGuestFunction(GuestType(guest_fn), symbol_name);
84
85 return true;
86 }
87
88 } // namespace berberis
89
90 #endif // BERBERIS_GUEST_LOADER_GUEST_LOADER_IMPL_H_
91