Re: Fwd: Mips, -fpie and TLS management
2009/3/16 Daniel Jacobowitz d...@false.org: On Mon, Mar 16, 2009 at 06:19:01PM +0100, Joel Porquet wrote: 2009/3/12 Daniel Jacobowitz d...@false.org: On Thu, Mar 12, 2009 at 02:02:36PM +0100, Joel Porquet wrote: Check what symbol is at, or near, 0x4003 + 22368. It's probably the GOT plus a constant bias. It seems there is nothing at this address. Here is the program header: Don't know then. Look at compiler-generated assembly instead of disassembly; that often helps. Do you mean the object file produced by gcc before linkage? That will do, but the actual assembly (-S) is more helpful sometimes. This is a *module* relocation. In local dynamic the module is always the current DSO; it does not need a symbol. But what if the DSO access other module's TLS? Then it does not use Local Dynamic to do so. I don't understand how the runtime loader could know that! As far as I know, the tls model is not embedded in reloc information. Finally, I noticed another problem. GCC seems to not make room for the 4 arguments as specified in the ABI, when calling __get_tls_addr. For example, here is an extract of the code for calling (we see that data are stored directly at the top of the stack): ... 5ffe0bfc: 27bdfff0 addiu sp,sp,-16 5ffe0c00: afbf000c sw ra,12(sp) 5ffe0c04: afbc sw gp,0(sp) That line is bogus. Figure out where it came from; the cprestore offset should not be zero. I don't know how to figure this out (actually, that's why I'm writing on this ml). I just wrote a small function which uses a tls variable and gcc did the rest. __thread unsigned int *tty; void puts(char *str) { while(*str) *tty = *str++; }
Re: Fwd: Mips, -fpie and TLS management
On Tue, Mar 17, 2009 at 10:26:05AM +0100, Joel Porquet wrote: I don't understand how the runtime loader could know that! As far as I know, the tls model is not embedded in reloc information. Sure it is. I suggest you go back to Ulrich Drepper's TLS paper for more information about the relocations. I don't know how to figure this out (actually, that's why I'm writing on this ml). I just wrote a small function which uses a tls variable and gcc did the rest. __thread unsigned int *tty; void puts(char *str) { while(*str) *tty = *str++; } If you believe there is a bug, and you have a testcase, please report it in bugzilla. Thanks. -- Daniel Jacobowitz CodeSourcery
Re: Fwd: Mips, -fpie and TLS management
2009/3/17 Daniel Jacobowitz d...@false.org: On Tue, Mar 17, 2009 at 10:26:05AM +0100, Joel Porquet wrote: I don't understand how the runtime loader could know that! As far as I know, the tls model is not embedded in reloc information. Sure it is. I suggest you go back to Ulrich Drepper's TLS paper for more information about the relocations. The only information is whether the module uses a static model. So we are able to distinguish *-dynamic from *-exec models. Nevertheless, I still don't see how the runtime loader can distinguish local-dynamic and global-dynamic: when it goes through the relocations, it only sees *DTPMOD32 which is common for both models. I don't know how to figure this out (actually, that's why I'm writing on this ml). I just wrote a small function which uses a tls variable and gcc did the rest. __thread unsigned int *tty; void puts(char *str) { while(*str) *tty = *str++; } If you believe there is a bug, and you have a testcase, please report it in bugzilla. Thanks. -- Daniel Jacobowitz CodeSourcery
Re: Fwd: Mips, -fpie and TLS management
On Tue, Mar 17, 2009 at 04:03:45PM +0100, Joel Porquet wrote: 2009/3/17 Daniel Jacobowitz d...@false.org: On Tue, Mar 17, 2009 at 10:26:05AM +0100, Joel Porquet wrote: I don't understand how the runtime loader could know that! As far as I know, the tls model is not embedded in reloc information. Sure it is. I suggest you go back to Ulrich Drepper's TLS paper for more information about the relocations. The only information is whether the module uses a static model. So we are able to distinguish *-dynamic from *-exec models. Nevertheless, I still don't see how the runtime loader can distinguish local-dynamic and global-dynamic: when it goes through the relocations, it only sees *DTPMOD32 which is common for both models. It's based on the symbol referenced by the relocation. -- Daniel Jacobowitz CodeSourcery
Re: Fwd: Mips, -fpie and TLS management
2009/3/17 Daniel Jacobowitz d...@false.org: On Tue, Mar 17, 2009 at 04:03:45PM +0100, Joel Porquet wrote: 2009/3/17 Daniel Jacobowitz d...@false.org: On Tue, Mar 17, 2009 at 10:26:05AM +0100, Joel Porquet wrote: I don't understand how the runtime loader could know that! As far as I know, the tls model is not embedded in reloc information. Sure it is. I suggest you go back to Ulrich Drepper's TLS paper for more information about the relocations. The only information is whether the module uses a static model. So we are able to distinguish *-dynamic from *-exec models. Nevertheless, I still don't see how the runtime loader can distinguish local-dynamic and global-dynamic: when it goes through the relocations, it only sees *DTPMOD32 which is common for both models. It's based on the symbol referenced by the relocation. Problem is how can you find the symbol referenced by the relocation when the symbol index is null?? Then, should we consider that a null symbol index means that the module relocation is the DSO itself?
Re: Fwd: Mips, -fpie and TLS management
On Tue, Mar 17, 2009 at 04:21:18PM +0100, Joel Porquet wrote: Problem is how can you find the symbol referenced by the relocation when the symbol index is null?? Then, should we consider that a null symbol index means that the module relocation is the DSO itself? Yes, that's what I said. This is how the uClibc and GLIBC dynamic loaders work and I believe it's described in Ulrich's paper. -- Daniel Jacobowitz CodeSourcery
Re: Fwd: Mips, -fpie and TLS management
2009/3/12 Daniel Jacobowitz d...@false.org: On Thu, Mar 12, 2009 at 02:02:36PM +0100, Joel Porquet wrote: Check what symbol is at, or near, 0x4003 + 22368. It's probably the GOT plus a constant bias. It seems there is nothing at this address. Here is the program header: Don't know then. Look at compiler-generated assembly instead of disassembly; that often helps. Do you mean the object file produced by gcc before linkage? If yes, the code looks like: 3c05lui a1,0x0 40: R_MIPS_TLS_DTPREL_HI16 a which will be computed later as 3c054003lui a1,0x4003 By the way, how did you test the code of TLS for mips? I mean, uclibc seems the more advanced lib for mips, and although this lib seems to have the necessary code to manage tls once it is installed, the ldso doesn't contain any code for handling TLS (relocation, tls allocation, etc)... That statement about uclibc strikes me as bizarre. I tested it with glibc, naturally. GLIBC has a much more reliable TLS implementation than uclibc's in-progress one. I just downloaded the glibc archive without noticing that the mips port was in another archive... My mistake.. Last question, is there a difference between DSO and PIE objects other than the INTERP entry in the program header? Yes. Symbol preemption is allowed for DSOs but not for PIEs or normal executables. That explains the different choice of model. But this is only a property, isn't it? I was meaning, how can you differenciate them at loading time, when you analyse the elf file. You can't. As you surely know, ELF_R_SYM() macro performs (val8) which gives the symbol index in order to retrieve the name of the symbol. This name then allows to look up the symbol. Unfortunately, in the case of local-dynamic, ELF_R_SYM will return 0 which is not correct (the same for global-dynamic will return 9): we can see by the way that readelf is not able to get the symbol name. What do you think about this? This is a *module* relocation. In local dynamic the module is always the current DSO; it does not need a symbol. But what if the DSO access other module's TLS? Finally, I noticed another problem. GCC seems to not make room for the 4 arguments as specified in the ABI, when calling __get_tls_addr. For example, here is an extract of the code for calling (we see that data are stored directly at the top of the stack): ... 5ffe0bfc: 27bdfff0addiu sp,sp,-16 5ffe0c00: afbf000csw ra,12(sp) 5ffe0c04: afbcsw gp,0(sp) 5ffe0c08: afa40010sw a0,16(sp) 5ffe0c0c: 100db 5ffe0c44 puts+0x54 5ffe0c10: nop 5ffe0c14: 8f998030lw t9,-32720(gp) 5ffe0c18: 27848038addiu a0,gp,-32712 5ffe0c1c: 0320f809jalrt9 5ffe0c20: nop 5ffe0c24: 8fbclw gp,0(sp) ... The jalr t9 is the call to get_tls_addr whose code is: ... 5ffe0b40: 27bdffe8addiu sp,sp,-24 5ffe0b44: afbcsw gp,0(sp) 5ffe0b48: afa40018sw a0,24(sp) 5ffe0b4c: 7c03e83b0x7c03e83b ... We notice then that sw a0, 24(sp) will erase $gp which was saved at the same place (sw gp, 0(gp)) by the caller. Regards, Joel
Re: Fwd: Mips, -fpie and TLS management
On Mon, Mar 16, 2009 at 06:19:01PM +0100, Joel Porquet wrote: 2009/3/12 Daniel Jacobowitz d...@false.org: On Thu, Mar 12, 2009 at 02:02:36PM +0100, Joel Porquet wrote: Check what symbol is at, or near, 0x4003 + 22368. It's probably the GOT plus a constant bias. It seems there is nothing at this address. Here is the program header: Don't know then. Look at compiler-generated assembly instead of disassembly; that often helps. Do you mean the object file produced by gcc before linkage? That will do, but the actual assembly (-S) is more helpful sometimes. This is a *module* relocation. In local dynamic the module is always the current DSO; it does not need a symbol. But what if the DSO access other module's TLS? Then it does not use Local Dynamic to do so. Finally, I noticed another problem. GCC seems to not make room for the 4 arguments as specified in the ABI, when calling __get_tls_addr. For example, here is an extract of the code for calling (we see that data are stored directly at the top of the stack): ... 5ffe0bfc: 27bdfff0addiu sp,sp,-16 5ffe0c00: afbf000csw ra,12(sp) 5ffe0c04: afbcsw gp,0(sp) That line is bogus. Figure out where it came from; the cprestore offset should not be zero. -- Daniel Jacobowitz CodeSourcery
Re: Fwd: Mips, -fpie and TLS management
Check what symbol is at, or near, 0x4003 + 22368. It's probably the GOT plus a constant bias. It seems there is nothing at this address. Here is the program header: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x34 0x5ffe0034 0x5ffe0034 0x000c0 0x000c0 R E 0x4 INTERP 0xf4 0x5ffe00f4 0x5ffe00f4 0x00013 0x00013 R 0x1 [Requesting program interpreter: /usr/lib/libc.so.1] LOAD 0x00 0x5ffe 0x5ffe 0x00488 0x00488 R E 0x1000 LOAD 0x000488 0x5ffe1488 0x5ffe1488 0x0002c 0x0002c RW 0x1000 DYNAMIC0x000120 0x5ffe0120 0x5ffe0120 0x002e6 0x002e6 R 0x4 TLS0x000488 0x5ffe1488 0x5ffe1488 0x4 0x4 R 0x4 And no symbol is near the given address. All are around 0x5ffe... This time, it seems gcc expects __get_tls_addr to return the DTP+0x8000. Indeed the access to variable b is done with lw v0,-32768(v1) and 32768==0x8000. Are you sure both of those code sequences are calling __tls_get_addr? If so, compare the arguments they passed. My mistake, you're certainly right on this one. When relocating symbol DTPREL in the runtime-loader, we return offset - 0x8000 (as PowerPC does), so with the global-dynamic model, tls_get_addr will return the exact address of tls variable. By the way, how did you test the code of TLS for mips? I mean, uclibc seems the more advanced lib for mips, and although this lib seems to have the necessary code to manage tls once it is installed, the ldso doesn't contain any code for handling TLS (relocation, tls allocation, etc)... Last question, is there a difference between DSO and PIE objects other than the INTERP entry in the program header? Yes. Symbol preemption is allowed for DSOs but not for PIEs or normal executables. That explains the different choice of model. But this is only a property, isn't it? I was meaning, how can you differenciate them at loading time, when you analyse the elf file. Finally, I observed another strange thing with the local-dynamic model. It concerns the reloc symbols. Here is the rel.dyn with local-dynamic: Relocation section '.rel.dyn' at offset 0x3d0 contains 2 entries: Offset InfoTypeSym.Value Sym. Name R_MIPS_NONE 5ffe1470 0026 R_MIPS_TLS_DTPMOD And the same with global-dynamic: Relocation section '.rel.dyn' at offset 0x3d0 contains 3 entries: Offset InfoTypeSym.Value Sym. Name R_MIPS_NONE 5ffe1470 0926 R_MIPS_TLS_DTPMOD a 5ffe1474 0927 R_MIPS_TLS_DTPREL a As you surely know, ELF_R_SYM() macro performs (val8) which gives the symbol index in order to retrieve the name of the symbol. This name then allows to look up the symbol. Unfortunately, in the case of local-dynamic, ELF_R_SYM will return 0 which is not correct (the same for global-dynamic will return 9): we can see by the way that readelf is not able to get the symbol name. What do you think about this? Regards, Joel
Re: Fwd: Mips, -fpie and TLS management
On Thu, Mar 12, 2009 at 02:02:36PM +0100, Joel Porquet wrote: Check what symbol is at, or near, 0x4003 + 22368. It's probably the GOT plus a constant bias. It seems there is nothing at this address. Here is the program header: Don't know then. Look at compiler-generated assembly instead of disassembly; that often helps. By the way, how did you test the code of TLS for mips? I mean, uclibc seems the more advanced lib for mips, and although this lib seems to have the necessary code to manage tls once it is installed, the ldso doesn't contain any code for handling TLS (relocation, tls allocation, etc)... That statement about uclibc strikes me as bizarre. I tested it with glibc, naturally. GLIBC has a much more reliable TLS implementation than uclibc's in-progress one. Last question, is there a difference between DSO and PIE objects other than the INTERP entry in the program header? Yes. Symbol preemption is allowed for DSOs but not for PIEs or normal executables. That explains the different choice of model. But this is only a property, isn't it? I was meaning, how can you differenciate them at loading time, when you analyse the elf file. You can't. As you surely know, ELF_R_SYM() macro performs (val8) which gives the symbol index in order to retrieve the name of the symbol. This name then allows to look up the symbol. Unfortunately, in the case of local-dynamic, ELF_R_SYM will return 0 which is not correct (the same for global-dynamic will return 9): we can see by the way that readelf is not able to get the symbol name. What do you think about this? This is a *module* relocation. In local dynamic the module is always the current DSO; it does not need a symbol. -- Daniel Jacobowitz CodeSourcery
Re: Fwd: Mips, -fpie and TLS management
Dear GCC-list and Daniel, Lately, I continued working on TLS for mips and a few things bother me. Firstly, it seems the -ftls-model option for gcc is not completely respected when compiling Position-Independent Executable (-fpie). Here is a sample of code for app.c: __thread int a = 0; extern __thread int b; By default, the chosen tls model is initial-exec, which causes one relocation for b (R_MIPS_TLS_TPREL32). If I specify local-exec, the behavior is as expected, I get no relocation at all. But whenever I choose a dynamic model (local-dynamic or global-dynamic), I still get a R_MIPS_TLS_TPREL32 which is not a dynamic relocation. Why this? Therefore, I have to explicitely associate an attribute to the variable to get the expected behavior, such as: extern __thread int b __attribute__((tls_model(local-dynamic))); Secondly, I observe a very strange calculation of GCC. Here is the code: extern __thread int b __attribute__((tls_model(local-dynamic))); int main() { b++; } I compile this code with the following CFLAGS: CFLAGS=-nostdinc -nostdlib -fno-builtin \ -Wall \ -fomit-frame-pointer \ -mips2 -EL -mno-branch-likely \ -mabicalls \ -G0 \ -ftls-model=local-dynamic \ -fpie -Os and following LDFLAGS: -pie -app.o -o app.x -l:libc.so -L. (fyi, the libc.so defines the variable b) And I get the following generated code (fyi, the jalr jumps to __get_tls_addr): 5ffe03fc main: 5ffe03fc: 3c1c0001lui gp,0x1 5ffe0400: 279c9054addiu gp,gp,-28588 5ffe0404: 0399e021addugp,gp,t9 5ffe0408: 27bdfff0addiu sp,sp,-16 5ffe040c: afbf000csw ra,12(sp) 5ffe0410: afbcsw gp,0(sp) 5ffe0414: 8f99802clw t9,-32724(gp) 5ffe0418: 27848030addiu a0,gp,-32720 5ffe041c: 0320f809jalrt9 5ffe0420: nop 5ffe0424: 3c034003lui v1,0x4003 5ffe0428: 00621821adduv1,v1,v0 5ffe042c: 8c625760lw v0,22368(v1) 5ffe0430: 8fbf000clw ra,12(sp) 5ffe0434: 8fbclw gp,0(sp) 5ffe0438: 24420001addiu v0,v0,1 5ffe043c: ac625760sw v0,22368(v1) 5ffe0440: 03e8jr ra 5ffe0444: 27bd0010addiu sp,sp,16 The suspicious instruction is lui v1,0x4003. I don't understand where does 0x4003 comes from... Now, if I drop the size optimization, I get the following code: 5ffe040c main: 5ffe040c: 3c1c0001lui gp,0x1 5ffe0410: 279c9064addiu gp,gp,-28572 5ffe0414: 0399e021addugp,gp,t9 5ffe0418: 27bdffe8addiu sp,sp,-24 5ffe041c: afbf0014sw ra,20(sp) 5ffe0420: afb00010sw s0,16(sp) 5ffe0424: afbcsw gp,0(sp) 5ffe0428: 8f99802clw t9,-32724(gp) 5ffe042c: 27848030addiu a0,gp,-32720 5ffe0430: 0320f809jalrt9 5ffe0434: nop 5ffe0438: 8fbclw gp,0(sp) 5ffe043c: 8c42lw v0,0(v0) 5ffe0440: 2451addiu s0,v0,1 5ffe0444: 8f99802clw t9,-32724(gp) 5ffe0448: 27848030addiu a0,gp,-32720 5ffe044c: 0320f809jalrt9 5ffe0450: nop 5ffe0454: 8fbclw gp,0(sp) 5ffe0458: ac50sw s0,0(v0) 5ffe045c: 8fbf0014lw ra,20(sp) 5ffe0460: 8fb00010lw s0,16(sp) 5ffe0464: 27bd0018addiu sp,sp,24 5ffe0468: 03e8jr ra 5ffe046c: nop It seems more correct, although I don't understand if the __get_tls_addr function should really return the address position of the DTP or DTP+0x8000. Here it seems gcc expect __get_tls_addr to return DTP since it accesses directly to the variable without any offset (lw v0,0(v0)). Now, if we look at the compilation of the library (libc.so) that defines the variable b, we get something else. Here is the code: __thread unsigned int* b; void puts(char* str) { b++; } The CFLAGS are the same as previously (with -Os), except -fpic is specified instead -fpie. And the LDFLAGS specify -shared instead of -pie. Here is the generated code: 5ffe03cc puts: 5ffe03cc: 3c1c0001lui gp,0x1 5ffe03d0: 279c9054addiu gp,gp,-28588 5ffe03d4: 0399e021addugp,gp,t9 5ffe03d8: 27bdfff0addiu sp,sp,-16 5ffe03dc: afbf000csw ra,12(sp) 5ffe03e0: afbcsw gp,0(sp) 5ffe03e4: 8f99802clw t9,-32724(gp) 5ffe03e8: 27848030addiu a0,gp,-32720 5ffe03ec: 0320f809jalrt9 5ffe03f0: nop 5ffe03f4: 3c03lui v1,0x0 5ffe03f8:
Re: Fwd: Mips, -fpie and TLS management
On Wed, Mar 11, 2009 at 11:03:10AM +0100, Joel Porquet wrote: By default, the chosen tls model is initial-exec, which causes one relocation for b (R_MIPS_TLS_TPREL32). If I specify local-exec, the behavior is as expected, I get no relocation at all. But whenever I choose a dynamic model (local-dynamic or global-dynamic), I still get a R_MIPS_TLS_TPREL32 which is not a dynamic relocation. Why this? No particular reason, it's just how GCC behaves. I consider it a bug, though minor. 5ffe0424: 3c034003lui v1,0x4003 5ffe0428: 00621821adduv1,v1,v0 5ffe042c: 8c625760lw v0,22368(v1) The suspicious instruction is lui v1,0x4003. I don't understand where does 0x4003 comes from... Check what symbol is at, or near, 0x4003 + 22368. It's probably the GOT plus a constant bias. This time, it seems gcc expects __get_tls_addr to return the DTP+0x8000. Indeed the access to variable b is done with lw v0,-32768(v1) and 32768==0x8000. Are you sure both of those code sequences are calling __tls_get_addr? If so, compare the arguments they passed. Last question, is there a difference between DSO and PIE objects other than the INTERP entry in the program header? Yes. Symbol preemption is allowed for DSOs but not for PIEs or normal executables. That explains the different choice of model. -- Daniel Jacobowitz CodeSourcery
Re: Fwd: Mips, -fpie and TLS management
2008/11/21 Daniel Jacobowitz [EMAIL PROTECTED]: No, there's nothing wrong with this. You can even use multiple models in the same executable for the same symbol. The linker will take care of everything necessary. For instance, the executable's TLS block is at a fixed offset from the DTV pointer. I didn't understand the fact that the TLS structure was independent of the way of accessing it (through models). If you're seeing a bug, then please give a test case that fails at runtime - there can always be bugs. But there is nothing wrong with the tests you've posted so far that I can see. I think there's no bug so far, I was mistaken. And the related reloc symbols are: 5ffe14b0 0026 R_MIPS_TLS_DTPMOD 5ffe14b8 0026 R_MIPS_TLS_DTPMOD Still, is R_MIPS_TLS_DTPMOD a correct symbol ? In the document you wrote about NPTL for mips (http://www.linux-mips.org/wiki/NPTL), there's no such relocation symbol: just R_MIPS_TLS_DTPMOD32 and R_MIPS_TLS_DTPMOD64. Your conclusion does not follow from the evidence. __tls_get_addr takes a pointer to a {module, offset} pair. There's no dynamic relocation for the offset, but that's OK - the linker has calculated it at link time. Take a look at the contents of the GOT starting at 0x5ffe14b0 for four words. The second and fourth words will be the offsets. This is a global dynamic sequence, since it passes non-zero offsets to __tls_get_addr. Indeed, the GOT seems to be already filled with the right offset, you were right. However the values are just a bit weird: 5ffe14b0: nop 5ffe14b4: 8004sdc3$31,-32764(ra) 5ffe14b8: nop 5ffe14bc: 8000sdc3$31,-32768(ra) We can see that the offsets are prefixed by 8. Why is that? Indeed, I guess that if the __tls_get_addr function is written in C, it forces to mask the value. Anyway, thanks for the answers, it did really help me, Joel
Re: Fwd: Mips, -fpie and TLS management
On Mon, Nov 24, 2008 at 03:27:55PM +0100, Joel Porquet wrote: And the related reloc symbols are: 5ffe14b0 0026 R_MIPS_TLS_DTPMOD 5ffe14b8 0026 R_MIPS_TLS_DTPMOD Still, is R_MIPS_TLS_DTPMOD a correct symbol ? In the document you wrote about NPTL for mips (http://www.linux-mips.org/wiki/NPTL), there's no such relocation symbol: just R_MIPS_TLS_DTPMOD32 and R_MIPS_TLS_DTPMOD64. There's only DTPMOD32 and DTPMOD64 relocations defined in binutils. I'm not sure why it's printing that - maybe it's just truncated? Try -W. Indeed, the GOT seems to be already filled with the right offset, you were right. However the values are just a bit weird: 5ffe14b0: nop 5ffe14b4: 8004sdc3$31,-32764(ra) 5ffe14b8: nop 5ffe14bc: 8000sdc3$31,-32768(ra) We can see that the offsets are prefixed by 8. Why is that? The offsets are biased; that's -32768, the lowest 16-bit signed offset. The bias is used to expand the addressable range of the thread pointer. Glad I could help! -- Daniel Jacobowitz CodeSourcery
Re: Fwd: Mips, -fpie and TLS management
This is one of the reasons that the generated code can only be used in executables. Okay, I abdicate on this point. Nevertheless, how could i have a coherent compilation concerning the TLS management, if my executable needs dynamically libraries ? Aren't the exec and dynamic models completely incompatible in the same whole (eg one executable and shared libraries) ? I mean you cannot access at the same storage, once with only a pointer and an offset and once with a DTV. So if my libraries are compiled with global-dynamic model but the executable referring to them (and thus to their TLS data) is compiled with initial-exec, don't we have a problem ?? The libraries will access their data through a call to tls_get_addr with a module number and an offset, while the executable will try to access the data through a simple pointer and an offset. It could be but firstly when the global-dynamic model is specified one should expect to get global-dynamic and not local-dynamic, and anyway it is not local-dynamic. I don't remember what the deal is with the command line option, but I've run into that before. The answer was, I think, that it is behaving as designed - but not intuitively. As for the model, you're right, it's not local dynamic. It's global dynamic linked into an executable. The linker has performed some optimization on your output file because it can determine the symbol binding at static link time. There's no need for a dynamic relocation to calculate DTPREL when it's a link-time constant. But there are no calculation. Here's the code for writing into two global dynamic variable local to my exec: __thread int test_loc1 __attribute((tls_model(global-dynamic))); __thread int test_loc2 __attribute((tls_model(global-dynamic))); void func() { test_loc1 = 2; test_loc2 = 3; } And the compiled and linked code: 5ffe043c: 8f99802clw t9,-32724(gp) 5ffe0440: 27848038addiu a0,gp,-32712 5ffe0444: 0320f809jalrt9 #jump to tls_get_addr 5ffe0448: nop 5ffe044c: 8fbclw gp,0(sp) 5ffe0450: 24030002li v1,2 5ffe0454: 8f99802clw t9,-32724(gp) 5ffe0458: 27848030addiu a0,gp,-32720 5ffe045c: 0320f809jalrt9 #jump to tls_get_addr 5ffe0460: ac43sw v1,0(v0) 5ffe0464: 8fbf000clw ra,12(sp) 5ffe0468: 24030003li v1,3 5ffe046c: 8fbclw gp,0(sp) 5ffe0470: ac43sw v1,0(v0) And the related reloc symbols are: 5ffe14b0 0026 R_MIPS_TLS_DTPMOD 5ffe14b8 0026 R_MIPS_TLS_DTPMOD You can see that both the store instruction have not precalculated offset but a 0 offset. It means that for accessing the two different variables, the only way is to provide two different values for R_MIPS_TLS_DTPMOD, which is incoherent. All the local variable for the exec should be accessed via the same module number. Well, I try but I really don't understand the intended optimizations you mention. All I see is an attempt to make local-dynamic access (but in a way that i don't understand and for which i cannot find any documentation), although the attribute clearly specify global-dynamic. This is all very interesting, but you didn't answer my question: is this causing some problem, or just confusing? These are all intended optimizations. I cannot answer to your question. It is confusing for sure, and personnally, I think there is a problem, but you seems to think otherwise, so
Re: Fwd: Mips, -fpie and TLS management
On Fri, Nov 21, 2008 at 06:51:26PM +0100, Joel Porquet wrote: Nevertheless, how could i have a coherent compilation concerning the TLS management, if my executable needs dynamically libraries ? Aren't the exec and dynamic models completely incompatible in the same whole (eg one executable and shared libraries) ? No, there's nothing wrong with this. You can even use multiple models in the same executable for the same symbol. The linker will take care of everything necessary. For instance, the executable's TLS block is at a fixed offset from the DTV pointer. If you're seeing a bug, then please give a test case that fails at runtime - there can always be bugs. But there is nothing wrong with the tests you've posted so far that I can see. And the related reloc symbols are: 5ffe14b0 0026 R_MIPS_TLS_DTPMOD 5ffe14b8 0026 R_MIPS_TLS_DTPMOD You can see that both the store instruction have not precalculated offset but a 0 offset. It means that for accessing the two different variables, the only way is to provide two different values for R_MIPS_TLS_DTPMOD, which is incoherent. Your conclusion does not follow from the evidence. __tls_get_addr takes a pointer to a {module, offset} pair. There's no dynamic relocation for the offset, but that's OK - the linker has calculated it at link time. Take a look at the contents of the GOT starting at 0x5ffe14b0 for four words. The second and fourth words will be the offsets. This is a global dynamic sequence, since it passes non-zero offsets to __tls_get_addr. -- Daniel Jacobowitz CodeSourcery