diff options
author | Fangrui Song <i@maskray.me> | 2021-04-21 15:58:20 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2021-04-21 15:58:20 -0700 |
commit | 775a9483e55efb365691bc425ed107568ad6daf8 (patch) | |
tree | 8d1d3006715e69a26315f9154c1bd1ceab57286d /llvm/lib/IR/Module.cpp | |
parent | 875654f897ac01ad91a1a5f5dc23d07ac548a0e0 (diff) | |
download | llvm-775a9483e55efb365691bc425ed107568ad6daf8.zip llvm-775a9483e55efb365691bc425ed107568ad6daf8.tar.gz llvm-775a9483e55efb365691bc425ed107568ad6daf8.tar.bz2 |
[IR][sanitizer] Set nounwind on module ctor/dtor, additionally set uwtable if -fasynchronous-unwind-tables
On ELF targets, if a function has uwtable or personality, or does not have
nounwind (`needsUnwindTableEntry`), it marks that `.eh_frame` is needed in the module.
Then, a function gets `.eh_frame` if `needsUnwindTableEntry` or `-g[123]` is specified.
(i.e. If -g[123], every function gets `.eh_frame`.
This behavior is strange but that is the status quo on GCC and Clang.)
Let's take asan as an example. Other sanitizers are similar.
`asan.module_[cd]tor` has no attribute. `needsUnwindTableEntry` returns true,
so every function gets `.eh_frame` if `-g[123]` is specified.
This is the root cause that
`-fno-exceptions -fno-asynchronous-unwind-tables -g` produces .debug_frame
while
`-fno-exceptions -fno-asynchronous-unwind-tables -g -fsanitize=address` produces .eh_frame.
This patch
* sets the nounwind attribute on sanitizer module ctor/dtor.
* let Clang emit a module flag metadata "uwtable" for -fasynchronous-unwind-tables. If "uwtable" is set, sanitizer module ctor/dtor additionally get the uwtable attribute.
The "uwtable" mechanism is generic: synthesized functions not cloned/specialized
from existing ones should consider `Function::createWithDefaultAttr` instead of
`Function::create` if they want to get some default attributes which
have more of module semantics.
Other candidates: "frame-pointer" (https://github.com/ClangBuiltLinux/linux/issues/955
https://github.com/ClangBuiltLinux/linux/issues/1238), dso_local, etc.
Differential Revision: https://reviews.llvm.org/D100251
Diffstat (limited to 'llvm/lib/IR/Module.cpp')
-rw-r--r-- | llvm/lib/IR/Module.cpp | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 41666e8..b5108f7 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -669,6 +669,13 @@ void Module::setRtLibUseGOT() { addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1); } +bool Module::getUwtable() const { + auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable")); + return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0); +} + +void Module::setUwtable() { addModuleFlag(ModFlagBehavior::Max, "uwtable", 1); } + void Module::setSDKVersion(const VersionTuple &V) { SmallVector<unsigned, 3> Entries; Entries.push_back(V.getMajor()); |