When calling _d_throw dmd always uses the name _d_throw@4 regardless of the operating system. Dynamic ELF libraries support versioning symbols using the syntax name@version. Therefore when ld encounters _d_throw@4 it reads "symbol _d_throw, version 4" and complains that there is no version 4. As long as this isn't fixed Dynamic D libraries can't be created on operating systems using ELF executables.
See also:
http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=112648
and the links referred in the newspost.
Comment #1 by johannespfau — 2010-06-27T10:46:51Z
Created attachment 678
Patch for dmd2
Patch for dmd2.
This patch also fixes the _seh_longjmp_unwind@4 and _cpp_longjmp_unwind@4 symbols. This might not be necessary, it seems those symbols are used on windows only.
This also requires a patch to druntime, and both must be applied or there will be link errors on linux.
BTW: If I understand windows name mangling correctly, @4 means the arguments have size 4 bytes. As the argument is a pointer hardcoding it to 4 will not work on 64bit.
Comment #2 by johannespfau — 2010-06-27T10:53:23Z
Created attachment 679
Patch for druntime
This is the patch required for druntime.
In /src/rt/deh2.d "void _d_throw(Object *h)" must be extern(Windows) for windows and extern(C) for all other platforms.
In /src/rt/deh.c "void __stdcall _d_throw(Object *h)" must have __stdcall for windows and "void _d_throw(Object *h)" for all other platforms.
The other 2 symbols modified in the dmd patch are not used in druntime.
This patch places the whole functions in version blocks. Therefore a lot of code is duplicated. I guess this could be done in a better way, but I could get it to work with e.g. alias.
Comment #3 by johannespfau — 2010-06-27T11:04:12Z
I wanted to say "but I could _not_ get
it to work with e.g. alias".
A different solution to this problem is to use extern(C) everywhere, even for windows. This also solves the 64bit problem. However, I'm not sure why __stdcall was used on windows, maybe it is needed (performance related?).
Comment #4 by leandro.lucarella — 2010-06-27T17:00:08Z
First of all, thanks for tackling this!
I wonder if there is any way to avoid code duplication in druntime, as (unless I'm missing something) the _d_throw() body seems to be the same for Windows and Posix, only the function signature changes.
Isn't extern (System) -which, btw, seems to be missing in the docs- exactly for this case?
Comment #5 by e.insafutdinov — 2010-06-28T03:11:27Z
To avoid code duplication in case extern(System) won't help you here you can use string mixins.
P.S. Is it the only issue that prevents dmd from being able to build shared libraries on linux or there are more?
Comment #6 by doob — 2010-06-28T05:57:47Z
The runtime needs to be modified of course, then there is always the chance of new bugs showing up.
Comment #7 by leandro.lucarella — 2010-06-28T06:40:40Z
(In reply to comment #5)
> To avoid code duplication in case extern(System) won't help you here
Why? Doesn't extern(System) means extern(Windows) if version is Windows and extern (C) if version is Posix?
Comment #8 by e.insafutdinov — 2010-06-28T06:46:39Z
(In reply to comment #7)
> (In reply to comment #5)
> > To avoid code duplication in case extern(System) won't help you here
>
> Why? Doesn't extern(System) means extern(Windows) if version is Windows and
> extern (C) if version is Posix?
Yes that's entirely correct. I meant that in case you have some other types of linkage or other variations in function signature you can use string mixins. Sorry for confusion.
Comment #9 by leandro.lucarella — 2010-06-28T06:50:36Z
(In reply to comment #8)
> (In reply to comment #7)
> > (In reply to comment #5)
> > > To avoid code duplication in case extern(System) won't help you here
> >
> > Why? Doesn't extern(System) means extern(Windows) if version is Windows and
> > extern (C) if version is Posix?
>
> Yes that's entirely correct. I meant that in case you have some other types of
> linkage or other variations in function signature you can use string mixins.
> Sorry for confusion.
Woops, my eyes completely ignored the "in case". My mistake =)
Comment #10 by johannespfau — 2010-06-28T07:53:42Z
Created attachment 683
Updated patch for druntime
Added a new patch for druntime using extern(System). If extern(System) is extern(Windows) on windows and extern(C) on posix, this will work fine, I just did not know about extern(System).
I also removed the version blocks in src/rt/deh.c (first it's a c file, so version blocks don't belong there anyway, second the whole file is in an "#if _WIN32" block)
(a stupid mistake, deh.c is not compiled on posix, so I didn't see the error)
(related note: deh2.d is not used on windows, so extern(C) would work as well, just the current extern(Windows) can't work)
@Eldar Insafutdinov thanks for the string mixin advice
Comment #11 by johannespfau — 2010-06-28T08:04:46Z
Created attachment 684
Updated patch for dmd2
Somehow switched LONGJMP_MANGLE_NAME and CPP_LONGJMP_MANGLE_NAME in the first patch.
Comment #12 by leandro.lucarella — 2010-06-28T08:14:08Z
(In reply to comment #10)
> Created an attachment (id=683) [details]
> Updated patch for druntime
>
> Added a new patch for druntime using extern(System). If extern(System) is
> extern(Windows) on windows and extern(C) on posix, this will work fine, I just
> did not know about extern(System).
I filled a bug (bug 4399) because as far as I can see, it's undocumented (I knew it existed because it's in the changelog and I remember some discussion about it in the group).
Comment #13 by johannespfau — 2010-06-28T08:28:14Z
Created attachment 685
Patch for druntime, third edition
I was wrong, there is a linux _d_throw(Object *h) in deh.c, but it seems deprecated by deh2.d. Just in case this new patch also fixes the _d_throw in deh.c.
Comment #14 by nfxjfg — 2010-10-10T05:46:28Z
Most retarded patch ever and supports my theory that Walter is just trolling everyone, instead of intending to produce something useful.
WHY.
Comment #15 by nfxjfg — 2010-10-10T05:48:52Z
(In reply to comment #14)
> patch
I mean bug.
Uf dmd had a healthy development model, this should have been fixed 5 minutes after the bug was reported.
Comment #16 by dmdtracker — 2010-10-10T06:20:39Z
(In reply to comment #5)
> To avoid code duplication in case extern(System) won't help you here you can
> use string mixins.
>
> P.S. Is it the only issue that prevents dmd from being able to build shared
> libraries on linux or there are more?
I just tried the patches on dmd.1.064
It crashes upon new exception.
#0 0x00000001 in ?? ()
#1 0xb7fdea83 in test.Test.badboy (this=0xb7d2ef90) at test.d:13
#2 0x08049b39 in D main ()
#3 0x0805a1c6 in rt.compiler.dmd.rt.dmain2.main() ()
#4 0x0805a120 in rt.compiler.dmd.rt.dmain2.main() ()
#5 0x0805a203 in rt.compiler.dmd.rt.dmain2.main() ()
#6 0x0805a120 in rt.compiler.dmd.rt.dmain2.main() ()
#7 0x0805a0d6 in main ()
--Marenz
Comment #17 by doob — 2010-10-10T06:29:39Z
I don't think that the attached patches are correct. As far as I can see looking at the makefiles, deh.c is used on windows and deh2.d is used on posix. So _d_throw in deh2.d would be extern (C) or extern (Windows) (doesn't really matter) then _d_throw in deh.c would still be __stdcall.
Comment #18 by doob — 2010-10-10T06:30:33Z
(In reply to comment #17)
> I don't think that the attached patches are correct. As far as I can see
> looking at the makefiles, deh.c is used on windows and deh2.d is used on posix.
> So _d_throw in deh2.d would be extern (C) or extern (Windows) (doesn't really
> matter) then _d_throw in deh.c would still be __stdcall.
Sorry, extern (C) or extern (System)
Comment #19 by dmdtracker — 2010-10-10T06:35:05Z
(In reply to comment #18)
> (In reply to comment #17)
> > I don't think that the attached patches are correct. As far as I can see
> > looking at the makefiles, deh.c is used on windows and deh2.d is used on posix.
> > So _d_throw in deh2.d would be extern (C) or extern (Windows) (doesn't really
> > matter) then _d_throw in deh.c would still be __stdcall.
>
> Sorry, extern (C) or extern (System)
Sorry, I should have mentioned: I tested on linux and I used tango (which has the same files). So the deh.c should not have been used at all, right?
--Marenz
Comment #20 by doob — 2010-10-10T06:42:16Z
(In reply to comment #19)
> (In reply to comment #18)
> > (In reply to comment #17)
> > > I don't think that the attached patches are correct. As far as I can see
> > > looking at the makefiles, deh.c is used on windows and deh2.d is used on posix.
> > > So _d_throw in deh2.d would be extern (C) or extern (Windows) (doesn't really
> > > matter) then _d_throw in deh.c would still be __stdcall.
> >
> > Sorry, extern (C) or extern (System)
>
> Sorry, I should have mentioned: I tested on linux and I used tango (which has
> the same files). So the deh.c should not have been used at all, right?
>
> --Marenz
Correct, deh.c should not have been used at all. But tango should not build that file when building on linux.
Comment #21 by johannespfau — 2010-10-10T08:51:57Z
Created attachment 780
Yet another druntime patch
Comment #22 by johannespfau — 2010-10-10T08:54:35Z
True, deh.c should stay as it is. My understanding of C and druntime wasn't that great at the time I wrote the patch. I'll attach an updated patch, but Walter will likely have to look into this again anyway when he starts to implement support for shared libraries on Linux. This patch alone won't help much there though, it's just the first step for shared library support, there are way bigger issues.
Tango and phobos1 need to be patched as well. I haven't looked into tango, but if the code is the same as the druntime code the deh2.d patch should work. I tested the patched compiler and druntime on Linux back then and I'm sure it worked.
Comment #23 by bugzilla — 2010-10-24T21:37:52Z
deh.c is Windows only. It is in C because it interacts with all the complex Windows header definitions for Windows SEH that have not been ported to D. D's eh mechanism on Windows is layered on top of Windows SEH.
For other platforms, deh2.d is used instead, as D uses its own invented exception handling mechanism. (It is not compatible with the C++ eh ELF mechanism.)
Comment #24 by bugzilla — 2010-10-24T21:46:02Z
No need to mess with LONGJMP_MANGLE_NAME and CPP_LONGJMP_MANGLE_NAME as they are for the C++ compiler. They are never referenced by dmd, and do not appear in Phobos.