Previously, runtime calls introduced by ASan instrumentation into EH
pads were missing the funclet token expected by WinEHPrepare.
WinEHPrepare would then identify the containing BB as invalid and
discard it, causing invalid code generation that most likely crashes.
Also fixed localescape test, switching its EH personality to match code
without funclets.
This PR is based on the Phabricator patch
https://reviews.llvm.org/D143108
Fixes https://github.com/llvm/llvm-project/issues/64990
llvm-project/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp:650:13:
error: private field 'OwnerFn' is not used [-Werror,-Wunused-private-field]
Function *OwnerFn = nullptr;
^
1 error generated.
This is in preparation for an upcoming commit that will add "funclet"
OpBundle to the inserted runtime calls where the function's EH
personality requires it.
See PR https://github.com/llvm/llvm-project/pull/82533
As part of the RemoveDIs project we need LLVM to insert instructions using
iterators wherever possible, so that the iterators can carry a bit of
debug-info. This commit implements some of that by updating the contents of
llvm/lib/Transforms/Utils to always use iterator-versions of instruction
constructors.
There are two general flavours of update:
* Almost all call-sites just call getIterator on an instruction
* Several make use of an existing iterator (scenarios where the code is
actually significant for debug-info)
The underlying logic is that any call to getFirstInsertionPt or similar
APIs that identify the start of a block need to have that iterator passed
directly to the insertion function, without being converted to a bare
Instruction pointer along the way.
Noteworthy changes:
* FindInsertedValue now takes an optional iterator rather than an
instruction pointer, as we need to always insert with iterators,
* I've added a few iterator-taking versions of some value-tracking and
DomTree methods -- they just unwrap the iterator. These are purely
convenience methods to avoid extra syntax in some passes.
* A few calls to getNextNode become std::next instead (to keep in the
theme of using iterators for positions),
* SeparateConstOffsetFromGEP has it's insertion-position field changed.
Noteworthy because it's not a purely localised spelling change.
All this should be NFC.
For COFF, available_externally global will be instrumented because of
the lack of filtering, and will trigger the Verifier pass assertion and
crash the compilation. This patch will filter out the
available_externally global for COFF.
For non-COFF, `!G->hasExactDefinition()` in line 1954 will filter out
the available_externally globals.
There is a related bug reported in
https://bugs.llvm.org/show_bug.cgi?id=47950 /
https://github.com/llvm/llvm-project/issues/47294. I tried the
reproducer posted on the page and this will fix the problem.
Reproducer:
```
#include <locale>
void grouping_impl() {
std::use_facet<std::numpunct<char>>(std::locale());
}
// clang -fsanitize=address -D_DLL -std=c++14 -c format.cc
```
Assertion failure `(i >= FTy->getNumParams() || FTy->getParamType(i) ==
Args[i]->getType()) && "Calling a function with a bad signature!"'. The
'llvm.memcpy' intercepted by ASan instrumentation pass is implemented by
it's own __asan_memcpy implementation. The second argument of
llvm.memcpy accepts ptr to addrspace(4), __asan_memcpy also has to
follow ptr to addrspace(4) convention.
---------
Co-authored-by: Amit Pandey <amit.pandey@amd.com>
StackSafetyAnalysis determines whether stack-allocated variables are
guaranteed to be safe from memory access bugs and enables the removal of
certain unneeded instrumentations.
(hwasan enables StackSafetyAnalysis in https://reviews.llvm.org/D108381)
In a release build of clang, text sections are 9% smaller.
Test updates:
* asan-stack-safety.ll: test the -asan-use-stack-safety=1 default
* lifetime-uar-uas.ll: switch to an indexed store to prevent
StackSafetyAnalysis from optimizing out instrumentation for %c
* alloca_vla_interact.cpp: add a load to prevent StackSafetyAnalysis
from optimizing out `__asan_alloca_poison` for the VLA `array`
* scariness_score_test.cpp: add -asan-use-stack-safety=0 to make a load
of a `__asan_poison_memory_region`-poisoned local variable fail as
intended.
* other .ll tests: add -asan-use-stack-safety=0
Reviewed By: kstoimenov
Pull Request: https://github.com/llvm/llvm-project/pull/77210
StackSafetyAnalysis determines whether stack-allocated variables are
guaranteed to be safe from memory access bugs and enables the removal of
certain unneeded instrumentations.
(hwasan enables StackSafetyAnalysis in https://reviews.llvm.org/D108381)
Test updates:
* asan-stack-safety.ll: test the -asan-use-stack-safety=1 default
* lifetime-uar-uas.ll: switch to an indexed store to prevent
StackSafetyAnalysis from optimizing out instrumentation for %c
* alloca_vla_interact.cpp: add a load to prevent StackSafetyAnalysis
from optimizing out `__asan_alloca_poison` for the VLA `array`
* scariness_score_test.cpp: add -asan-use-stack-safety=0 to make a load
of a `__asan_poison_memory_region`-poisoned local variable fail as
intended.
* other .ll tests: add -asan-use-stack-safety=0
Reviewers: kstoimenov, eugenis, vitalybuka
Reviewed By: kstoimenov
Pull Request: https://github.com/llvm/llvm-project/pull/77210
The use of std::pair makes the values it holds opaque. Using classes
improves this while keeping the POD aspect of a std::pair. As a nice
addition, the "known" functions held inappropriately in the Visitor
classes can now properly reside in the value classes. :-)
Address sanitizer checks for AMDGPU target in non-recovery mode aren't
quite efficient at the moment which can be illustrated with a program:
```
instr_before;
load ptr1;
instr_in_the_middle;
load ptr2;
instr_after;
```
ASAN generates the following instrumentation:
```
instr_before;
if (sanity_check_passed(ptr1))
load ptr1;
instr_in_the_middle;
if (sanity_check_passed(ptr2))
load ptr2;
instr_after;
else
// ASAN report block 2
__asan_report(ptr2); // wave terminates
unreachable;
else
// ASAN report block 1
__asan_report(ptr1); // wave terminates
unreachable;
```
Each sanitizer check is treated as a non-uniform condition (and this is
true because some lanes may pass the check and some don't). This results
in the program above: basically normal program flow is continued in
_then_ blocks. This way it allows lanes that pass all sanity checks to
complete the program and then the wave terminates at the first reporting
_else_ block. For each _else_ block it has to keep execmask and pointer
value to report error consuming tons (megatons!) of registers which are
live till the program end.
This patch changes the behavior on a failing sanity check: instead of
waiting when passing lanes reach program end report error and terminate
as soon as any lane has violated the sanity check. Sanity check
condition is treated uniform with this approach and the resulting
program looks much like ordinary CPU code:
```
instr_before;
if (any_lane_violated(sanity_check_passed(ptr1)))
// ASAN report block 1
__asan_report(ptr1); // abort the program
unreachable;
load ptr1;
instr_in_the_middle;
if (any_lane_violated(sanity_check_passed(ptr2)))
// ASAN report block 2
__asan_report(ptr2); // abort the program
unreachable;
load ptr2;
instr_after;
```
However it has to use a trick to pass structurizer and some later
passes: ASAN check is generated like in recovery mode but reporting
function aborts, that is standard _unreachable_ instruction isn't used:
```
...
if (any_lane_violated(sanity_check_passed(ptr1)))
// ASAN report block 1
__asan_report(ptr1); // abort the program
// pretend we're going to continue the program
load ptr1;
...
```
This may create some undesirable effects:
1. Register allocator generates a lot of code for save/restore registers
for asan_report call. This may potentially bloat the code since we have
a report block for every accessed pointer.
2. Loop invariant code in report blocks is hoisted into a loop
preheader. I'm not sure but probably this can be solved using block
frequency information, but most likely this isn't a problem at all.
These problems are to be addressed later.
### Flattening address sanitizer check
In order to simplify divergent CFG this patch also changes the
instrumentation code from:
```
uint64_t address = ptr;
sbyte *shadow_address = MemToShadow(address);
sbyte shadow_value = *shadow_address;
if (shadow_value) {
sbyte last_accessed_byte = (address & 7) + kAccessSize - 1;
if (last_accessed_byte >= shadow_value) {
ReportError(address, kAccessSize, kIsWrite);
abort();
}
}
```
to
```
uint64_t address = ptr;
sbyte *shadow_address = MemToShadow(address);
sbyte shadow_value = *shadow_address;
sbyte last_accessed_byte = (address & 7) + kAccessSize - 1;
if (shadow_value && last_accessed_byte >= shadow_value) {
ReportError(address, kAccessSize, kIsWrite);
abort();
}
```
It saves one _if_ which really avoids very few instructions and their
latency can be hidden by the load from shadow memory.
When ASan.MaxInlinePoisoningSize == 0 , it means that no shadow memory
operations should be made via inlined instrumentation code,
but only via calls to shadow setting functions. This change fixes one
violation of this, which happened when the function allocas count
was small, i.e. less than 5 - in the code modifying the shadow just
before ret instruction.
We now explicitly check ASan.MaxInlinePoisoningSize , and if it's 0 then
we disallow inlining. It is required for the instrumentation
emitting code suitable for handling by ABI implementation.
rdar://119513720
Co-authored-by: Mariusz Borsa <m_borsa@apple.com>
We'd like to make various instrprof globals large to make them not
contribute to relocation pressure since there are no direct accesses
to them in the module.
Similar to what was done for asan_globals in #74514.
This affects the __llvm_prf_vals, __llvm_prf_vnds, and __llvm_prf_names
sections.
The reland fixes platform.ll.
We'd like to make various instrprof globals large to make them not
contribute to relocation pressure since there are no direct accesses
to them in the module.
Similar to what was done for asan_globals in #74514.
This affects the __llvm_prf_vals, __llvm_prf_vnds, and __llvm_prf_names
sections.
We'd like to make the asan_globals section large to make it not
contribute to relocation pressure since there are no direct PC32
references to it.
Following #74498, we can do that by marking the code model for the
global explicitly large.
Without this change, asan_globals gets placed between .data and .bss.
With this change, it gets placed after .bss.
This patch adds the ability to pass values for the command line options
of -max-inline-poisoning-size, -instrumentation-with-calls-threshold and
-asan-guard-against-version-mismatch through the AddressSanitizerOptions
struct. The motivation is to use these new options when using the pass
in Swift.
rdar://118470958
Currently, the ConstructorKind member variable in AddressSanitizerPass
gets overriden by the ClConstructorKind whether the option is passed
from the command line or not. This override should only happen if the
ClConstructorKind argument is passed from the command line. Otherwise,
the constructor should honor the argument passed to it. This patch makes
this fix.
rdar://118423755
On ELF platforms, when there is no global variable and the unique module ID is
non-empty, COMDAT asan.module_ctor is created with no
`__asan_register_elf_globals` calls. If this COMDAT is the prevailing copy
selected by the linker, the linkage unit will have no
`__asan_register_elf_globals` call: the redzone will not be poisoned and ODR
violation checker will not work (#67677).
This behavior is benign for -fno-sanitize-address-globals-dead-stripping because
asan.module_ctor functions that call `__asan_register_globals`
(`InstrumentGlobalsWithMetadataArray`) do not use COMDAT.
To fix#67677:
* Use COMDAT for -fsanitize-address-globals-dead-stripping on ELF platforms.
* Call `__asan_register_elf_globals` even if there is no global variable.
* If the unique module ID is empty, don't call SetComdatForGlobalMetadata:
placing `@.str` in a COMDAT would incorrectly discard internal COMDAT `@.str`
in other compile units.
Alternatively, when there is no global variable, asan.module_ctor is not COMDAT
and does not call `__asan_register_elf_globals`. However, the asan.module_ctor
function cannot be eliminated by the linker.
Tested the following script. Only ELF -fsanitize-address-globals-dead-stripping has changed behaviors.
```
echo > a.cc # no global variable, empty uniqueModuleId
echo 'void f() {}' > b.cc # with global variable, with uniqueModuleId
echo 'int g;' > c.cc # with global variable
for t in x86_64-linux-gnu arm64-apple-macosx x86_64-windows-msvc; do
for gc in -f{,no-}sanitize-address-globals-dead-stripping; do
for f in a.cc b.cc c.cc; do
echo /tmp/Rel/bin/clang -S --target=$t -fsanitize=address $gc $f -o -
/tmp/Rel/bin/clang -S --target=$t -fsanitize=address $gc $f -o - | sed -n '/asan.module_ctor/,/ret/p'
done
done
done
```
---
Identical to commit 16eed8c906875e748c3cb610f3dc4b875f3882aa.
6420d3301cd4f0793adcf11f59e8398db73737d8 is an incorrect revert for genuine
purely internal issues.
* Remove if its sole use is to support an unnecessary ptr-to-ptr bitcast
(remove the bitcast as well)
* Replace with use of other APIs.
NFC opaque pointer cleanup effort.
On ELF platforms, when there is no global variable and the unique module ID is
non-empty, COMDAT asan.module_ctor is created with no
`__asan_register_elf_globals` calls. If this COMDAT is the prevailing copy
selected by the linker, the linkage unit will have no
`__asan_register_elf_globals` call: the redzone will not be poisoned and ODR
violation checker will not work (#67677).
This behavior is benign for -fno-sanitize-address-globals-dead-stripping because
asan.module_ctor functions that call `__asan_register_globals`
(`InstrumentGlobalsWithMetadataArray`) do not use COMDAT.
To fix#67677:
* Use COMDAT for -fsanitize-address-globals-dead-stripping on ELF platforms.
* Call `__asan_register_elf_globals` even if there is no global variable.
* If the unique module ID is empty, don't call SetComdatForGlobalMetadata:
placing `@.str` in a COMDAT would incorrectly discard internal COMDAT `@.str`
in other compile units.
Alternatively, when there is no global variable, asan.module_ctor is not COMDAT
and does not call `__asan_register_elf_globals`. However, the asan.module_ctor
function cannot be eliminated by the linker.
Tested the following script. Only ELF -fsanitize-address-globals-dead-stripping has changed behaviors.
```
echo > a.cc # no global variable, empty uniqueModuleId
echo 'void f() {}' > b.cc # with global variable, with uniqueModuleId
echo 'int g;' > c.cc # with global variable
for t in x86_64-linux-gnu arm64-apple-macosx x86_64-windows-msvc; do
for gc in -f{,no-}sanitize-address-globals-dead-stripping; do
for f in a.cc b.cc c.cc; do
echo /tmp/Rel/bin/clang -S --target=$t -fsanitize=address $gc $f -o -
/tmp/Rel/bin/clang -S --target=$t -fsanitize=address $gc $f -o - | sed -n '/asan.module_ctor/,/ret/p'
done
done
done
```
This reverts commit 1a4b9b6f73391d94f4f96cc964cbf89cfdd59b5b.
When getUniqueModuleId(&M) is empty, we may add comdat to internal constants
like $.str, causing spurious `error: relocation refers to a symbol in a
discarded section` lld errors.
On ELF platforms, when there is no global variable, COMDAT asan.module_ctor is
created with no `__asan_register_elf_globals` calls. If this COMDAT is the
prevailing copy selected by the linker, the linkage unit will have no
`__asan_register_elf_globals` call: the redzone will not be poisoned and ODR
violation checker will not work (#67677).
This behavior is benign for -fno-sanitize-address-globals-dead-stripping because
asan.module_ctor functions that call `__asan_register_globals`
(`InstrumentGlobalsWithMetadataArray`) do not use COMDAT.
To fix#67677:
* Use COMDAT for -fsanitize-address-globals-dead-stripping on ELF platforms.
* Call `__asan_register_elf_globals` even if there is no global variable.
Alternatively, when there is no global variable, asan.module_ctor is not COMDAT
and does not call `__asan_register_elf_globals`. However, the asan.module_ctor
function cannot be eliminated by the linker.
Tested the following script. Only ELF -fsanitize-address-globals-dead-stripping has changed behaviors.
```
echo > a.cc # no global variable, empty uniqueModuleId
echo 'void f() {}' > b.cc # with global variable, with uniqueModuleId
echo 'int g;' > c.cc # with global variable
for t in x86_64-linux-gnu arm64-apple-macosx x86_64-windows-msvc; do
for gc in -f{,no-}sanitize-address-globals-dead-stripping; do
for f in a.cc b.cc c.cc; do
echo /tmp/Rel/bin/clang -S --target=$t -fsanitize=address $gc $f -o -
/tmp/Rel/bin/clang -S --target=$t -fsanitize=address $gc $f -o - | sed -n '/asan.module_ctor/,/ret/p'
done
done
done
```
When building the kernel with LTO, KASAN & debug information enabled,
multiple inlinable AddressSanitizer functions require debug information
present.
In such cases we repurpose the InstrumentationIRBuilder that ensures
the necessary debug information is added if necessary.
This has been done analogous to the work for the ThreadSanitizer
in D124937.
Bug: https://github.com/ClangBuiltLinux/linux/issues/1721
Reviewed By: melver
Differential Revision: https://reviews.llvm.org/D155376
The patch uses a way similiar to vp.load/store and consider the mask popcount as
the effetive vector length.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D151713
The patch handle masked.gather/scatter just like the way D149245 handles
vp.gather/scatter.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D151545
When a 128-bit load/store is aligned by 8, we incorrectly emit `load i16, ptr ..., align 2`
while the shadow memory address may not be aligned by 2.
This manifests as possibly-misaligned shadow memory load with `-mstrict-align`,
e.g. `clang --target=aarch64-linux -O2 -mstrict-align -fsanitize=address`
```
__attribute__((noinline)) void foo(unsigned long *ptr) {
ptr[0] = 3;
ptr[1] = 3;
}
// ldrh w8, [x9, x8] // the shadow memory load may not be aligned by 2
```
Infer the shadow memory alignment from the load/store alignment to set the
correct alignment. The generated code now uses two ldrb and one orr.
Fix https://github.com/llvm/llvm-project/issues/63258
Differential Revision: https://reviews.llvm.org/D152663
The patch supports vp.gather/scatter by allowing addresses being pointer vectors.
And then we just need to check each active pointer element of those pointer vectors.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D149245
The patch adds new member MaybeStride into InterestingMemoryOperand to represent
the stride value of experimental.vp.strided.load/store.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D149073
The patch adds new member MaybeEVL into InterestingMemoryOperand to represent
the effective vector length for vp intrinsics. It may be extended for some target intrinsics in the future.
Reviewed By: kito-cheng
Differential Revision: https://reviews.llvm.org/D146208
This patch adjusts the memory instrumentation to account for scalable vector types in allocas. Note that we don't allow scalable vector globals, so we don't need to update that codepath.
A couple points.
First, this simply disables the optimization for scalable allocas. We can revisit this in the future, but it requires a bit of plumbing to get scalable object sizes through the visitor to be useful.
Second, I am simply disabling stack poisoning for scalable vector allocas. This is mostly for staging the change as I can't write a working test for memory instrumentation without doing so. I don't think it's unreasonable to do on it's own basis as without the bailout, we crash the compiler.
Differential Revision: https://reviews.llvm.org/D145259
The new API matches a case we also need in MSAN. For the moment, I'm staging this as a local-to-ASAN commit, but I expect to move this to a shared location and reuse in the next day or two.
These idioms already appear a number of places in code, and upcoming changes to the various sanitizers continue to need more instances of the same patterns.
Differential Revision: https://reviews.llvm.org/D145945
This takes the approach of using the loop based formation for scalable vectors only. We could potentially use the loop form for fixed vectors only, but we'd loose the unroll and specialize on constant vector logic which is already present. I don't have a strong opinion on whether the existing logic is worthwhile, I kept it mostly to minimize test churn.
Worth noting is that there is a better lowering available. The plain vector lowering appears to check only the first and last byte. By analogy, we should be able to check only the first active and last active byte in the masked op. This is a more invasive change to asan, and I decided simply supporting scalable vectors at all was a better starting place.
Differential Revision: https://reviews.llvm.org/D145198
This only covers the common load/store case. There will be further patches required for masked load/store and some of the fast-path optimization cases.
Differential Revision: https://reviews.llvm.org/D145175
This is a mechanical prep change for scalable vector support. All it does is move the point of TypeSize to unsigned (i.e. the unsafe cast) closer to point of use.
This is a mechanical prep change for scalable vector support. All it does is move the point of TypeSize to unsigned (i.e. the unsafe cast) closer to point of use.