⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thunk.c

📁 qemu虚拟机代码
💻 C
字号:
/* *  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 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include "qemu.h"#include "thunk.h"//#define DEBUG#define MAX_STRUCTS 128/* XXX: make it dynamic */StructEntry struct_entries[MAX_STRUCTS];static inline const argtype *thunk_type_next(const argtype *type_ptr){    int type;    type = *type_ptr++;    switch(type) {    case TYPE_CHAR:    case TYPE_SHORT:    case TYPE_INT:    case TYPE_LONGLONG:    case TYPE_ULONGLONG:    case TYPE_LONG:    case TYPE_ULONG:    case TYPE_PTRVOID:        return type_ptr;    case TYPE_PTR:        return thunk_type_next(type_ptr);    case TYPE_ARRAY:        return thunk_type_next(type_ptr + 1);    case TYPE_STRUCT:        return type_ptr + 1;    default:        return NULL;    }}void thunk_register_struct(int id, const char *name, const argtype *types){    const argtype *type_ptr;    StructEntry *se;    int nb_fields, offset, max_align, align, size, i, j;    se = struct_entries + id;        /* first we count the number of fields */    type_ptr = types;    nb_fields = 0;    while (*type_ptr != TYPE_NULL) {        type_ptr = thunk_type_next(type_ptr);        nb_fields++;    }    se->field_types = types;    se->nb_fields = nb_fields;    se->name = name;#ifdef DEBUG    printf("struct %s: id=%d nb_fields=%d\n",            se->name, id, se->nb_fields);#endif    /* now we can alloc the data */    for(i = 0;i < 2; i++) {        offset = 0;        max_align = 1;        se->field_offsets[i] = malloc(nb_fields * sizeof(int));        type_ptr = se->field_types;        for(j = 0;j < nb_fields; j++) {            size = thunk_type_size(type_ptr, i);            align = thunk_type_align(type_ptr, i);            offset = (offset + align - 1) & ~(align - 1);            se->field_offsets[i][j] = offset;            offset += size;            if (align > max_align)                max_align = align;            type_ptr = thunk_type_next(type_ptr);        }        offset = (offset + max_align - 1) & ~(max_align - 1);        se->size[i] = offset;        se->align[i] = max_align;#ifdef DEBUG        printf("%s: size=%d align=%d\n",                i == THUNK_HOST ? "host" : "target", offset, max_align);#endif    }}void thunk_register_struct_direct(int id, const char *name, StructEntry *se1){    StructEntry *se;    se = struct_entries + id;    *se = *se1;    se->name = name;}/* now we can define the main conversion functions */const argtype *thunk_convert(void *dst, const void *src,                              const argtype *type_ptr, int to_host){    int type;    type = *type_ptr++;    switch(type) {    case TYPE_CHAR:        *(uint8_t *)dst = *(uint8_t *)src;        break;    case TYPE_SHORT:        *(uint16_t *)dst = tswap16(*(uint16_t *)src);        break;    case TYPE_INT:        *(uint32_t *)dst = tswap32(*(uint32_t *)src);        break;    case TYPE_LONGLONG:    case TYPE_ULONGLONG:        *(uint64_t *)dst = tswap64(*(uint64_t *)src);        break;#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32    case TYPE_LONG:    case TYPE_ULONG:    case TYPE_PTRVOID:        *(uint32_t *)dst = tswap32(*(uint32_t *)src);        break;#elif HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32    case TYPE_LONG:    case TYPE_ULONG:    case TYPE_PTRVOID:        if (to_host) {            *(uint64_t *)dst = tswap32(*(uint32_t *)src);        } else {            *(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);        }        break;#else#warning unsupported conversion#endif    case TYPE_ARRAY:        {            int array_length, i, dst_size, src_size;            const uint8_t *s;            uint8_t  *d;            array_length = *type_ptr++;            dst_size = thunk_type_size(type_ptr, to_host);            src_size = thunk_type_size(type_ptr, 1 - to_host);            d = dst;            s = src;            for(i = 0;i < array_length; i++) {                thunk_convert(d, s, type_ptr, to_host);                d += dst_size;                s += src_size;            }            type_ptr = thunk_type_next(type_ptr);        }        break;    case TYPE_STRUCT:        {            int i;            const StructEntry *se;            const uint8_t *s;            uint8_t  *d;            const argtype *field_types;            const int *dst_offsets, *src_offsets;                        se = struct_entries + *type_ptr++;            if (se->convert[0] != NULL) {                /* specific conversion is needed */                (*se->convert[to_host])(dst, src);            } else {                /* standard struct conversion */                field_types = se->field_types;                dst_offsets = se->field_offsets[to_host];                src_offsets = se->field_offsets[1 - to_host];                d = dst;                s = src;                for(i = 0;i < se->nb_fields; i++) {                    field_types = thunk_convert(d + dst_offsets[i],                                                 s + src_offsets[i],                                                 field_types, to_host);                }            }        }        break;    default:        fprintf(stderr, "Invalid type 0x%x\n", type);        break;    }    return type_ptr;}/* from em86 *//* Utility function: Table-driven functions to translate bitmasks * between X86 and Alpha formats... */unsigned int target_to_host_bitmask(unsigned int x86_mask,                                     bitmask_transtbl * trans_tbl){    bitmask_transtbl *	btp;    unsigned int	alpha_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;	}    }    return(alpha_mask);}unsigned int host_to_target_bitmask(unsigned int alpha_mask,                                     bitmask_transtbl * trans_tbl){    bitmask_transtbl *	btp;    unsigned int	x86_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;	}    }    return(x86_mask);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -