www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Requesting D ABI clarifications

reply Gregor Richards <Richards codu.org> writes:
<preface>
I'm writing a D compiler using C as an intermediary language et cetera 
et cetera http://www.dsource.org/projects/tdc/
</preface>

I have the lofty goal of DMD compatibility on those systems that DMD 
supports, but unfortunately the ABI spec on the page isn't complete ... 
I believe I have everything right (it seems to work) except for:

A) Function calling semantics
	- Some initial tests putting 'this' in %eax generated almost 100% 
compatible code, but there were occasional strange, difficult to trace 
errors - these could just be my mistakes, or I could be doing calling 
semantics improperly.  Is that the only major difference from C calling 
conventions, or is there something else specific I need to do?

B) Exception handling
	- For GNU/Linux, DMD's exception handling is for all intents and 
purposes undocumed ... it mentions that it has a static location for 
exception handling buffers, but that's about it.  I think I should be 
able to get SEH working (I've found a few nice docs on it), but don't 
have much of a base point for GNU/Linux ... all I know is a few symbols 
(_deh_end et al).


Could somebody (Walter?) either explain how these work in DMD or point 
me to where these are explained?  I would really like to be compatible, 
or at least as compatible as possible, with the reference ABI ... 
hopefully this is doable from C (I'm willing to use GCC __attribute__'s 
and inline assembly where necessary, this is how I got a parameter into 
%eax).

Thanks for any response.

  - Gregor Richards
May 10 2006
next sibling parent Gregor Richards <Richards codu.org> writes:
Gregor Richards wrote:
     - Some initial tests putting 'this' in %eax generated almost 100% 
 compatible code, but there were occasional strange, difficult to trace 
 errors - these could just be my mistakes, [snip]

And were my mistakes. - Gregor Richards
May 10 2006
prev sibling next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Gregor Richards wrote:

 Could somebody (Walter?) either explain how these work in DMD or point 
 me to where these are explained?  I would really like to be compatible, 
 or at least as compatible as possible, with the reference ABI ... 
 hopefully this is doable from C (I'm willing to use GCC __attribute__'s 
 and inline assembly where necessary, this is how I got a parameter into 
 %eax).

Seconded, this would be a good thing for GDC compatibility as well... Currently one difference that I know about is how arrays are passed: typedef struct dstr dstr; // D string #ifndef __GDC__ // DMD currently uses a 32-bit hack typedef unsigned long long dstrret; static inline dstrret dstr_ret(const wxString& str) { return str.length() | (((dstrret)(unsigned long)str.data())<<32); } static inline dstrret dstr_ret(const wxString* str) { return str->length() | (((dstrret)(unsigned long)str->data())<<32); } #else #define dstrret dstr #define dstr_ret(str) dstr(str) #endif That is, they are returned as a struct in GDC and as a ulong in DMD. --anders PS. Example from wxD
May 11 2006
prev sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <e3u06e$2hg9$1 digitaldaemon.com>, Gregor Richards says...
<preface>
I'm writing a D compiler using C as an intermediary language et cetera 
et cetera http://www.dsource.org/projects/tdc/
</preface>

I have the lofty goal of DMD compatibility on those systems that DMD 
supports, but unfortunately the ABI spec on the page isn't complete ... 
I believe I have everything right (it seems to work) except for:

A) Function calling semantics
	- Some initial tests putting 'this' in %eax generated almost 100% 
compatible code, but there were occasional strange, difficult to trace 
errors - these could just be my mistakes, or I could be doing calling 
semantics improperly.  Is that the only major difference from C calling 
conventions, or is there something else specific I need to do?

B) Exception handling
	- For GNU/Linux, DMD's exception handling is for all intents and 
purposes undocumed ... it mentions that it has a static location for 
exception handling buffers, but that's about it.  I think I should be 
able to get SEH working (I've found a few nice docs on it), but don't 
have much of a base point for GNU/Linux ... all I know is a few symbols 
(_deh_end et al).


Could somebody (Walter?) either explain how these work in DMD or point 
me to where these are explained?  I would really like to be compatible, 
or at least as compatible as possible, with the reference ABI ... 
hopefully this is doable from C (I'm willing to use GCC __attribute__'s 
and inline assembly where necessary, this is how I got a parameter into 
%eax).

Thanks for any response.

  - Gregor Richards

Well, I do know that there are some variations in how D is supported across Windows and Linux. I say this because Walter himself seems rather dubious that aiming for cross-platform runtime linking (ala DDL) is "folly" since there are subtle differences. While I'd like to maintain that this only applies under certain circumstances, I honestly don't know what the baseline for binary compatiblity really is. A) I think you're on the right track with using eax. It was mentioned some time ago that the *first* parameter of any function/method signature is placed into eax rather than on the stack. I believe that eax is also used for return values - no suprises there. :) B) If memory serves, I think Walter went on the record as saying that the exception handling mechanisms are *different* between win32 and linux (the latter having to do with GDC/GDB compatibility I guess). I hope I'm wrong about that, as this just seems to make life harder than necessary. IMNSHO, using separate SEH mechanisms kind of ruins the idea of a true ABI. Other things, I've learned through a good amount of hacking. But they really center around how OMF objects are generated - I'm still learning the ELF side of things, but so far there aren't many suprises. Personally, I'd like to know more, and to see more of the ABI fleshed out so I can make some sound technical decisions in my project. Like you, I'd rather not just poke around in the dark and make reccomendations and decisions based on what just happens to work. - EricAnderton at yahoo
May 11 2006
next sibling parent Gregor Richards <Richards codu.org> writes:
pragma wrote:
 B) If memory serves, I think Walter went on the record as saying that the
 exception handling mechanisms are *different* between win32 and linux (the
 latter having to do with GDC/GDB compatibility I guess).  I hope I'm wrong
about
 that, as this just seems to make life harder than necessary.  IMNSHO, using
 separate SEH mechanisms kind of ruins the idea of a true ABI.

On Windows, it's using Windows' built-in exception handling. Can't exactly use that elsewhere :) - Gregor Richards
May 11 2006
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
pragma wrote:
 In article <e3u06e$2hg9$1 digitaldaemon.com>, Gregor Richards says...
 <preface>
 I'm writing a D compiler using C as an intermediary language et cetera 
 et cetera http://www.dsource.org/projects/tdc/
 </preface>

 I have the lofty goal of DMD compatibility on those systems that DMD 
 supports, but unfortunately the ABI spec on the page isn't complete ... 
 I believe I have everything right (it seems to work) except for:

 A) Function calling semantics
 	- Some initial tests putting 'this' in %eax generated almost 100% 
 compatible code, but there were occasional strange, difficult to trace 
 errors - these could just be my mistakes, or I could be doing calling 
 semantics improperly.  Is that the only major difference from C calling 
 conventions, or is there something else specific I need to do?

 B) Exception handling
 	- For GNU/Linux, DMD's exception handling is for all intents and 
 purposes undocumed ... it mentions that it has a static location for 
 exception handling buffers, but that's about it.  I think I should be 
 able to get SEH working (I've found a few nice docs on it), but don't 
 have much of a base point for GNU/Linux ... all I know is a few symbols 
 (_deh_end et al).


 Could somebody (Walter?) either explain how these work in DMD or point 
 me to where these are explained?  I would really like to be compatible, 
 or at least as compatible as possible, with the reference ABI ... 
 hopefully this is doable from C (I'm willing to use GCC __attribute__'s 
 and inline assembly where necessary, this is how I got a parameter into 
 %eax).

 Thanks for any response.

  - Gregor Richards

Well, I do know that there are some variations in how D is supported across Windows and Linux. I say this because Walter himself seems rather dubious that aiming for cross-platform runtime linking (ala DDL) is "folly" since there are subtle differences. While I'd like to maintain that this only applies under certain circumstances, I honestly don't know what the baseline for binary compatiblity really is.

Ideally, it should be that libraries can be built with one compiler and linked against code compiled with another. At the very least, this suggests that object layout, function calling conventions, and exception handling should be standardized for any specific platform.
 B) If memory serves, I think Walter went on the record as saying that the
 exception handling mechanisms are *different* between win32 and linux (the
 latter having to do with GDC/GDB compatibility I guess).  I hope I'm wrong
about
 that, as this just seems to make life harder than necessary.  IMNSHO, using
 separate SEH mechanisms kind of ruins the idea of a true ABI.

While I think this is certainly possible, it would be somewhat more difficult as you wouldn't be able to use Windows SEH. But perhaps binary compatibility between Windows and Unix platforms isn't a tremendous concern? Sean
May 11 2006
parent pragma <pragma_member pathlink.com> writes:
In article <e3vos6$1quk$1 digitaldaemon.com>, Sean Kelly says...
pragma wrote:
 Well, I do know that there are some variations in how D is supported across
 Windows and Linux.  I say this because Walter himself seems rather dubious that
 aiming for cross-platform runtime linking (ala DDL) is "folly" since there are
 subtle differences.  While I'd like to maintain that this only applies under
 certain circumstances, I honestly don't know what the baseline for binary
 compatiblity really is.

Ideally, it should be that libraries can be built with one compiler and linked against code compiled with another. At the very least, this suggests that object layout, function calling conventions, and exception handling should be standardized for any specific platform.

Agreed. Again, I wish there was a firm statement in the ABI covering these points. Personally, I consider all of those points a "must have" as it makes writing a third-party D compiler almost impossible (as Gregor has demonstrated).
 B) If memory serves, I think Walter went on the record as saying that the
 exception handling mechanisms are *different* between win32 and linux (the
 latter having to do with GDC/GDB compatibility I guess).  I hope I'm wrong
about
 that, as this just seems to make life harder than necessary.  IMNSHO, using
 separate SEH mechanisms kind of ruins the idea of a true ABI.

While I think this is certainly possible, it would be somewhat more difficult as you wouldn't be able to use Windows SEH.

Right, the compiler would have to include some kind of thunk between D's standard exception handling and the native exception handling (for one or more platforms, depending on what that standard is) when calling extern(C) and extern(Windows) functions. So there'd be an efficency loss in some places for talking with legacy code, but D-to-D calls would work just fine.
But perhaps 
binary compatibility between Windows and Unix platforms isn't a 
tremendous concern?

I guess it depends on what folks really want. :) From where I'm standing its seems like a "nobody's concerned because they don't have it yet" kind of thing. Granted, that's just unsubstantiated opinion, but I cannot fathom developers actively rejecting the idea were it suddenly made practical. - EricAnderton at yahoo
May 11 2006
prev sibling next sibling parent reply Walter Bright <newshound digitalmars.com> writes:
pragma wrote:
 Well, I do know that there are some variations in how D is supported across
 Windows and Linux.  I say this because Walter himself seems rather dubious that
 aiming for cross-platform runtime linking (ala DDL) is "folly" since there are
 subtle differences.  While I'd like to maintain that this only applies under
 certain circumstances, I honestly don't know what the baseline for binary
 compatiblity really is.

The baseline is being ABI compatible with the host C compiler on the target platform.
 A) I think you're on the right track with using eax. It was mentioned some time
 ago that the *first* parameter of any function/method signature is placed into
 eax rather than on the stack.  I believe that eax is also used for return
values
 - no suprises there. :)

Actually, the *last* parameter goes into EAX, if it fits.
 B) If memory serves, I think Walter went on the record as saying that the
 exception handling mechanisms are *different* between win32 and linux (the
 latter having to do with GDC/GDB compatibility I guess).  I hope I'm wrong
about
 that, as this just seems to make life harder than necessary.  IMNSHO, using
 separate SEH mechanisms kind of ruins the idea of a true ABI.

They are different. Win32 uses the NT SEH, which has no counterpart on linux. For linux, I would use g++'s .eh_frame method, but it is (as far as I can tell) completely undocumented. So I gave up on that, and simply used what I'd invented for C++ exceptions on 32 bit DOSX. The code to make it work is in phobos/internal/deh2.d.
 Other things, I've learned through a good amount of hacking. But they really
 center around how OMF objects are generated - I'm still learning the ELF side
of
 things, but so far there aren't many suprises.
 
 Personally, I'd like to know more, and to see more of the ABI fleshed out so I
 can make some sound technical decisions in my project.  Like you, I'd rather
not
 just poke around in the dark and make reccomendations and decisions based on
 what just happens to work.
 
 - EricAnderton at yahoo

May 13 2006
parent pragma <pragma_member pathlink.com> writes:
Gotcha. :)  

Sorry about the disinformation there, and thanks for shedding some light on all
this.

- Eric

In article <e443as$1kmt$1 digitaldaemon.com>, Walter Bright says...
pragma wrote:
 Well, I do know that there are some variations in how D is supported across
 Windows and Linux.  I say this because Walter himself seems rather dubious that
 aiming for cross-platform runtime linking (ala DDL) is "folly" since there are
 subtle differences.  While I'd like to maintain that this only applies under
 certain circumstances, I honestly don't know what the baseline for binary
 compatiblity really is.

The baseline is being ABI compatible with the host C compiler on the target platform.
 A) I think you're on the right track with using eax. It was mentioned some time
 ago that the *first* parameter of any function/method signature is placed into
 eax rather than on the stack.  I believe that eax is also used for return
values
 - no suprises there. :)

Actually, the *last* parameter goes into EAX, if it fits.
 B) If memory serves, I think Walter went on the record as saying that the
 exception handling mechanisms are *different* between win32 and linux (the
 latter having to do with GDC/GDB compatibility I guess).  I hope I'm wrong
about
 that, as this just seems to make life harder than necessary.  IMNSHO, using
 separate SEH mechanisms kind of ruins the idea of a true ABI.

They are different. Win32 uses the NT SEH, which has no counterpart on linux. For linux, I would use g++'s .eh_frame method, but it is (as far as I can tell) completely undocumented. So I gave up on that, and simply used what I'd invented for C++ exceptions on 32 bit DOSX. The code to make it work is in phobos/internal/deh2.d.
 Other things, I've learned through a good amount of hacking. But they really
 center around how OMF objects are generated - I'm still learning the ELF side
of
 things, but so far there aren't many suprises.
 
 Personally, I'd like to know more, and to see more of the ABI fleshed out so I
 can make some sound technical decisions in my project.  Like you, I'd rather
not
 just poke around in the dark and make reccomendations and decisions based on
 what just happens to work.
 
 - EricAnderton at yahoo


May 13 2006
prev sibling parent Brad Roberts <braddr puremagic.com> writes:
On Sat, 13 May 2006, Walter Bright wrote:

 pragma wrote:
 B) If memory serves, I think Walter went on the record as saying that the
 exception handling mechanisms are *different* between win32 and linux (the
 latter having to do with GDC/GDB compatibility I guess).  I hope I'm wrong
 about
 that, as this just seems to make life harder than necessary.  IMNSHO, using
 separate SEH mechanisms kind of ruins the idea of a true ABI.

They are different. Win32 uses the NT SEH, which has no counterpart on linux. For linux, I would use g++'s .eh_frame method, but it is (as far as I can tell) completely undocumented. So I gave up on that, and simply used what I'd invented for C++ exceptions on 32 bit DOSX. The code to make it work is in phobos/internal/deh2.d.

Here's the documentation for the industry standard abi that's being used by essentially all unix compiler writers for the last several years (gcc as of version 3): http://www.codesourcery.com/cxx-abi/ http://www.codesourcery.com/cxx-abi/abi-eh.html Later, Brad
May 13 2006