From: Philippe Mathieu-Daudé Date: Fri, 22 Mar 2024 10:08:12 +0000 (+0100) Subject: user: Move 'thunk.h' from 'exec/user' to 'user' X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=4e111653168acc058044885c679015d50fcaf474;p=qemu.git user: Move 'thunk.h' from 'exec/user' to 'user' Keep all user emulation headers under the same user/ directory. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20240428221450.26460-2-philmd@linaro.org> --- diff --git a/MAINTAINERS b/MAINTAINERS index 302b6fd00c..96411e6adf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3692,7 +3692,6 @@ Overall usermode emulation M: Riku Voipio S: Maintained F: accel/tcg/user-exec*.c -F: include/exec/user/ F: include/user/ F: common-user/ diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index a0c1ad7efa..a916724de9 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -26,7 +26,7 @@ extern char **environ; -#include "exec/user/thunk.h" +#include "user/thunk.h" #include "target_arch.h" #include "syscall_defs.h" #include "target_syscall.h" diff --git a/include/exec/user/thunk.h b/include/exec/user/thunk.h deleted file mode 100644 index 9f35c888f9..0000000000 --- a/include/exec/user/thunk.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Generic thunking code to convert data between host and target CPU - * - * Copyright (c) 2003 Fabrice Bellard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#ifndef THUNK_H -#define THUNK_H - -#include "cpu.h" -#include "user/abitypes.h" - -/* types enums definitions */ - -typedef enum argtype { - TYPE_NULL, - TYPE_CHAR, - TYPE_SHORT, - TYPE_INT, - TYPE_LONG, - TYPE_ULONG, - TYPE_PTRVOID, /* pointer on unknown data */ - TYPE_LONGLONG, - TYPE_ULONGLONG, - TYPE_PTR, - TYPE_ARRAY, - TYPE_STRUCT, - TYPE_OLDDEVT, -} argtype; - -#define MK_PTR(type) TYPE_PTR, type -#define MK_ARRAY(type, size) TYPE_ARRAY, (int)(size), type -#define MK_STRUCT(id) TYPE_STRUCT, id - -#define THUNK_TARGET 0 -#define THUNK_HOST 1 - -typedef struct { - /* standard struct handling */ - const argtype *field_types; - int nb_fields; - int *field_offsets[2]; - /* special handling */ - void (*convert[2])(void *dst, const void *src); - void (*print)(void *arg); - int size[2]; - int align[2]; - const char *name; -} StructEntry; - -/* Translation table for bitmasks... */ -typedef struct bitmask_transtbl { - unsigned int target_mask; - unsigned int target_bits; - unsigned int host_mask; - unsigned int host_bits; -} bitmask_transtbl; - -void thunk_register_struct(int id, const char *name, const argtype *types); -void thunk_register_struct_direct(int id, const char *name, - const StructEntry *se1); -const argtype *thunk_convert(void *dst, const void *src, - const argtype *type_ptr, int to_host); -const argtype *thunk_print(void *arg, const argtype *type_ptr); - -extern StructEntry *struct_entries; - -int thunk_type_size_array(const argtype *type_ptr, int is_host); -int thunk_type_align_array(const argtype *type_ptr, int is_host); - -static inline int thunk_type_size(const argtype *type_ptr, int is_host) -{ - int type, size; - const StructEntry *se; - - type = *type_ptr; - switch(type) { - case TYPE_CHAR: - return 1; - case TYPE_SHORT: - return 2; - case TYPE_INT: - return 4; - case TYPE_LONGLONG: - case TYPE_ULONGLONG: - return 8; - case TYPE_LONG: - case TYPE_ULONG: - case TYPE_PTRVOID: - case TYPE_PTR: - if (is_host) { - return sizeof(void *); - } else { - return TARGET_ABI_BITS / 8; - } - break; - case TYPE_OLDDEVT: - if (is_host) { -#if defined(HOST_X86_64) - return 8; -#elif defined(HOST_MIPS) || defined(HOST_SPARC64) - return 4; -#elif defined(HOST_PPC) - return sizeof(void *); -#else - return 2; -#endif - } else { -#if defined(TARGET_X86_64) - return 8; -#elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \ - defined(TARGET_PARISC) || defined(TARGET_SPARC64) - return 4; -#elif defined(TARGET_PPC) - return TARGET_ABI_BITS / 8; -#else - return 2; -#endif - } - break; - case TYPE_ARRAY: - size = type_ptr[1]; - return size * thunk_type_size_array(type_ptr + 2, is_host); - case TYPE_STRUCT: - se = struct_entries + type_ptr[1]; - return se->size[is_host]; - default: - g_assert_not_reached(); - } -} - -static inline int thunk_type_align(const argtype *type_ptr, int is_host) -{ - int type; - const StructEntry *se; - - type = *type_ptr; - switch(type) { - case TYPE_CHAR: - return 1; - case TYPE_SHORT: - if (is_host) { - return __alignof__(short); - } else { - return ABI_SHORT_ALIGNMENT; - } - case TYPE_INT: - if (is_host) { - return __alignof__(int); - } else { - return ABI_INT_ALIGNMENT; - } - case TYPE_LONGLONG: - case TYPE_ULONGLONG: - if (is_host) { - return __alignof__(long long); - } else { - return ABI_LLONG_ALIGNMENT; - } - case TYPE_LONG: - case TYPE_ULONG: - case TYPE_PTRVOID: - case TYPE_PTR: - if (is_host) { - return __alignof__(long); - } else { - return ABI_LONG_ALIGNMENT; - } - break; - case TYPE_OLDDEVT: - return thunk_type_size(type_ptr, is_host); - case TYPE_ARRAY: - return thunk_type_align_array(type_ptr + 2, is_host); - case TYPE_STRUCT: - se = struct_entries + type_ptr[1]; - return se->align[is_host]; - default: - g_assert_not_reached(); - } -} - -unsigned int target_to_host_bitmask_len(unsigned int target_mask, - const bitmask_transtbl *trans_tbl, - size_t trans_len); -unsigned int host_to_target_bitmask_len(unsigned int host_mask, - const bitmask_transtbl * trans_tbl, - size_t trans_len); - -#define target_to_host_bitmask(M, T) \ - target_to_host_bitmask_len(M, T, ARRAY_SIZE(T)) -#define host_to_target_bitmask(M, T) \ - host_to_target_bitmask_len(M, T, ARRAY_SIZE(T)) - -void thunk_init(unsigned int max_structs); - -#endif diff --git a/include/user/thunk.h b/include/user/thunk.h new file mode 100644 index 0000000000..2a2104b568 --- /dev/null +++ b/include/user/thunk.h @@ -0,0 +1,213 @@ +/* + * Generic thunking code to convert data between host and target CPU + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef USER_THUNK_H +#define USER_THUNK_H + +#ifndef CONFIG_USER_ONLY +#error Cannot include this header from system emulation +#endif + +#include "cpu.h" +#include "user/abitypes.h" + +/* types enums definitions */ + +typedef enum argtype { + TYPE_NULL, + TYPE_CHAR, + TYPE_SHORT, + TYPE_INT, + TYPE_LONG, + TYPE_ULONG, + TYPE_PTRVOID, /* pointer on unknown data */ + TYPE_LONGLONG, + TYPE_ULONGLONG, + TYPE_PTR, + TYPE_ARRAY, + TYPE_STRUCT, + TYPE_OLDDEVT, +} argtype; + +#define MK_PTR(type) TYPE_PTR, type +#define MK_ARRAY(type, size) TYPE_ARRAY, (int)(size), type +#define MK_STRUCT(id) TYPE_STRUCT, id + +#define THUNK_TARGET 0 +#define THUNK_HOST 1 + +typedef struct { + /* standard struct handling */ + const argtype *field_types; + int nb_fields; + int *field_offsets[2]; + /* special handling */ + void (*convert[2])(void *dst, const void *src); + void (*print)(void *arg); + int size[2]; + int align[2]; + const char *name; +} StructEntry; + +/* Translation table for bitmasks... */ +typedef struct bitmask_transtbl { + unsigned int target_mask; + unsigned int target_bits; + unsigned int host_mask; + unsigned int host_bits; +} bitmask_transtbl; + +void thunk_register_struct(int id, const char *name, const argtype *types); +void thunk_register_struct_direct(int id, const char *name, + const StructEntry *se1); +const argtype *thunk_convert(void *dst, const void *src, + const argtype *type_ptr, int to_host); +const argtype *thunk_print(void *arg, const argtype *type_ptr); + +extern StructEntry *struct_entries; + +int thunk_type_size_array(const argtype *type_ptr, int is_host); +int thunk_type_align_array(const argtype *type_ptr, int is_host); + +static inline int thunk_type_size(const argtype *type_ptr, int is_host) +{ + int type, size; + const StructEntry *se; + + type = *type_ptr; + switch(type) { + case TYPE_CHAR: + return 1; + case TYPE_SHORT: + return 2; + case TYPE_INT: + return 4; + case TYPE_LONGLONG: + case TYPE_ULONGLONG: + return 8; + case TYPE_LONG: + case TYPE_ULONG: + case TYPE_PTRVOID: + case TYPE_PTR: + if (is_host) { + return sizeof(void *); + } else { + return TARGET_ABI_BITS / 8; + } + break; + case TYPE_OLDDEVT: + if (is_host) { +#if defined(HOST_X86_64) + return 8; +#elif defined(HOST_MIPS) || defined(HOST_SPARC64) + return 4; +#elif defined(HOST_PPC) + return sizeof(void *); +#else + return 2; +#endif + } else { +#if defined(TARGET_X86_64) + return 8; +#elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \ + defined(TARGET_PARISC) || defined(TARGET_SPARC64) + return 4; +#elif defined(TARGET_PPC) + return TARGET_ABI_BITS / 8; +#else + return 2; +#endif + } + break; + case TYPE_ARRAY: + size = type_ptr[1]; + return size * thunk_type_size_array(type_ptr + 2, is_host); + case TYPE_STRUCT: + se = struct_entries + type_ptr[1]; + return se->size[is_host]; + default: + g_assert_not_reached(); + } +} + +static inline int thunk_type_align(const argtype *type_ptr, int is_host) +{ + int type; + const StructEntry *se; + + type = *type_ptr; + switch(type) { + case TYPE_CHAR: + return 1; + case TYPE_SHORT: + if (is_host) { + return __alignof__(short); + } else { + return ABI_SHORT_ALIGNMENT; + } + case TYPE_INT: + if (is_host) { + return __alignof__(int); + } else { + return ABI_INT_ALIGNMENT; + } + case TYPE_LONGLONG: + case TYPE_ULONGLONG: + if (is_host) { + return __alignof__(long long); + } else { + return ABI_LLONG_ALIGNMENT; + } + case TYPE_LONG: + case TYPE_ULONG: + case TYPE_PTRVOID: + case TYPE_PTR: + if (is_host) { + return __alignof__(long); + } else { + return ABI_LONG_ALIGNMENT; + } + break; + case TYPE_OLDDEVT: + return thunk_type_size(type_ptr, is_host); + case TYPE_ARRAY: + return thunk_type_align_array(type_ptr + 2, is_host); + case TYPE_STRUCT: + se = struct_entries + type_ptr[1]; + return se->align[is_host]; + default: + g_assert_not_reached(); + } +} + +unsigned int target_to_host_bitmask_len(unsigned int target_mask, + const bitmask_transtbl *trans_tbl, + size_t trans_len); +unsigned int host_to_target_bitmask_len(unsigned int host_mask, + const bitmask_transtbl * trans_tbl, + size_t trans_len); + +#define target_to_host_bitmask(M, T) \ + target_to_host_bitmask_len(M, T, ARRAY_SIZE(T)) +#define host_to_target_bitmask(M, T) \ + host_to_target_bitmask_len(M, T, ARRAY_SIZE(T)) + +void thunk_init(unsigned int max_structs); + +#endif diff --git a/linux-user/thunk.c b/linux-user/thunk.c index 071aad4b5f..3cd19e79c6 100644 --- a/linux-user/thunk.c +++ b/linux-user/thunk.c @@ -20,7 +20,7 @@ #include "qemu/log.h" #include "qemu.h" -#include "exec/user/thunk.h" +#include "user/thunk.h" //#define DEBUG diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h index ce11d9e21c..5c7f173ceb 100644 --- a/linux-user/user-internals.h +++ b/linux-user/user-internals.h @@ -18,7 +18,7 @@ #ifndef LINUX_USER_USER_INTERNALS_H #define LINUX_USER_USER_INTERNALS_H -#include "exec/user/thunk.h" +#include "user/thunk.h" #include "exec/exec-all.h" #include "exec/tb-flush.h" #include "qemu/log.h"