This is an archive of the discontinued LLVM Phabricator instance.

[asan] Make ASan compatible with linker dead stripping on Windows
ClosedPublic

Authored by rnk on Nov 16 2016, 3:18 PM.

Details

Summary

This is similar to what was done for Darwin in rL264645 /
http://reviews.llvm.org/D16737, but it uses COFF COMDATs to achive the
same result instead of relying on new custom linker features.

As on MachO, this creates one metadata global per instrumented global.
The metadata global is placed in the custom .ASAN$GL section, which the
ASan runtime will iterate over during initialization. There are no other
references to the metadata, so normal linker dead stripping would
discard it. However, the metadata is put in a COMDAT group with the
instrumented global, so that it will be discarded if and only if the
instrumented global is discarded.

I didn't update the ASan ABI version check since this doesn't affect
non-Windows platforms, and the WinASan ABI isn't really stable yet.

Implementing this for ELF will require extending LLVM IR and MC a bit so
that we can use non-COMDAT section groups.

Diff Detail

Repository
rL LLVM

Event Timeline

rnk updated this revision to Diff 78273.Nov 16 2016, 3:18 PM
rnk retitled this revision from to [asan] Make ASan compatible with linker dead stripping on Windows.
rnk updated this object.
rnk added reviewers: pcc, kcc, mehdi_amini, kubamracek.
rnk added a subscriber: llvm-commits.
rnk added a comment.Nov 16 2016, 4:20 PM

This passed check-asan, but it goes without saying that this needs an LLVM-only test too.

rnk added a reviewer: rgov.Nov 17 2016, 9:01 AM
rnk updated this revision to Diff 78425.Nov 17 2016, 3:03 PM
  • Add instrumentation test
inglorion added inline comments.
lib/Transforms/Instrumentation/AddressSanitizer.cpp
1566 ↗(On Diff #78425)

This would make it not use comdat metadata on ELF, right? Would it work to instead do the equivalent of

bool UseMachOGlobalsSection = ShouldUseMachOGlobalsSection();
bool UseComdatMetadata = !UseMachOGlobalsSection && TargetTriple.supportsCOMDAT();
bool UseMetadataArray = !(UseComdatMetadata || UseMachOGlobalsSection);

so that we get the MachO special implementation where applicable, else try to use comdats, and only fall back to the metadata array if neither of the other options will work?

rnk added inline comments.Nov 18 2016, 10:18 AM
lib/Transforms/Instrumentation/AddressSanitizer.cpp
1566 ↗(On Diff #78425)

There's a bit more work to do for ELF:

  1. COMDAT groups around internal symbols don't work the way I expected, this is what my comment about "Implementing this for ELF will require extending LLVM IR and MC a bit so that we can use non-COMDAT section groups." is about. If you enable this code on ELF, you end up with "relocation against discarded section" errors for strings and other static globals.
  2. Once that's all prototyped, I need to do a bit more work to verify that --gc-sections actually discards unused globals and retains asan global metadata for used globals
  3. We need to add an initializer to every DSO containing asan-instrumented code to register these globals. On Windows, users are required to statically link a small bit of ASan RTL code into every DLL that uses ASan, so I put the registration code there.
rnk added a comment.Nov 21 2016, 10:49 AM

Ping for LLVM side

vitalybuka accepted this revision.Nov 21 2016, 10:56 AM
vitalybuka edited edge metadata.

LGTM

This revision is now accepted and ready to land.Nov 21 2016, 10:56 AM
This revision was automatically updated to reflect the committed changes.