]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
reflect: Fix MakeFunc for 386 when returning a struct.
authorIan Lance Taylor <ian@gcc.gnu.org>
Sat, 30 Nov 2013 17:14:50 +0000 (17:14 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Sat, 30 Nov 2013 17:14:50 +0000 (17:14 +0000)
When a 386 function returns a struct, it needs to return using
an rtd instruction that pops the hidden struct parameter off
the stack.  That wasn't happening.

From-SVN: r205551

libgo/go/reflect/makefunc_386.S
libgo/go/reflect/makefuncgo_386.go

index 5878bc44c56317f089f1d93243e40b5802836e61..20e542b062b6b2f4f394794b8b4db254943e8098 100644 (file)
@@ -26,8 +26,11 @@ reflect.makeFuncStub:
             esp uint32         // 0x0
             eax uint32         // 0x4
             st0 uint64         // 0x8
+            rs  int32          // 0x10
           }
-       */
+          The rs field is set by the function to a non-zero value if
+          the function takes a struct hidden pointer that must be
+          popped off the stack.  */
 
        pushl   %ebp
 .LCFI0:
@@ -73,12 +76,19 @@ reflect.makeFuncStub:
        movsd   -16(%ebp), %xmm0
 #endif
 
+       movl    -8(%ebp), %edx
+
        addl    $36, %esp
        popl    %ebx
 .LCFI3:
        popl    %ebp
 .LCFI4:
+
+       testl   %edx,%edx
+       jne     1f
        ret
+1:
+       ret     $4
 .LFE1:
 #ifdef __ELF__
        .size   reflect.makeFuncStub, . - reflect.makeFuncStub
index 0fac1f488a46765b636ee5736f27ba95986a3726..7559af6f6acc6f6a9ed5906c10d72950d09e6f45 100644 (file)
@@ -16,6 +16,7 @@ type i386Regs struct {
        esp uint32
        eax uint32 // Value to return in %eax.
        st0 uint64 // Value to return in %st(0).
+       sr  int32  // Set to non-zero if hidden struct pointer.
 }
 
 // MakeFuncStubGo implements the 386 calling convention for MakeFunc.
@@ -56,10 +57,12 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) {
        in := make([]Value, 0, len(ftyp.in))
        ap := uintptr(regs.esp)
 
+       regs.sr = 0
        var retPtr unsafe.Pointer
        if retStruct {
                retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap))
                ap += ptrSize
+               regs.sr = 1
        }
 
        for _, rt := range ftyp.in {