Re: TLS with static non-PIE binaries
On Wed, Nov 08, 2017 at 10:58:09PM -0800, Philip Guenther wrote: > @nobits means the section won't have filespace (where the initialization > data is) included in the loaded data. It should work with @progbits > instead. Wow, I suck at assembly. However, once again binutils saved me: $ readelf -SW test.o | grep .tdata [ 4] .tdataPROGBITS 4c 04 00 WAT 0 0 4 I'm afraid changing it to @progbits in the source doesn't make any difference to the result. It still returns the correct thing when dynamically linked but zero when statically linked. -- Charles
Re: TLS with static non-PIE binaries
On Sun, Nov 05, 2017 at 01:02:36PM -0800, Philip Guenther wrote: > Well, ld.so and libc _should_ currently support startup-time TLS using the > initial-exec and local-exec modules. I can't see support for R_x_TPOFF64 relocations in ld.so(1) so I don't think initial-exec will work. But local-exec doesn't require any relocations by the dynamic linker so that should work. > The diff below fixes that, at least on amd64, by checking whether no > AUX_phdr value was found and, if so, trying to instead find them via the > ELF header referenced via the linker-provided __executable_start symbol. The patch fixed the segfaults I was seeing. However, initialized TLS data doesn't work in static executables: it appears as zero. $ cat test.s .globl foo .section.tdata,"awT",@nobits .align 4 .size foo, 4 foo: .int42 .text .globl get_foo .type get_foo, @function get_foo: movl%fs:foo@tpoff, %eax ret $ cc -o test.o -c test.s $ cc -o test test.o main.c $ ./test 42 $ cc -static -o test test.o main.c $ ./test 0 PIE/no-PIE doesn't seem to make any difference to this. I don't actually need initialized TLS data for my use, which is statically linking Go binaries, so you've fixed my problem: thank you! I've run the complete Go test-suite with your patch applied and everything that I'd expect to pass does pass. This is on AMD64 only; I don't have access to any other architecture for testing. -- Charles
Re: TLS with static non-PIE binaries
On Sun, Nov 05, 2017 at 04:17:50PM -0800, Philip Guenther wrote: > BTW, in the .s file in your original message you had this line: > .type foo, @object > > Since foo is in an SHF_TLS section, it has to be of type STT_TLS. You're right. But... > Indeed, binutils is silently overriding what you wrote. Yes, see: http://www.cygwin.com/ml/binutils/2002-11/msg00409.html That assembly was actually generated by GCC. Clang generates the same. The reason is that not all assemblers understand @tls_object. For example, Sun as(1) wants @tls_obj instead. So GCC relies on the fact that it will be fixed later. See: https://gcc.gnu.org/ml/gcc-patches/2015-07/msg00284.html Anyway, that was just a simple example to demonstrate the problem. I don't expect that code to outlive the e-mail. (At least, I hope not...) -- Charles
Re: TLS with static non-PIE binaries
On Sun, Nov 05, 2017 at 01:02:36PM -0800, Philip Guenther wrote: > The problem with static non-PIE executables is that we don't pass an AUX > vector to such processes, so the startup code can't find the TLS segment > and doesn't leave any space for it. Ah, thank you. > The diff below fixes that, at least on amd64 [...] I will test it. Thanks for your help and explanation. -- Charles
Re: TLS with static non-PIE binaries
On Mon, Nov 06, 2017 at 12:58:18AM +0200, Paul Irofti wrote: > We are missing dlopen-time TLS, dynamic TLS relocations and > thread storage-specifier support. Thanks. None of those things are needed for the Local Exec access model though, so that should be OK. Do you have any idea what might cause the segfault I saw? If it's expected behaviour at this stage then that's fine. I just didn't think it looked right. -- Charles
Re: TLS with static non-PIE binaries
On Sun, Nov 05, 2017 at 10:15:57PM +, Stuart Henderson wrote: > On 2017/11/05 21:08, Charles Collicutt wrote: > > I have a program that uses Thread-Local Storage (TLS) with the 'Local Exec' > > access model [1] on AMD64. This looks like it should work on OpenBSD and, > > indeed, it mostly does. > > OpenBSD doesn't have real thread-local storage yet. What does 'real' mean here? OpenBSD looks like it has everything needed for 'Local Exec' thread-local storage. You've got TLS block setup in ld.so(1), _csu_finish, and pthread_create(3). You've got the binutils linker, ld(1), which can handle R_x_TPOFF32 relocations. You don't need anything else for local exec TLS. This is mainly interesting to me because the Go runtime uses local exec TLS to store a pointer to the current goroutine. I know people use Go on OpenBSD: if you're saying that isn't actually expected to work, that would be good to know. -- Charles
Re: Static linking without PIE
On 14 June 2017 at 19:22, Ted Unangst <t...@tedunangst.com> wrote: > Charles Collicutt wrote: > > That works, thank you. gcc-local(1) only mentions -nopie as an option for > > the linker, so I thought it ought to be passed with -Wl,... > > I think I would interpret that sentence to mean linker as in the gcc > invoked > to link stuff. gcc -c is the compiler, gcc is the linker... > Fair enough. But evidently -nopie is also a valid (but undocumented?) option for ld(1). This came up because Go passes -Wl,-nopie to gcc if you run `go build` on OpenBSD. See: https://github.com/golang/go/blob/master/src/cmd/link/internal/ld/lib.go#L1092 From what you're saying, this sounds like a bug in Go. They should just be passing -nopie. Is that right? -- Charles
Re: Static linking without PIE
On 14 June 2017 at 17:34, Ted Unangstwrote: > gcc -static -nopie -o foo foo.c > That works, thank you. gcc-local(1) only mentions -nopie as an option for the linker, so I thought it ought to be passed with -Wl,... So passing -nopie to gcc both causes it to link against the correct crt0 and also passes -nopie to the linker? And passing -nopie to the linker disables PIE generation but doesn't affect which crt0 it uses? -- Charles
Static linking without PIE
Hi, Is the following expected behaviour? $ gcc -static -Wl,-nopie -Wl,-v -o foo foo.c collect2 version 4.2.1 20070719 (OpenBSD/x86-64 ELF) /usr/bin/ld -e __start -Bstatic -dynamic-linker /usr/libexec/ld.so -o foo /usr/lib/rcrt0.o /usr/lib/crtbegin.o -L/usr/lib/gcc-lib/amd64-unknown-openbsd6.1/4.2.1 -nopie -v /tmp//ccZ7VS0V.o -lgcc -lc -lgcc /usr/lib/crtend.o GNU ld version 2.17 /usr/lib/rcrt0.o: In function `__start': (.text+0x1a): undefined reference to `_DYNAMIC' collect2: ld returned 1 exit status I was expecting the -Wl,-nopie option to cause it to link against crt0.o but instead it seems to try to link against rcrt0.o but fails. This was using 6.1-release. -- Charles