|
From: Jeremy F. <je...@go...> - 2003-11-18 01:42:50
|
On Mon, 2003-11-17 at 16:10, Tom Hughes wrote: > There can actually be mutiple TLS segments in the ELF file - there > are typically .tdata and .tbss from what I can see. There's both .tdata and .tbss sections, but they both get mapped to the one PT_TLS segment. > In fact only the base executable seems to use direct %gs references. For > example, when xxx is a thread local variables, this code: > > xxx++; [...] > The function being called is ___tls_get_addr and the lea is setting > up some sort of index into the TLS segment. Yep, ___tls_get_addr is a function defined by the ABI to exist so the compiler can call it. There are many different types of reloc possible, depending on how much static info the compiler/linker has (like whether the code accessing the variable is necessarily in the same shared object or not). tls.pdf goes into (vast) detail about it. > Even the cloning is hard because although we have the pointer to > the thread area for the original thread we have no idea how big > that area is because ld.so seems to set it up with a size of -1 so > the area is effectively unlimited. Well, if we already have enough interaction with ld.so anyway, we can probably work out the size of the TLS chunk. I think it is sizeof(tcbheader_t). And clone() doesn't copy anything; it just sets up a new thread area at the given address, which libpthread points to its struct pthread. > In fact I believe the address passed to the kernel as the thread > area pointer is a pointer to the thread descriptor structure, with > the TLS data for the main executable just below it so that negative > offsets from %gs will find it. Other TLS data is found from the > thread descriptor somehow by the __tls_get_addr function. Yup, the ABI says something like that. But it is also part of the thread stack, so I'm not quite sure how much stuff is there. ___tls_get_addr is designed to hide a fair amount of the detail, and the compiler isn't allowed to make too many assumptions. > Trying to emulate the whole thing would be horrible, but given > the incestuous links between ld.so, libc and libpthread it's hard > to see how else it can be done. It would also be a maintenance > nightmare of course, as you say. Yes. It might be the only really sane way of doing it is to get some officially sanctioned hooks into glibc so that we can get enough information without too much interdependence. > I don't think they do make do without it, which is why valgrind > falls over if you try and load any program or library with a TLS > section in the ELF file. Setting LD_ASSUME_KERNEL causes ld.so to > use a glibc built without using TLS segments. Does that mean that code using TLS just SEGVs on a pre-TLS kernel? J |