ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ofw_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.