Historically, alignment and size weren't taken into account when freeing
allocations since `free` just takes a pointer. With `free_sized` and
`free_aligned_sized`, we can do these size and alignment checks in asan
now. This adds a new report type specifically for these functions.
Checking is hidden behind a new env flag `free_size_mismatch` which is
enabled by default, but downstream users can opt out of it.
The bulk of this PR was generated by gemini but thoroughly reviewed and
edited by me to the best of my ability.
The one new assembly source file, `arm/adddf3.S`, implements both
addition and subtraction via cross-branching after flipping signs, since
both operations must provide substantially the same logic. The new cmake
properties introduced in a prior commit are used to arrange that
including `adddf3.S` supersedes the C versions of both addition and
subtraction, and also informs the test suite that both functions are
available to test.
As noted in https://github.com/llvm/llvm-project/pull/188406 comments,
the documentation recommends guarding only with
__has_feature(address_sanitizer). This patch updates the test to follow
the same pattern by removing the
__SANITIZER_DISABLE_CONTAINER_OVERFLOW__ checks. Having this macro
defined results in the common_interface_defs.h header defining the
contiguous container functions as no-ops anyway.
This is a followup to https://github.com/llvm/llvm-project/pull/188406.
#171941 got the builtins tests running under LLVM_ENABLE_RUNTIMES by
testing the builtins as part of the runtimes build.
As a consequence, CMake in `lib/builtins/` is no longer visible when
configuring the tests (but `test/builtins/` is). This means that the
`cmake_dependent_option` from `lib/builtins/` is not accounted for by
the tests, allowing COMPILER_RT_BUILD_CRT to be YES when
COMPILER_RT_HAS_CRT is NO. As a consequence, the CRT tests are running
on platforms where COMPILER_RT_HAS_CRT is false (#176892).
367da15a11/compiler-rt/lib/builtins/CMakeLists.txt (L1106-L1108)
Although the long-term solution could be to split both the builtins (and
their tests) out of compiler-rt into a top-level directory with shared
options, this works around the issue for the moment by checking both
COMPILER_RT_HAS_CRT and COMPILER_RT_BUILD_CRT before enabling the "crt"
feature.
Fixes#176892
Summary:
This PR enables the basic unit tests for builtins to be run on the GPU
architectures. Other targets like profiling are supported, but the
host-device natures will make it more difficult to adequately unit
test. It may be be possible to do basic tests there, to simply verify
that
counters are present and in the proper format for when they are copied
to the host.
Now that the corresponding libcxx change has landed, these tests should
be passing on some platforms.
This patch re-enables them for all platforms, so that we can see which
bots these do not work on and mark them unsupported accordingly.
rdar://167946476
In the builtins library, most functions have a portable C implementation
(e.g. `mulsf3.c`), and platforms might provide an optimized assembler
implementation (e.g. `arm/mulsf3.S`). The cmake script automatically
excludes the C source file corresponding to each assembly source file it
includes. Additionally, each source file name is automatically
translated into a flag that lit tests can query, with a name like
`librt_has_mulsf3`, to indicate that a function is available to be
tested.
In future commits I plan to introduce cases where a single .S file
provides more than one function (so that they can share code easily),
and therefore, must supersede more than one existing source file.
I've introduced the `crt_supersedes` cmake property, which you can set
on a .S file to name a list of .c files that it should supersede. Also,
the `crt_provides` property can be set on any source file to indicate a
list of functions it makes available for testing, in addition to the one
implied by its name.
__asan_region_is_poisoned() uses an exclusive end address
(end = beg + size) to validate the region [beg, end) and to compute
the aligned inner shadow region. This causes correctness issue
near memory range upper boundary and could trigger address space
overflow on 32-bit targets.
1. Incorrect handling of the last byte of a memory range
The implementation checks AddrIsInMem(end) instead of the last
application byte (end - 1). For regions ending at the last byte
of Low/Mid/HighMem (e.g. __asan_region_is_poisoned(kHighMemEnd, 1)),
this returns end (kHighMemEnd + 1) instead of the original
pointer. This behavior is inconsistent with the function’s
semantics and with __asan_address_is_poisoned().
2) address space overflow and invalid shadow range
If a region ends at the top of the virtual address space (kHighMemEnd),
e.g. on 32-bit targets, end = beg + size could wrap to 0.
This violated the invariant beg < end and could trigger
the CHECK failure.
Additionally, overflow in RoundUpTo alignment computations
for aligned_b could produce an invalid shadow region spanning
LowShadow to HighShadow across ShadowGap, leading mem_is_zero()
to access unmapped memory and crash.
Fix by switching to an inclusive last byte:
last = beg + size - 1
All checks are now performed on beg and last. The aligned inner
shadow region is also computed from [beg, last]. Additional guard
for aligned_b prevents the mapping to shadow if aligned_b is wrapped
(in this case the aligned inner region is also empty and doesn't
require the shadow scan via mem_is_zero()).
This fixes incorrect return values at memory range ends and
prevents overflow related crashes on 32-bit targets.
Test is extended to cover these boundary cases.
---------
Co-authored-by: Vitaly Buka <vitalybuka@gmail.com>
Add the architecture-specific pieces needed for the ASan and UBSan
sanitizer runtimes to build and run on hexagon-unknown-linux-musl.
Without this patch, building sanitizer runtimes for Hexagon Linux fails
with:
sanitizer_linux.cpp: error: member access into incomplete type
'struct stat64'
because musl libc does not provide struct stat64. This patch routes
Hexagon through the statx() syscall path (like LoongArch) to avoid the
stat64 dependency entirely.
Changes:
* asan_mapping.h: Add ASAN_SHADOW_OFFSET_CONST (0x20000000) for Hexagon
with shadow layout documentation.
* sanitizer_linux.cpp: Implement internal_clone() for Hexagon using
inline assembly (trap0 syscall, generic clone argument order: flags,
stack, ptid, ctid, tls). Route Hexagon through the statx() path for stat
operations since musl lacks struct stat64.
* sanitizer_linux.h: Add Hexagon to the internal_clone() declaration
guard.
* sanitizer_stoptheworld_linux_libcdep.cpp: Add Hexagon to the
StopTheWorld architecture guard with register definitions.
* sanitizer_asm.h: Define ASM_TAIL_CALL as 'jump' for Hexagon.
* CMakeLists.txt: Add -fno-emulated-tls for Hexagon targets. Hexagon
Linux uses native TLS via the UGP register; emulated TLS produces broken
sanitizer runtimes with unresolvable __emutls references.
When the sum of two sub-normal values is not also subnormal, we need to
set the exponent to one.
Test case:
static volatile float x = 0x1.362b4p-127;
static volatile float x2 = 0x1.362b4p-127 * 2;
int
main (void)
{
printf("x %a x2 %a x + x %a\n", x, x2, x + x);
return x2 == x + x ? 0 : 1;
}
Signed-off-by: Keith Packard <keithp@keithp.com>
On sufficiently old versions of the Arm architecture, the optimized FP
routines are not enabled. So commit a84ee1416b6c179 should not have
enabled the extra-strict tests that go with them.
Also in that commit, I wrote a comment saying I was setting two separate
compile-time definitions (-DCOMPILER_RT_ARM_OPTIMIZED_FP and
-DCOMPILER_RT_ARM_OPTIMIZED_FP_THUMB1), and then didn't actually do it!
This caused the strict mulsf3 tests to be wrongly disabled in Thumb2.
Both of these tests will cause an unsuccessful pass when using msvc.
`shadowed-stack-serialization.cpp` - XFAIL due to the metadata not being
generated.
`fakeframe-right-redzone.cpp` - UNSUPPORTED due to the optimization
limitations of the msvc compiler.
---------
Co-authored-by: MacGyver Codilla <mcodilla@microsoft.com>
I have seen that very occasionally this test is failing on a bot, with
only 3 files in the corpus. After running the test in a loop 4000+
times, I witnessed this same failure twice.
In both cases the first corpus member was some string not containing a
'F'; the second corpus member was 'F[' or 'FZ'; and the final corpus
member 'FUZ'.
In a normal run there is an intermediate corpus member 'FU.' - so this
test is failing in very rare cases where the fuzzer gets lucky and
matches 2 branch conditions in one mutation.
This patch allows the FileCheck condition to match 3 or 4 corpus files.
It may be possible for the fuzzer to reach the target in 2 files, but I
think that if that is possible, it will be exceptionally rare.
rdar://170440934
Commit 5efce7392f3f6cc added optimized AArch32 assembly versions of
mulsf3 and divsf3, with more thorough tests. The new tests included test
cases specific to Arm's particular NaN handling rules, which are
disabled on most platforms, but were intended to be enabled for Arm.
Unfortunately, they were not enabled under any circumstances, because I
made a mistake in `test/builtins/CMakeLists.txt`: the command-line `-D`
option that should have enabled them was added to the cflags list too
early, before the list was reinitialized from scratch. So it never ended
up on the command line.
Also, the test file mulsf3.S only even _tried_ to enable strict mode in
Thumb1, even though the Arm/Thumb2 implementation would also have met
its requirements.
Because the strict-mode tests weren't enabled, I didn't notice that they
would also have failed absolutely everything, because they checked the
results using the wrong sense of comparison! I used `==`, but that
comparison was supposed to be a drop-in replacement for
`compareResultF`, which returns zero for equality. Changed the tests to
use `!=`.
Finally, I've also added a macro to each test so that it records the
source line number of each failing test case. That way, when a test
fails, you can find it in the test source more easily, without having to
search for the hex numbers mentioned in the failure message.
The new test case added in 781719778003ca298ca57e486ab629b7f384844b
didn't work in mingw mode; defines set through `/D` only works when
using the clang-cl compiler driver, not the regular clang compiler
driver.
Switch this to use `-D`, which works with both plain clang and
clang-cl, so we don't need to use a lit macro for expanding
the right option to use.
This is a follow up to #155943
On Windows, ASan's allocator internally upgrades zero-size allocation
requests to size 1 (since malloc(0) must return a unique non-NULL
pointer). However, when the user queries the allocation size through
Windows heap APIs (RtlSizeHeap, HeapSize, \_msize, GlobalSize,
LocalSize), ASan reports the internal size (1) instead of the originally
requested size (0).
This causes false positive heap-buffer-overflow errors in a common
pattern:
```c++
void *buf = HeapAlloc(GetProcessHeap(), 0, 0);
SIZE_T size = HeapSize(GetProcessHeap(), 0, buf); // Returns 1, should be 0
if(size > 0) // could remove this and still be correct
memset(buf, 0, size); // ASan reports heap-buffer-overflow
```
The change adds a `from_zero_alloc` bit to `ChunkHeader` that tracks
whether an allocation was originally zero-size. This bit fits in the
existing spare capacity of the header's bitfield byte, so the 16-byte
ChunkHeader size is unchanged, but it also isn't the most elegant.
The 1-byte user region of a zero-size allocation is still poisoned, so
any actual access to it is correctly reported as an overflow.
The existing ELF/COFF correlation code mostly "just works" on Mach-O
files, with one gotcha: on disk, the pointers in `__llvm_covdata` are
stored in an encoded format due to dyld fixup chains. (In memory, they
would normally be fixed up at load time in a running binary, but the
correlator only looks at the on-disk values.)
LLVM's Mach-O reader knows how to decode the format, so this patch walks
the fixup table to create a set of mappings that the correlator can use
to resolve the values.
rdar://168259786
On AIX, when both the `__VEC__` and `_ALL_SOURCE` macros are defined
(they are defined by default), the malloc and calloc system calls are
mapped to vec_malloc and vec_calloc respectively, so we need the
following vec_malloc and vec_calloc interceptors.
Issue: #138916
The `UBSan-Standalone-x86_64 :: TestCases/Misc/Posix/static-link.cpp`
test currently `FAIL`s on Solaris/x86_64 with
```
ld: fatal: option '-z record' is incompatible with building a static executable
```
One cannot create static executables on Solaris since no `libc.a` is
delivered, so this patch skips the test.
Tested on `x86_64-pc-solaris2.11`.
The `__cxa_atexit` interceptor is disabled for `SANITIZER_AIX` because
Clang on AIX neither uses `__cxa_atexit` nor links against a library
with such. This interceptor calls `StopInitOrderChecking()`, which is
needed to prevent false positives for the `initialization-order-fiasco`
error observed in the asan test `init-order-atexit.cpp` that uses the
`strict_init_order` flag. For now, we'll disable the `strict_init_order`
flag, but we'll look to support it in the future by implementing an
`exit` interceptor or some other alternative. With the flag disabled, we
won't update `init-order-atexit.cpp` to ensure it continues to pass and
the false positive doesn't show up.
Currently, the AIX linker and loader do not provide a mechanism to
implement ifuncs similar to GNU_ifunc on ELF Linux.
On AIX, we will lower `__attribute__((ifunc("resolver"))` to the llvm
`ifunc` as other platforms do. The llvm `ifunc` in turn will get lowered
at late stages of the optimization pipeline to an AIX-specific
implementation. No special linkage or relocations are needed when
generating assembly/object output.
On AIX, a function `foo` has two symbols associated with it: a function
descriptor (`foo`) residing in the `.data` section, and an entry point
(`.foo`) residing in the `.text` section. The first field of the
descriptor is the address of the entry point. Typically, the address
field in the descriptor is initialized once: statically, at load time
(?), or at runtime if runtime linking is enabled.
Here we would like to use the address field in the descriptor to
implement the `ifunc` semantics. Specifically, the ifunc function will
become a stub that jumps to the entry point in the address field. A
constructor function is linked into every linkage module. The
constructor walks an array of `{descriptor, resolver}` pairs, calling
the resolver and saving the result in the address field in the
descriptor (thus setting `foo`'s descriptor to point to the resolved
version early during program runtime).
Known limitations:
- Due to bug #161576, which affects object generation path, you will
need either `-ffunction-sections` or `-fno-integrated-as` to generate a
correct/linkable object file.
- aliases to ifuncs are not supported, a testcase has been added and
marked XFAIL. I'm planning to address in a follow-up PR because it's not
important enough, IMHO, for this PR
- dead ifuncs in a CU that contains at least one live ifunc, will result
in all ifuncs being kept by the linker. The fix for this is common with
a similar problem we have with PGO. PR #159435 is trying to provide a
mechanism that will allow the ifunc and PGO implementations to avoid the
dead code retention at the link step.
- the resolver must return a function that is in the same DSO as the
ifunc; the compiler will try to detect if this condition is violated and
report it, but it cannot detect it in general. To be safe, all candidate
functions (returned by a particular resolver) must either be static or
have hidden/protected visibility. This is so that the ifunc stub doesn't
have to save and restore the TOC register r2. In future work, this case
will be supported and the requirement will be lifted.
---------
Co-authored-by: Wael Yehia <wyehia@ca.ibm.com>
This patch adds implementations for the __aeabi_uread and __aeabi_uwrite
helper functions to compiler-rt.
Without these helpers, LLVM would need to inline byte wise sequences ,
which can increases code size, especially at -Os/-Oz. Using the helper
functions allows to retain correctness while avoiding the code-size
growth.
GCC-based toolchains already provide these AEABI helpers, so supporting
them in compiler-rt ensures parity and avoids accidental dependencies on
libgcc when LLVM begins emitting these calls.
This PR fixes
1. issue #175509 about missing support of deinitialize on ELF platform.
2. missing support of execution order by proirity at both initialize and
deinitialize stage.
cc: @tqchen @joker-eph
As `\+` is a GNU extension, it is not supported by the system grep on
AIX. This change replaces `%[0-9]\+` with `%[0-9][0-9]*`, which is
POSIX-compliant and therefore compatible with AIX.
There is an issue in certain versions of LD which causes the wrong
libLTO to be used if the DYLD_LIBRARY_PATH is not normalized.
Will fix these failures:
```
AddressSanitizer-x86_64-darwin.TestCases/Darwin.odr-lto.cpp
AddressSanitizer-x86_64h-darwin.TestCases/Darwin.odr-lto.cpp
```
https://green.lab.llvm.org/job/llvm.org/job/clang-stage1-cmake-RA-incremental/13428/
rdar://168024431
LSan, by design, can have false negatives, making it unreliable to check
that the leak was found in the stack-allocated case:
```
==123685==Scanning STACK range 0x7ffe6e554ca0-0x7ffe6e557000.
==123685==0x7ffe6e554de0: found 0x51e0000009f0 pointing into chunk 0x51e000000000-0x51e000000c00 of size 3072.
==123685==0x7ffe6e554e30: found 0x51e000000c00 pointing into chunk 0x51e000000c00-0x51e000001668 of size 2664. <- this prevented the leak from being found
```
This has led to flakiness on the buildbots e.g.,
https://lab.llvm.org/buildbot/#/builders/66/builds/24669
```
# | /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lsan/TestCases/swapcontext.cpp:44:11: error: CHECK: expected string not found in input
# | // CHECK: SUMMARY: {{.*}}Sanitizer: 2664 byte(s) leaked in 1 allocation(s)
...
Failed Tests (2):
LeakSanitizer-HWAddressSanitizer-x86_64 :: TestCases/swapcontext.cpp
LeakSanitizer-Standalone-x86_64 :: TestCases/swapcontext.cpp
```
This patch fixes the issue by clearing the buffer, as suggested by
Vitaly.
Some tests are already supported on "remote" devices and simulators.
However, there is currently no way to distinguish a remote macOS host
from a local one.
This adds the darwin-remote feature which is common to all test targets
which use a wrapper script (e.g. iossim_run.py).
rdar://167735355
---------
Co-authored-by: Dan Blackwell <danblackwell95@gmail.com>
The option added in #174522 breaks simulator tests, since `set_default`
overrides `False` values with the default.
Since these options are either string or boolean, this patches
set_default to override only un-set or empty string values (empty string
is not truth-y and therefore would be overwritten by defaults currently,
so this is NFCI)
Darwin supports running tests on targets other than the host machine
e.g. simulators. In such configurations, tests are run via a wrapper
script (e.g. iossim_run.py).
This refactors the lit test config to use a dedicated option to
distinguish test suites that run on the host from those that run in any
other configuration. This will allow the test suites to distinguish a
local osx configuration from a "remote" one.
rdar://167591463
After #171941, there are two issues:
First, some buildbots that use the old-style build are failing at:
```
Target ${BUILTIN_LIB_TARGET_NAME} does not exist"
```
Example failure:
https://lab.llvm.org/buildbot/#/builders/139/builds/25097
...during CMake configure. This appears to be caused by mismatch between
the builtin library's _target_ name and the output name from
set_output_name. This reverts the change to BUILTIN_LIB_TARGET_NAME made
by #171941, but still use the output name for naming the .sources.txt
file used for configuring builtins tests.
Second, this speculatively fixes an issue caused by two builtins
libraries that are produced with the same name in different directories
because of `LLVM_ENABLE_PER_TARGET_RUNTIME_DIR` (e.g.
`lib/clang/22/lib/i386-unknown-linux-gnu/libclang_rt.builtins.a` and
`lib/clang/22/lib/x86_64-unknown-linux-gnu/libclang_rt.builtins.a`), and
thus the `.sources.txt` paths alias. This causes us to run the wrong
tests against one of the builtins libraries. The chosen fix is to store
the .sources.txt files in `get_compiler_rt_output_dir` (which takes
`LLVM_ENABLE_PER_TARGET_RUNTIME_DIR` into account) rather than
`CMAKE_BINARY_DIR`.
As a side-effect, this allows for the replacement of
`COMPILER_RT_TEST_BUILTINS_DIR` with a simpler boolean option
`COMPILER_RT_TEST_EXTERNAL_BUILTINS`.
Example failure:
https://lab.llvm.org/buildbot/#/builders/66/builds/24433
This fixes cmake error from
https://github.com/llvm/llvm-project/pull/171941 in chrome's llvm build
where we have `COMPILER_RT_BUILD_BUILTINS=OFF` and have
`COMPILER_RT_TEST_BUILTINS_DIR` set. That change makes it to depend on
`crt` even if we don't have it in the prebuilt dir.
Log:
```
CMake Error at CMakeLists.txt:349 (add_dependencies):
The dependency target "crt" of target "runtimes-test-depends" does not
exist.
CMake Error at /b/s/w/ir/cache/builder/src/third_party/llvm/llvm/cmake/modules/AddLLVM.cmake:2104 (add_dependencies):
The dependency target "crt" of target "check-runtimes" does not exist.
Call Stack (most recent call first):
/b/s/w/ir/cache/builder/src/third_party/llvm/llvm/cmake/modules/AddLLVM.cmake:2145 (add_lit_target)
CMakeLists.txt:353 (umbrella_lit_testsuite_end)
CMake Error at /b/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/test/CMakeLists.txt:127 (add_dependencies):
The dependency target "crt" of target "compiler-rt-test-depends" does not
exist.
CMake Error at /b/s/w/ir/cache/builder/src/third_party/llvm/llvm/cmake/modules/AddLLVM.cmake:2104 (add_dependencies):
The dependency target "crt" of target "check-compiler-rt" does not exist.
Call Stack (most recent call first):
/b/s/w/ir/cache/builder/src/third_party/llvm/llvm/cmake/modules/AddLLVM.cmake:2145 (add_lit_target)
/b/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/test/CMakeLists.txt:129 (umbrella_lit_testsuite_end)
CMake Error at /b/s/w/ir/cache/builder/src/third_party/llvm/llvm/cmake/modules/AddLLVM.cmake:2104 (add_dependencies):
The dependency target "crt" of target "check-builtins" does not exist.
Call Stack (most recent call first):
/b/s/w/ir/cache/builder/src/third_party/llvm/llvm/cmake/modules/AddLLVM.cmake:2171 (add_lit_target)
/b/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/test/builtins/CMakeLists.txt:137 (add_lit_testsuite)
```