ReactOS  0.4.14-dev-323-g6fe6a88
ofw_interface.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <iostream>
3 #include <fstream>
4 #include <sstream>
5 #include <string>
6 #include <vector>
7 
8 class ofw_wrappers {
9 public:
16 };
17 
18 class vartype {
19 public:
20  vartype( const std::string &typestr ) {
21  size_t amp = typestr.find('&');
22  size_t col = typestr.find(':');
23  if( amp != std::string::npos ) {
24  if( col > amp && col != std::string::npos )
25  lit_value = typestr.substr(amp+1,col-amp+1);
26  else lit_value = typestr.substr(amp+1);
27  }
28  if( col != std::string::npos ) {
29  if( amp > col && amp != std::string::npos )
30  len = typestr.substr(col+1,amp-col+1);
31  else len = typestr.substr(col+1);
32  }
33 
34  if( amp != std::string::npos && amp < col ) col = amp;
35  if( col == std::string::npos ) col = typestr.size();
36  c_type = typestr.substr(0,col);
37  }
38 
39  vartype( const vartype &other )
40  : c_type(other.c_type),
41  len(other.len),
43  }
44 
46  c_type = other.c_type;
47  len = other.len;
48  lit_value = other.lit_value;
49  return *this;
50  }
51 
55 };
56 
57 std::string uppercase( const std::string &toucase ) {
58  std::vector<char> ucase_work(toucase.size());
59  for( size_t i = 0; i < toucase.size(); i++ ) {
60  ucase_work[i] = toupper(toucase[i]);
61  }
62  return std::string(&ucase_work[0], toucase.size());
63 }
64 
66  size_t found;
67  for( size_t i = 0; i < eol_marks.size(); i++ ) {
68  found = in.find( eol_marks[i] );
69  if( found != std::string::npos )
70  in = in.substr( 0, found );
71  }
72  return in;
73 }
74 
75 int round_up( int x, int factor ) {
76  return (x + (factor - 1)) & ~(factor - 1);
77 }
78 
81  bool make_function = true, method_call = false, make_stub = true, comma;
82  std::string name, nametext, argtype, rettype;
83  std::vector<vartype> argtypes;
84  int args, rets, i, local_offset, total_stack, userarg_start = 0;
85  size_t f;
86  std::ostringstream function, ct_csource, le_stub, of_call;
87 
88  iss >> name >> args >> rets;
89 
90  if( !name.size() ) return;
91 
92  if( (f = name.find('!')) != std::string::npos ) {
93  nametext = name.substr(f+1);
94  name = name.substr(0,f);
95  }
96  if( name[0] == '-' ) {
97  name = name.substr(1);
98  make_function = false;
99  }
100  if( name[0] == '+' ) {
101  name = name.substr(1);
102  make_stub = false;
103  }
104  if( name[0] == '@' ) {
105  name = name.substr(1);
106  method_call = true;
107  make_function = false;
108  }
109 
110  if( !nametext.size() ) nametext = name;
111 
112  for( i = 1; i < (int)name.size(); i++ )
113  if( name[i] == '-' ) name[i] = '_';
114 
115  if( nametext == "call-method" )
116  wrapper.method_ctindex = wrapper.ctindex;
117 
118  for( i = 0; i < args; i++ ) {
119  iss >> argtype;
120  argtypes.push_back(vartype(argtype));
121  }
122 
123  if( method_call ) {
124  userarg_start = 1;
125  args += 2;
126  }
127 
128  iss >> rettype;
129  if( !rettype.size() ) rettype = "void";
130 
131  local_offset = (3 + rets + args) * 4;
132  total_stack = round_up(12 + local_offset, 16);
133 
134  function << "asm_ofw_" << name << ":\n"
135  << "\t/* Reserve stack space */\n"
136  << "\tsubi %r1,%r1," << total_stack << "\n"
137  << "\t/* Store r8, r9, lr */\n"
138  << "\tstw %r8," << (local_offset + 0) << "(%r1)\n"
139  << "\tstw %r9," << (local_offset + 4) << "(%r1)\n"
140  << "\tmflr %r8\n"
141  << "\tstw %r8," << (local_offset + 8) << "(%r1)\n"
142  << "\t/* Get read name */\n"
143  << "\tlis %r8," << name << "_ofw_name@ha\n"
144  << "\taddi %r9,%r8," << name << "_ofw_name@l\n"
145  << "\tstw %r9,0(%r1)\n"
146  << "\t/* " << args << " arguments and " << rets << " return */\n"
147  << "\tli %r9," << args << "\n"
148  << "\tstw %r9,4(%r1)\n"
149  << "\tli %r9," << rets << "\n"
150  << "\tstw %r9,8(%r1)\n";
151 
152  for( int i = 0; i < args; i++ )
153  function << "\tstw %r" << (i+3) << "," << (4 * (i + 3)) << "(%r1)\n";
154 
155  function << "\t/* Load up the call address */\n"
156  << "\tlis %r10,ofw_call_addr@ha\n"
157  << "\tlwz %r9,ofw_call_addr@l(%r10)\n"
158  << "\tmtlr %r9\n"
159  << "\t/* Set argument */\n"
160  << "\tmr %r3,%r1\n"
161  << "\t/* Fire */\n"
162  << "\tblrl\n"
163  << "\tlwz %r3," << (local_offset - 4) << "(%r1)\n"
164  << "\t/* Restore registers */\n"
165  << "\tlwz %r8," << (local_offset + 8) << "(%r1)\n"
166  << "\tmtlr %r8\n"
167  << "\tlwz %r9," << (local_offset + 4) << "(%r1)\n"
168  << "\tlwz %r8," << (local_offset + 0) << "(%r1)\n"
169  << "\t/* Return */\n"
170  << "\taddi %r1,%r1," << total_stack << "\n"
171  << "\tblr\n";
172 
173  if( method_call ) {
174  argtypes.insert(argtypes.begin(),vartype("int"));
175  argtypes.insert(argtypes.begin(),vartype("char*"));
176  }
177 
178  le_stub << rettype << " ofw_" << name << "(";
179 
180  comma = false;
181  for( i = userarg_start; i < args; i++ ) {
182  if( !argtypes[i].lit_value.size() ) {
183  if( !comma ) comma = true; else le_stub << ",";
184  le_stub << argtypes[i].c_type << " arg" << i;
185  }
186  }
187  le_stub << ")";
188  of_call << le_stub.str() << ";\n";
189 
190  le_stub << " {\n";
191  if( rettype != "void" )
192  le_stub << "\t" << rettype << " ret;\n";
193 
194  if( method_call ) {
195  le_stub << "\tchar arg0["
196  << round_up(nametext.size()+1,8)
197  << "] = \"" << nametext << "\";\n";
198  }
199 
200  for( i = 0; i < args; i++ ) {
201  if( argtypes[i].lit_value.size() ) {
202  le_stub << "\t" << argtypes[i].c_type << " arg" << i << " = "
203  << argtypes[i].lit_value << ";\n";
204  }
205  }
206 
207  le_stub << "\t";
208  if( rettype != "void" ) le_stub << "ret = (" << rettype << ")";
209 
210  le_stub << "ofproxy(" <<
211  (method_call ? (wrapper.method_ctindex * 4) : (wrapper.ctindex * 4));
212 
213  for( i = 0; i < 6; i++ ) {
214  if( i < args ) le_stub << ",(void *)arg" << i;
215  else le_stub << ",NULL";
216  }
217 
218  le_stub << ");\n";
219 
220  if( rettype != "void" )
221  le_stub << "\treturn ret;\n";
222 
223  le_stub << "}\n";
224 
225  if( make_function ) wrapper.functions += function.str();
226  if( make_stub ) {
227  wrapper.le_stubs += le_stub.str();
228  wrapper.of_call += of_call.str();
229  }
230  if( !method_call ) {
231  wrapper.names += name + "_ofw_name:\n\t.asciz \"" + nametext + "\"\n";
232  wrapper.calltable += std::string("\t.long asm_ofw_") + name + "\n";
233  wrapper.ctindex++;
234  }
235 }
236 
237 int main( int argc, char **argv ) {
238  int status = 0;
240  std::ofstream out, outcsource, outcheader;
242  const char *eol_marks = "#\r\n";
243  ofw_wrappers wrappers;
244 
245  wrappers.base = 0xe00000;
246  wrappers.ctindex = 0;
247 
248  if( argc < 5 ) {
249  fprintf( stderr, "%s [interface.ofw] [ofw.s] [le_stub.c] [le_stub.h]\n", argv[0] );
250  return 1;
251  }
252 
253  in.open( argv[1] );
254  if( !in ) {
255  fprintf( stderr, "can't open %s\n", argv[1] );
256  status = 1;
257  goto error;
258  }
259 
260  out.open( argv[2] );
261  if( !out ) {
262  fprintf( stderr, "can't open %s\n", argv[2] );
263  status = 1;
264  goto error;
265  }
266 
267  outcsource.open( argv[3] );
268  if( !outcsource ) {
269  fprintf( stderr, "can't open %s\n", argv[3] );
270  status = 1;
271  goto error;
272  }
273 
274  outcheader.open( argv[4] );
275  if( !outcheader ) {
276  fprintf( stderr, "can't open %s\n", argv[4] );
277  status = 1;
278  goto error;
279  }
280 
281  while( std::getline( in, line ) ) {
282  line = clip_eol( line, eol_marks );
283  if( line.size() ) populate_definition( wrappers, line );
284  }
285 
286  out << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n"
287  << "\t.section .text\n"
288  << "\t.align 4\n"
289  << "\t.globl _start\n"
290  << "\t.globl ofw_functions\n"
291  << "\t.globl ofw_call_addr\n"
292  << "ofw_call_addr:\n"
293  << "\t.long 0\n"
294  << "\n/* Function Wrappers */\n\n"
295  << wrappers.functions
296  << "\n/* Function Names */\n\n"
297  << wrappers.names
298  << "\n/* Function Call Table for Freeldr */\n\n"
299  << "\t.align 4\n"
300  << "ofw_functions:\n"
301  << wrappers.calltable
302  << "\n/* End */\n";
303 
304  outcsource << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n"
305  << "#include \"of.h\"\n"
306  << wrappers.le_stubs;
307 
308  outcheader << "/* AUTOMATICALLY GENERATE BY ofw_interface */\n"
309  << "#ifndef _OFW_CALLS_H\n"
310  << "#define _OFW_CALLS_H\n"
311  << wrappers.of_call
312  << "#endif/*_OFW_CALLS_H*/\n";
313 
314 error:
315  return status;
316 }
static int argc
Definition: ServiceArgs.c:12
#define error(str)
Definition: mkdosfs.c:1605
basic_ostringstream< char, char_traits< char >, allocator< char > > ostringstream
Definition: _iosfwd.h:127
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint factor
Definition: glfuncs.h:178
int other
Definition: msacm.c:1376
static const size_t npos
Definition: _string_npos.h:26
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
std::string names
#define argv
Definition: mplay32.c:18
Definition: match.c:390
std::string lit_value
argtype
Definition: disassembler.h:81
int round_up(int x, int factor)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
std::string calltable
basic_ifstream< char, char_traits< char > > ifstream
Definition: _iosfwd.h:131
Definition: parser.c:48
std::string len
vartype & operator=(const vartype &other)
std::string clip_eol(std::string in, const std::string &eol_marks)
GLfloat f
Definition: glext.h:7540
int toupper(int c)
Definition: utclib.c:881
basic_ofstream< char, char_traits< char > > ofstream
Definition: _iosfwd.h:132
int main(int argc, char **argv)
static FILE * out
Definition: regtests2xml.c:44
std::string functions
char line[200]
Definition: main.c:97
std::string uppercase(const std::string &toucase)
vartype(const std::string &typestr)
GLenum GLsizei len
Definition: glext.h:6722
char string[160]
Definition: util.h:11
std::string c_type
std::string of_call
void populate_definition(ofw_wrappers &wrapper, const std::string &line)
basic_istringstream< char, char_traits< char >, allocator< char > > istringstream
Definition: _iosfwd.h:126
GLuint in
Definition: glext.h:9616
#define f
Definition: ke_i.h:83
std::string le_stubs
Definition: name.c:36
FILE * stderr
static SERVICE_STATUS status
Definition: service.c:31
#define args
Definition: format.c:66
vartype(const vartype &other)
#define getline
Definition: schily.h:567
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
Definition: ps.c:97
GLuint const GLchar * name
Definition: glext.h:6031