April 09, 2012
On 9 April 2012 20:37,  <"Timo Westkämper\" <timo.westkamper@gmail.com>"@puremagic.com> wrote:
> On Monday, 9 April 2012 at 15:14:45 UTC, Ellery Newcomer wrote:
>>
>> Well, if you're really hankering for a shared lib, try ldc. I have gotten it to compile working shared libs in the past.
>>
>> On 04/09/2012 01:24 AM, "Timo Westkämper" <timo.westkamper@gmail.com>" wrote:
>>>
>>> On Sunday, 8 April 2012 at 17:59:28 UTC, Timo Westkämper wrote:
>>>>
>>>> Does someone know why the lib (.a) packaging instead of objects (.o)
>>>> works better in this case?
>>>
>>>
>>> Didn't work after all with -lib. I mixed up outputs.
>
>
> Thanks, I might switch to ldc, if dmd and gdc fail here.
>
> I found this tls.S script in the druntime sources (src/rt/tls.S). Do you think it could be included in the library to make tls initialization work?
>
> #if linux
>
> /* The memory between the addresses of _tlsstart and _tlsend is the storage
> for
>  * thread-local data in D 2.0.  Both of these rely on the default linker
> script
>  * of:
>  *      .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
>  *      .tbss  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
>  * to group the sections in that order.
>  *
>  * Sadly, this does not work because ld orders .tdata after .tdata.*,
> despite
>  * what the linker script says.
>  */
>
> .file "tls.S"
>
> .globl _tlsstart
>    .section .tdata,"awT",@progbits
>    .align 4
>    .type   _tlsstart, @object
>    .size   _tlsstart, 4
> _tlsstart:
>    .long   3
>
> .globl _tlsend
>    .section .tcommon,"awT",@nobits
>    .align 4
>    .type   _tlsend, @object
>    .size   _tlsend, 4
> _tlsend:
>    .zero   4
>
> #endif
>
>

That assembly file does nothing for shared library support.  I have been meaning to finish up a solution to help support shared libs, would mean more deviation from the dmd compiler's runtime library, but that's fine.

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
April 09, 2012
On Monday, 9 April 2012 at 19:59:18 UTC, Iain Buclaw wrote:
> On 9 April 2012 20:37,  <"Timo Westkämper\"
> <timo.westkamper@gmail.com>"@puremagic.com> wrote:
>> On Monday, 9 April 2012 at 15:14:45 UTC, Ellery Newcomer wrote:
>>>
>>> Well, if you're really hankering for a shared lib, try ldc. I have gotten
>>> it to compile working shared libs in the past.
>>>
>>> On 04/09/2012 01:24 AM, "Timo Westkämper" <timo.westkamper@gmail.com>"
>>> wrote:
>>>>
>>>> On Sunday, 8 April 2012 at 17:59:28 UTC, Timo Westkämper wrote:
>>>>>
>>>>> Does someone know why the lib (.a) packaging instead of objects (.o)
>>>>> works better in this case?
>>>>
>>>>
>>>> Didn't work after all with -lib. I mixed up outputs.
>>
>>
>> Thanks, I might switch to ldc, if dmd and gdc fail here.
>>
>> I found this tls.S script in the druntime sources (src/rt/tls.S). Do you
>> think it could be included in the library to make tls initialization work?
>>
>> #if linux
>>
>> /* The memory between the addresses of _tlsstart and _tlsend is the storage
>> for
>>  * thread-local data in D 2.0.  Both of these rely on the default linker
>> script
>>  * of:
>>  *      .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
>>  *      .tbss  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
>>  * to group the sections in that order.
>>  *
>>  * Sadly, this does not work because ld orders .tdata after .tdata.*,
>> despite
>>  * what the linker script says.
>>  */
>>
>> .file "tls.S"
>>
>> .globl _tlsstart
>>    .section .tdata,"awT",@progbits
>>    .align 4
>>    .type   _tlsstart, @object
>>    .size   _tlsstart, 4
>> _tlsstart:
>>    .long   3
>>
>> .globl _tlsend
>>    .section .tcommon,"awT",@nobits
>>    .align 4
>>    .type   _tlsend, @object
>>    .size   _tlsend, 4
>> _tlsend:
>>    .zero   4
>>
>> #endif
>>
>>
>
> That assembly file does nothing for shared library support.  I have
> been meaning to finish up a solution to help support shared libs,
> would mean more deviation from the dmd compiler's runtime library, but
> that's fine.

Ok. Good to know. Here is what I came up with for now.

I have not yet much knowledge of DMD internals so I just played around with declarations:

import std.stdio;

// FIXME
__gshared extern(C) void* __data_start;

// FIXME tls marks
extern(C) int _tlsstart;
extern(C) int _tlsend;

// FIXME exception handling markers
extern(C) void _deh_beg() { }
extern(C) void _deh_end() { }

// hooks for init and term
extern (C) void rt_init();
extern (C) void rt_term();

extern (C) void hiD() {
  rt_init();
  writeln("hi from D lib");
  rt_term();
}

//void main();

/*extern(C) {

  void _init() {
    rt_init();
  }

  void _fini() {
    rt_term();
  }

}*/


For some reasons, the _init and _fini parts don't yet work properly.

And here the part of the Makefile that created the library:

  dmd -c -g test.d -fPIC
  ld -shared -o libtest.so test.o -lrt -lphobos2 -lpthread

This mostly reflects Jacob Carlborg's comment in the beginning of what features are still missing

* Proper initialization of TLS data
* Setting up exception handling tables
* Setting up module info
April 09, 2012
On Monday, 9 April 2012 at 20:31:44 UTC, Timo Westkämper wrote:
> On Monday, 9 April 2012 at 19:59:18 UTC, Iain Buclaw wrote:
>> On 9 April 2012 20:37,  <"Timo Westkämper\"
>> <timo.westkamper@gmail.com>"@puremagic.com> wrote:
>>> On Monday, 9 April 2012 at 15:14:45 UTC, Ellery Newcomer wrote:
>>>>
>>>> Well, if you're really hankering for a shared lib, try ldc. I have gotten
>>>> it to compile working shared libs in the past.
>>>>
>>>> On 04/09/2012 01:24 AM, "Timo Westkämper" <timo.westkamper@gmail.com>"
>>>> wrote:
>>>>>
>>>>> On Sunday, 8 April 2012 at 17:59:28 UTC, Timo Westkämper wrote:
>>>>>>
>>>>>> Does someone know why the lib (.a) packaging instead of objects (.o)
>>>>>> works better in this case?
>>>>>
>>>>>
>>>>> Didn't work after all with -lib. I mixed up outputs.
>>>
>>>
>>> Thanks, I might switch to ldc, if dmd and gdc fail here.
>>>
>>> I found this tls.S script in the druntime sources (src/rt/tls.S). Do you
>>> think it could be included in the library to make tls initialization work?
>>>
>>> #if linux
>>>
>>> /* The memory between the addresses of _tlsstart and _tlsend is the storage
>>> for
>>>  * thread-local data in D 2.0.  Both of these rely on the default linker
>>> script
>>>  * of:
>>>  *      .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
>>>  *      .tbss  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
>>>  * to group the sections in that order.
>>>  *
>>>  * Sadly, this does not work because ld orders .tdata after .tdata.*,
>>> despite
>>>  * what the linker script says.
>>>  */
>>>
>>> .file "tls.S"
>>>
>>> .globl _tlsstart
>>>    .section .tdata,"awT",@progbits
>>>    .align 4
>>>    .type   _tlsstart, @object
>>>    .size   _tlsstart, 4
>>> _tlsstart:
>>>    .long   3
>>>
>>> .globl _tlsend
>>>    .section .tcommon,"awT",@nobits
>>>    .align 4
>>>    .type   _tlsend, @object
>>>    .size   _tlsend, 4
>>> _tlsend:
>>>    .zero   4
>>>
>>> #endif
>>>
>>>
>>
>> That assembly file does nothing for shared library support.  I have
>> been meaning to finish up a solution to help support shared libs,
>> would mean more deviation from the dmd compiler's runtime library, but
>> that's fine.
>
> Ok. Good to know. Here is what I came up with for now.
>
> I have not yet much knowledge of DMD internals so I just played around with declarations:
>
> import std.stdio;
>
> // FIXME
> __gshared extern(C) void* __data_start;
>
> // FIXME tls marks
> extern(C) int _tlsstart;
> extern(C) int _tlsend;
>
> // FIXME exception handling markers
> extern(C) void _deh_beg() { }
> extern(C) void _deh_end() { }
>
> // hooks for init and term
> extern (C) void rt_init();
> extern (C) void rt_term();
>
> extern (C) void hiD() {
>   rt_init();
>   writeln("hi from D lib");
>   rt_term();
> }
>
> //void main();
>
> /*extern(C) {
>
>   void _init() {
>     rt_init();
>   }
>
>   void _fini() {
>     rt_term();
>   }
>
> }*/
>
>
> For some reasons, the _init and _fini parts don't yet work properly.
>
> And here the part of the Makefile that created the library:
>
>   dmd -c -g test.d -fPIC
>   ld -shared -o libtest.so test.o -lrt -lphobos2 -lpthread
>
> This mostly reflects Jacob Carlborg's comment in the beginning of what features are still missing
>
> * Proper initialization of TLS data
> * Setting up exception handling tables
> * Setting up module info

I just figured out this alternative approach which works as well:

import std.stdio;

// FIXME
__gshared extern(C) void* __data_start;

// hooks for init and term
extern (C) void rt_init();
extern (C) void rt_term();

extern (C) void hiD() {
  rt_init();
  writeln("hi from D lib");
  rt_term();
}

void main() {}


The declaration of the main method adds the tls and deh parts.

April 09, 2012
On 04/09/2012 03:31 PM, "Timo Westkämper" <timo.westkamper@gmail.com>" wrote:
>
>
> For some reasons, the _init and _fini parts don't yet work properly.
>

what's wrong with them? if it is a link problem, use gcc -nostartfiles.
Well, I'm doing that, and it compiles and rt_init is called, but doesn't seem to be calling the module constructors, so maybe that is a very bad idea.
April 10, 2012
On 2012-04-09 21:59, Iain Buclaw wrote:

> That assembly file does nothing for shared library support.  I have
> been meaning to finish up a solution to help support shared libs,
> would mean more deviation from the dmd compiler's runtime library, but
> that's fine.

Martin Nowak was/is working on shared library support in druntime, if I recall correctly.

-- 
/Jacob Carlborg
April 10, 2012
On 2012-04-09 23:58, Ellery Newcomer wrote:
> On 04/09/2012 03:31 PM, "Timo Westkämper" <timo.westkamper@gmail.com>"
> wrote:
>>
>>
>> For some reasons, the _init and _fini parts don't yet work properly.
>>
>
> what's wrong with them? if it is a link problem, use gcc -nostartfiles.
> Well, I'm doing that, and it compiles and rt_init is called, but doesn't
> seem to be calling the module constructors, so maybe that is a very bad
> idea.

The module info (contains the module constructors) need to be setup differently when linking as a shared library.

-- 
/Jacob Carlborg
April 10, 2012
On 04/10/2012 01:31 AM, Jacob Carlborg wrote:
>
> The module info (contains the module constructors) need to be setup
> differently when linking as a shared library.
>

The odd thing is, when you skip _init and _fini and just do

rt_init();
writeln("stuff");
rt_term();

it doesn't segfault
April 10, 2012
On 2012-04-10 16:21, Ellery Newcomer wrote:
> On 04/10/2012 01:31 AM, Jacob Carlborg wrote:
>>
>> The module info (contains the module constructors) need to be setup
>> differently when linking as a shared library.
>>
>
> The odd thing is, when you skip _init and _fini and just do
>
> rt_init();
> writeln("stuff");
> rt_term();
>
> it doesn't segfault

Are the module constructors run?

-- 
/Jacob Carlborg
April 10, 2012
On 04/10/2012 12:04 PM, Jacob Carlborg wrote:

>>
>> The odd thing is, when you skip _init and _fini and just do
>>
>> rt_init();
>> writeln("stuff");
>> rt_term();
>>
>> it doesn't segfault
>
> Are the module constructors run?
>

they would have to be for writeln to not segfault
April 10, 2012
On 2012-04-10 19:12, Ellery Newcomer wrote:

> they would have to be for writeln to not segfault

Ok, I see.

-- 
/Jacob Carlborg