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-forward-visitor.c (9240B)


      1/*
      2 * Forward Visitor
      3 *
      4 * Copyright (C) 2021 Red Hat, Inc.
      5 *
      6 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
      7 * See the COPYING.LIB file in the top-level directory.
      8 *
      9 */
     10
     11#include "qemu/osdep.h"
     12#include "qapi/compat-policy.h"
     13#include "qapi/error.h"
     14#include "qapi/forward-visitor.h"
     15#include "qapi/visitor-impl.h"
     16#include "qemu/queue.h"
     17#include "qapi/qmp/qjson.h"
     18#include "qapi/qmp/qbool.h"
     19#include "qapi/qmp/qdict.h"
     20#include "qapi/qmp/qerror.h"
     21#include "qapi/qmp/qlist.h"
     22#include "qapi/qmp/qnull.h"
     23#include "qapi/qmp/qnum.h"
     24#include "qapi/qmp/qstring.h"
     25#include "qemu/cutils.h"
     26#include "qemu/option.h"
     27
     28struct ForwardFieldVisitor {
     29    Visitor visitor;
     30
     31    Visitor *target;
     32    char *from;
     33    char *to;
     34
     35    int depth;
     36};
     37
     38static ForwardFieldVisitor *to_ffv(Visitor *v)
     39{
     40    return container_of(v, ForwardFieldVisitor, visitor);
     41}
     42
     43static bool forward_field_translate_name(ForwardFieldVisitor *v, const char **name,
     44                                         Error **errp)
     45{
     46    if (v->depth) {
     47        return true;
     48    }
     49    if (g_str_equal(*name, v->from)) {
     50        *name = v->to;
     51        return true;
     52    }
     53    error_setg(errp, QERR_MISSING_PARAMETER, *name);
     54    return false;
     55}
     56
     57static bool forward_field_check_struct(Visitor *v, Error **errp)
     58{
     59    ForwardFieldVisitor *ffv = to_ffv(v);
     60
     61    return visit_check_struct(ffv->target, errp);
     62}
     63
     64static bool forward_field_start_struct(Visitor *v, const char *name, void **obj,
     65                                       size_t size, Error **errp)
     66{
     67    ForwardFieldVisitor *ffv = to_ffv(v);
     68
     69    if (!forward_field_translate_name(ffv, &name, errp)) {
     70        return false;
     71    }
     72    if (!visit_start_struct(ffv->target, name, obj, size, errp)) {
     73        return false;
     74    }
     75    ffv->depth++;
     76    return true;
     77}
     78
     79static void forward_field_end_struct(Visitor *v, void **obj)
     80{
     81    ForwardFieldVisitor *ffv = to_ffv(v);
     82
     83    assert(ffv->depth);
     84    ffv->depth--;
     85    visit_end_struct(ffv->target, obj);
     86}
     87
     88static bool forward_field_start_list(Visitor *v, const char *name,
     89                                     GenericList **list, size_t size,
     90                                     Error **errp)
     91{
     92    ForwardFieldVisitor *ffv = to_ffv(v);
     93
     94    if (!forward_field_translate_name(ffv, &name, errp)) {
     95        return false;
     96    }
     97    ffv->depth++;
     98    return visit_start_list(ffv->target, name, list, size, errp);
     99}
    100
    101static GenericList *forward_field_next_list(Visitor *v, GenericList *tail,
    102                                            size_t size)
    103{
    104    ForwardFieldVisitor *ffv = to_ffv(v);
    105
    106    assert(ffv->depth);
    107    return visit_next_list(ffv->target, tail, size);
    108}
    109
    110static bool forward_field_check_list(Visitor *v, Error **errp)
    111{
    112    ForwardFieldVisitor *ffv = to_ffv(v);
    113
    114    assert(ffv->depth);
    115    return visit_check_list(ffv->target, errp);
    116}
    117
    118static void forward_field_end_list(Visitor *v, void **obj)
    119{
    120    ForwardFieldVisitor *ffv = to_ffv(v);
    121
    122    assert(ffv->depth);
    123    ffv->depth--;
    124    visit_end_list(ffv->target, obj);
    125}
    126
    127static bool forward_field_start_alternate(Visitor *v, const char *name,
    128                                          GenericAlternate **obj, size_t size,
    129                                          Error **errp)
    130{
    131    ForwardFieldVisitor *ffv = to_ffv(v);
    132
    133    if (!forward_field_translate_name(ffv, &name, errp)) {
    134        return false;
    135    }
    136    /*
    137     * The name passed to start_alternate is used also in the visit_type_* calls
    138     * that retrieve the alternate's content; so, do not increase depth here.
    139     */
    140    return visit_start_alternate(ffv->target, name, obj, size, errp);
    141}
    142
    143static void forward_field_end_alternate(Visitor *v, void **obj)
    144{
    145    ForwardFieldVisitor *ffv = to_ffv(v);
    146
    147    visit_end_alternate(ffv->target, obj);
    148}
    149
    150static bool forward_field_type_int64(Visitor *v, const char *name, int64_t *obj,
    151                                     Error **errp)
    152{
    153    ForwardFieldVisitor *ffv = to_ffv(v);
    154
    155    if (!forward_field_translate_name(ffv, &name, errp)) {
    156        return false;
    157    }
    158    return visit_type_int64(ffv->target, name, obj, errp);
    159}
    160
    161static bool forward_field_type_uint64(Visitor *v, const char *name,
    162                                      uint64_t *obj, Error **errp)
    163{
    164    ForwardFieldVisitor *ffv = to_ffv(v);
    165
    166    if (!forward_field_translate_name(ffv, &name, errp)) {
    167        return false;
    168    }
    169    return visit_type_uint64(ffv->target, name, obj, errp);
    170}
    171
    172static bool forward_field_type_bool(Visitor *v, const char *name, bool *obj,
    173                                    Error **errp)
    174{
    175    ForwardFieldVisitor *ffv = to_ffv(v);
    176
    177    if (!forward_field_translate_name(ffv, &name, errp)) {
    178        return false;
    179    }
    180    return visit_type_bool(ffv->target, name, obj, errp);
    181}
    182
    183static bool forward_field_type_str(Visitor *v, const char *name, char **obj,
    184                                   Error **errp)
    185{
    186    ForwardFieldVisitor *ffv = to_ffv(v);
    187
    188    if (!forward_field_translate_name(ffv, &name, errp)) {
    189        return false;
    190    }
    191    return visit_type_str(ffv->target, name, obj, errp);
    192}
    193
    194static bool forward_field_type_size(Visitor *v, const char *name, uint64_t *obj,
    195                                    Error **errp)
    196{
    197    ForwardFieldVisitor *ffv = to_ffv(v);
    198
    199    if (!forward_field_translate_name(ffv, &name, errp)) {
    200        return false;
    201    }
    202    return visit_type_size(ffv->target, name, obj, errp);
    203}
    204
    205static bool forward_field_type_number(Visitor *v, const char *name, double *obj,
    206                                      Error **errp)
    207{
    208    ForwardFieldVisitor *ffv = to_ffv(v);
    209
    210    if (!forward_field_translate_name(ffv, &name, errp)) {
    211        return false;
    212    }
    213    return visit_type_number(ffv->target, name, obj, errp);
    214}
    215
    216static bool forward_field_type_any(Visitor *v, const char *name, QObject **obj,
    217                                   Error **errp)
    218{
    219    ForwardFieldVisitor *ffv = to_ffv(v);
    220
    221    if (!forward_field_translate_name(ffv, &name, errp)) {
    222        return false;
    223    }
    224    return visit_type_any(ffv->target, name, obj, errp);
    225}
    226
    227static bool forward_field_type_null(Visitor *v, const char *name,
    228                                    QNull **obj, Error **errp)
    229{
    230    ForwardFieldVisitor *ffv = to_ffv(v);
    231
    232    if (!forward_field_translate_name(ffv, &name, errp)) {
    233        return false;
    234    }
    235    return visit_type_null(ffv->target, name, obj, errp);
    236}
    237
    238static void forward_field_optional(Visitor *v, const char *name, bool *present)
    239{
    240    ForwardFieldVisitor *ffv = to_ffv(v);
    241
    242    if (!forward_field_translate_name(ffv, &name, NULL)) {
    243        *present = false;
    244        return;
    245    }
    246    visit_optional(ffv->target, name, present);
    247}
    248
    249static bool forward_field_deprecated_accept(Visitor *v, const char *name,
    250                                            Error **errp)
    251{
    252    ForwardFieldVisitor *ffv = to_ffv(v);
    253
    254    if (!forward_field_translate_name(ffv, &name, errp)) {
    255        return false;
    256    }
    257    return visit_deprecated_accept(ffv->target, name, errp);
    258}
    259
    260static bool forward_field_deprecated(Visitor *v, const char *name)
    261{
    262    ForwardFieldVisitor *ffv = to_ffv(v);
    263
    264    if (!forward_field_translate_name(ffv, &name, NULL)) {
    265        return false;
    266    }
    267    return visit_deprecated(ffv->target, name);
    268}
    269
    270static void forward_field_complete(Visitor *v, void *opaque)
    271{
    272    /*
    273     * Do nothing, the complete method will be called in due time
    274     * on the target visitor.
    275     */
    276}
    277
    278static void forward_field_free(Visitor *v)
    279{
    280    ForwardFieldVisitor *ffv = to_ffv(v);
    281
    282    g_free(ffv->from);
    283    g_free(ffv->to);
    284    g_free(ffv);
    285}
    286
    287Visitor *visitor_forward_field(Visitor *target, const char *from, const char *to)
    288{
    289    ForwardFieldVisitor *v = g_new0(ForwardFieldVisitor, 1);
    290
    291    /*
    292     * Clone and dealloc visitors don't use a name for the toplevel
    293     * visit, so they make no sense here.
    294     */
    295    assert(target->type == VISITOR_OUTPUT || target->type == VISITOR_INPUT);
    296
    297    v->visitor.type = target->type;
    298    v->visitor.start_struct = forward_field_start_struct;
    299    v->visitor.check_struct = forward_field_check_struct;
    300    v->visitor.end_struct = forward_field_end_struct;
    301    v->visitor.start_list = forward_field_start_list;
    302    v->visitor.next_list = forward_field_next_list;
    303    v->visitor.check_list = forward_field_check_list;
    304    v->visitor.end_list = forward_field_end_list;
    305    v->visitor.start_alternate = forward_field_start_alternate;
    306    v->visitor.end_alternate = forward_field_end_alternate;
    307    v->visitor.type_int64 = forward_field_type_int64;
    308    v->visitor.type_uint64 = forward_field_type_uint64;
    309    v->visitor.type_size = forward_field_type_size;
    310    v->visitor.type_bool = forward_field_type_bool;
    311    v->visitor.type_str = forward_field_type_str;
    312    v->visitor.type_number = forward_field_type_number;
    313    v->visitor.type_any = forward_field_type_any;
    314    v->visitor.type_null = forward_field_type_null;
    315    v->visitor.optional = forward_field_optional;
    316    v->visitor.deprecated_accept = forward_field_deprecated_accept;
    317    v->visitor.deprecated = forward_field_deprecated;
    318    v->visitor.complete = forward_field_complete;
    319    v->visitor.free = forward_field_free;
    320
    321    v->target = target;
    322    v->from = g_strdup(from);
    323    v->to = g_strdup(to);
    324
    325    return &v->visitor;
    326}