Merge remote-tracking branch 'upstream/master'

This commit is contained in:
chenhuitao 2020-04-30 14:02:01 +08:00
commit 8a30e1ac0d
15 changed files with 1071 additions and 450 deletions

4
.gitignore vendored
View File

@ -28,10 +28,6 @@ qemu/sparc-softmmu/
qemu/i386-softmmu/
qemu/x86_64-softmmu/
qemu/qapi-types.h
qemu/qapi-visit.h
qemu/qapi-types.c
qemu/qapi-visit.c
tags
qemu/config-host.ld
qemu/config.log

View File

@ -82,17 +82,58 @@ if(MSVC)
string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
endif()
else()
# check python
find_program(PYTHON_CMD python)
if (NOT PYTHON_CMD)
find_program(PYTHON_CMD python3)
if (NOT PYTHON_CMD)
find_program(PYTHON_CMD python2)
if (NOT PYTHON_CMD)
message(FATAL_ERROR "Please install python.")
endif()
# detect host arch.
execute_process(COMMAND ${CMAKE_C_COMPILER} -dM -E -
INPUT_FILE /dev/null
OUTPUT_VARIABLE UC_COMPILER_MACRO)
while(TRUE)
string(FIND ${UC_COMPILER_MACRO} "__x86_64__" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "i386")
break()
endif()
endif()
string(FIND ${UC_COMPILER_MACRO} "__i386__" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "i386")
break()
endif()
string(FIND ${UC_COMPILER_MACRO} "__arm__" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "arm")
break()
endif()
string(FIND ${UC_COMPILER_MACRO} "__aarch64__" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "aarch64")
break()
endif()
string(FIND ${UC_COMPILER_MACRO} "__mips__" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "mips")
break()
endif()
string(FIND ${UC_COMPILER_MACRO} "__sparc__" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "sparc")
break()
endif()
string(FIND ${UC_COMPILER_MACRO} "__ia64__" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "ia64")
break()
endif()
string(FIND ${UC_COMPILER_MACRO} "_ARCH_PPC" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "ppc")
break()
endif()
string(FIND ${UC_COMPILER_MACRO} "__s390__" UC_RET)
if (${UC_RET} GREATER "0")
set(UNICORN_TARGET_ARCH "s390")
break()
endif()
message(FATAL_ERROR "Unknown host compiler: ${CMAKE_C_COMPILER}.")
endwhile(TRUE)
set(EXTRA_CFLAGS "--extra-cflags=")
if (UNICORN_HAS_X86)
@ -138,7 +179,6 @@ else()
# GEN dynamic source files
execute_process(COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/qemu/configure
--python=${PYTHON_CMD}
${EXTRA_CFLAGS}
${TARGET_LIST}
)
@ -206,20 +246,8 @@ else()
OUTPUT_FILE ${CMAKE_BINARY_DIR}/sparc64-softmmu/config-target.h
)
endif()
execute_process(COMMAND ${PYTHON_CMD} -B ${CMAKE_CURRENT_SOURCE_DIR}/qemu/scripts/qapi-types.py
-h -o ${CMAKE_BINARY_DIR} -b -i ${CMAKE_CURRENT_SOURCE_DIR}/qemu/qapi-schema.json
)
execute_process(COMMAND ${PYTHON_CMD} -B ${CMAKE_CURRENT_SOURCE_DIR}/qemu/scripts/qapi-types.py
-c -o ${CMAKE_BINARY_DIR} -b -i ${CMAKE_CURRENT_SOURCE_DIR}/qemu/qapi-schema.json
)
execute_process(COMMAND ${PYTHON_CMD} -B ${CMAKE_CURRENT_SOURCE_DIR}/qemu/scripts/qapi-visit.py
-h -o ${CMAKE_BINARY_DIR} -b -i ${CMAKE_CURRENT_SOURCE_DIR}/qemu/qapi-schema.json
)
execute_process(COMMAND ${PYTHON_CMD} -B ${CMAKE_CURRENT_SOURCE_DIR}/qemu/scripts/qapi-visit.py
-c -o ${CMAKE_BINARY_DIR} -b -i ${CMAKE_CURRENT_SOURCE_DIR}/qemu/qapi-schema.json
)
add_compile_options(
-I${CMAKE_CURRENT_SOURCE_DIR}/qemu/tcg/i386
-I${CMAKE_CURRENT_SOURCE_DIR}/qemu/tcg/${UNICORN_TARGET_ARCH}
-D_GNU_SOURCE
-D_FILE_OFFSET_BITS=64
-D_LARGEFILE_SOURCE
@ -794,8 +822,8 @@ else()
${UNICORN_SRCS_COMMON}
qemu/util/oslib-posix.c
qemu/util/qemu-thread-posix.c
${CMAKE_BINARY_DIR}/qapi-types.c
${CMAKE_BINARY_DIR}/qapi-visit.c
qemu/qapi-types.c
qemu/qapi-visit.c
)
endif()

View File

@ -237,8 +237,6 @@ LIBRARY_SYMLINK = lib$(LIBNAME).$(EXT)
endif
endif
UNICORN_QEMU_FLAGS += --python=$(shell which /usr/bin/python || which python || which python2 || which python3)
ifeq ($(UNICORN_STATIC),yes)
ifneq ($(filter MINGW%,$(UNAME_S)),)
ARCHIVE = $(LIBNAME).$(AR_EXT)

View File

@ -6,7 +6,7 @@ This documentation explains how to compile Unicorn with CMake on Windows or
Requirements:
- Windows: MicroSoft Visual Studio(>=2013).
- *nix: GNU gcc and Python CLI to generate dynamic source files.
- *nix: GNU gcc or clang to generate dynamic source files.
Get CMake for free from http://www.cmake.org.

View File

@ -35,22 +35,19 @@ Unicorn can be compiled either on Ubuntu or Windows.
- To compile for Windows 32-bit, run:
$ pacman -S python2
$ pacman -S make
$ pacman -S mingw-w64-i686-toolchain
- To compile for Windows 64-bit, run:
$ pacman -S python2
$ pacman -S make
$ pacman -S mingw-w64-x86_64-toolchain
- For Cygwin, "make", "gcc-core", "libpcre-devel", "zlib-devel", "python2-setuptools"
are needed.
- For Cygwin, "make", "gcc-core", "libpcre-devel", "zlib-devel" are needed.
If apt-cyg is available, you can install these with:
$ apt-cyg install make gcc-core libpcre-devel zlib-devel python2-setuptools
$ apt-cyg install make gcc-core libpcre-devel zlib-devel

View File

@ -34,8 +34,6 @@ endif
endif
GENERATED_HEADERS = config-host.h
GENERATED_HEADERS += qapi-types.h qapi-visit.h
GENERATED_SOURCES += qapi-types.c qapi-visit.c
# Don't try to regenerate Makefile or configure
# We don't generate any of them
@ -91,29 +89,11 @@ recurse-all: $(SUBDIR_RULES)
######################################################################
gen-out-type = $(subst .,-,$(suffix $@))
qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json
qapi-types.c qapi-types.h :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
$(gen-out-type) -o "." -b -i $<, \
" GEN $@")
qapi-visit.c qapi-visit.h :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
$(gen-out-type) -o "." -b -i $<, \
" GEN $@")
clean:
find . \( -name '*.l[oa]' -o -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} +
rm -f TAGS *~ */*~
@# May not be present in GENERATED_HEADERS
rm -f $(foreach f,$(GENERATED_HEADERS),$(f) $(f)-timestamp)
rm -f $(foreach f,$(GENERATED_SOURCES),$(f) $(f)-timestamp)
for d in $(TARGET_DIRS); do \
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
done

24
qemu/configure vendored
View File

@ -451,7 +451,6 @@ Haiku)
esac
: ${make=${MAKE-make}}
: ${python=${PYTHON-python}}
# Default objcc to clang if available, otherwise use CC
if has clang; then
@ -494,8 +493,6 @@ for opt do
;;
--make=*) make="$optarg"
;;
--python=*) python="$optarg"
;;
--extra-cflags=*)
;;
--extra-ldflags=*)
@ -544,24 +541,6 @@ for opt do
esac
done
if ! has $python; then
error_exit "Python not found. Use --python=/path/to/python"
fi
# Note that if the Python conditional here evaluates True we will exit
# with status 1 which is a shell 'false' value.
if ! $python -c 'import sys; sys.exit(sys.version_info < (2,4))'; then
error_exit "Cannot use '$python', Python 2.4 or later is required." \
"Use --python=/path/to/python to specify a supported Python."
fi
# The -B switch was added in Python 2.6.
# If it is supplied, compiled files are not written.
# Use it for Python versions which support it.
if $python -B -c 'import sys; sys.exit(0)' 2>/dev/null; then
python="$python -B"
fi
case "$cpu" in
ppc)
CPU_CFLAGS="-m32"
@ -641,7 +620,6 @@ Advanced options (experts only):
--extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS
--extra-ldflags=LDFLAGS append extra linker flags LDFLAGS
--make=MAKE use specified make [$make]
--python=PYTHON use specified python [$python]
--static enable static build [$static]
--enable-debug-tcg enable TCG debugging
--disable-debug-tcg disable TCG debugging (default)
@ -1083,7 +1061,6 @@ echo "CFLAGS $CFLAGS"
echo "QEMU_CFLAGS $QEMU_CFLAGS"
echo "LDFLAGS $LDFLAGS"
echo "make $make"
echo "python $python"
echo "host CPU $cpu"
echo "host big endian $bigendian"
echo "target list $target_list"
@ -1185,7 +1162,6 @@ fi
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg $QEMU_INCLUDES"
echo "MAKE=$make" >> $config_host_mak
echo "PYTHON=$python" >> $config_host_mak
echo "CC=$cc" >> $config_host_mak
echo "CC_I386=$cc_i386" >> $config_host_mak
echo "HOST_CC=$host_cc" >> $config_host_mak

293
qemu/qapi-types.c Normal file
View File

@ -0,0 +1,293 @@
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
/*
* deallocation functions for schema-defined QAPI types
*
* Copyright IBM, Corp. 2011
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
* Michael Roth <mdroth@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*
*/
#include "qapi/dealloc-visitor.h"
#include "qapi-types.h"
#include "qapi-visit.h"
const char *ErrorClass_lookup[] = {
"GenericError",
"CommandNotFound",
"DeviceEncrypted",
"DeviceNotActive",
"DeviceNotFound",
"KVMMissingCap",
NULL,
};
const char *X86CPURegister32_lookup[] = {
"EAX",
"EBX",
"ECX",
"EDX",
"ESP",
"EBP",
"ESI",
"EDI",
NULL,
};
#ifndef QAPI_TYPES_BUILTIN_CLEANUP_DEF_H
#define QAPI_TYPES_BUILTIN_CLEANUP_DEF_H
void qapi_free_strList(strList *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_strList(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_intList(intList *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_intList(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_numberList(numberList *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_numberList(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_boolList(boolList *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_boolList(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_int8List(int8List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_int8List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_int16List(int16List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_int16List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_int32List(int32List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_int32List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_int64List(int64List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_int64List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_uint8List(uint8List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_uint8List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_uint16List(uint16List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_uint16List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_uint32List(uint32List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_uint32List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_uint64List(uint64List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_uint64List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
#endif /* QAPI_TYPES_BUILTIN_CLEANUP_DEF_H */
void qapi_free_ErrorClassList(ErrorClassList *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_ErrorClassList(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_X86CPURegister32List(X86CPURegister32List *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_X86CPURegister32List(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_X86CPUFeatureWordInfoList(X86CPUFeatureWordInfoList *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_X86CPUFeatureWordInfoList(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_X86CPUFeatureWordInfo(X86CPUFeatureWordInfo *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_X86CPUFeatureWordInfo(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}

228
qemu/qapi-types.h Normal file
View File

@ -0,0 +1,228 @@
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
/*
* schema-defined QAPI types
*
* Copyright IBM, Corp. 2011
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*
*/
#ifndef QAPI_TYPES_H
#define QAPI_TYPES_H
#include "unicorn/platform.h"
#ifndef QAPI_TYPES_BUILTIN_STRUCT_DECL_H
#define QAPI_TYPES_BUILTIN_STRUCT_DECL_H
typedef struct strList
{
union {
char *value;
uint64_t padding;
};
struct strList *next;
} strList;
typedef struct intList
{
union {
int64_t value;
uint64_t padding;
};
struct intList *next;
} intList;
typedef struct numberList
{
union {
double value;
uint64_t padding;
};
struct numberList *next;
} numberList;
typedef struct boolList
{
union {
bool value;
uint64_t padding;
};
struct boolList *next;
} boolList;
typedef struct int8List
{
union {
int8_t value;
uint64_t padding;
};
struct int8List *next;
} int8List;
typedef struct int16List
{
union {
int16_t value;
uint64_t padding;
};
struct int16List *next;
} int16List;
typedef struct int32List
{
union {
int32_t value;
uint64_t padding;
};
struct int32List *next;
} int32List;
typedef struct int64List
{
union {
int64_t value;
uint64_t padding;
};
struct int64List *next;
} int64List;
typedef struct uint8List
{
union {
uint8_t value;
uint64_t padding;
};
struct uint8List *next;
} uint8List;
typedef struct uint16List
{
union {
uint16_t value;
uint64_t padding;
};
struct uint16List *next;
} uint16List;
typedef struct uint32List
{
union {
uint32_t value;
uint64_t padding;
};
struct uint32List *next;
} uint32List;
typedef struct uint64List
{
union {
uint64_t value;
uint64_t padding;
};
struct uint64List *next;
} uint64List;
#endif /* QAPI_TYPES_BUILTIN_STRUCT_DECL_H */
extern const char *ErrorClass_lookup[];
typedef enum ErrorClass
{
ERROR_CLASS_GENERIC_ERROR = 0,
ERROR_CLASS_COMMAND_NOT_FOUND = 1,
ERROR_CLASS_DEVICE_ENCRYPTED = 2,
ERROR_CLASS_DEVICE_NOT_ACTIVE = 3,
ERROR_CLASS_DEVICE_NOT_FOUND = 4,
ERROR_CLASS_KVM_MISSING_CAP = 5,
ERROR_CLASS_MAX = 6,
} ErrorClass;
typedef struct ErrorClassList
{
union {
ErrorClass value;
uint64_t padding;
};
struct ErrorClassList *next;
} ErrorClassList;
extern const char *X86CPURegister32_lookup[];
typedef enum X86CPURegister32
{
X86_CPU_REGISTER32_EAX = 0,
X86_CPU_REGISTER32_EBX = 1,
X86_CPU_REGISTER32_ECX = 2,
X86_CPU_REGISTER32_EDX = 3,
X86_CPU_REGISTER32_ESP = 4,
X86_CPU_REGISTER32_EBP = 5,
X86_CPU_REGISTER32_ESI = 6,
X86_CPU_REGISTER32_EDI = 7,
X86_CPU_REGISTER32_MAX = 8,
} X86CPURegister32;
typedef struct X86CPURegister32List
{
union {
X86CPURegister32 value;
uint64_t padding;
};
struct X86CPURegister32List *next;
} X86CPURegister32List;
typedef struct X86CPUFeatureWordInfo X86CPUFeatureWordInfo;
typedef struct X86CPUFeatureWordInfoList
{
union {
X86CPUFeatureWordInfo *value;
uint64_t padding;
};
struct X86CPUFeatureWordInfoList *next;
} X86CPUFeatureWordInfoList;
#ifndef QAPI_TYPES_BUILTIN_CLEANUP_DECL_H
#define QAPI_TYPES_BUILTIN_CLEANUP_DECL_H
void qapi_free_strList(strList *obj);
void qapi_free_intList(intList *obj);
void qapi_free_numberList(numberList *obj);
void qapi_free_boolList(boolList *obj);
void qapi_free_int8List(int8List *obj);
void qapi_free_int16List(int16List *obj);
void qapi_free_int32List(int32List *obj);
void qapi_free_int64List(int64List *obj);
void qapi_free_uint8List(uint8List *obj);
void qapi_free_uint16List(uint16List *obj);
void qapi_free_uint32List(uint32List *obj);
void qapi_free_uint64List(uint64List *obj);
#endif /* QAPI_TYPES_BUILTIN_CLEANUP_DECL_H */
void qapi_free_ErrorClassList(ErrorClassList *obj);
void qapi_free_X86CPURegister32List(X86CPURegister32List *obj);
struct X86CPUFeatureWordInfo
{
int64_t cpuid_input_eax;
bool has_cpuid_input_ecx;
int64_t cpuid_input_ecx;
X86CPURegister32 cpuid_register;
int64_t features;
};
void qapi_free_X86CPUFeatureWordInfoList(X86CPUFeatureWordInfoList *obj);
void qapi_free_X86CPUFeatureWordInfo(X86CPUFeatureWordInfo *obj);
#endif

428
qemu/qapi-visit.c Normal file
View File

@ -0,0 +1,428 @@
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
/*
* schema-defined QAPI visitor functions
*
* Copyright IBM, Corp. 2011
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*
*/
#include "qemu-common.h"
#include "qapi-visit.h"
void visit_type_strList(Visitor *m, strList **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
strList *native_i = (strList *)i;
visit_type_str(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_intList(Visitor *m, intList **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
intList *native_i = (intList *)i;
visit_type_int(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_numberList(Visitor *m, numberList **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
numberList *native_i = (numberList *)i;
visit_type_number(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_boolList(Visitor *m, boolList **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
boolList *native_i = (boolList *)i;
visit_type_bool(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_int8List(Visitor *m, int8List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
int8List *native_i = (int8List *)i;
visit_type_int8(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_int16List(Visitor *m, int16List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
int16List *native_i = (int16List *)i;
visit_type_int16(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_int32List(Visitor *m, int32List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
int32List *native_i = (int32List *)i;
visit_type_int32(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_int64List(Visitor *m, int64List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
int64List *native_i = (int64List *)i;
visit_type_int64(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_uint8List(Visitor *m, uint8List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
uint8List *native_i = (uint8List *)i;
visit_type_uint8(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_uint16List(Visitor *m, uint16List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
uint16List *native_i = (uint16List *)i;
visit_type_uint16(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_uint32List(Visitor *m, uint32List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
uint32List *native_i = (uint32List *)i;
visit_type_uint32(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_uint64List(Visitor *m, uint64List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
uint64List *native_i = (uint64List *)i;
visit_type_uint64(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_ErrorClassList(Visitor *m, ErrorClassList **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
ErrorClassList *native_i = (ErrorClassList *)i;
visit_type_ErrorClass(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_ErrorClass(Visitor *m, ErrorClass *obj, const char *name, Error **errp)
{
visit_type_enum(m, (int *)obj, ErrorClass_lookup, "ErrorClass", name, errp);
}
void visit_type_X86CPURegister32List(Visitor *m, X86CPURegister32List **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
X86CPURegister32List *native_i = (X86CPURegister32List *)i;
visit_type_X86CPURegister32(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}
void visit_type_X86CPURegister32(Visitor *m, X86CPURegister32 *obj, const char *name, Error **errp)
{
visit_type_enum(m, (int *)obj, X86CPURegister32_lookup, "X86CPURegister32", name, errp);
}
static void visit_type_X86CPUFeatureWordInfo_fields(Visitor *m, X86CPUFeatureWordInfo **obj, Error **errp)
{
Error *err = NULL;
visit_type_int(m, &(*obj)->cpuid_input_eax, "cpuid-input-eax", &err);
if (err) {
goto out;
}
visit_optional(m, &(*obj)->has_cpuid_input_ecx, "cpuid-input-ecx", &err);
if (!err && (*obj)->has_cpuid_input_ecx) {
visit_type_int(m, &(*obj)->cpuid_input_ecx, "cpuid-input-ecx", &err);
}
if (err) {
goto out;
}
visit_type_X86CPURegister32(m, &(*obj)->cpuid_register, "cpuid-register", &err);
if (err) {
goto out;
}
visit_type_int(m, &(*obj)->features, "features", &err);
if (err) {
goto out;
}
out:
error_propagate(errp, err);
}
void visit_type_X86CPUFeatureWordInfo(Visitor *m, X86CPUFeatureWordInfo **obj, const char *name, Error **errp)
{
Error *err = NULL;
visit_start_struct(m, (void **)obj, "X86CPUFeatureWordInfo", name, sizeof(X86CPUFeatureWordInfo), &err);
if (!err) {
if (*obj) {
visit_type_X86CPUFeatureWordInfo_fields(m, obj, errp);
}
visit_end_struct(m, &err);
}
error_propagate(errp, err);
}
void visit_type_X86CPUFeatureWordInfoList(Visitor *m, X86CPUFeatureWordInfoList **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev, &err)) != NULL;
prev = &i) {
X86CPUFeatureWordInfoList *native_i = (X86CPUFeatureWordInfoList *)i;
visit_type_X86CPUFeatureWordInfo(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m, &err);
out:
error_propagate(errp, err);
}

51
qemu/qapi-visit.h Normal file
View File

@ -0,0 +1,51 @@
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
/*
* schema-defined QAPI visitor functions
*
* Copyright IBM, Corp. 2011
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*
*/
#ifndef QAPI_VISIT_H
#define QAPI_VISIT_H
#include "qapi/visitor.h"
#include "qapi-types.h"
#ifndef QAPI_VISIT_BUILTIN_VISITOR_DECL_H
#define QAPI_VISIT_BUILTIN_VISITOR_DECL_H
void visit_type_strList(Visitor *m, strList **obj, const char *name, Error **errp);
void visit_type_intList(Visitor *m, intList **obj, const char *name, Error **errp);
void visit_type_numberList(Visitor *m, numberList **obj, const char *name, Error **errp);
void visit_type_boolList(Visitor *m, boolList **obj, const char *name, Error **errp);
void visit_type_int8List(Visitor *m, int8List **obj, const char *name, Error **errp);
void visit_type_int16List(Visitor *m, int16List **obj, const char *name, Error **errp);
void visit_type_int32List(Visitor *m, int32List **obj, const char *name, Error **errp);
void visit_type_int64List(Visitor *m, int64List **obj, const char *name, Error **errp);
void visit_type_uint8List(Visitor *m, uint8List **obj, const char *name, Error **errp);
void visit_type_uint16List(Visitor *m, uint16List **obj, const char *name, Error **errp);
void visit_type_uint32List(Visitor *m, uint32List **obj, const char *name, Error **errp);
void visit_type_uint64List(Visitor *m, uint64List **obj, const char *name, Error **errp);
#endif /* QAPI_VISIT_BUILTIN_VISITOR_DECL_H */
void visit_type_ErrorClass(Visitor *m, ErrorClass *obj, const char *name, Error **errp);
void visit_type_ErrorClassList(Visitor *m, ErrorClassList **obj, const char *name, Error **errp);
void visit_type_X86CPURegister32(Visitor *m, X86CPURegister32 *obj, const char *name, Error **errp);
void visit_type_X86CPURegister32List(Visitor *m, X86CPURegister32List **obj, const char *name, Error **errp);
void visit_type_X86CPUFeatureWordInfo(Visitor *m, X86CPUFeatureWordInfo **obj, const char *name, Error **errp);
void visit_type_X86CPUFeatureWordInfoList(Visitor *m, X86CPUFeatureWordInfoList **obj, const char *name, Error **errp);
#endif

View File

@ -0,0 +1,14 @@
#!/bin/sh
# Run this scripts to create qapi below files in root dir
# ../qapi-types.c
# ../qapi-types.h
# ../qapi-visit.c
# ../qapi-visit.h
python qapi-types.py -h -o .. -b -i qapi-schema.json
python qapi-types.py -c -o .. -b -i qapi-schema.json
python qapi-visit.py -h -o .. -b -i qapi-schema.json
python qapi-visit.py -c -o .. -b -i qapi-schema.json

View File

@ -1,368 +0,0 @@
#
# QAPI event generator
#
# Copyright (c) 2014 Wenchao Xia
#
# Authors:
# Wenchao Xia <wenchaoqemu@gmail.com>
#
# This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.
from ordereddict import OrderedDict
from qapi import *
import sys
import os
import getopt
import errno
def _generate_event_api_name(event_name, params):
api_name = "void qapi_event_send_%s(" % c_fun(event_name).lower();
l = len(api_name)
if params:
for argname, argentry, optional, structured in parse_args(params):
if optional:
api_name += "bool has_%s,\n" % c_var(argname)
api_name += "".ljust(l)
api_name += "%s %s,\n" % (c_type(argentry, is_param=True),
c_var(argname))
api_name += "".ljust(l)
api_name += "Error **errp)"
return api_name;
# Following are the core functions that generate C APIs to emit event.
def generate_event_declaration(api_name):
return mcgen('''
%(api_name)s;
''',
api_name = api_name)
def generate_event_implement(api_name, event_name, params):
# step 1: declare any variables
ret = mcgen("""
%(api_name)s
{
QDict *qmp;
Error *local_err = NULL;
QMPEventFuncEmit emit;
""",
api_name = api_name)
if params:
ret += mcgen("""
QmpOutputVisitor *qov;
Visitor *v;
QObject *obj;
""")
# step 2: check emit function, create a dict
ret += mcgen("""
emit = qmp_event_get_func_emit();
if (!emit) {
return;
}
qmp = qmp_event_build_dict("%(event_name)s");
""",
event_name = event_name)
# step 3: visit the params if params != None
if params:
ret += mcgen("""
qov = qmp_output_visitor_new();
g_assert(qov);
v = qmp_output_get_visitor(qov);
g_assert(v);
/* Fake visit, as if all members are under a structure */
visit_start_struct(v, NULL, "", "%(event_name)s", 0, &local_err);
if (local_err) {
goto clean;
}
""",
event_name = event_name)
for argname, argentry, optional, structured in parse_args(params):
if optional:
ret += mcgen("""
if (has_%(var)s) {
""",
var = c_var(argname))
push_indent()
if argentry == "str":
var_type = "(char **)"
else:
var_type = ""
ret += mcgen("""
visit_type_%(type)s(v, %(var_type)s&%(var)s, "%(name)s", &local_err);
if (local_err) {
goto clean;
}
""",
var_type = var_type,
var = c_var(argname),
type = type_name(argentry),
name = argname)
if optional:
pop_indent()
ret += mcgen("""
}
""")
ret += mcgen("""
visit_end_struct(v, &local_err);
if (local_err) {
goto clean;
}
obj = qmp_output_get_qobject(qov);
g_assert(obj != NULL);
qdict_put_obj(qmp, "data", obj);
""")
# step 4: call qmp event api
ret += mcgen("""
emit(%(event_enum_value)s, qmp, &local_err);
""",
event_enum_value = event_enum_value)
# step 5: clean up
if params:
ret += mcgen("""
clean:
qmp_output_visitor_cleanup(qov);
""")
ret += mcgen("""
error_propagate(errp, local_err);
QDECREF(qmp);
}
""")
return ret
# Following are the functions that generate an enum type for all defined
# events, similar to qapi-types.py. Here we already have enum name and
# values which were generated before and recorded in event_enum_*. It also
# works around the issue that "import qapi-types" can't work.
def generate_event_enum_decl(event_enum_name, event_enum_values):
lookup_decl = mcgen('''
extern const char *%(event_enum_name)s_lookup[];
''',
event_enum_name = event_enum_name)
enum_decl = mcgen('''
typedef enum %(event_enum_name)s
{
''',
event_enum_name = event_enum_name)
# append automatically generated _MAX value
enum_max_value = generate_enum_full_value(event_enum_name, "MAX")
enum_values = event_enum_values + [ enum_max_value ]
i = 0
for value in enum_values:
enum_decl += mcgen('''
%(value)s = %(i)d,
''',
value = value,
i = i)
i += 1
enum_decl += mcgen('''
} %(event_enum_name)s;
''',
event_enum_name = event_enum_name)
return lookup_decl + enum_decl
def generate_event_enum_lookup(event_enum_name, event_enum_strings):
ret = mcgen('''
const char *%(event_enum_name)s_lookup[] = {
''',
event_enum_name = event_enum_name)
i = 0
for string in event_enum_strings:
ret += mcgen('''
"%(string)s",
''',
string = string)
ret += mcgen('''
NULL,
};
''')
return ret
# Start the real job
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
["source", "header", "builtins", "prefix=",
"input-file=", "output-dir="])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
input_file = ""
output_dir = ""
prefix = ""
c_file = 'qapi-event.c'
h_file = 'qapi-event.h'
do_c = False
do_h = False
do_builtins = False
for o, a in opts:
if o in ("-p", "--prefix"):
prefix = a
elif o in ("-i", "--input-file"):
input_file = a
elif o in ("-o", "--output-dir"):
output_dir = a + "/"
elif o in ("-c", "--source"):
do_c = True
elif o in ("-h", "--header"):
do_h = True
elif o in ("-b", "--builtins"):
do_builtins = True
if not do_c and not do_h:
do_c = True
do_h = True
c_file = output_dir + prefix + c_file
h_file = output_dir + prefix + h_file
try:
os.makedirs(output_dir)
except os.error, e:
if e.errno != errno.EEXIST:
raise
def maybe_open(really, name, opt):
if really:
return open(name, opt)
else:
import StringIO
return StringIO.StringIO()
fdef = maybe_open(do_c, c_file, 'w')
fdecl = maybe_open(do_h, h_file, 'w')
fdef.write(mcgen('''
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
/*
* schema-defined QAPI event functions
*
* Copyright (c) 2014 Wenchao Xia
*
* Authors:
* Wenchao Xia <wenchaoqemu@gmail.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*
*/
#include "qemu-common.h"
#include "%(header)s"
#include "%(prefix)sqapi-visit.h"
#include "qapi/qmp-output-visitor.h"
#include "qapi/qmp-event.h"
''',
prefix=prefix, header=basename(h_file)))
fdecl.write(mcgen('''
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
/*
* schema-defined QAPI event functions
*
* Copyright (c) 2014 Wenchao Xia
*
* Authors:
* Wenchao Xia <wenchaoqemu@gmail.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*
*/
#ifndef %(guard)s
#define %(guard)s
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "%(prefix)sqapi-types.h"
''',
prefix=prefix, guard=guardname(h_file)))
exprs = parse_schema(input_file)
event_enum_name = prefix.upper().replace('-', '_') + "QAPIEvent"
event_enum_values = []
event_enum_strings = []
for expr in exprs:
if expr.has_key('event'):
event_name = expr['event']
params = expr.get('data')
if params and len(params) == 0:
params = None
api_name = _generate_event_api_name(event_name, params)
ret = generate_event_declaration(api_name)
fdecl.write(ret)
# We need an enum value per event
event_enum_value = generate_enum_full_value(event_enum_name,
event_name)
ret = generate_event_implement(api_name, event_name, params)
fdef.write(ret)
# Record it, and generate enum later
event_enum_values.append(event_enum_value)
event_enum_strings.append(event_name)
ret = generate_event_enum_decl(event_enum_name, event_enum_values)
fdecl.write(ret)
ret = generate_event_enum_lookup(event_enum_name, event_enum_strings)
fdef.write(ret)
fdecl.write('''
#endif
''')
fdecl.flush()
fdecl.close()
fdef.flush()
fdef.close()