Jump to page: 1 2
Thread overview
Solaris/x86 port - how to get the TLS section?
Nov 25, 2014
Kai Nacke
Nov 25, 2014
Joakim
Nov 26, 2014
Joakim
Nov 26, 2014
Jacob Carlborg
Nov 26, 2014
Joakim
Nov 26, 2014
Kai Nacke
Nov 25, 2014
Jacob Carlborg
Nov 26, 2014
Kai Nacke
Nov 27, 2014
Jacob Carlborg
Nov 27, 2014
Kai Nacke
Nov 27, 2014
Jacob Carlborg
November 25, 2014
Hi!

GitHub master contains a close-to-working port of LDC to Solaris/x86. The only missing piece is getting a pointer to the TLS section. I tried the following:

1) Solaris uses the ELF file format. Unfortunately, it does not support the dl_phdr_info.dlpi_tls_modid field which is used on FreeBSD to get the module id of the TLS section.

2) On glibc-based systems, the function dlinfo(RTLD_SELF, RTLD_DI_TLS_MODID, &modid) can be used to get the module id. Again, this is not supported on Solaris.

Does somebody else know a way to get a pointer to or the module id of the TLS section? Maybe a linkmap or a /proc/<pid>/map based solution? Every suggestion is welcome!

Regards,
Kai
November 25, 2014
On Tuesday, 25 November 2014 at 17:59:48 UTC, Kai Nacke wrote:
> Hi!
>
> GitHub master contains a close-to-working port of LDC to Solaris/x86. The only missing piece is getting a pointer to the TLS section. I tried the following:
>
> 1) Solaris uses the ELF file format. Unfortunately, it does not support the dl_phdr_info.dlpi_tls_modid field which is used on FreeBSD to get the module id of the TLS section.
>
> 2) On glibc-based systems, the function dlinfo(RTLD_SELF, RTLD_DI_TLS_MODID, &modid) can be used to get the module id. Again, this is not supported on Solaris.
>
> Does somebody else know a way to get a pointer to or the module id of the TLS section? Maybe a linkmap or a /proc/<pid>/map based solution? Every suggestion is welcome!
>
> Regards,
> Kai

Take a look at Drepper's TLS reference, if you haven't already:

http://www.akkadia.org/drepper/tls.pdf

He talks a lot about how Solaris is different in there.
November 25, 2014
On 2014-11-25 18:59, Kai Nacke wrote:

> Does somebody else know a way to get a pointer to or the module id of
> the TLS section? Maybe a linkmap or a /proc/<pid>/map based solution?
> Every suggestion is welcome!

How about manually iterating the sections, would that be possible?

I found this link that might be of help: https://docs.oracle.com/cd/E26502_01/html/E26507/chapter8-1.html#scrolltoc

-- 
/Jacob Carlborg
November 26, 2014
On Tuesday, 25 November 2014 at 19:35:36 UTC, Joakim wrote:
> On Tuesday, 25 November 2014 at 17:59:48 UTC, Kai Nacke wrote:
>> Hi!
>>
>> GitHub master contains a close-to-working port of LDC to Solaris/x86. The only missing piece is getting a pointer to the TLS section. I tried the following:
>>
>> 1) Solaris uses the ELF file format. Unfortunately, it does not support the dl_phdr_info.dlpi_tls_modid field which is used on FreeBSD to get the module id of the TLS section.
>>
>> 2) On glibc-based systems, the function dlinfo(RTLD_SELF, RTLD_DI_TLS_MODID, &modid) can be used to get the module id. Again, this is not supported on Solaris.
>>
>> Does somebody else know a way to get a pointer to or the module id of the TLS section? Maybe a linkmap or a /proc/<pid>/map based solution? Every suggestion is welcome!
>>
>> Regards,
>> Kai
>
> Take a look at Drepper's TLS reference, if you haven't already:
>
> http://www.akkadia.org/drepper/tls.pdf
>
> He talks a lot about how Solaris is different in there.

Hmm, I don't see it in there.  btw, isn't the TLS module id for the executable itself usually 1?  If you don't plan on supporting shared libraries, maybe you can just hard-code it for now?
November 26, 2014
On 2014-11-26 03:11, Joakim wrote:

> Hmm, I don't see it in there.

Yeah, I couldn't find any information specific for a given operating system. Only information for a given architecture.


-- 
/Jacob Carlborg
November 26, 2014
On Wednesday, 26 November 2014 at 06:59:42 UTC, Jacob Carlborg wrote:
> On 2014-11-26 03:11, Joakim wrote:
>
>> Hmm, I don't see it in there.
>
> Yeah, I couldn't find any information specific for a given operating system. Only information for a given architecture.

Do a search for Sun: there are a lot of specifics about how the Sun x86 ABI is different for the various thread models.  But it doesn't go into what OS APIs, ie structs and functions, to use to access the TLS data.
November 26, 2014
On Wednesday, 26 November 2014 at 02:11:10 UTC, Joakim wrote:
> On Tuesday, 25 November 2014 at 19:35:36 UTC, Joakim wrote:
>> On Tuesday, 25 November 2014 at 17:59:48 UTC, Kai Nacke wrote:
>>> Hi!
>>>
>>> GitHub master contains a close-to-working port of LDC to Solaris/x86. The only missing piece is getting a pointer to the TLS section. I tried the following:
>>>
>>> 1) Solaris uses the ELF file format. Unfortunately, it does not support the dl_phdr_info.dlpi_tls_modid field which is used on FreeBSD to get the module id of the TLS section.
>>>
>>> 2) On glibc-based systems, the function dlinfo(RTLD_SELF, RTLD_DI_TLS_MODID, &modid) can be used to get the module id. Again, this is not supported on Solaris.
>>>
>>> Does somebody else know a way to get a pointer to or the module id of the TLS section? Maybe a linkmap or a /proc/<pid>/map based solution? Every suggestion is welcome!
>>>
>>> Regards,
>>> Kai
>>
>> Take a look at Drepper's TLS reference, if you haven't already:
>>
>> http://www.akkadia.org/drepper/tls.pdf
>>
>> He talks a lot about how Solaris is different in there.
>
> Hmm, I don't see it in there.  btw, isn't the TLS module id for the executable itself usually 1?  If you don't plan on supporting shared libraries, maybe you can just hard-code it for now?

That's a good hint. I try this.

Regards,
Kai
November 26, 2014
On Tuesday, 25 November 2014 at 20:27:40 UTC, Jacob Carlborg wrote:
> On 2014-11-25 18:59, Kai Nacke wrote:
>
>> Does somebody else know a way to get a pointer to or the module id of
>> the TLS section? Maybe a linkmap or a /proc/<pid>/map based solution?
>> Every suggestion is welcome!
>
> How about manually iterating the sections, would that be possible?

That is no problem. The trouble starts because the TLS section is allocated for every thread (at least if the thread touches a variable in this section). I need to find the start of the section at runtime for a thread. The module id helps her because __tls_get_addr() can then be used.

> I found this link that might be of help: https://docs.oracle.com/cd/E26502_01/html/E26507/chapter8-1.html#scrolltoc

That's a nice summary of the Drepper paper only for Solaris. Unfortunately all the OS stuff is missing.

Regards,
Kai
November 27, 2014
On 2014-11-26 18:33, Kai Nacke wrote:

> That is no problem. The trouble starts because the TLS section is
> allocated for every thread (at least if the thread touches a variable in
> this section). I need to find the start of the section at runtime for a
> thread. The module id helps her because __tls_get_addr() can then be used.

Are you referring what you're supposed to pass to __tls_get_addr when generating a call to __tls_get_addr in the compiler?

Or is it in the runtime where you need to access the TLS data to get the roots for the GC?

-- 
/Jacob Carlborg
November 27, 2014
On Thursday, 27 November 2014 at 12:23:18 UTC, Jacob Carlborg wrote:
> On 2014-11-26 18:33, Kai Nacke wrote:
>
>> That is no problem. The trouble starts because the TLS section is
>> allocated for every thread (at least if the thread touches a variable in
>> this section). I need to find the start of the section at runtime for a
>> thread. The module id helps her because __tls_get_addr() can then be used.
>
> Are you referring what you're supposed to pass to __tls_get_addr when generating a call to __tls_get_addr in the compiler?
>
> Or is it in the runtime where you need to access the TLS data to get the roots for the GC?

Here are the dirty details:

On Linux and FreeBSD, the module id and size of the TLS section is found in the ELF structure dl_phdr_info. The module id is converted to a pointer to the first byte of the TLS section for every thread:

    auto ti = tls_index(moduleId, 0);
    return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz];

(sz is the size)

Solaris does not have the dl_phdr_info.dlpi_tls_modid field therefore this methods breaks.

But I think I found the solution. After reading the link you posted the tenth time I realized the following sentence:

"The static TLS arena associated with the calculated TLS size tlssizeS, is placed immediately preceding the thread pointer tpt. Accesses to this TLS data is based off of subtractions from tpt."

The thread pointer is fs:0 or gs:0 on Intel and r7 on Sparc. The size of the TLS data is found in the ELF header as before. I simply need to do the rounding as documented in the chapter and then I can calculate the required pointer.

Great!!!

Regards,
Kai
« First   ‹ Prev
1 2