Re: TLS with static non-PIE binaries

2017-11-09 Thread Charles Collicutt
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

2017-11-08 Thread Charles Collicutt
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

2017-11-06 Thread Charles Collicutt
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

2017-11-05 Thread Charles Collicutt
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

2017-11-05 Thread Charles Collicutt
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

2017-11-05 Thread Charles Collicutt
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

2017-06-14 Thread Charles Collicutt
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

2017-06-14 Thread Charles Collicutt
On 14 June 2017 at 17:34, Ted Unangst  wrote:

> 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

2017-06-14 Thread Charles Collicutt
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