> > What about this instead of the last three lines:
> >
> > print "\taddl $" #argsize ", %esp\n";
> > print "\tret\n";
>
> I did that and it does not solve the problem : it crashes at the same
> GL call (glGetString) but this time at address 0x00000000 and not
> 0x00001F00 as before.
>
> How can I help debugging this further (except by looking at an x86 ASM
> book :-) ) ?
Hmm. I have finally managed to test it and it work fine for me.
In addition to a simple example application, I ran through _every_
OpenGL API with NULL values using winapi_test.
You do compile with -fPIC don't you?
Anyway here is my latest version.
Index: wine/dlls/opengl32/make_opengl_norm
===================================================================
RCS file: /home/wine/wine/dlls/opengl32/make_opengl_norm,v
retrieving revision 1.2
diff -u -u -r1.2 make_opengl_norm
--- wine/dlls/opengl32/make_opengl_norm 2000/05/18 00:07:53 1.2
+++ wine/dlls/opengl32/make_opengl_norm 2000/05/20 00:09:05
@@ -1,5 +1,9 @@
#!/usr/bin/perl -w
+my $i386 = 1;
+my $critical_section = 1;
+my $pic = 1;
+
print "
/* Auto-generated file... Do not edit ! */
@@ -9,10 +13,56 @@
";
+print '#define THUNK_STDCALL_TO_CDECL(stdcall_name, cdecl_name, argsize)' .
" \\\n";
+print ' asm("\t.globl\t" #stdcall_name "\n"' . " \\\n";
+print ' "\t.type\t" #stdcall_name ", @function\n"' . " \\\n";
+print ' #stdcall_name ":\n"' . " \\\n";
+print ' "\tmovl (%esp), %eax\n"' . " \\\n";
+print ' "\tleal " #argsize "(%esp), %edx\n"' . " \\\n";
+print ' "." #stdcall_name ":\n"' . " \\\n";
+print ' "\tmovl (%edx), %ecx\n"' . " \\\n";
+print ' "\tmovl %eax, (%edx)\n"' . " \\\n";
+print ' "\tmovl %ecx, %eax\n"' . " \\\n";
+print ' "\tsubl $4, %edx\n"' . " \\\n";
+print ' "\tleal (%esp), %ecx\n"' . " \\\n";
+print ' "\tcmpl %ecx, %edx\n"' . " \\\n";
+print ' "\tjge ." #stdcall_name "\n"' . " \\\n";
+if($critical_section) {
+ if($pic) {
+ print ' "\tcall ." #stdcall_name ".getgot.enter\n"' . " \\\n";
+ print ' "." #stdcall_name ".getgot.enter:\n"' . " \\\n";
+ print ' "\tpopl %ebx\n"' . " \\\n";
+ print ' "\taddl $_GLOBAL_OFFSET_TABLE_+[.-." #stdcall_name
".getgot.enter], %ebx\n"' . " \\\n";
+ print ' "\tpushl X11DRV_CritSection@GOT(%ebx)\n"' . " \\\n";
+ print ' "\tcall EnterCriticalSection@PLT\n"' . " \\\n";
+ } else {
+ print ' "\tpushl $X11DRV_CritSection\n"' . " \\\n";
+ print ' "\tcall EnterCriticalSection\n"' . " \\\n";
+ }
+}
+print ' "\tcall " #cdecl_name "@PLT\n"' . " \\\n";
+if($critical_section) {
+ if($pic) {
+ print ' "\tcall ." #stdcall_name ".getgot.leave\n"' . " \\\n";
+ print ' "." #stdcall_name ".getgot.leave:\n"' . " \\\n";
+ print ' "\tpopl %ebx\n"' . " \\\n";
+ print ' "\taddl $_GLOBAL_OFFSET_TABLE_+[.-." #stdcall_name
".getgot.leave], %ebx\n"' . " \\\n";
+ print ' "\tpushl X11DRV_CritSection@GOT(%ebx)\n"' . " \\\n";
+ print ' "\tcall LeaveCriticalSection@PLT\n"' . " \\\n";
+ } else {
+ print ' "\tpushl $X11DRV_CritSection\n"' . " \\\n";
+ print ' "\tcall LeaveCriticalSection\n"' . " \\\n";
+ }
+}
+print ' "\taddl $" #argsize ", %esp\n"' . " \\\n";
+print ' "\tret\n"' . " \\\n";
+print ' "\t.size\t" #stdcall_name ", .-" #stdcall_name "\n"' . " \\\n";
+print ' );' . "\n";
+
#
# Now, the functions from the include file
#
-open(INC, "/usr/X11R6/include/GL/gl.h") || die "Could not open GL/gl.h";
+open(INC, "/usr/include/GL/gl.h") || die "Could not open GL/gl.h";
while ($line = <INC>) {
if ($line =~ /GLAPI.*GLAPIENTRY/) {
# Start of a function declaration
@@ -22,9 +72,11 @@
if (($name !~ /(MESA|PGI|ARB|EXT)/) ||
($name =~ /MultiTexCoord/) ||
($name =~ /ActiveTextureARB/)) {
+
print
"/***********************************************************************\n"
;
print " *\t\t$name\n";
print " */\n";
+ print "\n/* " if $i386;
print "$ret WINAPI wine_$name(";
@rargs = ();
@names = ();
@@ -61,32 +113,41 @@
foreach (@rargs) {
print ", $_";
}
- print ") {\n";
- if ($ret !~ /void/) {
- print " $ret ret;\n";
- }
- print " ENTER_GL();\n";
- if ($ret !~ /void/) {
- print " ret = ";
+ if($i386) {
+ print ") */\n";
} else {
- print " ";
+ print ") {\n";
}
- print "$name(";
-
- $farg = shift @names;
- if ($farg) {
- print "$farg";
- foreach (@names) {
- print ", $_";
+ if(!$i386) {
+ if ($ret !~ /void/) {
+ print " $ret ret;\n";
}
+ print " ENTER_GL();\n";
+ if ($ret !~ /void/) {
+ print " ret = ";
+ } else {
+ print " ";
+ }
+ print "$name(";
+
+ $farg = shift @names;
+ if ($farg) {
+ print "$farg";
+
+ foreach (@names) {
+ print ", $_";
+ }
+ }
+ print ");\n";
+ print " LEAVE_GL();\n";
+ if ($ret !~ /void/) {
+ print " return ret;\n";
+ }
+ print "}\n\n";
+ } else {
+ print "THUNK_STDCALL_TO_CDECL(wine_$name,$name," .
4*($#rargs+2) . ")\n\n";
}
- print ");\n";
- print " LEAVE_GL();\n";
- if ($ret !~ /void/) {
- print " return ret;\n";
- }
- print "}\n\n";
}
}
}