| /* | |
| * user-internals.h: prototypes etc internal to the linux-user implementation | |
| * | |
| * This program is free software; you can redistribute it and/or modify | |
| * it under the terms of the GNU General Public License as published by | |
| * the Free Software Foundation; either version 2 of the License, or | |
| * (at your option) any later version. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
| */ | |
| #ifndef LINUX_USER_USER_INTERNALS_H | |
| #define LINUX_USER_USER_INTERNALS_H | |
| #include "user/thunk.h" | |
| #include "qemu/log.h" | |
| #include "exec/tb-flush.h" | |
| #include "exec/translation-block.h" | |
| #include "user/probe-guest-base.h" | |
| extern char *exec_path; | |
| extern char real_exec_path[PATH_MAX]; | |
| void init_task_state(TaskState *ts); | |
| void task_settid(TaskState *); | |
| void stop_all_tasks(void); | |
| extern const char *qemu_uname_release; | |
| typedef struct IOCTLEntry IOCTLEntry; | |
| typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp, | |
| int fd, int cmd, abi_long arg); | |
| struct IOCTLEntry { | |
| int target_cmd; | |
| unsigned int host_cmd; | |
| const char *name; | |
| int access; | |
| do_ioctl_fn *do_ioctl; | |
| const argtype arg_type[5]; | |
| }; | |
| extern IOCTLEntry ioctl_entries[]; | |
| #define IOC_R 0x0001 | |
| #define IOC_W 0x0002 | |
| #define IOC_RW (IOC_R | IOC_W) | |
| /* | |
| * Returns true if the image uses the FDPIC ABI. If this is the case, | |
| * we have to provide some information (loadmap, pt_dynamic_info) such | |
| * that the program can be relocated adequately. This is also useful | |
| * when handling signals. | |
| */ | |
| int info_is_fdpic(struct image_info *info); | |
| void target_set_brk(abi_ulong new_brk); | |
| void syscall_init(void); | |
| abi_long do_syscall(CPUArchState *cpu_env, int num, abi_long arg1, | |
| abi_long arg2, abi_long arg3, abi_long arg4, | |
| abi_long arg5, abi_long arg6, abi_long arg7, | |
| abi_long arg8); | |
| extern __thread CPUState *thread_cpu; | |
| abi_long get_errno(abi_long ret); | |
| const char *target_strerror(int err); | |
| int get_osversion(void); | |
| void init_qemu_uname_release(void); | |
| void clone_fork_start(void); | |
| void clone_fork_end(bool child); | |
| void fork_start(void); | |
| void fork_end(pid_t pid); | |
| /** | |
| * linux_probe_guest_base: | |
| * @image_name: the executable being loaded | |
| * @image_range: the fixed addresses within the executable | |
| * | |
| * Creates the initial guest address space in the host memory space. | |
| * | |
| * If @image_range is NULL, then no address in the executable is fixed, | |
| * i.e. it is fully relocatable. | |
| * | |
| * This function will not return if a valid value for guest_base | |
| * cannot be chosen. On return, the executable loader can expect | |
| * | |
| * target_mmap(i->lo, i->hi - i->lo + 1, ...) | |
| * | |
| * to succeed. | |
| */ | |
| void linux_probe_guest_base(const char *image_name, const PGBRange *image_range); | |
| /* syscall.c */ | |
| int host_to_target_waitstatus(int status); | |
| #ifdef TARGET_I386 | |
| /* vm86.c */ | |
| void save_v86_state(CPUX86State *env); | |
| void handle_vm86_trap(CPUX86State *env, int trapno); | |
| int do_vm86(CPUX86State *env, long subfunction, abi_ulong v86_addr); | |
| #elif defined(TARGET_SPARC64) | |
| void sparc64_set_context(CPUSPARCState *env); | |
| void sparc64_get_context(CPUSPARCState *env); | |
| #endif | |
| static inline int is_error(abi_long ret) | |
| { | |
| return (abi_ulong)ret >= (abi_ulong)(-4096); | |
| } | |
| #if (TARGET_ABI_BITS == 32) && !defined(TARGET_ABI_MIPSN32) | |
| static inline uint64_t target_offset64(uint32_t word0, uint32_t word1) | |
| { | |
| #if TARGET_BIG_ENDIAN | |
| return ((uint64_t)word0 << 32) | word1; | |
| #else | |
| return ((uint64_t)word1 << 32) | word0; | |
| #endif | |
| } | |
| #else /* TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32) */ | |
| static inline uint64_t target_offset64(uint64_t word0, uint64_t word1) | |
| { | |
| return word0; | |
| } | |
| #endif /* TARGET_ABI_BITS != 32 */ | |
| void print_termios(void *arg); | |
| #ifdef TARGET_TCGETS2 | |
| void print_termios2(void *arg); | |
| #endif | |
| /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */ | |
| #if defined(TARGET_ARM) && !defined(TARGET_AARCH64) | |
| static inline int regpairs_aligned(CPUArchState *cpu_env, int num) | |
| { | |
| return cpu_env->eabi; | |
| } | |
| #elif defined(TARGET_MIPS) && defined(TARGET_ABI_MIPSO32) | |
| static inline int regpairs_aligned(CPUArchState *cpu_env, int num) { return 1; } | |
| #elif defined(TARGET_PPC) && !defined(TARGET_PPC64) | |
| /* | |
| * SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs | |
| * of registers which translates to the same as ARM/MIPS, because we start with | |
| * r3 as arg1 | |
| */ | |
| static inline int regpairs_aligned(CPUArchState *cpu_env, int num) { return 1; } | |
| #elif defined(TARGET_SH4) | |
| /* SH4 doesn't align register pairs, except for p{read,write}64 */ | |
| static inline int regpairs_aligned(CPUArchState *cpu_env, int num) | |
| { | |
| switch (num) { | |
| case TARGET_NR_pread64: | |
| case TARGET_NR_pwrite64: | |
| return 1; | |
| default: | |
| return 0; | |
| } | |
| } | |
| #elif defined(TARGET_XTENSA) | |
| static inline int regpairs_aligned(CPUArchState *cpu_env, int num) { return 1; } | |
| #elif defined(TARGET_HEXAGON) | |
| static inline int regpairs_aligned(CPUArchState *cpu_env, int num) { return 1; } | |
| #else | |
| static inline int regpairs_aligned(CPUArchState *cpu_env, int num) { return 0; } | |
| #endif | |
| /** | |
| * preexit_cleanup: housekeeping before the guest exits | |
| * | |
| * env: the CPU state | |
| * code: the exit code | |
| */ | |
| void preexit_cleanup(CPUArchState *env, int code); | |
| /** | |
| * begin_parallel_context | |
| * @cs: the CPU context | |
| * | |
| * Called when starting the second vcpu, or joining shared memory. | |
| */ | |
| static inline void begin_parallel_context(CPUState *cs) | |
| { | |
| if (!tcg_cflags_has(cs, CF_PARALLEL)) { | |
| tb_flush__exclusive_or_serial(); | |
| tcg_cflags_set(cs, CF_PARALLEL); | |
| } | |
| } | |
| /** | |
| * init_main_thread: Set CPU state for main thread | |
| * @cs: CPU context to set | |
| * @info: information about the image being loaded | |
| * | |
| * This function must be provided by the per-target code. It should | |
| * set the initial CPU state based on the information about the | |
| * starting binary in @image_info. This will be at a minimum setting | |
| * the initial guest program counter and stack pointer; it should | |
| * also set up any other guest register values where the Linux ABI | |
| * defines that they start set to some other value than what the | |
| * guest CPU architecture gives you out of reset. | |
| */ | |
| void init_main_thread(CPUState *cs, struct image_info *info); | |
| /* Clone cpu state */ | |
| CPUArchState *cpu_copy(CPUArchState *env); | |
| /* | |
| * Include target-specific struct and function definitions; | |
| * they may need access to the target-independent structures | |
| * above, so include them last. | |
| */ | |
| #include "target_cpu.h" | |
| #include "target_structs.h" | |
| #endif |