This is an archive of the discontinued LLVM Phabricator instance.

[sanitizers] [SystemZ] Add __tls_get_offset interceptor.
ClosedPublic

Authored by koriakin on May 1 2016, 1:04 PM.

Details

Summary

s390 is special again - instead of tls_get_addr, it has tls_get_offset
with special calling conventions: the result is TP relative, and
the argument is GOT-relative. Since we need to get address of the caller's
GOT, which is in %r12, we have to use assembly like glibc does.

Aside of tls_get_offset, glibc also implements a slightly saner
tls_get_addr_internal, which takes a pointer as argument, but still
returns a TP-relative offset. It is used for dlsym() called on TLS
symbols, so we have to intercept it was well. Our __tls_get_offset
is also implemented by delegating to it.

Diff Detail

Repository
rL LLVM

Event Timeline

koriakin retitled this revision from to [sanitizers] [SystemZ] Add __tls_get_offset interceptor..
koriakin updated this object.
koriakin added reviewers: kcc, eugenis, uweigand.
koriakin set the repository for this revision to rL LLVM.
koriakin added a project: Restricted Project.
koriakin added a subscriber: llvm-commits.
eugenis edited edge metadata.May 2 2016, 1:45 PM

All these macro definitions and conditionals make __tls_get_addr interceptor confusing.
Maybe just copy the whole thing, then you'll end up with a few duplicated lines of code, but each version would be a lot simpler.

Is it possible to avoid this module-level asm by implementing an honest interceptor for __tls_get_offset, and a tiny chunk of asm that simply returns %r12, or finds the address of GOT some other way (aren't there linker symbols for the start of each section?) ?

kcc edited edge metadata.May 2 2016, 1:47 PM

+1
As I've said before -- avoid #ifdefs inside the code at all costs.

All these macro definitions and conditionals make __tls_get_addr interceptor confusing.
Maybe just copy the whole thing, then you'll end up with a few duplicated lines of code, but each version would be a lot simpler.

OK.

Is it possible to avoid this module-level asm by implementing an honest interceptor for __tls_get_offset, and a tiny chunk of asm that simply returns %r12, or finds the address of GOT some other way (aren't there linker symbols for the start of each section?) ?

Finding the address of GOT would be rather hard (you need the caller's GOT not your own, so the symbol isn't of much use). A tiny chunk of asm in a function would be nice, but by that point the register allocator could've already used %r12 for something else. A naked function would make this code slightly less ugly, but it's not supported by gcc for s390. I really don't see how to avoid that top-level assembly...

koriakin planned changes to this revision.May 2 2016, 1:54 PM
koriakin edited edge metadata.

This version duplicates the code for s390.

LGTM but please wait for a comment from kcc

kcc accepted this revision.May 2 2016, 4:50 PM
kcc edited edge metadata.

LGTM (I did not try to review the actual code under #ifdef)
If we get more of these, please move them into a separate s390-specific file

This revision is now accepted and ready to land.May 2 2016, 4:50 PM
In D19778#419333, @kcc wrote:

LGTM (I did not try to review the actual code under #ifdef)
If we get more of these, please move them into a separate s390-specific file

Thanks, that should be the last s390-specific code change for asan - I've got the testsuite passing already, but still need to land many patches on the llvm side.

This revision was automatically updated to reflect the committed changes.