X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=thunk.c;h=7f31cffe0968c87a83d59b27ecab2f1f79e78d99;hb=5d0980a459774a52e3f3729cee0a2562d11026d2;hp=7331aeb477d7f8fe124317e221fc3199b171d9ba;hpb=265531154a05a26e9b79819ddd068c285e681cbc;p=mirror_qemu.git diff --git a/thunk.c b/thunk.c index 7331aeb477..7f31cffe09 100644 --- a/thunk.c +++ b/thunk.c @@ -14,22 +14,17 @@ * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see . */ -#include -#include -#include +#include "qemu/osdep.h" #include "qemu.h" -#include "thunk.h" +#include "exec/user/thunk.h" //#define DEBUG -#define MAX_STRUCTS 128 - -/* XXX: make it dynamic */ -StructEntry struct_entries[MAX_STRUCTS]; +static unsigned int max_struct_entries; +StructEntry *struct_entries; static const argtype *thunk_type_next_ptr(const argtype *type_ptr); @@ -47,6 +42,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr) case TYPE_LONG: case TYPE_ULONG: case TYPE_PTRVOID: + case TYPE_OLDDEVT: return type_ptr; case TYPE_PTR: return thunk_type_next_ptr(type_ptr); @@ -70,7 +66,7 @@ void thunk_register_struct(int id, const char *name, const argtype *types) StructEntry *se; int nb_fields, offset, max_align, align, size, i, j; - se = struct_entries + id; + assert(id < max_struct_entries); /* first we count the number of fields */ type_ptr = types; @@ -79,6 +75,8 @@ void thunk_register_struct(int id, const char *name, const argtype *types) type_ptr = thunk_type_next(type_ptr); nb_fields++; } + assert(nb_fields > 0); + se = struct_entries + id; se->field_types = types; se->nb_fields = nb_fields; se->name = name; @@ -88,10 +86,10 @@ void thunk_register_struct(int id, const char *name, const argtype *types) #endif /* now we can alloc the data */ - for(i = 0;i < 2; i++) { + for (i = 0; i < ARRAY_SIZE(se->field_offsets); i++) { offset = 0; max_align = 1; - se->field_offsets[i] = malloc(nb_fields * sizeof(int)); + se->field_offsets[i] = g_new(int, nb_fields); type_ptr = se->field_types; for(j = 0;j < nb_fields; j++) { size = thunk_type_size(type_ptr, i); @@ -113,9 +111,12 @@ void thunk_register_struct(int id, const char *name, const argtype *types) } } -void thunk_register_struct_direct(int id, const char *name, StructEntry *se1) +void thunk_register_struct_direct(int id, const char *name, + const StructEntry *se1) { StructEntry *se; + + assert(id < max_struct_entries); se = struct_entries + id; *se = *se1; se->name = name; @@ -188,6 +189,33 @@ const argtype *thunk_convert(void *dst, const void *src, #else #warning unsupported conversion #endif + case TYPE_OLDDEVT: + { + uint64_t val = 0; + switch (thunk_type_size(type_ptr - 1, !to_host)) { + case 2: + val = *(uint16_t *)src; + break; + case 4: + val = *(uint32_t *)src; + break; + case 8: + val = *(uint64_t *)src; + break; + } + switch (thunk_type_size(type_ptr - 1, to_host)) { + case 2: + *(uint16_t *)dst = tswap16(val); + break; + case 4: + *(uint32_t *)dst = tswap32(val); + break; + case 8: + *(uint64_t *)dst = tswap64(val); + break; + } + break; + } case TYPE_ARRAY: { int array_length, i, dst_size, src_size; @@ -216,6 +244,7 @@ const argtype *thunk_convert(void *dst, const void *src, const argtype *field_types; const int *dst_offsets, *src_offsets; + assert(*type_ptr < max_struct_entries); se = struct_entries + *type_ptr++; if (se->convert[0] != NULL) { /* specific conversion is needed */ @@ -245,37 +274,36 @@ const argtype *thunk_convert(void *dst, const void *src, /* from em86 */ /* Utility function: Table-driven functions to translate bitmasks - * between X86 and Alpha formats... + * between host and target formats */ -unsigned int target_to_host_bitmask(unsigned int x86_mask, - bitmask_transtbl * trans_tbl) +unsigned int target_to_host_bitmask(unsigned int target_mask, + const bitmask_transtbl * trans_tbl) { - bitmask_transtbl * btp; - unsigned int alpha_mask = 0; + const bitmask_transtbl *btp; + unsigned int host_mask = 0; - for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) { - if((x86_mask & btp->x86_mask) == btp->x86_bits) { - alpha_mask |= btp->alpha_bits; - } + for (btp = trans_tbl; btp->target_mask && btp->host_mask; btp++) { + if ((target_mask & btp->target_mask) == btp->target_bits) { + host_mask |= btp->host_bits; + } } - return(alpha_mask); + return host_mask; } -unsigned int host_to_target_bitmask(unsigned int alpha_mask, - bitmask_transtbl * trans_tbl) +unsigned int host_to_target_bitmask(unsigned int host_mask, + const bitmask_transtbl * trans_tbl) { - bitmask_transtbl * btp; - unsigned int x86_mask = 0; + const bitmask_transtbl *btp; + unsigned int target_mask = 0; - for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) { - if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) { - x86_mask |= btp->x86_bits; - } + for (btp = trans_tbl; btp->target_mask && btp->host_mask; btp++) { + if ((host_mask & btp->host_mask) == btp->host_bits) { + target_mask |= btp->target_bits; + } } - return(x86_mask); + return target_mask; } -#ifndef NO_THUNK_TYPE_SIZE int thunk_type_size_array(const argtype *type_ptr, int is_host) { return thunk_type_size(type_ptr, is_host); @@ -285,4 +313,9 @@ int thunk_type_align_array(const argtype *type_ptr, int is_host) { return thunk_type_align(type_ptr, is_host); } -#endif /* ndef NO_THUNK_TYPE_SIZE */ + +void thunk_init(unsigned int max_structs) +{ + max_struct_entries = max_structs; + struct_entries = g_new0(StructEntry, max_structs); +}