This is an archive of the discontinued LLVM Phabricator instance.

[HIP] Preserve ASAN bitcode library functions
ClosedPublic

Authored by yaxunl on Jul 19 2021, 2:36 PM.

Details

Summary

Address sanitizer passes may generate call of ASAN bitcode library
functions after bitcode linking in lld, therefore lld cannot add
those symbols since it does not know they will be used later.

To solve this issue, clang emits a reference to a bicode library
function which calls all ASAN functions which need to be
preserved. This basically force all ASAN functions to be
linked in.

Diff Detail

Event Timeline

yaxunl created this revision.Jul 19 2021, 2:36 PM
yaxunl requested review of this revision.Jul 19 2021, 2:36 PM
tra accepted this revision.Jul 22 2021, 4:56 PM

LGTM in general.

One question -- does it have to be a function calling other functions just for the sake of preserving them?
Can it be a flat array of pointers to the functions you need to keep around?

This revision is now accepted and ready to land.Jul 22 2021, 4:56 PM

LGTM in general.

One question -- does it have to be a function calling other functions just for the sake of preserving them?
Can it be a flat array of pointers to the functions you need to keep around?

Yes that's possible. However that would require FE to know these functions and declare them, whereas the current approach leave the concern to the device library.

This revision was landed with ongoing or failed builds.Jul 23 2021, 7:36 AM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptJul 23 2021, 7:36 AM
tra added a comment.Jul 23 2021, 10:58 AM

Yes that's possible. However that would require FE to know these functions and declare them, whereas the current approach leave the concern to the device library.

I was thinking of just adding a pointer to an array of pointers to @llvm.compiler.used.
The array itself would come from the bitcode library and would be populated there. I'm not sure if it's doable without knowing the array size, though.

e.g

; Added by compiler
@llvm.compiler.used = appending global [1 x i8*] [i8* bitcast ([16 x i8*]* @_ZL5funcs to i8*)], section "llvm.metadata"

; comes from the bitcode library, initialized with the pointers to functions you need to keep.
@_ZL5funcs = internal global [16 x i8*] zeroinitializer, align 4

It should be possible to make the pointer to the array opaque with an intermadiate variable in the library.

Yes that's possible. However that would require FE to know these functions and declare them, whereas the current approach leave the concern to the device library.

I was thinking of just adding a pointer to an array of pointers to @llvm.compiler.used.
The array itself would come from the bitcode library and would be populated there. I'm not sure if it's doable without knowing the array size, though.

e.g

; Added by compiler
@llvm.compiler.used = appending global [1 x i8*] [i8* bitcast ([16 x i8*]* @_ZL5funcs to i8*)], section "llvm.metadata"

; comes from the bitcode library, initialized with the pointers to functions you need to keep.
@_ZL5funcs = internal global [16 x i8*] zeroinitializer, align 4

It should be possible to make the pointer to the array opaque with an intermadiate variable in the library.

Yes that is possible. Actually it can be simpler. We can add __attribute__((used)) to the dummy function in the bitcode lib, and it will be kept when linked by -mlink-builtin-bitcode.

However, it has a drawback compared to the current approach. It has no control when to keep the dummy function, whereas the current approach only keep it for -fsanitize=asan.