www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9931] New: Bus error interfacing with C function returning structs with floats

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931

           Summary: Bus error interfacing with C function returning
                    structs with floats
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Mac OS X
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: doob me.com


--- Comment #0 from Jacob Carlborg <doob me.com> 2013-04-14 09:25:06 PDT ---
This code:

http://pastebin.com/U5XdFfDq

Will result in a bus error when compiled as 32bit. Three ways the bus error
won't happen:

* If I compile as 64bit everything works fine
* If the function "foo" is moved inline in the "main" function everything works
fine
* If I store the return value of "fp" in "foo" in a temporary variable and then
return it

Mac OS X 10.8.2.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 14 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Martin Nowak <code dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |code dawg.eu
         Resolution|                            |INVALID


--- Comment #1 from Martin Nowak <code dawg.eu> 2013-04-14 09:53:35 PDT ---
You can't cast the "..." part o a C vararg function away.
You also don't pass a pointer to the struct return to objc_msgSend_stret, which
is the first parameter.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 14 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Jacob Carlborg <doob me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |


--- Comment #2 from Jacob Carlborg <doob me.com> 2013-04-14 11:43:05 PDT ---
You're supposed to invoke the functions like that. The objc_msgSend functions
need to be casted to the correct signature.

http://stackoverflow.com/questions/8405737/how-do-i-return-a-struct-value-from-a-runtime-defined-class-method-under-arc

This works perfectly fine in C:

http://pastebin.com/cTfn0PJS

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 14 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #3 from Martin Nowak <code dawg.eu> 2013-04-14 16:56:04 PDT ---
NSRect foo (id screen)
{
    alias extern (C) NSRect function (id, SEL) frameFp;
    auto fp = cast(frameFp) &objc_msgSend_stret;
    return fp(screen, sel_registerName("visibleFrame".ptr));
}

- You omit the pointer to the return value, that might accidently work on some
ABIs because a hidden pointer to the return value is passed as first argument.

What's the problem with this?

NSRect foo(id screen)
{
    NSRect res;
    objc_msgSend_stret(&res, screen, sel_registerName("visibleFrame"));
    return res;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 14 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #4 from Jacob Carlborg <doob me.com> 2013-04-14 23:38:54 PDT ---
(In reply to comment #3)
 NSRect foo (id screen)
 {
     alias extern (C) NSRect function (id, SEL) frameFp;
     auto fp = cast(frameFp) &objc_msgSend_stret;
     return fp(screen, sel_registerName("visibleFrame".ptr));
 }
 
 - You omit the pointer to the return value, that might accidently work on some
 ABIs because a hidden pointer to the return value is passed as first argument.
I don't know why it behaves like this but that's how you're supposed to invoke the function. This is the Objective-C runtime and it's kind of special.
 What's the problem with this?
 
 NSRect foo(id screen)
 {
     NSRect res;
     objc_msgSend_stret(&res, screen, sel_registerName("visibleFrame"));
     return res;
 }
On Mac OS X 10.6.3 it segfaults. I haven't tried on 10.8.2 yet. It also segfaults if I cast it to: extern (C) void function (NSRect*, id, SEL). BTW, the original example doesn't _not_ cause a bus error on Mac OS X 10.6.3. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 14 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #5 from Jacob Carlborg <doob me.com> 2013-04-16 00:10:33 PDT ---
Here's one of my post from the discussion of this issue at the newsgroup:

http://forum.dlang.org/thread/kkefk8$2663$1 digitalmars.com

I've done some investigation about how the "objc_msgSend" family of functions
work, including "objc_msgSend_stret". For those who don't know they're are part
of the Objective-C runtime used for calling Objective-C methods.

These functions are _not_ regular C functions, they're completely implemented
using assembly. What they basically do is looking up the Objective-C method to
call and just calls it (some caching is involved as well).

What's special about this is that it won't mess with any resister or stack used
for passing function arguments or sending back return values. What happens when
it has found the correct Objective-C method is that it will just jump to the
function. All registers and the stack are already correct, from the call to the
objc_msgSend itself. I assume that is way the objc_msgSend method need to be
cast to the correct signature before calling it. We don't want to use the ABI
for variadic functions (as declared by objc_msgSend), we want the ABI used for
the target function, that is, the Objective-C method.

An Objective-C method is implement like a regular C function, following the ABI
of the platform. It has to take at least these two parameters:

void foo (id self, SEL _cmd);

"self" would be the object we're calling the method on. "_cmd" is the selector
(method) being called.

Then what's objc_msgSend_stret used for. The objc_msgSend_stret function is
used for returning structs that are too large to fit in the register. This is
completely dependent on the platform ABI.

I don't know if this helps.

Some info about how objc_msgSend works:

http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/

Some info about why objc_msgSend_stret exists:

http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 16 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #6 from Jacob Carlborg <doob me.com> 2013-04-16 12:28:13 PDT ---
I think I found smaller test case for this problem, without the casts and
Objective-C runtime functions:

http://forum.dlang.org/thread/kkk8kh$2jsu$1 digitalmars.com

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 16 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #7 from Martin Nowak <code dawg.eu> 2013-04-16 17:57:26 PDT ---
Seems like OSX deviates from the SysV IA-32 ABI for memory struct returns.
The callee does NOT return the hidden pointer in EAX.
Instead the caller has to use the value passed as argument.

0x0000267c <D4test3barFZS4test3Foo+20>: call   0x26a0 <foo>
0x00002681 <D4test3barFZS4test3Foo+25>: add    $0xc,%esp
0x00002684 <D4test3barFZS4test3Foo+28>: mov    %eax,%esi // <- EAX is trashed
0x00002686 <D4test3barFZS4test3Foo+30>: mov    -0x4(%ebp),%edi
0x00002689 <D4test3barFZS4test3Foo+33>: movsl  %ds:(%esi),%es:(%edi)
0x0000268a <D4test3barFZS4test3Foo+34>: movsl  %ds:(%esi),%es:(%edi)
0x0000268b <D4test3barFZS4test3Foo+35>: movsl  %ds:(%esi),%es:(%edi)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 16 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #8 from Jacob Carlborg <doob me.com> 2013-04-16 23:38:53 PDT ---
(In reply to comment #7)
 Seems like OSX deviates from the SysV IA-32 ABI for memory struct returns.
 The callee does NOT return the hidden pointer in EAX.
 Instead the caller has to use the value passed as argument.
I don't know if this is what you're but the the ABI documentation says: "When a function returns a structure or union larger than 8 bytes, the caller passes a pointer to appropriate storage as the first argument to the function." And: "The called function returns structures according to their aligned size. * Structures 1 or 2 bytes in size are placed in EAX. * Structures 4 or 8 bytes in size are placed in: EAX and EDX. * Structures of other sizes are placed at the address supplied by the caller. For example, the C++ language occasionally forces the compiler to return a value in memory when it would normally be returned in registers. See “Passing Arguments” for more information." http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 16 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931


John Colvin <john.loughran.colvin gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |john.loughran.colvin gmail.
                   |                            |com


--- Comment #9 from John Colvin <john.loughran.colvin gmail.com> 2013-04-17
08:04:52 BST ---
(In reply to comment #7)
 0x0000267c <D4test3barFZS4test3Foo+20>: call   0x26a0 <foo>
 0x00002681 <D4test3barFZS4test3Foo+25>: add    $0xc,%esp
 0x00002684 <D4test3barFZS4test3Foo+28>: mov    %eax,%esi // <- EAX is trashed
 0x00002686 <D4test3barFZS4test3Foo+30>: mov    -0x4(%ebp),%edi
 0x00002689 <D4test3barFZS4test3Foo+33>: movsl  %ds:(%esi),%es:(%edi)
 0x0000268a <D4test3barFZS4test3Foo+34>: movsl  %ds:(%esi),%es:(%edi)
 0x0000268b <D4test3barFZS4test3Foo+35>: movsl  %ds:(%esi),%es:(%edi)
You're reading it the wrong way around, at&t is src,des -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #10 from John Colvin <john.loughran.colvin gmail.com> 2013-04-17
10:58:11 BST ---
(In reply to comment #9)
 (In reply to comment #7)
 0x0000267c <D4test3barFZS4test3Foo+20>: call   0x26a0 <foo>
 0x00002681 <D4test3barFZS4test3Foo+25>: add    $0xc,%esp
 0x00002684 <D4test3barFZS4test3Foo+28>: mov    %eax,%esi // <- EAX is trashed
 0x00002686 <D4test3barFZS4test3Foo+30>: mov    -0x4(%ebp),%edi
 0x00002689 <D4test3barFZS4test3Foo+33>: movsl  %ds:(%esi),%es:(%edi)
 0x0000268a <D4test3barFZS4test3Foo+34>: movsl  %ds:(%esi),%es:(%edi)
 0x0000268b <D4test3barFZS4test3Foo+35>: movsl  %ds:(%esi),%es:(%edi)
You're reading it the wrong way around, at&t is src,des
Sorry, my mistake, I misunderstood you. Martin, you are completely correct. Dmd is presuming that the pointer to the struct is returned in eax but foo sets that to 0, as it is entitled to. Hence movs is reading from 0. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Jacob Carlborg <doob me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|D2                          |D1 & D2
           Severity|normal                      |critical


--- Comment #11 from Jacob Carlborg <doob me.com> 2013-04-17 04:16:38 PDT ---
Raising to critical.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #12 from Jacob Carlborg <doob me.com> 2013-04-17 04:18:45 PDT ---
I'm still wondering though:

* Why does it work on Mac OS X 10.6.3, luck?
* Is using a temporary variable in "bar" a safe workaround?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #13 from Jacob Carlborg <doob me.com> 2013-04-17 04:20:57 PDT ---
Would "Mac OS X ABI not followed when returning structs for extern (C)" be a
better title for the issue. Can I changed that?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #14 from John Colvin <john.loughran.colvin gmail.com> 2013-04-17
12:55:37 BST ---
(In reply to comment #12)
 I'm still wondering though:
 
 * Why does it work on Mac OS X 10.6.3, luck?
http://forum.dlang.org/post/ixoawrwanlopvgzljost forum.dlang.org
 * Is using a temporary variable in "bar" a safe workaround?
Based on how the codegen changes with adding a temporary variable in linux, it should be safe. Disassembly from OS X could confirm that. BUT: That's only for this particular example, with a particular set of compiler setting. It's exactly the sort of thing optimisers mess around with. Personally I would not risk it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #15 from John Colvin <john.loughran.colvin gmail.com> 2013-04-17
12:56:05 BST ---
(In reply to comment #13)
 Would "Mac OS X ABI not followed when returning structs for extern (C)" be a
 better title for the issue. Can I changed that?
Much better. Changed it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #16 from Jacob Carlborg <doob me.com> 2013-04-17 05:17:13 PDT ---
(In reply to comment #14)

 Based on how the codegen changes with adding a temporary variable in linux, it
 should be safe. Disassembly from OS X could confirm that.
 
 BUT:
 
 That's only for this particular example, with a particular set of compiler
 setting. It's exactly the sort of thing optimisers mess around with. Personally
 I would not risk it.
I suspected that. The thing is that I'm stuck with a D1 code base. I want to finished that before I port it to D2. So I'm hoping that a fix for this will be applied to the D1 branch as well. Otherwise I guess I'll have to avoid any optimizations until I've ported it to D2. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #17 from Jacob Carlborg <doob me.com> 2013-04-17 05:17:36 PDT ---
(In reply to comment #15)

 Much better. Changed it.
Cool, thanks. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #18 from Jacob Carlborg <doob me.com> 2013-04-23 01:37:46 PDT ---
If it's not clear, this issue happens for both 32 and 64bit.

Also, if I implement the C function in D with extern (C) it won't segfault.
This would indicate that DMD does something wrong in this case as well.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 23 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #19 from Martin Nowak <code dawg.eu> 2013-04-23 17:56:10 PDT ---
(In reply to comment #18)
 If it's not clear, this issue happens for both 32 and 64bit.
 
 Also, if I implement the C function in D with extern (C) it won't segfault.
 This would indicate that DMD does something wrong in this case as well.
It doesn't do anything wrong, it just sets EAX to contain the hidden pointer before returning. This is required by the SysV IA-32 ABI but apparently not on OSX. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 23 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #20 from Jacob Carlborg <doob me.com> 2013-04-23 23:30:49 PDT ---
(In reply to comment #19)

 It doesn't do anything wrong, it just sets EAX to contain the hidden pointer
 before returning. This is required by the SysV IA-32 ABI but apparently not on
 OSX.
First, Mac OS X uses a modified version of the SysV IA-32 ABI (there's a link a couple of posts up). Second, If an extern (C) function doesn't behave the same as a C function, in regards to ABI and calling conventions, I would say that the compiler is doing something wrong. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 23 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com


--- Comment #21 from Walter Bright <bugzilla digitalmars.com> 2013-04-25
23:09:41 PDT ---
(In reply to comment #0)
 This code:
 
 http://pastebin.com/U5XdFfDq
Here's the code from pastebin. I'd prefer small examples to be posted here rather than linked to. -------------------------------------------- version (D_LP64) alias double CGFloat; else alias float CGFloat; struct NSRect { NSPoint origin; NSSize size; } public struct NSPoint { public CGFloat x;// = 0.0; public CGFloat y;// = 0.0; } struct NSSize { public CGFloat width;// = 0.0; public CGFloat height;// = 0.0; } alias char* SEL; alias objc_class* Class; alias objc_object* id; struct objc_object { Class isa; } struct objc_class; extern (C) { Class objc_getClass (in char* name); id objc_msgSend (id theReceiver, SEL theSelector, ...); void objc_msgSend_stret(void* stretAddr, id theReceiver, SEL theSelector, ...); SEL sel_registerName (in char* str); } extern (C) int printf(in char*, ...); NSRect foo (id screen) { alias extern (C) NSRect function (id, SEL) frameFp; auto fp = cast(frameFp) &objc_msgSend_stret; return fp(screen, sel_registerName("visibleFrame".ptr)); } int main () { auto cls = objc_getClass("NSScreen".ptr); alias extern (C) id function (id, SEL) screenFp; auto screen = (cast(screenFp)&objc_msgSend)(cast(id) cls, sel_registerName("mainScreen".ptr)); auto frame = foo(screen); printf("x=%f y=%f width=%f height=%f\n".ptr, frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); return 0; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 25 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #22 from Jacob Carlborg <doob me.com> 2013-04-25 23:35:21 PDT ---
(In reply to comment #21)

 Here's the code from pastebin. I'd prefer small examples to be posted here
 rather than linked to.
Fair enough. Here's the latest test case. It doesn't depend on any external functions or casts: C code: struct Foo { int a; int b; int c; }; typedef struct Foo Foo; Foo foo (int a) { Foo f; f.a = 1; f.b = 2; f.c = 3; return f; } D code: struct Foo { int a; int b; int c; } extern (C) Foo foo (int a); Foo bar () { return foo(0); } extern (C) int printf(in char*, ...); void main () { auto frame = bar(); printf("a=%d b=%d c=%d\n".ptr, frame.a, frame.b, frame.c); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 25 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #23 from Walter Bright <bugzilla digitalmars.com> 2013-04-26
00:10:24 PDT ---
https://github.com/D-Programming-Language/dmd/pull/1938

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 26 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #24 from github-bugzilla puremagic.com 2013-04-26 08:50:36 PDT ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/a2c2ddc1be1890e48ac579a77037fb76bc322572
fix Issue 9931 - Mac OS X ABI not followed when returning structs for extern
(C)

https://github.com/D-Programming-Language/dmd/commit/5167cc1165b7d37c76817ab6c8d353963cf572a8
Merge pull request #1938 from WalterBright/fix9931

fix Issue 9931 - Mac OS X ABI not followed when returning structs for extern
(C)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 26 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #25 from github-bugzilla puremagic.com 2013-04-26 11:05:39 PDT ---
Commit pushed to dmd-1.x at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/3646e40bc1ebb451c361e4f6c624dd5a1172ef08
Merge pull request #1938 from WalterBright/fix9931

fix Issue 9931 - Mac OS X ABI not followed when returning structs for extern
(C)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 26 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|                            |FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 26 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931


Jacob Carlborg <doob me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |


--- Comment #26 from Jacob Carlborg <doob me.com> 2013-04-27 03:56:14 PDT ---
There's still problem with 64bit. It doesn't segfault now but the values of the
returned struct is completely wrong. Example:

a=-2077579799 b=32767 c=1517257856

The disassembly for the 64bit C version looks like this (all functions in the
same object file) :

main:
Relocation information (__TEXT,__text) 4 entries
address  pcrel length extern type    scattered symbolnum/value
000000ef True  long   True   BRANCH  False     _printf
000000c2 True  long   True   BRANCH  False     _bar
000000ab True  long   True   SIGNED  False     L_.str
0000005b True  long   True   BRANCH  False     _foo
Relocation information (__LD,__compact_unwind) 3 entries
address  pcrel length extern type    scattered symbolnum/value
00000040 False quad   False  UNSIGND False     1 (__TEXT,__text)
00000020 False quad   False  UNSIGND False     1 (__TEXT,__text)
00000000 False quad   False  UNSIGND False     1 (__TEXT,__text)
(__TEXT,__text) section
_foo:
0000000000000000    pushq    %rbp
0000000000000001    movq    %rsp,%rbp
0000000000000004    movl    %edi,0xec(%rbp)
0000000000000007    movl    $0x00000001,0xe0(%rbp)
000000000000000e    movl    $0x00000002,0xe4(%rbp)
0000000000000015    movl    $0x00000003,0xe8(%rbp)
000000000000001c    movq    0xe0(%rbp),%rax
0000000000000020    movq    %rax,0xf0(%rbp)
0000000000000024    movl    $0x00000003,0xf8(%rbp)
000000000000002b    movl    0xf0(%rbp),%edi
000000000000002e    movl    0xf4(%rbp),%ecx
0000000000000031    movl    0xf8(%rbp),%edx
0000000000000034    movl    %edx,0xd8(%rbp)
0000000000000037    movl    %ecx,0xd4(%rbp)
000000000000003a    movl    %edi,0xd0(%rbp)
000000000000003d    movq    0xd0(%rbp),%rax
0000000000000041    movl    0xd8(%rbp),%edx
0000000000000044    popq    %rbp
0000000000000045    ret
0000000000000046    nopw    %cs:_foo(%rax,%rax)
_bar:
0000000000000050    pushq    %rbp
0000000000000051    movq    %rsp,%rbp
0000000000000054    subq    $0x30,%rsp
0000000000000058    xorl    %edi,%edi
000000000000005a    callq    _foo
000000000000005f    movl    %edx,0xe8(%rbp)
0000000000000062    movq    %rax,0xe0(%rbp)
0000000000000066    movl    0xe0(%rbp),%edx
0000000000000069    movl    0xe4(%rbp),%edi
000000000000006c    movl    0xe8(%rbp),%ecx
000000000000006f    movl    %ecx,0xf8(%rbp)
0000000000000072    movl    %edi,0xf4(%rbp)
0000000000000075    movl    %edx,0xf0(%rbp)
0000000000000078    movl    0xf0(%rbp),%ecx
000000000000007b    movl    0xf4(%rbp),%edx
000000000000007e    movl    0xf8(%rbp),%edi
0000000000000081    movl    %edi,0xd8(%rbp)
0000000000000084    movl    %edx,0xd4(%rbp)
0000000000000087    movl    %ecx,0xd0(%rbp)
000000000000008a    movq    0xd0(%rbp),%rax
000000000000008e    movl    0xd8(%rbp),%edx
0000000000000091    addq    $0x30,%rsp
0000000000000095    popq    %rbp
0000000000000096    ret
0000000000000097    nopw    _foo(%rax,%rax)
_main:
00000000000000a0    pushq    %rbp
00000000000000a1    movq    %rsp,%rbp
00000000000000a4    subq    $0x40,%rsp
00000000000000a8    leaq    L_.str(%rip),%rax
00000000000000af    movl    $_foo,0xfc(%rbp)
00000000000000b6    movl    %edi,0xf8(%rbp)
00000000000000b9    movq    %rsi,0xf0(%rbp)
00000000000000bd    movq    %rax,0xc8(%rbp)
00000000000000c1    callq    _bar
00000000000000c6    movl    %edx,0xd8(%rbp)
00000000000000c9    movq    %rax,0xd0(%rbp)
00000000000000cd    movl    0xd0(%rbp),%edx
00000000000000d0    movl    0xd4(%rbp),%edi
00000000000000d3    movl    0xd8(%rbp),%ecx
00000000000000d6    movl    %ecx,0xe8(%rbp)
00000000000000d9    movl    %edi,0xe4(%rbp)
00000000000000dc    movl    %edx,0xe0(%rbp)
00000000000000df    movl    0xe0(%rbp),%esi
00000000000000e2    movl    0xe4(%rbp),%edx
00000000000000e5    movl    0xe8(%rbp),%ecx
00000000000000e8    movq    0xc8(%rbp),%rdi
00000000000000ec    movb    $_foo,%al
00000000000000ee    callq    _printf
00000000000000f3    movl    $_foo,%ecx
00000000000000f8    movl    %eax,0xc4(%rbp)
00000000000000fb    movl    %ecx,%eax
00000000000000fd    addq    $0x40,%rsp
0000000000000101    popq    %rbp
0000000000000102    ret

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 27 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #27 from Martin Nowak <code dawg.eu> 2013-04-27 06:48:42 PDT ---
 * If I compile as 64bit everything works fine
 There's still problem with 64bit.
Can you be a little more precise? Does it fail for the code in comment 22?
 all functions in the same object file
So everything in C or D? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 27 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9931



--- Comment #28 from Jacob Carlborg <doob me.com> 2013-04-27 07:15:30 PDT ---
(In reply to comment #27)
 Can you be a little more precise?
 Does it fail for the code in comment 22?
Yes, the code in comment 22.
 So everything in C or D?
The disassembly is in C. Below is the disassembly for the D version of the "bar" function from comment 22: _D4main3barFZS4main3Foo: 0000000100000b6c pushq %rbp 0000000100000b6d movq %rsp,%rbp 0000000100000b70 subq $0x20,%rsp 0000000100000b74 movq %rdi,0xf8(%rbp) 0000000100000b78 xorl %esi,%esi 0000000100000b7a leaq 0xe8(%rbp),%rdi 0000000100000b7e callq _foo 0000000100000b83 leaq 0xe8(%rbp),%rsi 0000000100000b87 movq 0xf8(%rbp),%rdi 0000000100000b8b movsq (%esi),(%edi) 0000000100000b8d movsb (%esi),(%edi) 0000000100000b8e movsb (%esi),(%edi) 0000000100000b8f movsb (%esi),(%edi) 0000000100000b90 movsb (%esi),(%edi) 0000000100000b91 movq 0xf8(%rbp),%rax 0000000100000b95 leave 0000000100000b96 ret 0000000100000b97 nopl 0x00(%rax,%rax) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 27 2013