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