diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /include/qom | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'include/qom')
| -rw-r--r-- | include/qom/cpu.h | 711 | ||||
| -rw-r--r-- | include/qom/object.h | 1509 | ||||
| -rw-r--r-- | include/qom/object_interfaces.h | 75 | ||||
| -rw-r--r-- | include/qom/qom-qobject.h | 42 | 
4 files changed, 2337 insertions, 0 deletions
diff --git a/include/qom/cpu.h b/include/qom/cpu.h new file mode 100644 index 00000000..20aabc9c --- /dev/null +++ b/include/qom/cpu.h @@ -0,0 +1,711 @@ +/* + * QEMU CPU model + * + * Copyright (c) 2012 SUSE LINUX Products GmbH + * + * 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/gpl-2.0.html> + */ +#ifndef QEMU_CPU_H +#define QEMU_CPU_H + +#include <signal.h> +#include <setjmp.h> +#include "hw/qdev-core.h" +#include "disas/bfd.h" +#include "exec/hwaddr.h" +#include "exec/memattrs.h" +#include "qemu/queue.h" +#include "qemu/thread.h" +#include "qemu/tls.h" +#include "qemu/typedefs.h" + +typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size, +                                     void *opaque); + +/** + * vaddr: + * Type wide enough to contain any #target_ulong virtual address. + */ +typedef uint64_t vaddr; +#define VADDR_PRId PRId64 +#define VADDR_PRIu PRIu64 +#define VADDR_PRIo PRIo64 +#define VADDR_PRIx PRIx64 +#define VADDR_PRIX PRIX64 +#define VADDR_MAX UINT64_MAX + +/** + * SECTION:cpu + * @section_id: QEMU-cpu + * @title: CPU Class + * @short_description: Base class for all CPUs + */ + +#define TYPE_CPU "cpu" + +/* Since this macro is used a lot in hot code paths and in conjunction with + * FooCPU *foo_env_get_cpu(), we deviate from usual QOM practice by using + * an unchecked cast. + */ +#define CPU(obj) ((CPUState *)(obj)) + +#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU) +#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU) + +typedef struct CPUState CPUState; + +typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, +                                    bool is_write, bool is_exec, int opaque, +                                    unsigned size); + +struct TranslationBlock; + +/** + * CPUClass: + * @class_by_name: Callback to map -cpu command line model name to an + * instantiatable CPU type. + * @parse_features: Callback to parse command line arguments. + * @reset: Callback to reset the #CPUState to its initial state. + * @reset_dump_flags: #CPUDumpFlags to use for reset logging. + * @has_work: Callback for checking if there is work to do. + * @do_interrupt: Callback for interrupt handling. + * @do_unassigned_access: Callback for unassigned access handling. + * @do_unaligned_access: Callback for unaligned access handling, if + * the target defines #ALIGNED_ONLY. + * @virtio_is_big_endian: Callback to return %true if a CPU which supports + * runtime configurable endianness is currently big-endian. Non-configurable + * CPUs can use the default implementation of this method. This method should + * not be used by any callers other than the pre-1.0 virtio devices. + * @memory_rw_debug: Callback for GDB memory access. + * @dump_state: Callback for dumping state. + * @dump_statistics: Callback for dumping statistics. + * @get_arch_id: Callback for getting architecture-dependent CPU ID. + * @get_paging_enabled: Callback for inquiring whether paging is enabled. + * @get_memory_mapping: Callback for obtaining the memory mappings. + * @set_pc: Callback for setting the Program Counter register. + * @synchronize_from_tb: Callback for synchronizing state from a TCG + * #TranslationBlock. + * @handle_mmu_fault: Callback for handling an MMU fault. + * @get_phys_page_debug: Callback for obtaining a physical address. + * @gdb_read_register: Callback for letting GDB read a register. + * @gdb_write_register: Callback for letting GDB write a register. + * @debug_excp_handler: Callback for handling debug exceptions. + * @write_elf64_note: Callback for writing a CPU-specific ELF note to a + * 64-bit VM coredump. + * @write_elf32_qemunote: Callback for writing a CPU- and QEMU-specific ELF + * note to a 32-bit VM coredump. + * @write_elf32_note: Callback for writing a CPU-specific ELF note to a + * 32-bit VM coredump. + * @write_elf32_qemunote: Callback for writing a CPU- and QEMU-specific ELF + * note to a 32-bit VM coredump. + * @vmsd: State description for migration. + * @gdb_num_core_regs: Number of core registers accessible to GDB. + * @gdb_core_xml_file: File name for core registers GDB XML description. + * @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop + *           before the insn which triggers a watchpoint rather than after it. + * @cpu_exec_enter: Callback for cpu_exec preparation. + * @cpu_exec_exit: Callback for cpu_exec cleanup. + * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec. + * @disas_set_info: Setup architecture specific components of disassembly info + * + * Represents a CPU family or model. + */ +typedef struct CPUClass { +    /*< private >*/ +    DeviceClass parent_class; +    /*< public >*/ + +    ObjectClass *(*class_by_name)(const char *cpu_model); +    void (*parse_features)(CPUState *cpu, char *str, Error **errp); + +    void (*reset)(CPUState *cpu); +    int reset_dump_flags; +    bool (*has_work)(CPUState *cpu); +    void (*do_interrupt)(CPUState *cpu); +    CPUUnassignedAccess do_unassigned_access; +    void (*do_unaligned_access)(CPUState *cpu, vaddr addr, +                                int is_write, int is_user, uintptr_t retaddr); +    bool (*virtio_is_big_endian)(CPUState *cpu); +    int (*memory_rw_debug)(CPUState *cpu, vaddr addr, +                           uint8_t *buf, int len, bool is_write); +    void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, +                       int flags); +    void (*dump_statistics)(CPUState *cpu, FILE *f, +                            fprintf_function cpu_fprintf, int flags); +    int64_t (*get_arch_id)(CPUState *cpu); +    bool (*get_paging_enabled)(const CPUState *cpu); +    void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, +                               Error **errp); +    void (*set_pc)(CPUState *cpu, vaddr value); +    void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb); +    int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int rw, +                            int mmu_index); +    hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); +    int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg); +    int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg); +    void (*debug_excp_handler)(CPUState *cpu); + +    int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, +                            int cpuid, void *opaque); +    int (*write_elf64_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, +                                void *opaque); +    int (*write_elf32_note)(WriteCoreDumpFunction f, CPUState *cpu, +                            int cpuid, void *opaque); +    int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, +                                void *opaque); + +    const struct VMStateDescription *vmsd; +    int gdb_num_core_regs; +    const char *gdb_core_xml_file; +    bool gdb_stop_before_watchpoint; + +    void (*cpu_exec_enter)(CPUState *cpu); +    void (*cpu_exec_exit)(CPUState *cpu); +    bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request); + +    void (*disas_set_info)(CPUState *cpu, disassemble_info *info); +} CPUClass; + +#ifdef HOST_WORDS_BIGENDIAN +typedef struct icount_decr_u16 { +    uint16_t high; +    uint16_t low; +} icount_decr_u16; +#else +typedef struct icount_decr_u16 { +    uint16_t low; +    uint16_t high; +} icount_decr_u16; +#endif + +typedef struct CPUBreakpoint { +    vaddr pc; +    int flags; /* BP_* */ +    QTAILQ_ENTRY(CPUBreakpoint) entry; +} CPUBreakpoint; + +typedef struct CPUWatchpoint { +    vaddr vaddr; +    vaddr len; +    vaddr hitaddr; +    MemTxAttrs hitattrs; +    int flags; /* BP_* */ +    QTAILQ_ENTRY(CPUWatchpoint) entry; +} CPUWatchpoint; + +struct KVMState; +struct kvm_run; + +#define TB_JMP_CACHE_BITS 12 +#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) + +/** + * CPUState: + * @cpu_index: CPU index (informative). + * @nr_cores: Number of cores within this CPU package. + * @nr_threads: Number of threads within this CPU. + * @numa_node: NUMA node this CPU is belonging to. + * @host_tid: Host thread ID. + * @running: #true if CPU is currently running (usermode). + * @created: Indicates whether the CPU thread has been successfully created. + * @interrupt_request: Indicates a pending interrupt request. + * @halted: Nonzero if the CPU is in suspended state. + * @stop: Indicates a pending stop request. + * @stopped: Indicates the CPU has been artificially stopped. + * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this + *           CPU and return to its top level loop. + * @singlestep_enabled: Flags for single-stepping. + * @icount_extra: Instructions until next timer event. + * @icount_decr: Number of cycles left, with interrupt flag in high bit. + * This allows a single read-compare-cbranch-write sequence to test + * for both decrementer underflow and exceptions. + * @can_do_io: Nonzero if memory-mapped IO is safe. + * @env_ptr: Pointer to subclass-specific CPUArchState field. + * @current_tb: Currently executing TB. + * @gdb_regs: Additional GDB registers. + * @gdb_num_regs: Number of total registers accessible to GDB. + * @gdb_num_g_regs: Number of registers in GDB 'g' packets. + * @next_cpu: Next CPU sharing TB cache. + * @opaque: User data. + * @mem_io_pc: Host Program Counter at which the memory was accessed. + * @mem_io_vaddr: Target virtual address at which the memory was accessed. + * @kvm_fd: vCPU file descriptor for KVM. + * + * State of one CPU core or thread. + */ +struct CPUState { +    /*< private >*/ +    DeviceState parent_obj; +    /*< public >*/ + +    int nr_cores; +    int nr_threads; +    int numa_node; + +    struct QemuThread *thread; +#ifdef _WIN32 +    HANDLE hThread; +#endif +    int thread_id; +    uint32_t host_tid; +    bool running; +    struct QemuCond *halt_cond; +    struct qemu_work_item *queued_work_first, *queued_work_last; +    bool thread_kicked; +    bool created; +    bool stop; +    bool stopped; +    volatile sig_atomic_t exit_request; +    uint32_t interrupt_request; +    int singlestep_enabled; +    int64_t icount_extra; +    sigjmp_buf jmp_env; + +    AddressSpace *as; +    struct AddressSpaceDispatch *memory_dispatch; +    MemoryListener *tcg_as_listener; + +    void *env_ptr; /* CPUArchState */ +    struct TranslationBlock *current_tb; +    struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; +    struct GDBRegisterState *gdb_regs; +    int gdb_num_regs; +    int gdb_num_g_regs; +    QTAILQ_ENTRY(CPUState) node; + +    /* ice debug support */ +    QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; + +    QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; +    CPUWatchpoint *watchpoint_hit; + +    void *opaque; + +    /* In order to avoid passing too many arguments to the MMIO helpers, +     * we store some rarely used information in the CPU context. +     */ +    uintptr_t mem_io_pc; +    vaddr mem_io_vaddr; + +    int kvm_fd; +    bool kvm_vcpu_dirty; +    struct KVMState *kvm_state; +    struct kvm_run *kvm_run; + +    /* TODO Move common fields from CPUArchState here. */ +    int cpu_index; /* used by alpha TCG */ +    uint32_t halted; /* used by alpha, cris, ppc TCG */ +    union { +        uint32_t u32; +        icount_decr_u16 u16; +    } icount_decr; +    uint32_t can_do_io; +    int32_t exception_index; /* used by m68k TCG */ + +    /* Note that this is accessed at the start of every TB via a negative +       offset from AREG0.  Leave this field at the end so as to make the +       (absolute value) offset as small as possible.  This reduces code +       size, especially for hosts without large memory offsets.  */ +    volatile sig_atomic_t tcg_exit_req; +}; + +QTAILQ_HEAD(CPUTailQ, CPUState); +extern struct CPUTailQ cpus; +#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node) +#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node) +#define CPU_FOREACH_SAFE(cpu, next_cpu) \ +    QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu) +#define CPU_FOREACH_REVERSE(cpu) \ +    QTAILQ_FOREACH_REVERSE(cpu, &cpus, CPUTailQ, node) +#define first_cpu QTAILQ_FIRST(&cpus) + +DECLARE_TLS(CPUState *, current_cpu); +#define current_cpu tls_var(current_cpu) + +/** + * cpu_paging_enabled: + * @cpu: The CPU whose state is to be inspected. + * + * Returns: %true if paging is enabled, %false otherwise. + */ +bool cpu_paging_enabled(const CPUState *cpu); + +/** + * cpu_get_memory_mapping: + * @cpu: The CPU whose memory mappings are to be obtained. + * @list: Where to write the memory mappings to. + * @errp: Pointer for reporting an #Error. + */ +void cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, +                            Error **errp); + +/** + * cpu_write_elf64_note: + * @f: pointer to a function that writes memory to a file + * @cpu: The CPU whose memory is to be dumped + * @cpuid: ID number of the CPU + * @opaque: pointer to the CPUState struct + */ +int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, +                         int cpuid, void *opaque); + +/** + * cpu_write_elf64_qemunote: + * @f: pointer to a function that writes memory to a file + * @cpu: The CPU whose memory is to be dumped + * @cpuid: ID number of the CPU + * @opaque: pointer to the CPUState struct + */ +int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu, +                             void *opaque); + +/** + * cpu_write_elf32_note: + * @f: pointer to a function that writes memory to a file + * @cpu: The CPU whose memory is to be dumped + * @cpuid: ID number of the CPU + * @opaque: pointer to the CPUState struct + */ +int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu, +                         int cpuid, void *opaque); + +/** + * cpu_write_elf32_qemunote: + * @f: pointer to a function that writes memory to a file + * @cpu: The CPU whose memory is to be dumped + * @cpuid: ID number of the CPU + * @opaque: pointer to the CPUState struct + */ +int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, +                             void *opaque); + +/** + * CPUDumpFlags: + * @CPU_DUMP_CODE: + * @CPU_DUMP_FPU: dump FPU register state, not just integer + * @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state + */ +enum CPUDumpFlags { +    CPU_DUMP_CODE = 0x00010000, +    CPU_DUMP_FPU  = 0x00020000, +    CPU_DUMP_CCOP = 0x00040000, +}; + +/** + * cpu_dump_state: + * @cpu: The CPU whose state is to be dumped. + * @f: File to dump to. + * @cpu_fprintf: Function to dump with. + * @flags: Flags what to dump. + * + * Dumps CPU state. + */ +void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, +                    int flags); + +/** + * cpu_dump_statistics: + * @cpu: The CPU whose state is to be dumped. + * @f: File to dump to. + * @cpu_fprintf: Function to dump with. + * @flags: Flags what to dump. + * + * Dumps CPU statistics. + */ +void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, +                         int flags); + +#ifndef CONFIG_USER_ONLY +/** + * cpu_get_phys_page_debug: + * @cpu: The CPU to obtain the physical page address for. + * @addr: The virtual address. + * + * Obtains the physical page corresponding to a virtual one. + * Use it only for debugging because no protection checks are done. + * + * Returns: Corresponding physical page address or -1 if no page found. + */ +static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) +{ +    CPUClass *cc = CPU_GET_CLASS(cpu); + +    return cc->get_phys_page_debug(cpu, addr); +} +#endif + +/** + * cpu_reset: + * @cpu: The CPU whose state is to be reset. + */ +void cpu_reset(CPUState *cpu); + +/** + * cpu_class_by_name: + * @typename: The CPU base type. + * @cpu_model: The model string without any parameters. + * + * Looks up a CPU #ObjectClass matching name @cpu_model. + * + * Returns: A #CPUClass or %NULL if not matching class is found. + */ +ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); + +/** + * cpu_generic_init: + * @typename: The CPU base type. + * @cpu_model: The model string including optional parameters. + * + * Instantiates a CPU, processes optional parameters and realizes the CPU. + * + * Returns: A #CPUState or %NULL if an error occurred. + */ +CPUState *cpu_generic_init(const char *typename, const char *cpu_model); + +/** + * cpu_has_work: + * @cpu: The vCPU to check. + * + * Checks whether the CPU has work to do. + * + * Returns: %true if the CPU has work, %false otherwise. + */ +static inline bool cpu_has_work(CPUState *cpu) +{ +    CPUClass *cc = CPU_GET_CLASS(cpu); + +    g_assert(cc->has_work); +    return cc->has_work(cpu); +} + +/** + * qemu_cpu_is_self: + * @cpu: The vCPU to check against. + * + * Checks whether the caller is executing on the vCPU thread. + * + * Returns: %true if called from @cpu's thread, %false otherwise. + */ +bool qemu_cpu_is_self(CPUState *cpu); + +/** + * qemu_cpu_kick: + * @cpu: The vCPU to kick. + * + * Kicks @cpu's thread. + */ +void qemu_cpu_kick(CPUState *cpu); + +/** + * cpu_is_stopped: + * @cpu: The CPU to check. + * + * Checks whether the CPU is stopped. + * + * Returns: %true if run state is not running or if artificially stopped; + * %false otherwise. + */ +bool cpu_is_stopped(CPUState *cpu); + +/** + * run_on_cpu: + * @cpu: The vCPU to run on. + * @func: The function to be executed. + * @data: Data to pass to the function. + * + * Schedules the function @func for execution on the vCPU @cpu. + */ +void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); + +/** + * async_run_on_cpu: + * @cpu: The vCPU to run on. + * @func: The function to be executed. + * @data: Data to pass to the function. + * + * Schedules the function @func for execution on the vCPU @cpu asynchronously. + */ +void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); + +/** + * qemu_get_cpu: + * @index: The CPUState@cpu_index value of the CPU to obtain. + * + * Gets a CPU matching @index. + * + * Returns: The CPU or %NULL if there is no matching CPU. + */ +CPUState *qemu_get_cpu(int index); + +/** + * cpu_exists: + * @id: Guest-exposed CPU ID to lookup. + * + * Search for CPU with specified ID. + * + * Returns: %true - CPU is found, %false - CPU isn't found. + */ +bool cpu_exists(int64_t id); + +#ifndef CONFIG_USER_ONLY + +typedef void (*CPUInterruptHandler)(CPUState *, int); + +extern CPUInterruptHandler cpu_interrupt_handler; + +/** + * cpu_interrupt: + * @cpu: The CPU to set an interrupt on. + * @mask: The interupts to set. + * + * Invokes the interrupt handler. + */ +static inline void cpu_interrupt(CPUState *cpu, int mask) +{ +    cpu_interrupt_handler(cpu, mask); +} + +#else /* USER_ONLY */ + +void cpu_interrupt(CPUState *cpu, int mask); + +#endif /* USER_ONLY */ + +#ifdef CONFIG_SOFTMMU +static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr, +                                         bool is_write, bool is_exec, +                                         int opaque, unsigned size) +{ +    CPUClass *cc = CPU_GET_CLASS(cpu); + +    if (cc->do_unassigned_access) { +        cc->do_unassigned_access(cpu, addr, is_write, is_exec, opaque, size); +    } +} + +static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr, +                                        int is_write, int is_user, +                                        uintptr_t retaddr) +{ +    CPUClass *cc = CPU_GET_CLASS(cpu); + +    cc->do_unaligned_access(cpu, addr, is_write, is_user, retaddr); +} +#endif + +/** + * cpu_set_pc: + * @cpu: The CPU to set the program counter for. + * @addr: Program counter value. + * + * Sets the program counter for a CPU. + */ +static inline void cpu_set_pc(CPUState *cpu, vaddr addr) +{ +    CPUClass *cc = CPU_GET_CLASS(cpu); + +    cc->set_pc(cpu, addr); +} + +/** + * cpu_reset_interrupt: + * @cpu: The CPU to clear the interrupt on. + * @mask: The interrupt mask to clear. + * + * Resets interrupts on the vCPU @cpu. + */ +void cpu_reset_interrupt(CPUState *cpu, int mask); + +/** + * cpu_exit: + * @cpu: The CPU to exit. + * + * Requests the CPU @cpu to exit execution. + */ +void cpu_exit(CPUState *cpu); + +/** + * cpu_resume: + * @cpu: The CPU to resume. + * + * Resumes CPU, i.e. puts CPU into runnable state. + */ +void cpu_resume(CPUState *cpu); + +/** + * qemu_init_vcpu: + * @cpu: The vCPU to initialize. + * + * Initializes a vCPU. + */ +void qemu_init_vcpu(CPUState *cpu); + +#define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */ +#define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */ +#define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */ + +/** + * cpu_single_step: + * @cpu: CPU to the flags for. + * @enabled: Flags to enable. + * + * Enables or disables single-stepping for @cpu. + */ +void cpu_single_step(CPUState *cpu, int enabled); + +/* Breakpoint/watchpoint flags */ +#define BP_MEM_READ           0x01 +#define BP_MEM_WRITE          0x02 +#define BP_MEM_ACCESS         (BP_MEM_READ | BP_MEM_WRITE) +#define BP_STOP_BEFORE_ACCESS 0x04 +/* 0x08 currently unused */ +#define BP_GDB                0x10 +#define BP_CPU                0x20 +#define BP_WATCHPOINT_HIT_READ 0x40 +#define BP_WATCHPOINT_HIT_WRITE 0x80 +#define BP_WATCHPOINT_HIT (BP_WATCHPOINT_HIT_READ | BP_WATCHPOINT_HIT_WRITE) + +int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags, +                          CPUBreakpoint **breakpoint); +int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags); +void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint); +void cpu_breakpoint_remove_all(CPUState *cpu, int mask); + +int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len, +                          int flags, CPUWatchpoint **watchpoint); +int cpu_watchpoint_remove(CPUState *cpu, vaddr addr, +                          vaddr len, int flags); +void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint); +void cpu_watchpoint_remove_all(CPUState *cpu, int mask); + +void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...) +    GCC_FMT_ATTR(2, 3); +void cpu_exec_exit(CPUState *cpu); + +#ifdef CONFIG_SOFTMMU +extern const struct VMStateDescription vmstate_cpu_common; +#else +#define vmstate_cpu_common vmstate_dummy +#endif + +#define VMSTATE_CPU() {                                                     \ +    .name = "parent_obj",                                                   \ +    .size = sizeof(CPUState),                                               \ +    .vmsd = &vmstate_cpu_common,                                            \ +    .flags = VMS_STRUCT,                                                    \ +    .offset = 0,                                                            \ +} + +#endif diff --git a/include/qom/object.h b/include/qom/object.h new file mode 100644 index 00000000..807978ee --- /dev/null +++ b/include/qom/object.h @@ -0,0 +1,1509 @@ +/* + * QEMU Object Model + * + * Copyright IBM, Corp. 2011 + * + * Authors: + *  Anthony Liguori   <aliguori@us.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_OBJECT_H +#define QEMU_OBJECT_H + +#include <glib.h> +#include <stdint.h> +#include <stdbool.h> +#include "qemu/queue.h" +#include "qapi/error.h" + +struct Visitor; + +struct TypeImpl; +typedef struct TypeImpl *Type; + +typedef struct ObjectClass ObjectClass; +typedef struct Object Object; + +typedef struct TypeInfo TypeInfo; + +typedef struct InterfaceClass InterfaceClass; +typedef struct InterfaceInfo InterfaceInfo; + +#define TYPE_OBJECT "object" + +/** + * SECTION:object.h + * @title:Base Object Type System + * @short_description: interfaces for creating new types and objects + * + * The QEMU Object Model provides a framework for registering user creatable + * types and instantiating objects from those types.  QOM provides the following + * features: + * + *  - System for dynamically registering types + *  - Support for single-inheritance of types + *  - Multiple inheritance of stateless interfaces + * + * <example> + *   <title>Creating a minimal type</title> + *   <programlisting> + * #include "qdev.h" + * + * #define TYPE_MY_DEVICE "my-device" + * + * // No new virtual functions: we can reuse the typedef for the + * // superclass. + * typedef DeviceClass MyDeviceClass; + * typedef struct MyDevice + * { + *     DeviceState parent; + * + *     int reg0, reg1, reg2; + * } MyDevice; + * + * static const TypeInfo my_device_info = { + *     .name = TYPE_MY_DEVICE, + *     .parent = TYPE_DEVICE, + *     .instance_size = sizeof(MyDevice), + * }; + * + * static void my_device_register_types(void) + * { + *     type_register_static(&my_device_info); + * } + * + * type_init(my_device_register_types) + *   </programlisting> + * </example> + * + * In the above example, we create a simple type that is described by #TypeInfo. + * #TypeInfo describes information about the type including what it inherits + * from, the instance and class size, and constructor/destructor hooks. + * + * Every type has an #ObjectClass associated with it.  #ObjectClass derivatives + * are instantiated dynamically but there is only ever one instance for any + * given type.  The #ObjectClass typically holds a table of function pointers + * for the virtual methods implemented by this type. + * + * Using object_new(), a new #Object derivative will be instantiated.  You can + * cast an #Object to a subclass (or base-class) type using + * object_dynamic_cast().  You typically want to define macro wrappers around + * OBJECT_CHECK() and OBJECT_CLASS_CHECK() to make it easier to convert to a + * specific type: + * + * <example> + *   <title>Typecasting macros</title> + *   <programlisting> + *    #define MY_DEVICE_GET_CLASS(obj) \ + *       OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE) + *    #define MY_DEVICE_CLASS(klass) \ + *       OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE) + *    #define MY_DEVICE(obj) \ + *       OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE) + *   </programlisting> + * </example> + * + * # Class Initialization # + * + * Before an object is initialized, the class for the object must be + * initialized.  There is only one class object for all instance objects + * that is created lazily. + * + * Classes are initialized by first initializing any parent classes (if + * necessary).  After the parent class object has initialized, it will be + * copied into the current class object and any additional storage in the + * class object is zero filled. + * + * The effect of this is that classes automatically inherit any virtual + * function pointers that the parent class has already initialized.  All + * other fields will be zero filled. + * + * Once all of the parent classes have been initialized, #TypeInfo::class_init + * is called to let the class being instantiated provide default initialize for + * its virtual functions.  Here is how the above example might be modified + * to introduce an overridden virtual function: + * + * <example> + *   <title>Overriding a virtual function</title> + *   <programlisting> + * #include "qdev.h" + * + * void my_device_class_init(ObjectClass *klass, void *class_data) + * { + *     DeviceClass *dc = DEVICE_CLASS(klass); + *     dc->reset = my_device_reset; + * } + * + * static const TypeInfo my_device_info = { + *     .name = TYPE_MY_DEVICE, + *     .parent = TYPE_DEVICE, + *     .instance_size = sizeof(MyDevice), + *     .class_init = my_device_class_init, + * }; + *   </programlisting> + * </example> + * + * Introducing new virtual methods requires a class to define its own + * struct and to add a .class_size member to the #TypeInfo.  Each method + * will also have a wrapper function to call it easily: + * + * <example> + *   <title>Defining an abstract class</title> + *   <programlisting> + * #include "qdev.h" + * + * typedef struct MyDeviceClass + * { + *     DeviceClass parent; + * + *     void (*frobnicate) (MyDevice *obj); + * } MyDeviceClass; + * + * static const TypeInfo my_device_info = { + *     .name = TYPE_MY_DEVICE, + *     .parent = TYPE_DEVICE, + *     .instance_size = sizeof(MyDevice), + *     .abstract = true, // or set a default in my_device_class_init + *     .class_size = sizeof(MyDeviceClass), + * }; + * + * void my_device_frobnicate(MyDevice *obj) + * { + *     MyDeviceClass *klass = MY_DEVICE_GET_CLASS(obj); + * + *     klass->frobnicate(obj); + * } + *   </programlisting> + * </example> + * + * # Interfaces # + * + * Interfaces allow a limited form of multiple inheritance.  Instances are + * similar to normal types except for the fact that are only defined by + * their classes and never carry any state.  You can dynamically cast an object + * to one of its #Interface types and vice versa. + * + * # Methods # + * + * A <emphasis>method</emphasis> is a function within the namespace scope of + * a class. It usually operates on the object instance by passing it as a + * strongly-typed first argument. + * If it does not operate on an object instance, it is dubbed + * <emphasis>class method</emphasis>. + * + * Methods cannot be overloaded. That is, the #ObjectClass and method name + * uniquely identity the function to be called; the signature does not vary + * except for trailing varargs. + * + * Methods are always <emphasis>virtual</emphasis>. Overriding a method in + * #TypeInfo.class_init of a subclass leads to any user of the class obtained + * via OBJECT_GET_CLASS() accessing the overridden function. + * The original function is not automatically invoked. It is the responsibility + * of the overriding class to determine whether and when to invoke the method + * being overridden. + * + * To invoke the method being overridden, the preferred solution is to store + * the original value in the overriding class before overriding the method. + * This corresponds to |[ {super,base}.method(...) ]| in Java and C# + * respectively; this frees the overriding class from hardcoding its parent + * class, which someone might choose to change at some point. + * + * <example> + *   <title>Overriding a virtual method</title> + *   <programlisting> + * typedef struct MyState MyState; + * + * typedef void (*MyDoSomething)(MyState *obj); + * + * typedef struct MyClass { + *     ObjectClass parent_class; + * + *     MyDoSomething do_something; + * } MyClass; + * + * static void my_do_something(MyState *obj) + * { + *     // do something + * } + * + * static void my_class_init(ObjectClass *oc, void *data) + * { + *     MyClass *mc = MY_CLASS(oc); + * + *     mc->do_something = my_do_something; + * } + * + * static const TypeInfo my_type_info = { + *     .name = TYPE_MY, + *     .parent = TYPE_OBJECT, + *     .instance_size = sizeof(MyState), + *     .class_size = sizeof(MyClass), + *     .class_init = my_class_init, + * }; + * + * typedef struct DerivedClass { + *     MyClass parent_class; + * + *     MyDoSomething parent_do_something; + * } DerivedClass; + * + * static void derived_do_something(MyState *obj) + * { + *     DerivedClass *dc = DERIVED_GET_CLASS(obj); + * + *     // do something here + *     dc->parent_do_something(obj); + *     // do something else here + * } + * + * static void derived_class_init(ObjectClass *oc, void *data) + * { + *     MyClass *mc = MY_CLASS(oc); + *     DerivedClass *dc = DERIVED_CLASS(oc); + * + *     dc->parent_do_something = mc->do_something; + *     mc->do_something = derived_do_something; + * } + * + * static const TypeInfo derived_type_info = { + *     .name = TYPE_DERIVED, + *     .parent = TYPE_MY, + *     .class_size = sizeof(DerivedClass), + *     .class_init = derived_class_init, + * }; + *   </programlisting> + * </example> + * + * Alternatively, object_class_by_name() can be used to obtain the class and + * its non-overridden methods for a specific type. This would correspond to + * |[ MyClass::method(...) ]| in C++. + * + * The first example of such a QOM method was #CPUClass.reset, + * another example is #DeviceClass.realize. + */ + + +/** + * ObjectPropertyAccessor: + * @obj: the object that owns the property + * @v: the visitor that contains the property data + * @opaque: the object property opaque + * @name: the name of the property + * @errp: a pointer to an Error that is filled if getting/setting fails. + * + * Called when trying to get/set a property. + */ +typedef void (ObjectPropertyAccessor)(Object *obj, +                                      struct Visitor *v, +                                      void *opaque, +                                      const char *name, +                                      Error **errp); + +/** + * ObjectPropertyResolve: + * @obj: the object that owns the property + * @opaque: the opaque registered with the property + * @part: the name of the property + * + * Resolves the #Object corresponding to property @part. + * + * The returned object can also be used as a starting point + * to resolve a relative path starting with "@part". + * + * Returns: If @path is the path that led to @obj, the function + * returns the #Object corresponding to "@path/@part". + * If "@path/@part" is not a valid object path, it returns #NULL. + */ +typedef Object *(ObjectPropertyResolve)(Object *obj, +                                        void *opaque, +                                        const char *part); + +/** + * ObjectPropertyRelease: + * @obj: the object that owns the property + * @name: the name of the property + * @opaque: the opaque registered with the property + * + * Called when a property is removed from a object. + */ +typedef void (ObjectPropertyRelease)(Object *obj, +                                     const char *name, +                                     void *opaque); + +typedef struct ObjectProperty +{ +    gchar *name; +    gchar *type; +    gchar *description; +    ObjectPropertyAccessor *get; +    ObjectPropertyAccessor *set; +    ObjectPropertyResolve *resolve; +    ObjectPropertyRelease *release; +    void *opaque; + +    QTAILQ_ENTRY(ObjectProperty) node; +} ObjectProperty; + +/** + * ObjectUnparent: + * @obj: the object that is being removed from the composition tree + * + * Called when an object is being removed from the QOM composition tree. + * The function should remove any backlinks from children objects to @obj. + */ +typedef void (ObjectUnparent)(Object *obj); + +/** + * ObjectFree: + * @obj: the object being freed + * + * Called when an object's last reference is removed. + */ +typedef void (ObjectFree)(void *obj); + +#define OBJECT_CLASS_CAST_CACHE 4 + +/** + * ObjectClass: + * + * The base for all classes.  The only thing that #ObjectClass contains is an + * integer type handle. + */ +struct ObjectClass +{ +    /*< private >*/ +    Type type; +    GSList *interfaces; + +    const char *object_cast_cache[OBJECT_CLASS_CAST_CACHE]; +    const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE]; + +    ObjectUnparent *unparent; +}; + +/** + * Object: + * + * The base for all objects.  The first member of this object is a pointer to + * a #ObjectClass.  Since C guarantees that the first member of a structure + * always begins at byte 0 of that structure, as long as any sub-object places + * its parent as the first member, we can cast directly to a #Object. + * + * As a result, #Object contains a reference to the objects type as its + * first member.  This allows identification of the real type of the object at + * run time. + * + * #Object also contains a list of #Interfaces that this object + * implements. + */ +struct Object +{ +    /*< private >*/ +    ObjectClass *class; +    ObjectFree *free; +    QTAILQ_HEAD(, ObjectProperty) properties; +    uint32_t ref; +    Object *parent; +}; + +/** + * TypeInfo: + * @name: The name of the type. + * @parent: The name of the parent type. + * @instance_size: The size of the object (derivative of #Object).  If + *   @instance_size is 0, then the size of the object will be the size of the + *   parent object. + * @instance_init: This function is called to initialize an object.  The parent + *   class will have already been initialized so the type is only responsible + *   for initializing its own members. + * @instance_post_init: This function is called to finish initialization of + *   an object, after all @instance_init functions were called. + * @instance_finalize: This function is called during object destruction.  This + *   is called before the parent @instance_finalize function has been called. + *   An object should only free the members that are unique to its type in this + *   function. + * @abstract: If this field is true, then the class is considered abstract and + *   cannot be directly instantiated. + * @class_size: The size of the class object (derivative of #ObjectClass) + *   for this object.  If @class_size is 0, then the size of the class will be + *   assumed to be the size of the parent class.  This allows a type to avoid + *   implementing an explicit class type if they are not adding additional + *   virtual functions. + * @class_init: This function is called after all parent class initialization + *   has occurred to allow a class to set its default virtual method pointers. + *   This is also the function to use to override virtual methods from a parent + *   class. + * @class_base_init: This function is called for all base classes after all + *   parent class initialization has occurred, but before the class itself + *   is initialized.  This is the function to use to undo the effects of + *   memcpy from the parent class to the descendents. + * @class_finalize: This function is called during class destruction and is + *   meant to release and dynamic parameters allocated by @class_init. + * @class_data: Data to pass to the @class_init, @class_base_init and + *   @class_finalize functions.  This can be useful when building dynamic + *   classes. + * @interfaces: The list of interfaces associated with this type.  This + *   should point to a static array that's terminated with a zero filled + *   element. + */ +struct TypeInfo +{ +    const char *name; +    const char *parent; + +    size_t instance_size; +    void (*instance_init)(Object *obj); +    void (*instance_post_init)(Object *obj); +    void (*instance_finalize)(Object *obj); + +    bool abstract; +    size_t class_size; + +    void (*class_init)(ObjectClass *klass, void *data); +    void (*class_base_init)(ObjectClass *klass, void *data); +    void (*class_finalize)(ObjectClass *klass, void *data); +    void *class_data; + +    InterfaceInfo *interfaces; +}; + +/** + * OBJECT: + * @obj: A derivative of #Object + * + * Converts an object to a #Object.  Since all objects are #Objects, + * this function will always succeed. + */ +#define OBJECT(obj) \ +    ((Object *)(obj)) + +/** + * OBJECT_CLASS: + * @class: A derivative of #ObjectClass. + * + * Converts a class to an #ObjectClass.  Since all objects are #Objects, + * this function will always succeed. + */ +#define OBJECT_CLASS(class) \ +    ((ObjectClass *)(class)) + +/** + * OBJECT_CHECK: + * @type: The C type to use for the return value. + * @obj: A derivative of @type to cast. + * @name: The QOM typename of @type + * + * A type safe version of @object_dynamic_cast_assert.  Typically each class + * will define a macro based on this type to perform type safe dynamic_casts to + * this object type. + * + * If an invalid object is passed to this function, a run time assert will be + * generated. + */ +#define OBJECT_CHECK(type, obj, name) \ +    ((type *)object_dynamic_cast_assert(OBJECT(obj), (name), \ +                                        __FILE__, __LINE__, __func__)) + +/** + * OBJECT_CLASS_CHECK: + * @class: The C type to use for the return value. + * @obj: A derivative of @type to cast. + * @name: the QOM typename of @class. + * + * A type safe version of @object_class_dynamic_cast_assert.  This macro is + * typically wrapped by each type to perform type safe casts of a class to a + * specific class type. + */ +#define OBJECT_CLASS_CHECK(class, obj, name) \ +    ((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name), \ +                                               __FILE__, __LINE__, __func__)) + +/** + * OBJECT_GET_CLASS: + * @class: The C type to use for the return value. + * @obj: The object to obtain the class for. + * @name: The QOM typename of @obj. + * + * This function will return a specific class for a given object.  Its generally + * used by each type to provide a type safe macro to get a specific class type + * from an object. + */ +#define OBJECT_GET_CLASS(class, obj, name) \ +    OBJECT_CLASS_CHECK(class, object_get_class(OBJECT(obj)), name) + +/** + * InterfaceInfo: + * @type: The name of the interface. + * + * The information associated with an interface. + */ +struct InterfaceInfo { +    const char *type; +}; + +/** + * InterfaceClass: + * @parent_class: the base class + * + * The class for all interfaces.  Subclasses of this class should only add + * virtual methods. + */ +struct InterfaceClass +{ +    ObjectClass parent_class; +    /*< private >*/ +    ObjectClass *concrete_class; +    Type interface_type; +}; + +#define TYPE_INTERFACE "interface" + +/** + * INTERFACE_CLASS: + * @klass: class to cast from + * Returns: An #InterfaceClass or raise an error if cast is invalid + */ +#define INTERFACE_CLASS(klass) \ +    OBJECT_CLASS_CHECK(InterfaceClass, klass, TYPE_INTERFACE) + +/** + * INTERFACE_CHECK: + * @interface: the type to return + * @obj: the object to convert to an interface + * @name: the interface type name + * + * Returns: @obj casted to @interface if cast is valid, otherwise raise error. + */ +#define INTERFACE_CHECK(interface, obj, name) \ +    ((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name), \ +                                             __FILE__, __LINE__, __func__)) + +/** + * object_new: + * @typename: The name of the type of the object to instantiate. + * + * This function will initialize a new object using heap allocated memory. + * The returned object has a reference count of 1, and will be freed when + * the last reference is dropped. + * + * Returns: The newly allocated and instantiated object. + */ +Object *object_new(const char *typename); + +/** + * object_new_with_type: + * @type: The type of the object to instantiate. + * + * This function will initialize a new object using heap allocated memory. + * The returned object has a reference count of 1, and will be freed when + * the last reference is dropped. + * + * Returns: The newly allocated and instantiated object. + */ +Object *object_new_with_type(Type type); + +/** + * object_new_with_props: + * @typename:  The name of the type of the object to instantiate. + * @parent: the parent object + * @id: The unique ID of the object + * @errp: pointer to error object + * @...: list of property names and values + * + * This function will initialize a new object using heap allocated memory. + * The returned object has a reference count of 1, and will be freed when + * the last reference is dropped. + * + * The @id parameter will be used when registering the object as a + * child of @parent in the composition tree. + * + * The variadic parameters are a list of pairs of (propname, propvalue) + * strings. The propname of %NULL indicates the end of the property + * list. If the object implements the user creatable interface, the + * object will be marked complete once all the properties have been + * processed. + * + * <example> + *   <title>Creating an object with properties</title> + *   <programlisting> + *   Error *err = NULL; + *   Object *obj; + * + *   obj = object_new_with_props(TYPE_MEMORY_BACKEND_FILE, + *                               object_get_objects_root(), + *                               "hostmem0", + *                               &err, + *                               "share", "yes", + *                               "mem-path", "/dev/shm/somefile", + *                               "prealloc", "yes", + *                               "size", "1048576", + *                               NULL); + * + *   if (!obj) { + *     g_printerr("Cannot create memory backend: %s\n", + *                error_get_pretty(err)); + *   } + *   </programlisting> + * </example> + * + * The returned object will have one stable reference maintained + * for as long as it is present in the object hierarchy. + * + * Returns: The newly allocated, instantiated & initialized object. + */ +Object *object_new_with_props(const char *typename, +                              Object *parent, +                              const char *id, +                              Error **errp, +                              ...) QEMU_SENTINEL; + +/** + * object_new_with_propv: + * @typename:  The name of the type of the object to instantiate. + * @parent: the parent object + * @id: The unique ID of the object + * @errp: pointer to error object + * @vargs: list of property names and values + * + * See object_new_with_props() for documentation. + */ +Object *object_new_with_propv(const char *typename, +                              Object *parent, +                              const char *id, +                              Error **errp, +                              va_list vargs); + +/** + * object_set_props: + * @obj: the object instance to set properties on + * @errp: pointer to error object + * @...: list of property names and values + * + * This function will set a list of properties on an existing object + * instance. + * + * The variadic parameters are a list of pairs of (propname, propvalue) + * strings. The propname of %NULL indicates the end of the property + * list. + * + * <example> + *   <title>Update an object's properties</title> + *   <programlisting> + *   Error *err = NULL; + *   Object *obj = ...get / create object...; + * + *   obj = object_set_props(obj, + *                          &err, + *                          "share", "yes", + *                          "mem-path", "/dev/shm/somefile", + *                          "prealloc", "yes", + *                          "size", "1048576", + *                          NULL); + * + *   if (!obj) { + *     g_printerr("Cannot set properties: %s\n", + *                error_get_pretty(err)); + *   } + *   </programlisting> + * </example> + * + * The returned object will have one stable reference maintained + * for as long as it is present in the object hierarchy. + * + * Returns: -1 on error, 0 on success + */ +int object_set_props(Object *obj, +                     Error **errp, +                     ...) QEMU_SENTINEL; + +/** + * object_set_propv: + * @obj: the object instance to set properties on + * @errp: pointer to error object + * @vargs: list of property names and values + * + * See object_set_props() for documentation. + * + * Returns: -1 on error, 0 on success + */ +int object_set_propv(Object *obj, +                     Error **errp, +                     va_list vargs); + +/** + * object_initialize_with_type: + * @data: A pointer to the memory to be used for the object. + * @size: The maximum size available at @data for the object. + * @type: The type of the object to instantiate. + * + * This function will initialize an object.  The memory for the object should + * have already been allocated.  The returned object has a reference count of 1, + * and will be finalized when the last reference is dropped. + */ +void object_initialize_with_type(void *data, size_t size, Type type); + +/** + * object_initialize: + * @obj: A pointer to the memory to be used for the object. + * @size: The maximum size available at @obj for the object. + * @typename: The name of the type of the object to instantiate. + * + * This function will initialize an object.  The memory for the object should + * have already been allocated.  The returned object has a reference count of 1, + * and will be finalized when the last reference is dropped. + */ +void object_initialize(void *obj, size_t size, const char *typename); + +/** + * object_dynamic_cast: + * @obj: The object to cast. + * @typename: The @typename to cast to. + * + * This function will determine if @obj is-a @typename.  @obj can refer to an + * object or an interface associated with an object. + * + * Returns: This function returns @obj on success or #NULL on failure. + */ +Object *object_dynamic_cast(Object *obj, const char *typename); + +/** + * object_dynamic_cast_assert: + * + * See object_dynamic_cast() for a description of the parameters of this + * function.  The only difference in behavior is that this function asserts + * instead of returning #NULL on failure if QOM cast debugging is enabled. + * This function is not meant to be called directly, but only through + * the wrapper macro OBJECT_CHECK. + */ +Object *object_dynamic_cast_assert(Object *obj, const char *typename, +                                   const char *file, int line, const char *func); + +/** + * object_get_class: + * @obj: A derivative of #Object + * + * Returns: The #ObjectClass of the type associated with @obj. + */ +ObjectClass *object_get_class(Object *obj); + +/** + * object_get_typename: + * @obj: A derivative of #Object. + * + * Returns: The QOM typename of @obj. + */ +const char *object_get_typename(Object *obj); + +/** + * type_register_static: + * @info: The #TypeInfo of the new type. + * + * @info and all of the strings it points to should exist for the life time + * that the type is registered. + * + * Returns: 0 on failure, the new #Type on success. + */ +Type type_register_static(const TypeInfo *info); + +/** + * type_register: + * @info: The #TypeInfo of the new type + * + * Unlike type_register_static(), this call does not require @info or its + * string members to continue to exist after the call returns. + * + * Returns: 0 on failure, the new #Type on success. + */ +Type type_register(const TypeInfo *info); + +/** + * object_class_dynamic_cast_assert: + * @klass: The #ObjectClass to attempt to cast. + * @typename: The QOM typename of the class to cast to. + * + * See object_class_dynamic_cast() for a description of the parameters + * of this function.  The only difference in behavior is that this function + * asserts instead of returning #NULL on failure if QOM cast debugging is + * enabled.  This function is not meant to be called directly, but only through + * the wrapper macros OBJECT_CLASS_CHECK and INTERFACE_CHECK. + */ +ObjectClass *object_class_dynamic_cast_assert(ObjectClass *klass, +                                              const char *typename, +                                              const char *file, int line, +                                              const char *func); + +/** + * object_class_dynamic_cast: + * @klass: The #ObjectClass to attempt to cast. + * @typename: The QOM typename of the class to cast to. + * + * Returns: If @typename is a class, this function returns @klass if + * @typename is a subtype of @klass, else returns #NULL. + * + * If @typename is an interface, this function returns the interface + * definition for @klass if @klass implements it unambiguously; #NULL + * is returned if @klass does not implement the interface or if multiple + * classes or interfaces on the hierarchy leading to @klass implement + * it.  (FIXME: perhaps this can be detected at type definition time?) + */ +ObjectClass *object_class_dynamic_cast(ObjectClass *klass, +                                       const char *typename); + +/** + * object_class_get_parent: + * @klass: The class to obtain the parent for. + * + * Returns: The parent for @klass or %NULL if none. + */ +ObjectClass *object_class_get_parent(ObjectClass *klass); + +/** + * object_class_get_name: + * @klass: The class to obtain the QOM typename for. + * + * Returns: The QOM typename for @klass. + */ +const char *object_class_get_name(ObjectClass *klass); + +/** + * object_class_is_abstract: + * @klass: The class to obtain the abstractness for. + * + * Returns: %true if @klass is abstract, %false otherwise. + */ +bool object_class_is_abstract(ObjectClass *klass); + +/** + * object_class_by_name: + * @typename: The QOM typename to obtain the class for. + * + * Returns: The class for @typename or %NULL if not found. + */ +ObjectClass *object_class_by_name(const char *typename); + +void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), +                          const char *implements_type, bool include_abstract, +                          void *opaque); + +/** + * object_class_get_list: + * @implements_type: The type to filter for, including its derivatives. + * @include_abstract: Whether to include abstract classes. + * + * Returns: A singly-linked list of the classes in reverse hashtable order. + */ +GSList *object_class_get_list(const char *implements_type, +                              bool include_abstract); + +/** + * object_ref: + * @obj: the object + * + * Increase the reference count of a object.  A object cannot be freed as long + * as its reference count is greater than zero. + */ +void object_ref(Object *obj); + +/** + * qdef_unref: + * @obj: the object + * + * Decrease the reference count of a object.  A object cannot be freed as long + * as its reference count is greater than zero. + */ +void object_unref(Object *obj); + +/** + * object_property_add: + * @obj: the object to add a property to + * @name: the name of the property.  This can contain any character except for + *  a forward slash.  In general, you should use hyphens '-' instead of + *  underscores '_' when naming properties. + * @type: the type name of the property.  This namespace is pretty loosely + *   defined.  Sub namespaces are constructed by using a prefix and then + *   to angle brackets.  For instance, the type 'virtio-net-pci' in the + *   'link' namespace would be 'link<virtio-net-pci>'. + * @get: The getter to be called to read a property.  If this is NULL, then + *   the property cannot be read. + * @set: the setter to be called to write a property.  If this is NULL, + *   then the property cannot be written. + * @release: called when the property is removed from the object.  This is + *   meant to allow a property to free its opaque upon object + *   destruction.  This may be NULL. + * @opaque: an opaque pointer to pass to the callbacks for the property + * @errp: returns an error if this function fails + * + * Returns: The #ObjectProperty; this can be used to set the @resolve + * callback for child and link properties. + */ +ObjectProperty *object_property_add(Object *obj, const char *name, +                                    const char *type, +                                    ObjectPropertyAccessor *get, +                                    ObjectPropertyAccessor *set, +                                    ObjectPropertyRelease *release, +                                    void *opaque, Error **errp); + +void object_property_del(Object *obj, const char *name, Error **errp); + +/** + * object_property_find: + * @obj: the object + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Look up a property for an object and return its #ObjectProperty if found. + */ +ObjectProperty *object_property_find(Object *obj, const char *name, +                                     Error **errp); + +void object_unparent(Object *obj); + +/** + * object_property_get: + * @obj: the object + * @v: the visitor that will receive the property value.  This should be an + *   Output visitor and the data will be written with @name as the name. + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Reads a property from a object. + */ +void object_property_get(Object *obj, struct Visitor *v, const char *name, +                         Error **errp); + +/** + * object_property_set_str: + * @value: the value to be written to the property + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Writes a string value to a property. + */ +void object_property_set_str(Object *obj, const char *value, +                             const char *name, Error **errp); + +/** + * object_property_get_str: + * @obj: the object + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Returns: the value of the property, converted to a C string, or NULL if + * an error occurs (including when the property value is not a string). + * The caller should free the string. + */ +char *object_property_get_str(Object *obj, const char *name, +                              Error **errp); + +/** + * object_property_set_link: + * @value: the value to be written to the property + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Writes an object's canonical path to a property. + */ +void object_property_set_link(Object *obj, Object *value, +                              const char *name, Error **errp); + +/** + * object_property_get_link: + * @obj: the object + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Returns: the value of the property, resolved from a path to an Object, + * or NULL if an error occurs (including when the property value is not a + * string or not a valid object path). + */ +Object *object_property_get_link(Object *obj, const char *name, +                                 Error **errp); + +/** + * object_property_set_bool: + * @value: the value to be written to the property + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Writes a bool value to a property. + */ +void object_property_set_bool(Object *obj, bool value, +                              const char *name, Error **errp); + +/** + * object_property_get_bool: + * @obj: the object + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Returns: the value of the property, converted to a boolean, or NULL if + * an error occurs (including when the property value is not a bool). + */ +bool object_property_get_bool(Object *obj, const char *name, +                              Error **errp); + +/** + * object_property_set_int: + * @value: the value to be written to the property + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Writes an integer value to a property. + */ +void object_property_set_int(Object *obj, int64_t value, +                             const char *name, Error **errp); + +/** + * object_property_get_int: + * @obj: the object + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Returns: the value of the property, converted to an integer, or NULL if + * an error occurs (including when the property value is not an integer). + */ +int64_t object_property_get_int(Object *obj, const char *name, +                                Error **errp); + +/** + * object_property_get_enum: + * @obj: the object + * @name: the name of the property + * @typename: the name of the enum data type + * @errp: returns an error if this function fails + * + * Returns: the value of the property, converted to an integer, or + * undefined if an error occurs (including when the property value is not + * an enum). + */ +int object_property_get_enum(Object *obj, const char *name, +                             const char *typename, Error **errp); + +/** + * object_property_get_uint16List: + * @obj: the object + * @name: the name of the property + * @list: the returned int list + * @errp: returns an error if this function fails + * + * Returns: the value of the property, converted to integers, or + * undefined if an error occurs (including when the property value is not + * an list of integers). + */ +void object_property_get_uint16List(Object *obj, const char *name, +                                    uint16List **list, Error **errp); + +/** + * object_property_set: + * @obj: the object + * @v: the visitor that will be used to write the property value.  This should + *   be an Input visitor and the data will be first read with @name as the + *   name and then written as the property value. + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Writes a property to a object. + */ +void object_property_set(Object *obj, struct Visitor *v, const char *name, +                         Error **errp); + +/** + * object_property_parse: + * @obj: the object + * @string: the string that will be used to parse the property value. + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Parses a string and writes the result into a property of an object. + */ +void object_property_parse(Object *obj, const char *string, +                           const char *name, Error **errp); + +/** + * object_property_print: + * @obj: the object + * @name: the name of the property + * @human: if true, print for human consumption + * @errp: returns an error if this function fails + * + * Returns a string representation of the value of the property.  The + * caller shall free the string. + */ +char *object_property_print(Object *obj, const char *name, bool human, +                            Error **errp); + +/** + * object_property_get_type: + * @obj: the object + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Returns:  The type name of the property. + */ +const char *object_property_get_type(Object *obj, const char *name, +                                     Error **errp); + +/** + * object_get_root: + * + * Returns: the root object of the composition tree + */ +Object *object_get_root(void); + + +/** + * object_get_objects_root: + * + * Get the container object that holds user created + * object instances. This is the object at path + * "/objects" + * + * Returns: the user object container + */ +Object *object_get_objects_root(void); + +/** + * object_get_canonical_path_component: + * + * Returns: The final component in the object's canonical path.  The canonical + * path is the path within the composition tree starting from the root. + */ +gchar *object_get_canonical_path_component(Object *obj); + +/** + * object_get_canonical_path: + * + * Returns: The canonical path for a object.  This is the path within the + * composition tree starting from the root. + */ +gchar *object_get_canonical_path(Object *obj); + +/** + * object_resolve_path: + * @path: the path to resolve + * @ambiguous: returns true if the path resolution failed because of an + *   ambiguous match + * + * There are two types of supported paths--absolute paths and partial paths. + *  + * Absolute paths are derived from the root object and can follow child<> or + * link<> properties.  Since they can follow link<> properties, they can be + * arbitrarily long.  Absolute paths look like absolute filenames and are + * prefixed with a leading slash. + *  + * Partial paths look like relative filenames.  They do not begin with a + * prefix.  The matching rules for partial paths are subtle but designed to make + * specifying objects easy.  At each level of the composition tree, the partial + * path is matched as an absolute path.  The first match is not returned.  At + * least two matches are searched for.  A successful result is only returned if + * only one match is found.  If more than one match is found, a flag is + * returned to indicate that the match was ambiguous. + * + * Returns: The matched object or NULL on path lookup failure. + */ +Object *object_resolve_path(const char *path, bool *ambiguous); + +/** + * object_resolve_path_type: + * @path: the path to resolve + * @typename: the type to look for. + * @ambiguous: returns true if the path resolution failed because of an + *   ambiguous match + * + * This is similar to object_resolve_path.  However, when looking for a + * partial path only matches that implement the given type are considered. + * This restricts the search and avoids spuriously flagging matches as + * ambiguous. + * + * For both partial and absolute paths, the return value goes through + * a dynamic cast to @typename.  This is important if either the link, + * or the typename itself are of interface types. + * + * Returns: The matched object or NULL on path lookup failure. + */ +Object *object_resolve_path_type(const char *path, const char *typename, +                                 bool *ambiguous); + +/** + * object_resolve_path_component: + * @parent: the object in which to resolve the path + * @part: the component to resolve. + * + * This is similar to object_resolve_path with an absolute path, but it + * only resolves one element (@part) and takes the others from @parent. + * + * Returns: The resolved object or NULL on path lookup failure. + */ +Object *object_resolve_path_component(Object *parent, const gchar *part); + +/** + * object_property_add_child: + * @obj: the object to add a property to + * @name: the name of the property + * @child: the child object + * @errp: if an error occurs, a pointer to an area to store the area + * + * Child properties form the composition tree.  All objects need to be a child + * of another object.  Objects can only be a child of one object. + * + * There is no way for a child to determine what its parent is.  It is not + * a bidirectional relationship.  This is by design. + * + * The value of a child property as a C string will be the child object's + * canonical path. It can be retrieved using object_property_get_str(). + * The child object itself can be retrieved using object_property_get_link(). + */ +void object_property_add_child(Object *obj, const char *name, +                               Object *child, Error **errp); + +typedef enum { +    /* Unref the link pointer when the property is deleted */ +    OBJ_PROP_LINK_UNREF_ON_RELEASE = 0x1, +} ObjectPropertyLinkFlags; + +/** + * object_property_allow_set_link: + * + * The default implementation of the object_property_add_link() check() + * callback function.  It allows the link property to be set and never returns + * an error. + */ +void object_property_allow_set_link(Object *, const char *, +                                    Object *, Error **); + +/** + * object_property_add_link: + * @obj: the object to add a property to + * @name: the name of the property + * @type: the qobj type of the link + * @child: a pointer to where the link object reference is stored + * @check: callback to veto setting or NULL if the property is read-only + * @flags: additional options for the link + * @errp: if an error occurs, a pointer to an area to store the area + * + * Links establish relationships between objects.  Links are unidirectional + * although two links can be combined to form a bidirectional relationship + * between objects. + * + * Links form the graph in the object model. + * + * The <code>@check()</code> callback is invoked when + * object_property_set_link() is called and can raise an error to prevent the + * link being set.  If <code>@check</code> is NULL, the property is read-only + * and cannot be set. + * + * Ownership of the pointer that @child points to is transferred to the + * link property.  The reference count for <code>*@child</code> is + * managed by the property from after the function returns till the + * property is deleted with object_property_del().  If the + * <code>@flags</code> <code>OBJ_PROP_LINK_UNREF_ON_RELEASE</code> bit is set, + * the reference count is decremented when the property is deleted. + */ +void object_property_add_link(Object *obj, const char *name, +                              const char *type, Object **child, +                              void (*check)(Object *obj, const char *name, +                                            Object *val, Error **errp), +                              ObjectPropertyLinkFlags flags, +                              Error **errp); + +/** + * object_property_add_str: + * @obj: the object to add a property to + * @name: the name of the property + * @get: the getter or NULL if the property is write-only.  This function must + *   return a string to be freed by g_free(). + * @set: the setter or NULL if the property is read-only + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add a string property using getters/setters.  This function will add a + * property of type 'string'. + */ +void object_property_add_str(Object *obj, const char *name, +                             char *(*get)(Object *, Error **), +                             void (*set)(Object *, const char *, Error **), +                             Error **errp); + +/** + * object_property_add_bool: + * @obj: the object to add a property to + * @name: the name of the property + * @get: the getter or NULL if the property is write-only. + * @set: the setter or NULL if the property is read-only + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add a bool property using getters/setters.  This function will add a + * property of type 'bool'. + */ +void object_property_add_bool(Object *obj, const char *name, +                              bool (*get)(Object *, Error **), +                              void (*set)(Object *, bool, Error **), +                              Error **errp); + +/** + * object_property_add_enum: + * @obj: the object to add a property to + * @name: the name of the property + * @typename: the name of the enum data type + * @get: the getter or %NULL if the property is write-only. + * @set: the setter or %NULL if the property is read-only + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add an enum property using getters/setters.  This function will add a + * property of type '@typename'. + */ +void object_property_add_enum(Object *obj, const char *name, +                              const char *typename, +                              const char * const *strings, +                              int (*get)(Object *, Error **), +                              void (*set)(Object *, int, Error **), +                              Error **errp); + +/** + * object_property_add_tm: + * @obj: the object to add a property to + * @name: the name of the property + * @get: the getter or NULL if the property is write-only. + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add a read-only struct tm valued property using a getter function. + * This function will add a property of type 'struct tm'. + */ +void object_property_add_tm(Object *obj, const char *name, +                            void (*get)(Object *, struct tm *, Error **), +                            Error **errp); + +/** + * object_property_add_uint8_ptr: + * @obj: the object to add a property to + * @name: the name of the property + * @v: pointer to value + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add an integer property in memory.  This function will add a + * property of type 'uint8'. + */ +void object_property_add_uint8_ptr(Object *obj, const char *name, +                                   const uint8_t *v, Error **errp); + +/** + * object_property_add_uint16_ptr: + * @obj: the object to add a property to + * @name: the name of the property + * @v: pointer to value + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add an integer property in memory.  This function will add a + * property of type 'uint16'. + */ +void object_property_add_uint16_ptr(Object *obj, const char *name, +                                    const uint16_t *v, Error **errp); + +/** + * object_property_add_uint32_ptr: + * @obj: the object to add a property to + * @name: the name of the property + * @v: pointer to value + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add an integer property in memory.  This function will add a + * property of type 'uint32'. + */ +void object_property_add_uint32_ptr(Object *obj, const char *name, +                                    const uint32_t *v, Error **errp); + +/** + * object_property_add_uint64_ptr: + * @obj: the object to add a property to + * @name: the name of the property + * @v: pointer to value + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add an integer property in memory.  This function will add a + * property of type 'uint64'. + */ +void object_property_add_uint64_ptr(Object *obj, const char *name, +                                    const uint64_t *v, Error **Errp); + +/** + * object_property_add_alias: + * @obj: the object to add a property to + * @name: the name of the property + * @target_obj: the object to forward property access to + * @target_name: the name of the property on the forwarded object + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add an alias for a property on an object.  This function will add a property + * of the same type as the forwarded property. + * + * The caller must ensure that <code>@target_obj</code> stays alive as long as + * this property exists.  In the case of a child object or an alias on the same + * object this will be the case.  For aliases to other objects the caller is + * responsible for taking a reference. + */ +void object_property_add_alias(Object *obj, const char *name, +                               Object *target_obj, const char *target_name, +                               Error **errp); + +/** + * object_property_add_const_link: + * @obj: the object to add a property to + * @name: the name of the property + * @target: the object to be referred by the link + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add an unmodifiable link for a property on an object.  This function will + * add a property of type link<TYPE> where TYPE is the type of @target. + * + * The caller must ensure that @target stays alive as long as + * this property exists.  In the case @target is a child of @obj, + * this will be the case.  Otherwise, the caller is responsible for + * taking a reference. + */ +void object_property_add_const_link(Object *obj, const char *name, +                                    Object *target, Error **errp); + +/** + * object_property_set_description: + * @obj: the object owning the property + * @name: the name of the property + * @description: the description of the property on the object + * @errp: if an error occurs, a pointer to an area to store the error + * + * Set an object property's description. + * + */ +void object_property_set_description(Object *obj, const char *name, +                                     const char *description, Error **errp); + +/** + * object_child_foreach: + * @obj: the object whose children will be navigated + * @fn: the iterator function to be called + * @opaque: an opaque value that will be passed to the iterator + * + * Call @fn passing each child of @obj and @opaque to it, until @fn returns + * non-zero. + * + * Returns: The last value returned by @fn, or 0 if there is no child. + */ +int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), +                         void *opaque); + +/** + * container_get: + * @root: root of the #path, e.g., object_get_root() + * @path: path to the container + * + * Return a container object whose path is @path.  Create more containers + * along the path if necessary. + * + * Returns: the container object. + */ +Object *container_get(Object *root, const char *path); + + +#endif diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h new file mode 100644 index 00000000..283ae0db --- /dev/null +++ b/include/qom/object_interfaces.h @@ -0,0 +1,75 @@ +#ifndef OBJECT_INTERFACES_H +#define OBJECT_INTERFACES_H + +#include "qom/object.h" + +#define TYPE_USER_CREATABLE "user-creatable" + +#define USER_CREATABLE_CLASS(klass) \ +     OBJECT_CLASS_CHECK(UserCreatableClass, (klass), \ +                        TYPE_USER_CREATABLE) +#define USER_CREATABLE_GET_CLASS(obj) \ +     OBJECT_GET_CLASS(UserCreatableClass, (obj), \ +                      TYPE_USER_CREATABLE) +#define USER_CREATABLE(obj) \ +     INTERFACE_CHECK(UserCreatable, (obj), \ +                     TYPE_USER_CREATABLE) + + +typedef struct UserCreatable { +    /* <private> */ +    Object Parent; +} UserCreatable; + +/** + * UserCreatableClass: + * @parent_class: the base class + * @complete: callback to be called after @obj's properties are set. + * @can_be_deleted: callback to be called before an object is removed + * to check if @obj can be removed safely. + * + * Interface is designed to work with -object/object-add/object_add + * commands. + * Interface is mandatory for objects that are designed to be user + * creatable (i.e. -object/object-add/object_add, will accept only + * objects that inherit this interface). + * + * Interface also provides an optional ability to do the second + * stage * initialization of the object after its properties were + * set. + * + * For objects created without using -object/object-add/object_add, + * @user_creatable_complete() wrapper should be called manually if + * object's type implements USER_CREATABLE interface and needs + * complete() callback to be called. + */ +typedef struct UserCreatableClass { +    /* <private> */ +    InterfaceClass parent_class; + +    /* <public> */ +    void (*complete)(UserCreatable *uc, Error **errp); +    bool (*can_be_deleted)(UserCreatable *uc, Error **errp); +} UserCreatableClass; + +/** + * user_creatable_complete: + * @obj: the object whose complete() method is called if defined + * @errp: if an error occurs, a pointer to an area to store the error + * + * Wrapper to call complete() method if one of types it's inherited + * from implements USER_CREATABLE interface, otherwise the call does + * nothing. + */ +void user_creatable_complete(Object *obj, Error **errp); + +/** + * user_creatable_can_be_deleted: + * @uc: the object whose can_be_deleted() method is called if implemented + * @errp: if an error occurs, a pointer to an area to store the error + * + * Wrapper to call can_be_deleted() method if one of types it's inherited + * from implements USER_CREATABLE interface. + */ +bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp); +#endif diff --git a/include/qom/qom-qobject.h b/include/qom/qom-qobject.h new file mode 100644 index 00000000..77cd717e --- /dev/null +++ b/include/qom/qom-qobject.h @@ -0,0 +1,42 @@ +/* + * QEMU Object Model - QObject wrappers + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Author: Paolo Bonzini <pbonzini@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_QOM_QOBJECT_H +#define QEMU_QOM_QOBJECT_H + +#include "qom/object.h" + +/* + * object_property_get_qobject: + * @obj: the object + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Returns: the value of the property, converted to QObject, or NULL if + * an error occurs. + */ +struct QObject *object_property_get_qobject(Object *obj, const char *name, +                                            struct Error **errp); + +/** + * object_property_set_qobject: + * @obj: the object + * @ret: The value that will be written to the property. + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Writes a property to a object. + */ +void object_property_set_qobject(Object *obj, struct QObject *qobj, +                                 const char *name, struct Error **errp); + +#endif  | 
