cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

qapi-visit-core.c (10621B)


      1/*
      2 * Core Definitions for QAPI Visitor Classes
      3 *
      4 * Copyright (C) 2012-2016 Red Hat, Inc.
      5 * Copyright IBM, Corp. 2011
      6 *
      7 * Authors:
      8 *  Anthony Liguori   <aliguori@us.ibm.com>
      9 *
     10 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
     11 * See the COPYING.LIB file in the top-level directory.
     12 *
     13 */
     14
     15#include "qemu/osdep.h"
     16#include "qapi/error.h"
     17#include "qapi/qmp/qerror.h"
     18#include "qapi/visitor.h"
     19#include "qapi/visitor-impl.h"
     20#include "trace.h"
     21
     22void visit_complete(Visitor *v, void *opaque)
     23{
     24    assert(v->type != VISITOR_OUTPUT || v->complete);
     25    trace_visit_complete(v, opaque);
     26    if (v->complete) {
     27        v->complete(v, opaque);
     28    }
     29}
     30
     31void visit_free(Visitor *v)
     32{
     33    trace_visit_free(v);
     34    if (v) {
     35        v->free(v);
     36    }
     37}
     38
     39bool visit_start_struct(Visitor *v, const char *name, void **obj,
     40                        size_t size, Error **errp)
     41{
     42    bool ok;
     43
     44    trace_visit_start_struct(v, name, obj, size);
     45    if (obj) {
     46        assert(size);
     47        assert(!(v->type & VISITOR_OUTPUT) || *obj);
     48    }
     49    ok = v->start_struct(v, name, obj, size, errp);
     50    if (obj && (v->type & VISITOR_INPUT)) {
     51        assert(ok != !*obj);
     52    }
     53    return ok;
     54}
     55
     56bool visit_check_struct(Visitor *v, Error **errp)
     57{
     58    trace_visit_check_struct(v);
     59    return v->check_struct ? v->check_struct(v, errp) : true;
     60}
     61
     62void visit_end_struct(Visitor *v, void **obj)
     63{
     64    trace_visit_end_struct(v, obj);
     65    v->end_struct(v, obj);
     66}
     67
     68bool visit_start_list(Visitor *v, const char *name, GenericList **list,
     69                      size_t size, Error **errp)
     70{
     71    bool ok;
     72
     73    assert(!list || size >= sizeof(GenericList));
     74    trace_visit_start_list(v, name, list, size);
     75    ok = v->start_list(v, name, list, size, errp);
     76    if (list && (v->type & VISITOR_INPUT)) {
     77        assert(ok || !*list);
     78    }
     79    return ok;
     80}
     81
     82GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
     83{
     84    assert(tail && size >= sizeof(GenericList));
     85    trace_visit_next_list(v, tail, size);
     86    return v->next_list(v, tail, size);
     87}
     88
     89bool visit_check_list(Visitor *v, Error **errp)
     90{
     91    trace_visit_check_list(v);
     92    return v->check_list ? v->check_list(v, errp) : true;
     93}
     94
     95void visit_end_list(Visitor *v, void **obj)
     96{
     97    trace_visit_end_list(v, obj);
     98    v->end_list(v, obj);
     99}
    100
    101bool visit_start_alternate(Visitor *v, const char *name,
    102                           GenericAlternate **obj, size_t size,
    103                           Error **errp)
    104{
    105    bool ok;
    106
    107    assert(obj && size >= sizeof(GenericAlternate));
    108    assert(!(v->type & VISITOR_OUTPUT) || *obj);
    109    trace_visit_start_alternate(v, name, obj, size);
    110    if (!v->start_alternate) {
    111        assert(!(v->type & VISITOR_INPUT));
    112        return true;
    113    }
    114    ok = v->start_alternate(v, name, obj, size, errp);
    115    if (v->type & VISITOR_INPUT) {
    116        assert(ok != !*obj);
    117    }
    118    return ok;
    119}
    120
    121void visit_end_alternate(Visitor *v, void **obj)
    122{
    123    trace_visit_end_alternate(v, obj);
    124    if (v->end_alternate) {
    125        v->end_alternate(v, obj);
    126    }
    127}
    128
    129bool visit_optional(Visitor *v, const char *name, bool *present)
    130{
    131    trace_visit_optional(v, name, present);
    132    if (v->optional) {
    133        v->optional(v, name, present);
    134    }
    135    return *present;
    136}
    137
    138bool visit_deprecated_accept(Visitor *v, const char *name, Error **errp)
    139{
    140    trace_visit_deprecated_accept(v, name);
    141    if (v->deprecated_accept) {
    142        return v->deprecated_accept(v, name, errp);
    143    }
    144    return true;
    145}
    146
    147bool visit_deprecated(Visitor *v, const char *name)
    148{
    149    trace_visit_deprecated(v, name);
    150    if (v->deprecated) {
    151        return v->deprecated(v, name);
    152    }
    153    return true;
    154}
    155
    156bool visit_is_input(Visitor *v)
    157{
    158    return v->type == VISITOR_INPUT;
    159}
    160
    161bool visit_is_dealloc(Visitor *v)
    162{
    163    return v->type == VISITOR_DEALLOC;
    164}
    165
    166bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
    167{
    168    assert(obj);
    169    trace_visit_type_int(v, name, obj);
    170    return v->type_int64(v, name, obj, errp);
    171}
    172
    173static bool visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
    174                             uint64_t max, const char *type, Error **errp)
    175{
    176    uint64_t value = *obj;
    177
    178    assert(v->type == VISITOR_INPUT || value <= max);
    179
    180    if (!v->type_uint64(v, name, &value, errp)) {
    181        return false;
    182    }
    183    if (value > max) {
    184        assert(v->type == VISITOR_INPUT);
    185        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
    186                   name ? name : "null", type);
    187        return false;
    188    }
    189    *obj = value;
    190    return true;
    191}
    192
    193bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
    194                      Error **errp)
    195{
    196    uint64_t value;
    197    bool ok;
    198
    199    trace_visit_type_uint8(v, name, obj);
    200    value = *obj;
    201    ok = visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
    202    *obj = value;
    203    return ok;
    204}
    205
    206bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
    207                       Error **errp)
    208{
    209    uint64_t value;
    210    bool ok;
    211
    212    trace_visit_type_uint16(v, name, obj);
    213    value = *obj;
    214    ok = visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp);
    215    *obj = value;
    216    return ok;
    217}
    218
    219bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
    220                       Error **errp)
    221{
    222    uint64_t value;
    223    bool ok;
    224
    225    trace_visit_type_uint32(v, name, obj);
    226    value = *obj;
    227    ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
    228    *obj = value;
    229    return ok;
    230}
    231
    232bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
    233                       Error **errp)
    234{
    235    assert(obj);
    236    trace_visit_type_uint64(v, name, obj);
    237    return v->type_uint64(v, name, obj, errp);
    238}
    239
    240static bool visit_type_intN(Visitor *v, int64_t *obj, const char *name,
    241                            int64_t min, int64_t max, const char *type,
    242                            Error **errp)
    243{
    244    int64_t value = *obj;
    245
    246    assert(v->type == VISITOR_INPUT || (value >= min && value <= max));
    247
    248    if (!v->type_int64(v, name, &value, errp)) {
    249        return false;
    250    }
    251    if (value < min || value > max) {
    252        assert(v->type == VISITOR_INPUT);
    253        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
    254                   name ? name : "null", type);
    255        return false;
    256    }
    257    *obj = value;
    258    return true;
    259}
    260
    261bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp)
    262{
    263    int64_t value;
    264    bool ok;
    265
    266    trace_visit_type_int8(v, name, obj);
    267    value = *obj;
    268    ok = visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp);
    269    *obj = value;
    270    return ok;
    271}
    272
    273bool visit_type_int16(Visitor *v, const char *name, int16_t *obj,
    274                      Error **errp)
    275{
    276    int64_t value;
    277    bool ok;
    278
    279    trace_visit_type_int16(v, name, obj);
    280    value = *obj;
    281    ok = visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t",
    282                         errp);
    283    *obj = value;
    284    return ok;
    285}
    286
    287bool visit_type_int32(Visitor *v, const char *name, int32_t *obj,
    288                      Error **errp)
    289{
    290    int64_t value;
    291    bool ok;
    292
    293    trace_visit_type_int32(v, name, obj);
    294    value = *obj;
    295    ok = visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t",
    296                        errp);
    297    *obj = value;
    298    return ok;
    299}
    300
    301bool visit_type_int64(Visitor *v, const char *name, int64_t *obj,
    302                      Error **errp)
    303{
    304    assert(obj);
    305    trace_visit_type_int64(v, name, obj);
    306    return v->type_int64(v, name, obj, errp);
    307}
    308
    309bool visit_type_size(Visitor *v, const char *name, uint64_t *obj,
    310                     Error **errp)
    311{
    312    assert(obj);
    313    trace_visit_type_size(v, name, obj);
    314    if (v->type_size) {
    315        return v->type_size(v, name, obj, errp);
    316    }
    317    return v->type_uint64(v, name, obj, errp);
    318}
    319
    320bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
    321{
    322    assert(obj);
    323    trace_visit_type_bool(v, name, obj);
    324    return v->type_bool(v, name, obj, errp);
    325}
    326
    327bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
    328{
    329    bool ok;
    330
    331    assert(obj);
    332    /* TODO: Fix callers to not pass NULL when they mean "", so that we
    333     * can enable:
    334    assert(!(v->type & VISITOR_OUTPUT) || *obj);
    335     */
    336    trace_visit_type_str(v, name, obj);
    337    ok = v->type_str(v, name, obj, errp);
    338    if (v->type & VISITOR_INPUT) {
    339        assert(ok != !*obj);
    340    }
    341    return ok;
    342}
    343
    344bool visit_type_number(Visitor *v, const char *name, double *obj,
    345                       Error **errp)
    346{
    347    assert(obj);
    348    trace_visit_type_number(v, name, obj);
    349    return v->type_number(v, name, obj, errp);
    350}
    351
    352bool visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
    353{
    354    bool ok;
    355
    356    assert(obj);
    357    assert(v->type != VISITOR_OUTPUT || *obj);
    358    trace_visit_type_any(v, name, obj);
    359    ok = v->type_any(v, name, obj, errp);
    360    if (v->type == VISITOR_INPUT) {
    361        assert(ok != !*obj);
    362    }
    363    return ok;
    364}
    365
    366bool visit_type_null(Visitor *v, const char *name, QNull **obj,
    367                     Error **errp)
    368{
    369    trace_visit_type_null(v, name, obj);
    370    return v->type_null(v, name, obj, errp);
    371}
    372
    373static bool output_type_enum(Visitor *v, const char *name, int *obj,
    374                             const QEnumLookup *lookup, Error **errp)
    375{
    376    int value = *obj;
    377    char *enum_str;
    378
    379    enum_str = (char *)qapi_enum_lookup(lookup, value);
    380    return visit_type_str(v, name, &enum_str, errp);
    381}
    382
    383static bool input_type_enum(Visitor *v, const char *name, int *obj,
    384                            const QEnumLookup *lookup, Error **errp)
    385{
    386    int64_t value;
    387    char *enum_str;
    388
    389    if (!visit_type_str(v, name, &enum_str, errp)) {
    390        return false;
    391    }
    392
    393    value = qapi_enum_parse(lookup, enum_str, -1, NULL);
    394    if (value < 0) {
    395        error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
    396        g_free(enum_str);
    397        return false;
    398    }
    399
    400    g_free(enum_str);
    401    *obj = value;
    402    return true;
    403}
    404
    405bool visit_type_enum(Visitor *v, const char *name, int *obj,
    406                     const QEnumLookup *lookup, Error **errp)
    407{
    408    assert(obj && lookup);
    409    trace_visit_type_enum(v, name, obj);
    410    switch (v->type) {
    411    case VISITOR_INPUT:
    412        return input_type_enum(v, name, obj, lookup, errp);
    413    case VISITOR_OUTPUT:
    414        return output_type_enum(v, name, obj, lookup, errp);
    415    case VISITOR_CLONE:
    416        /* nothing further to do, scalar value was already copied by
    417         * g_memdup() during visit_start_*() */
    418        return true;
    419    case VISITOR_DEALLOC:
    420        /* nothing to deallocate for a scalar */
    421        return true;
    422    default:
    423        abort();
    424    }
    425}