github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/tools/clang/declextract/output.h (about)

     1  // Copyright 2024 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  #ifndef SYZ_DECLEXTRACT_OUTPUT_H
     5  #define SYZ_DECLEXTRACT_OUTPUT_H
     6  
     7  #include <memory>
     8  #include <string>
     9  #include <unordered_set>
    10  #include <vector>
    11  
    12  const char* const AccessUnknown = "";
    13  const char* const AccessUser = "user";
    14  const char* const AccessNsAdmin = "ns_admin";
    15  const char* const AccessAdmin = "admin";
    16  
    17  struct IntType;
    18  struct PtrType;
    19  struct ArrType;
    20  struct BufferType;
    21  
    22  struct FieldType {
    23    std::unique_ptr<IntType> Int;
    24    std::unique_ptr<PtrType> Ptr;
    25    std::unique_ptr<ArrType> Array;
    26    std::unique_ptr<BufferType> Buffer;
    27    std::unique_ptr<std::string> Struct;
    28  
    29    FieldType() = default;
    30    FieldType(IntType&& Typ) : Int(std::make_unique<IntType>(std::move(Typ))) {}
    31    FieldType(PtrType&& Typ) : Ptr(std::make_unique<PtrType>(std::move(Typ))) {}
    32    FieldType(ArrType&& Typ) : Array(std::make_unique<ArrType>(std::move(Typ))) {}
    33    FieldType(BufferType&& Typ) : Buffer(std::make_unique<BufferType>(std::move(Typ))) {}
    34    FieldType(const std::string& Typ) : Struct(std::make_unique<std::string>(std::move(Typ))) {}
    35  };
    36  
    37  struct IntType {
    38    int ByteSize = 0;
    39    int64_t MinValue = 0;
    40    int64_t MaxValue = 0;
    41    bool IsConst = false;
    42    std::string Name;
    43    std::string Base;
    44    std::string Enum;
    45  };
    46  
    47  struct PtrType {
    48    FieldType Elem;
    49    bool IsConst = false;
    50  };
    51  
    52  struct ArrType {
    53    FieldType Elem;
    54    int MinSize = 0;
    55    int MaxSize = 0;
    56    int Align = 0;
    57    bool IsConstSize = false;
    58  };
    59  
    60  struct BufferType {
    61    int MinSize = 0;
    62    int MaxSize = 0;
    63    bool IsString = false;
    64    bool IsNonTerminated = false;
    65  };
    66  
    67  struct ConstInfo {
    68    std::string Name;
    69    std::string Filename;
    70    int64_t Value;
    71  };
    72  
    73  struct Field {
    74    std::string Name;
    75    bool IsAnonymous = false;
    76    int BitWidth = 0;
    77    int CountedBy = -1;
    78    FieldType Type;
    79  };
    80  
    81  struct Struct {
    82    std::string Name;
    83    int ByteSize = 0;
    84    int Align = 0;
    85    bool IsUnion = false;
    86    bool IsPacked = false;
    87    int AlignAttr = 0;
    88    std::vector<Field> Fields;
    89  };
    90  
    91  struct Enum {
    92    std::string Name;
    93    std::vector<std::string> Values;
    94  };
    95  
    96  struct Ioctl {
    97    std::string Name;
    98    FieldType Type;
    99  };
   100  
   101  struct FileOps {
   102    std::string Name;
   103    std::string Open;
   104    std::string Read;
   105    std::string Write;
   106    std::string Mmap;
   107    std::string Ioctl;
   108  };
   109  
   110  struct EntityReturn {
   111    std::string Func;
   112  };
   113  
   114  struct EntityArgument {
   115    std::string Func;
   116    unsigned Arg;
   117  };
   118  
   119  struct EntityField {
   120    std::string Struct;
   121    std::string Field;
   122  };
   123  
   124  struct EntityLocal {
   125    std::string Name;
   126  };
   127  
   128  struct EntityGlobalAddr {
   129    std::string Name;
   130  };
   131  
   132  struct EntityResource {
   133    std::string Type;
   134    std::string SubType;
   135  };
   136  
   137  struct TypingEntity {
   138    std::unique_ptr<EntityReturn> Return;
   139    std::unique_ptr<EntityArgument> Argument;
   140    std::unique_ptr<EntityField> Field;
   141    std::unique_ptr<EntityLocal> Local;
   142    std::unique_ptr<EntityGlobalAddr> GlobalAddr;
   143    std::unique_ptr<EntityResource> Resource;
   144  
   145    TypingEntity() = default;
   146    TypingEntity(EntityReturn&& E) : Return(std::make_unique<EntityReturn>(std::move(E))) {}
   147    TypingEntity(EntityArgument&& E) : Argument(std::make_unique<EntityArgument>(std::move(E))) {}
   148    TypingEntity(EntityField&& E) : Field(std::make_unique<EntityField>(std::move(E))) {}
   149    TypingEntity(EntityLocal&& E) : Local(std::make_unique<EntityLocal>(std::move(E))) {}
   150    TypingEntity(EntityGlobalAddr&& E) : GlobalAddr(std::make_unique<EntityGlobalAddr>(std::move(E))) {}
   151    TypingEntity(EntityResource&& E) : Resource(std::make_unique<EntityResource>(std::move(E))) {}
   152  };
   153  
   154  struct TypingFact {
   155    TypingEntity Src;
   156    TypingEntity Dst;
   157  };
   158  
   159  struct FunctionScope {
   160    int Arg = 0;
   161    int StartLine = 0;
   162    int EndLine = 0;
   163    std::vector<std::string> Values;
   164    std::vector<std::string> Calls;
   165    std::vector<TypingFact> Facts;
   166  };
   167  
   168  struct Function {
   169    std::string Name;
   170    std::string File;
   171    int StartLine = 0;
   172    int EndLine = 0;
   173    bool IsStatic = false;
   174    std::vector<FunctionScope> Scopes;
   175  };
   176  
   177  struct Syscall {
   178    std::string Func;
   179    std::vector<Field> Args;
   180  };
   181  
   182  struct IouringOp {
   183    std::string Name;
   184    std::string Func;
   185  };
   186  
   187  struct NetlinkOp {
   188    std::string Name;
   189    std::string Func;
   190    const char* Access = nullptr;
   191    std::string Policy;
   192  };
   193  
   194  struct NetlinkFamily {
   195    std::string Name;
   196    std::vector<NetlinkOp> Ops;
   197  };
   198  
   199  struct NetlinkAttr {
   200    std::string Name;
   201    std::string Kind;
   202    int MaxSize = 0;
   203    std::string NestedPolicy;
   204    std::unique_ptr<FieldType> Elem;
   205  };
   206  
   207  struct NetlinkPolicy {
   208    std::string Name;
   209    std::vector<NetlinkAttr> Attrs;
   210  };
   211  
   212  inline void print(JSONPrinter& Printer, const ConstInfo& V) {
   213    JSONPrinter::Scope Scope(Printer);
   214    Printer.Field("name", V.Name);
   215    Printer.Field("filename", V.Filename);
   216    Printer.Field("value", V.Value, true);
   217  }
   218  
   219  inline void print(JSONPrinter& Printer, const Field& V) {
   220    JSONPrinter::Scope Scope(Printer);
   221    Printer.Field("name", V.Name);
   222    Printer.Field("is_anonymous", V.IsAnonymous);
   223    Printer.Field("bit_width", V.BitWidth);
   224    Printer.Field("counted_by", V.CountedBy);
   225    Printer.Field("type", V.Type, true);
   226  }
   227  
   228  inline void print(JSONPrinter& Printer, const Struct& V) {
   229    JSONPrinter::Scope Scope(Printer);
   230    Printer.Field("name", V.Name);
   231    Printer.Field("align", V.Align);
   232    Printer.Field("byte_size", V.ByteSize);
   233    Printer.Field("is_union", V.IsUnion);
   234    Printer.Field("is_packed", V.IsPacked);
   235    Printer.Field("align_attr", V.AlignAttr);
   236    Printer.Field("fields", V.Fields, true);
   237  }
   238  
   239  inline void print(JSONPrinter& Printer, const Enum& V) {
   240    JSONPrinter::Scope Scope(Printer);
   241    Printer.Field("name", V.Name);
   242    Printer.Field("values", V.Values, true);
   243  }
   244  
   245  inline void print(JSONPrinter& Printer, const FieldType& V) {
   246    JSONPrinter::Scope Scope(Printer);
   247    if (V.Int)
   248      Printer.Field("int", *V.Int, true);
   249    else if (V.Ptr)
   250      Printer.Field("ptr", *V.Ptr, true);
   251    else if (V.Array)
   252      Printer.Field("array", *V.Array, true);
   253    else if (V.Buffer)
   254      Printer.Field("buffer", *V.Buffer, true);
   255    else
   256      Printer.Field("struct", *V.Struct, true);
   257  }
   258  
   259  inline void print(JSONPrinter& Printer, const IntType& V) {
   260    JSONPrinter::Scope Scope(Printer);
   261    Printer.Field("byte_size", V.ByteSize);
   262    Printer.Field("min_value", V.MinValue);
   263    Printer.Field("max_value", V.MaxValue);
   264    Printer.Field("is_const", V.IsConst);
   265    Printer.Field("name", V.Name);
   266    Printer.Field("base", V.Base);
   267    Printer.Field("enum", V.Enum, true);
   268  }
   269  
   270  inline void print(JSONPrinter& Printer, const PtrType& V) {
   271    JSONPrinter::Scope Scope(Printer);
   272    Printer.Field("elem", V.Elem);
   273    Printer.Field("is_const", V.IsConst, true);
   274  }
   275  
   276  inline void print(JSONPrinter& Printer, const ArrType& V) {
   277    JSONPrinter::Scope Scope(Printer);
   278    Printer.Field("elem", V.Elem);
   279    Printer.Field("min_size", V.MinSize);
   280    Printer.Field("max_size", V.MaxSize);
   281    Printer.Field("align", V.Align);
   282    Printer.Field("is_const_size", V.IsConstSize, true);
   283  }
   284  
   285  inline void print(JSONPrinter& Printer, const BufferType& V) {
   286    JSONPrinter::Scope Scope(Printer);
   287    Printer.Field("min_size", V.MinSize);
   288    Printer.Field("max_size", V.MaxSize);
   289    Printer.Field("is_string", V.IsString);
   290    Printer.Field("is_non_terminated", V.IsNonTerminated, true);
   291  }
   292  
   293  inline void print(JSONPrinter& Printer, const Ioctl& V) {
   294    JSONPrinter::Scope Scope(Printer);
   295    Printer.Field("name", V.Name);
   296    Printer.Field("type", V.Type, true);
   297  }
   298  
   299  inline void print(JSONPrinter& Printer, const FileOps& V) {
   300    JSONPrinter::Scope Scope(Printer);
   301    Printer.Field("name", V.Name);
   302    Printer.Field("open", V.Open);
   303    Printer.Field("read", V.Read);
   304    Printer.Field("write", V.Write);
   305    Printer.Field("mmap", V.Mmap);
   306    Printer.Field("ioctl", V.Ioctl, true);
   307  }
   308  
   309  inline void print(JSONPrinter& Printer, const EntityReturn& V) {
   310    JSONPrinter::Scope Scope(Printer);
   311    Printer.Field("func", V.Func, true);
   312  }
   313  
   314  inline void print(JSONPrinter& Printer, const EntityArgument& V) {
   315    JSONPrinter::Scope Scope(Printer);
   316    Printer.Field("func", V.Func);
   317    Printer.Field("arg", V.Arg, true);
   318  }
   319  
   320  inline void print(JSONPrinter& Printer, const EntityField& V) {
   321    JSONPrinter::Scope Scope(Printer);
   322    Printer.Field("struct", V.Struct);
   323    Printer.Field("field", V.Field, true);
   324  }
   325  
   326  inline void print(JSONPrinter& Printer, const EntityLocal& V) {
   327    JSONPrinter::Scope Scope(Printer);
   328    Printer.Field("name", V.Name, true);
   329  }
   330  
   331  inline void print(JSONPrinter& Printer, const EntityGlobalAddr& V) {
   332    JSONPrinter::Scope Scope(Printer);
   333    Printer.Field("name", V.Name, true);
   334  }
   335  
   336  inline void print(JSONPrinter& Printer, const EntityResource& V) {
   337    JSONPrinter::Scope Scope(Printer);
   338    Printer.Field("type", V.Type);
   339    Printer.Field("subtype", V.SubType, true);
   340  }
   341  
   342  inline void print(JSONPrinter& Printer, const TypingEntity& V) {
   343    JSONPrinter::Scope Scope(Printer);
   344    if (V.Return)
   345      Printer.Field("return", *V.Return, true);
   346    else if (V.Argument)
   347      Printer.Field("argument", *V.Argument, true);
   348    else if (V.Field)
   349      Printer.Field("field", *V.Field, true);
   350    else if (V.Local)
   351      Printer.Field("local", *V.Local, true);
   352    else if (V.GlobalAddr)
   353      Printer.Field("global_addr", *V.GlobalAddr, true);
   354    else
   355      Printer.Field("resource", *V.Resource, true);
   356  }
   357  
   358  inline void print(JSONPrinter& Printer, const TypingFact& V) {
   359    JSONPrinter::Scope Scope(Printer);
   360    Printer.Field("src", V.Src);
   361    Printer.Field("dst", V.Dst, true);
   362  }
   363  
   364  inline void print(JSONPrinter& Printer, const FunctionScope& V) {
   365    JSONPrinter::Scope Scope(Printer);
   366    Printer.Field("arg", V.Arg);
   367    Printer.Field("values", V.Values);
   368    Printer.Field("start_line", V.StartLine);
   369    Printer.Field("end_line", V.EndLine);
   370    Printer.Field("calls", V.Calls);
   371    Printer.Field("facts", V.Facts, true);
   372  }
   373  
   374  inline void print(JSONPrinter& Printer, const Function& V) {
   375    JSONPrinter::Scope Scope(Printer);
   376    Printer.Field("name", V.Name);
   377    Printer.Field("file", V.File);
   378    Printer.Field("start_line", V.StartLine);
   379    Printer.Field("end_line", V.EndLine);
   380    Printer.Field("is_static", V.IsStatic);
   381    Printer.Field("scopes", V.Scopes, true);
   382  }
   383  
   384  inline void print(JSONPrinter& Printer, const Syscall& V) {
   385    JSONPrinter::Scope Scope(Printer);
   386    Printer.Field("func", V.Func);
   387    Printer.Field("args", V.Args, true);
   388  }
   389  
   390  inline void print(JSONPrinter& Printer, const IouringOp& V) {
   391    JSONPrinter::Scope Scope(Printer);
   392    Printer.Field("name", V.Name);
   393    Printer.Field("func", V.Func, true);
   394  }
   395  
   396  inline void print(JSONPrinter& Printer, const NetlinkOp& V) {
   397    JSONPrinter::Scope Scope(Printer);
   398    Printer.Field("name", V.Name);
   399    Printer.Field("func", V.Func);
   400    Printer.Field("access", V.Access);
   401    Printer.Field("policy", V.Policy, true);
   402  }
   403  
   404  inline void print(JSONPrinter& Printer, const NetlinkFamily& V) {
   405    JSONPrinter::Scope Scope(Printer);
   406    Printer.Field("name", V.Name);
   407    Printer.Field("ops", V.Ops, true);
   408  }
   409  
   410  inline void print(JSONPrinter& Printer, const NetlinkAttr& V) {
   411    JSONPrinter::Scope Scope(Printer);
   412    Printer.Field("name", V.Name);
   413    Printer.Field("kind", V.Kind);
   414    Printer.Field("max_size", V.MaxSize);
   415    Printer.Field("nested_policy", V.NestedPolicy);
   416    Printer.Field("elem", V.Elem, true);
   417  }
   418  
   419  inline void print(JSONPrinter& Printer, const NetlinkPolicy& V) {
   420    JSONPrinter::Scope Scope(Printer);
   421    Printer.Field("name", V.Name);
   422    Printer.Field("attrs", V.Attrs, true);
   423  }
   424  
   425  // This type is used when we can't figure out the right type, but need some type to use.
   426  inline FieldType TodoType() {
   427    return IntType{
   428        .ByteSize = 1,
   429        .Name = "TODO",
   430        .Base = "long",
   431    };
   432  }
   433  
   434  class Output {
   435  public:
   436    void emit(Function&& V) { Functions.push_back(std::move(V)); }
   437    void emit(ConstInfo&& V) { Consts.push_back(std::move(V)); }
   438    void emit(Struct&& V) { Structs.push_back(std::move(V)); }
   439    void emit(Enum&& V) { Enums.push_back(std::move(V)); }
   440    void emit(Syscall&& V) { Syscalls.push_back(std::move(V)); }
   441    void emit(FileOps&& V) { FileOps.push_back(std::move(V)); }
   442    void emit(Ioctl&& V) { Ioctls.push_back(std::move(V)); }
   443    void emit(IouringOp&& V) { IouringOps.push_back(std::move(V)); }
   444    void emit(NetlinkFamily&& V) { NetlinkFamilies.push_back(std::move(V)); }
   445    void emit(NetlinkPolicy&& V) { NetlinkPolicies.push_back(std::move(V)); }
   446  
   447    void print() const {
   448      JSONPrinter Printer;
   449      Printer.Field("functions", Functions);
   450      Printer.Field("consts", Consts);
   451      Printer.Field("enums", Enums);
   452      Printer.Field("structs", Structs);
   453      Printer.Field("syscalls", Syscalls);
   454      Printer.Field("file_ops", FileOps);
   455      Printer.Field("ioctls", Ioctls);
   456      Printer.Field("iouring_ops", IouringOps);
   457      Printer.Field("netlink_families", NetlinkFamilies);
   458      Printer.Field("netlink_policies", NetlinkPolicies, true);
   459    }
   460  
   461  private:
   462    std::vector<Function> Functions;
   463    std::vector<ConstInfo> Consts;
   464    std::vector<Enum> Enums;
   465    std::vector<Struct> Structs;
   466    std::vector<Syscall> Syscalls;
   467    std::vector<FileOps> FileOps;
   468    std::vector<Ioctl> Ioctls;
   469    std::vector<IouringOp> IouringOps;
   470    std::vector<NetlinkFamily> NetlinkFamilies;
   471    std::vector<NetlinkPolicy> NetlinkPolicies;
   472  };
   473  
   474  #endif