10
* nothing about how a library is thunked. Any toolchain can implement the
11
* userspace side. Lorelei is one end-to-end implementation (guest/host
12
* runtimes plus a thunk compiler that generates thunks from a library's
13
- * headers):
13
+ * headers), and how it handles argument marshalling, callbacks and variadic
14
+ * functions can serve as a reference:
15
* https://github.com/rover2024/lorelei
16
*
17
* See docs/about/emulation.rst|Dynamic Linking Call for details and examples.
21
* execution in the QEMU host process. It is NOT a sandbox and provides no
22
* isolation; only load it for guests you fully trust.
23
*
23
- * WARNING: requires guest_base == 0, which is qemu-user's default. Pointer
24
- * operands are dereferenced as host addresses directly, and the invoked host
25
- * functions dereference guest pointers with no address translation, so guest
26
- * and host must share a single address space. A non-zero guest_base (e.g. set
27
- * via -B/-R) would make every pointer off by guest_base and hit unrelated
28
- * host memory.
24
+ * WARNING: requires guest_base == 0, which is qemu-user's default, and a
25
+ * guest whose pointer width and endianness match the host's. Pointer operands
26
+ * are dereferenced as host addresses directly, and the invoked host functions
27
+ * dereference guest pointers with no address translation, so guest and host
28
+ * must share a single address space and agree on how a pointer is stored. A
29
+ * non-zero guest_base (e.g. set via -B/-R) would make every pointer off by
30
+ * guest_base and hit unrelated host memory.
31
*
32
* SPDX-License-Identifier: GPL-2.0-or-later
33
*/
48
*
49
* It defaults to DLCALL_SYSCALL_DEFAULT and can be overridden at load time
50
* with the "syscall_num=N" argument. To avoid hijacking a real syscall the
49
- * guest might issue, N must be at least DLCALL_SYSCALL_MIN: every Linux ABI
50
- * keeps its syscall numbers well below this; numbers from here up are free.
51
+ * guest might issue, N must be at least DLCALL_SYSCALL_MIN, which most Linux
52
+ * ABIs keep their syscall numbers well below.
53
+ *
54
+ * N also has to reach the filter at all, which bounds it from above in a
55
+ * target specific way: arm32 answers anything past ARM_NR_BASE (0xf0000) with
56
+ * ENOSYS or SIGILL before do_syscall() runs, while aarch64 has no such bound.
57
+ *
58
+ * MIPS O32 bases its numbering at 4000, so the default is a real syscall there
59
+ * (getpriority). Raising N does not help either, because O32 rejects numbers
60
+ * its table does not define, again before the filter runs, which leaves no
61
+ * number that is both free and reachable on that ABI. Its N32 and N64 ABIs
62
+ * base at 6000 and 5000 and have no such gate, so they are unaffected.
63
*/
64
enum {
65
DLCALL_SYSCALL_DEFAULT = 4096,
180
case DLCALL_ID_FREE_LIBRARY: {
181
void *handle = (void *) a2;
182
int *ret_ptr = (int *) a3;
183
+ assert(ret_ptr);
184
*ret_ptr = dlclose(handle);
185
*sysret = 0;
186
break;
189
/* Get the last error message for a library event. */
190
case DLCALL_ID_GET_LIBRARY_ERROR: {
191
const char **error_ptr = (const char **) a2;
192
+ assert(error_ptr);
193
*error_ptr = dlerror();
194
*sysret = 0;
195
break;