1 // Copyright 2017 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <ctime> 8 #include <fstream> 9 #include <string> 10 11 #include "types.h" 12 13 // Interface for syscall generators. 14 class Generator { 15 public: 16 virtual bool header(std::ofstream& os); 17 virtual bool syscall(std::ofstream& os, const Syscall& sc) = 0; 18 virtual bool footer(std::ofstream& os); 19 20 protected: ~Generator()21 virtual ~Generator() {} 22 }; 23 24 // Interface for vDSO wrappers. 25 class CallWrapper { 26 public: 27 virtual bool applies(const Syscall& sc) const = 0; preCall(std::ofstream & os,const Syscall & sc)28 virtual void preCall(std::ofstream& os, const Syscall& sc) const {} postCall(std::ofstream & os,const Syscall & sc,std::string return_var)29 virtual void postCall(std::ofstream& os, const Syscall& sc, std::string return_var) const {} 30 31 protected: ~CallWrapper()32 virtual ~CallWrapper() {} 33 }; 34 35 // Generate the vDSO assembly stubs. 36 class VDsoAsmGenerator : public Generator { 37 public: VDsoAsmGenerator(const std::string & syscall_macro,const std::string & name_prefix,const std::vector<CallWrapper * > & call_wrappers)38 VDsoAsmGenerator(const std::string& syscall_macro, 39 const std::string& name_prefix, 40 const std::vector<CallWrapper*>& call_wrappers) 41 : syscall_macro_(syscall_macro), 42 name_prefix_(name_prefix), 43 wrappers_(call_wrappers) {} 44 45 bool syscall(std::ofstream& os, const Syscall& sc) override; 46 47 private: 48 const std::string syscall_macro_; 49 const std::string name_prefix_; 50 const std::vector<CallWrapper*> wrappers_; 51 }; 52 53 // Generate the syscall number definitions. 54 class SyscallNumbersGenerator : public Generator { 55 public: SyscallNumbersGenerator(const std::string & define_prefix)56 SyscallNumbersGenerator(const std::string& define_prefix) 57 : define_prefix_(define_prefix) {} 58 59 bool syscall(std::ofstream& os, const Syscall& sc) override; 60 bool footer(std::ofstream& os) override; 61 62 private: 63 const std::string define_prefix_; 64 int num_calls_ = 0; 65 }; 66 67 // Generate debug trace info. 68 class TraceInfoGenerator : public Generator { 69 public: 70 bool syscall(std::ofstream& os, const Syscall& sc) override; 71 }; 72 73 // Generate category list. 74 class CategoryGenerator : public Generator { 75 public: 76 bool syscall(std::ofstream& os, const Syscall& sc) override; 77 bool footer(std::ofstream& os) override; 78 79 private: 80 std::map<const std::string, std::vector<const std::string*>> category_map_; 81 }; 82 83 /* Generates the kernel syscall jump table and accoutrements. */ 84 class KernelBranchGenerator : public Generator { 85 public: 86 bool header(std::ofstream& os) override; 87 bool syscall(std::ofstream& os, const Syscall& sc) override; 88 }; 89 90 /* Generates the kernel syscall wrappers. */ 91 class KernelWrapperGenerator : public Generator { 92 public: KernelWrapperGenerator(const std::string & syscall_prefix,const std::string & wrapper_prefix,const std::string & define_prefix)93 KernelWrapperGenerator(const std::string& syscall_prefix, const std::string& wrapper_prefix, 94 const std::string& define_prefix) 95 : syscall_prefix_(syscall_prefix), wrapper_prefix_(wrapper_prefix), 96 define_prefix_(define_prefix) {} 97 98 bool header(std::ofstream& os) override; 99 bool syscall(std::ofstream& os, const Syscall& sc) override; 100 bool footer(std::ofstream& os) override; 101 102 private: 103 const std::string syscall_prefix_; 104 const std::string wrapper_prefix_; 105 const std::string define_prefix_; 106 }; 107 108 /* Generates the Rust bindings. */ 109 class RustBindingGenerator : public Generator { 110 public: 111 bool header(std::ofstream& os) override; 112 bool footer(std::ofstream& os) override; 113 bool syscall(std::ofstream& os, const Syscall& sc) override; 114 }; 115 116 /* Generates a JSON representation of the syscall list. */ 117 class JsonGenerator : public Generator { 118 public: 119 bool header(std::ofstream& os) override; 120 bool footer(std::ofstream& os) override; 121 bool syscall(std::ofstream& os, const Syscall& sc) override; 122 123 private: 124 bool first_syscall_ = true; 125 }; 126 127 // Writes the signature of a syscall, up to the end of the args list. 128 // 129 // Can wrap pointers with user_ptr. 130 // Can specify a type to substitute for no args. 131 // Doesn't write ';', '{}' or attributes. 132 void write_syscall_signature_line(std::ofstream& os, const Syscall& sc, std::string name_prefix, 133 std::string before_args, std::string inter_arg, 134 bool wrap_pointers_with_user_ptr, std::string no_args_type); 135 136 // Writes the return variable declaration for a syscall. 137 // 138 // Returns the name of the variable (or an empty string if the call was void). 139 std::string write_syscall_return_var(std::ofstream& os, const Syscall& sc); 140 141 // Writes an invocation of a syscall. 142 // 143 // Uses the argument names specified in the type description 144 // Performs no casting or pointer wrapping. 145 void write_syscall_invocation(std::ofstream& os, const Syscall& sc, 146 const std::string& return_var, const std::string& name_prefix); 147 148 void write_argument_annotation(std::ofstream& os, const TypeSpec& arg); 149