Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenofw_interface.cpp
Go to the documentation of this file.
00001 #include <stdio.h> 00002 #include <iostream> 00003 #include <fstream> 00004 #include <sstream> 00005 #include <string> 00006 #include <vector> 00007 00008 class ofw_wrappers { 00009 public: 00010 int base, ctindex, method_ctindex; 00011 std::string functions; 00012 std::string names; 00013 std::string calltable; 00014 std::string le_stubs; 00015 std::string of_call; 00016 }; 00017 00018 class vartype { 00019 public: 00020 vartype( const std::string &typestr ) { 00021 size_t amp = typestr.find('&'); 00022 size_t col = typestr.find(':'); 00023 if( amp != std::string::npos ) { 00024 if( col > amp && col != std::string::npos ) 00025 lit_value = typestr.substr(amp+1,col-amp+1); 00026 else lit_value = typestr.substr(amp+1); 00027 } 00028 if( col != std::string::npos ) { 00029 if( amp > col && amp != std::string::npos ) 00030 len = typestr.substr(col+1,amp-col+1); 00031 else len = typestr.substr(col+1); 00032 } 00033 00034 if( amp != std::string::npos && amp < col ) col = amp; 00035 if( col == std::string::npos ) col = typestr.size(); 00036 c_type = typestr.substr(0,col); 00037 } 00038 00039 vartype( const vartype &other ) 00040 : c_type(other.c_type), 00041 len(other.len), 00042 lit_value(other.lit_value) { 00043 } 00044 00045 vartype &operator = ( const vartype &other ) { 00046 c_type = other.c_type; 00047 len = other.len; 00048 lit_value = other.lit_value; 00049 return *this; 00050 } 00051 00052 std::string c_type; 00053 std::string len; 00054 std::string lit_value; 00055 }; 00056 00057 std::string uppercase( const std::string &toucase ) { 00058 std::vector<char> ucase_work(toucase.size()); 00059 for( size_t i = 0; i < toucase.size(); i++ ) { 00060 ucase_work[i] = toupper(toucase[i]); 00061 } 00062 return std::string(&ucase_work[0], toucase.size()); 00063 } 00064 00065 std::string clip_eol( std::string in, const std::string &eol_marks ) { 00066 size_t found; 00067 for( size_t i = 0; i < eol_marks.size(); i++ ) { 00068 found = in.find( eol_marks[i] ); 00069 if( found != std::string::npos ) 00070 in = in.substr( 0, found ); 00071 } 00072 return in; 00073 } 00074 00075 int round_up( int x, int factor ) { 00076 return (x + (factor - 1)) & ~(factor - 1); 00077 } 00078 00079 void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { 00080 std::istringstream iss(line); 00081 bool make_function = true, method_call = false, make_stub = true, comma; 00082 std::string name, nametext, argtype, rettype; 00083 std::vector<vartype> argtypes; 00084 int args, rets, i, local_offset, total_stack, userarg_start = 0; 00085 size_t f; 00086 std::ostringstream function, ct_csource, le_stub, of_call; 00087 00088 iss >> name >> args >> rets; 00089 00090 if( !name.size() ) return; 00091 00092 if( (f = name.find('!')) != std::string::npos ) { 00093 nametext = name.substr(f+1); 00094 name = name.substr(0,f); 00095 } 00096 if( name[0] == '-' ) { 00097 name = name.substr(1); 00098 make_function = false; 00099 } 00100 if( name[0] == '+' ) { 00101 name = name.substr(1); 00102 make_stub = false; 00103 } 00104 if( name[0] == '@' ) { 00105 name = name.substr(1); 00106 method_call = true; 00107 make_function = false; 00108 } 00109 00110 if( !nametext.size() ) nametext = name; 00111 00112 for( i = 1; i < (int)name.size(); i++ ) 00113 if( name[i] == '-' ) name[i] = '_'; 00114 00115 if( nametext == "call-method" ) 00116 wrapper.method_ctindex = wrapper.ctindex; 00117 00118 for( i = 0; i < args; i++ ) { 00119 iss >> argtype; 00120 argtypes.push_back(vartype(argtype)); 00121 } 00122 00123 if( method_call ) { 00124 userarg_start = 1; 00125 args += 2; 00126 } 00127 00128 iss >> rettype; 00129 if( !rettype.size() ) rettype = "void"; 00130 00131 local_offset = (3 + rets + args) * 4; 00132 total_stack = round_up(12 + local_offset, 16); 00133 00134 function << "asm_ofw_" << name << ":\n" 00135 << "\t/* Reserve stack space */\n" 00136 << "\tsubi %r1,%r1," << total_stack << "\n" 00137 << "\t/* Store r8, r9, lr */\n" 00138 << "\tstw %r8," << (local_offset + 0) << "(%r1)\n" 00139 << "\tstw %r9," << (local_offset + 4) << "(%r1)\n" 00140 << "\tmflr %r8\n" 00141 << "\tstw %r8," << (local_offset + 8) << "(%r1)\n" 00142 << "\t/* Get read name */\n" 00143 << "\tlis %r8," << name << "_ofw_name@ha\n" 00144 << "\taddi %r9,%r8," << name << "_ofw_name@l\n" 00145 << "\tstw %r9,0(%r1)\n" 00146 << "\t/* " << args << " arguments and " << rets << " return */\n" 00147 << "\tli %r9," << args << "\n" 00148 << "\tstw %r9,4(%r1)\n" 00149 << "\tli %r9," << rets << "\n" 00150 << "\tstw %r9,8(%r1)\n"; 00151 00152 for( int i = 0; i < args; i++ ) 00153 function << "\tstw %r" << (i+3) << "," << (4 * (i + 3)) << "(%r1)\n"; 00154 00155 function << "\t/* Load up the call address */\n" 00156 << "\tlis %r10,ofw_call_addr@ha\n" 00157 << "\tlwz %r9,ofw_call_addr@l(%r10)\n" 00158 << "\tmtlr %r9\n" 00159 << "\t/* Set argument */\n" 00160 << "\tmr %r3,%r1\n" 00161 << "\t/* Fire */\n" 00162 << "\tblrl\n" 00163 << "\tlwz %r3," << (local_offset - 4) << "(%r1)\n" 00164 << "\t/* Restore registers */\n" 00165 << "\tlwz %r8," << (local_offset + 8) << "(%r1)\n" 00166 << "\tmtlr %r8\n" 00167 << "\tlwz %r9," << (local_offset + 4) << "(%r1)\n" 00168 << "\tlwz %r8," << (local_offset + 0) << "(%r1)\n" 00169 << "\t/* Return */\n" 00170 << "\taddi %r1,%r1," << total_stack << "\n" 00171 << "\tblr\n"; 00172 00173 if( method_call ) { 00174 argtypes.insert(argtypes.begin(),vartype("int")); 00175 argtypes.insert(argtypes.begin(),vartype("char*")); 00176 } 00177 00178 le_stub << rettype << " ofw_" << name << "("; 00179 00180 comma = false; 00181 for( i = userarg_start; i < args; i++ ) { 00182 if( !argtypes[i].lit_value.size() ) { 00183 if( !comma ) comma = true; else le_stub << ","; 00184 le_stub << argtypes[i].c_type << " arg" << i; 00185 } 00186 } 00187 le_stub << ")"; 00188 of_call << le_stub.str() << ";\n"; 00189 00190 le_stub << " {\n"; 00191 if( rettype != "void" ) 00192 le_stub << "\t" << rettype << " ret;\n"; 00193 00194 if( method_call ) { 00195 le_stub << "\tchar arg0[" 00196 << round_up(nametext.size()+1,8) 00197 << "] = \"" << nametext << "\";\n"; 00198 } 00199 00200 for( i = 0; i < args; i++ ) { 00201 if( argtypes[i].lit_value.size() ) { 00202 le_stub << "\t" << argtypes[i].c_type << " arg" << i << " = " 00203 << argtypes[i].lit_value << ";\n"; 00204 } 00205 } 00206 00207 le_stub << "\t"; 00208 if( rettype != "void" ) le_stub << "ret = (" << rettype << ")"; 00209 00210 le_stub << "ofproxy(" << 00211 (method_call ? (wrapper.method_ctindex * 4) : (wrapper.ctindex * 4)); 00212 00213 for( i = 0; i < 6; i++ ) { 00214 if( i < args ) le_stub << ",(void *)arg" << i; 00215 else le_stub << ",NULL"; 00216 } 00217 00218 le_stub << ");\n"; 00219 00220 if( rettype != "void" ) 00221 le_stub << "\treturn ret;\n"; 00222 00223 le_stub << "}\n"; 00224 00225 if( make_function ) wrapper.functions += function.str(); 00226 if( make_stub ) { 00227 wrapper.le_stubs += le_stub.str(); 00228 wrapper.of_call += of_call.str(); 00229 } 00230 if( !method_call ) { 00231 wrapper.names += name + "_ofw_name:\n\t.asciz \"" + nametext + "\"\n"; 00232 wrapper.calltable += std::string("\t.long asm_ofw_") + name + "\n"; 00233 wrapper.ctindex++; 00234 } 00235 } 00236 00237 int main( int argc, char **argv ) { 00238 int status = 0; 00239 std::ifstream in; 00240 std::ofstream out, outcsource, outcheader; 00241 std::string line; 00242 const char *eol_marks = "#\r\n"; 00243 ofw_wrappers wrappers; 00244 00245 wrappers.base = 0xe00000; 00246 wrappers.ctindex = 0; 00247 00248 if( argc < 5 ) { 00249 fprintf( stderr, "%s [interface.ofw] [ofw.s] [le_stub.c] [le_stub.h]\n", argv[0] ); 00250 return 1; 00251 } 00252 00253 in.open( argv[1] ); 00254 if( !in ) { 00255 fprintf( stderr, "can't open %s\n", argv[1] ); 00256 status = 1; 00257 goto error; 00258 } 00259 00260 out.open( argv[2] ); 00261 if( !out ) { 00262 fprintf( stderr, "can't open %s\n", argv[2] ); 00263 status = 1; 00264 goto error; 00265 } 00266 00267 outcsource.open( argv[3] ); 00268 if( !outcsource ) { 00269 fprintf( stderr, "can't open %s\n", argv[3] ); 00270 status = 1; 00271 goto error; 00272 } 00273 00274 outcheader.open( argv[4] ); 00275 if( !outcheader ) { 00276 fprintf( stderr, "can't open %s\n", argv[4] ); 00277 status = 1; 00278 goto error; 00279 } 00280 00281 while( std::getline( in, line ) ) { 00282 line = clip_eol( line, eol_marks ); 00283 if( line.size() ) populate_definition( wrappers, line ); 00284 } 00285 00286 out << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n" 00287 << "\t.section .text\n" 00288 << "\t.align 4\n" 00289 << "\t.globl _start\n" 00290 << "\t.globl ofw_functions\n" 00291 << "\t.globl ofw_call_addr\n" 00292 << "ofw_call_addr:\n" 00293 << "\t.long 0\n" 00294 << "\n/* Function Wrappers */\n\n" 00295 << wrappers.functions 00296 << "\n/* Function Names */\n\n" 00297 << wrappers.names 00298 << "\n/* Function Call Table for Freeldr */\n\n" 00299 << "\t.align 4\n" 00300 << "ofw_functions:\n" 00301 << wrappers.calltable 00302 << "\n/* End */\n"; 00303 00304 outcsource << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n" 00305 << "#include \"of.h\"\n" 00306 << wrappers.le_stubs; 00307 00308 outcheader << "/* AUTOMATICALLY GENERATE BY ofw_interface */\n" 00309 << "#ifndef _OFW_CALLS_H\n" 00310 << "#define _OFW_CALLS_H\n" 00311 << wrappers.of_call 00312 << "#endif/*_OFW_CALLS_H*/\n"; 00313 00314 error: 00315 return status; 00316 } Generated on Sun May 27 2012 04:37:46 for ReactOS by
1.7.6.1
|