257 Commits

Author SHA1 Message Date
Charlie Barto
423832421b [asan][windows] Weak function interception support in instruction size decoder. (#86570)
This makes it so we'll be able to decode the instructions used in the
weak function stubs from
https://github.com/llvm/llvm-project/pull/81677. This code doesn't
technically require those changes.

Co-authored-by: Amy Wishnousky <amyw@microsoft.com>
2024-03-28 09:52:25 -07:00
Zack Johnson
4b10d1fdd3 [compiler-rt] Fixing UB on Windows for trampoline allocations (#85639)
Fixing the type of the constant to avoid undefined behavior with respect
to overflow.
2024-03-19 15:16:18 +02:00
Alexander Richardson
55b90b5140 [compiler-rt] Remove llvm_gtest dependency from unit tests
All these unit tests already include ${COMPILER_RT_GTEST_SOURCE} as an
input source file and the target llvm_gtest does not exist for
standalone builds. Currently the DEPS argument is ignored for standalone
builds so the missing target is not a problem, but as part of fixing a
build race for standalone builds I am planning to include those
dependencies in COMPILER_RT_TEST_STANDALONE_BUILD_LIBS configurations.

Reviewed By: vitalybuka

Pull Request: https://github.com/llvm/llvm-project/pull/83649
2024-03-13 11:28:44 -07:00
Marco Elver
1c792d24e0 [compiler-rt] Fix interceptors with AArch64 BTI (#84061)
On AArch64 with BTI, we have to start functions with the appropriate
BTI hint to indicate that the function is a valid call target.

To support interceptors with AArch64 BTI, add "BTI c".
2024-03-13 09:01:00 +01:00
Fangrui Song
8443ce563b [sanitizer] Lift AsanDoesNotSupportStaticLinkage to sanitizer_common.h. NFC (#80948)
The `_DYNAMIC` reference from `AsanDoesNotSupportStaticLinkage` ensures
that `clang++ -fsanitize=address -static` gets a linker error.
`MemprofDoesNotSupportStaticLinkage` is similar for `-fmemory-profile`.
Move the functions to sanitizer_common.h to be used by more sanitizers
on ELF platforms.

Fuchsia does not use interposition and opts out the check (its
`AsanDoesNotSupportStaticLinkage` is a no-op).
2024-02-16 19:36:39 -08:00
YunQiang Su
0a64367a72 Sanitizer/MIPS: Use $t9 for preemptible function call (#76894)
Currently, almost all of the shared libraries of MIPS, rely on $t9
to get the address of current function, instead of PCREL instructions,
even on MIPSr6. So we have to set $t9 properly.

To get the address of preemptible function, we need the help of GOT.
MIPS/O32 has .cpload, which can help to generate 3 instructions to get GOT.
For __mips64, we can get GOT by:

lui $t8, %hi(%neg(%gp_rel(SANITIZER_STRINGIFY(TRAMPOLINE(func)))))
daddu $t8, $t8, $t9
daddiu $t8, $t8, %hi(%neg(%gp_rel(SANITIZER_STRINGIFY(TRAMPOLINE(func)))))

And then get the address of __interceptor_func, and jump to it

ld $t9, %got_disp(_interceptor" SANITIZER_STRINGIFY(func) ")($t8)
jr $t9

Fixes #74047

Co-authored-by: YunQiang Su <yunqiang.su@cipunited.com>
2024-01-16 23:11:50 -05:00
Charlie Barto
41b09bbe98 [ASAN][sanitizers][win] Allow windows-asan to be built with /MDd and intercept functions from the debug runtimes. (#77840)
It turns out this works _mostly_ fine, even when mixing debug versions
of asan with programs built with the release runtime. Using /MT (or
/MTd) with a dynamically linked asan has never really worked that well,
and I am planning on opening a PR that will completely remove the
static-asan configuration for windows and make programs linked with the
static CRT/runtime work with the DLL version of asan. This is better
than the current situation because the static linked version of asan
doesn't work well on windows if there are multiple DLLs in the process
using it.

The check for building asan with only /MD or /MT has been removed. It
was in AsanDoesNotSupportStaticLinkage, but was checking for debug CRTs,
not static linkage. The kind of static linkage this function is supposed
to check for (on linux for example) doesn't really exist on windows.

Note: There is one outstanding issue with this approach, if you mix a
/MDd DLLs and /MD dlls in the same process then the "real" function
called by asan interceptors will be the same for calls from both
contexts, potentially screwing up things like errno. This only happens
if you mix /MD and /MDd in the same process, because otherwise asan
won't find functions from both runtimes to intercept. We are working on
a fix for this, and it mainly hits with the CRT functions exported from
both ucrtbase and ntdll.


This change is being upstreamed from Microsoft's fork.
2024-01-16 13:19:03 -08:00
Zack Johnson
cbe27c45cd [ASan][Windows] Interception fix for 'mov al, byte ptr []' sequences (#72531) 2023-12-07 10:17:58 -05:00
Farzon Lotfi
d79aee9f73 Changes to support running tests for Windows arm64 asan (#66973)
1. Differentiate SANITIZER_WINDOWS64 for x64 and arm64
2. turn off interception tests that expect x86 assembly

---------

Co-authored-by: Farzon Lotfi <farzon@farzon.com>
2023-11-27 12:28:44 -05:00
Marco Elver
a855a16a02 [compiler-rt] Fix interceptors with Solaris as (#72973)
Jakub Jelínek reports:

As mentioned in https://gcc.gnu.org/PR112563, the new DECLARE_WRAPPER
macro
added in 37445e9 and ammended in 85d3873 doesn't work on SPARC/Solaris
with
  Solaris as.

While clang and GNU as when used from GCC seems to be forgiving on most
architectures and allow both %function and @function (with the latter
not being
allowed on ARM/AArch64 I believe because @ is assembler comment start
there),
  Solaris as doesn't allow the %function form.

Fix it by using %function only for ARM.

Co-developed-by: Jakub Jelínek <jakub@redhat.com>
Reported-by: Jakub Jelínek <jakub@redhat.com>
Closes: https://github.com/llvm/llvm-project/issues/72970
2023-11-21 20:48:01 +01:00
nicole mazzuca
160e8eb449 [ASan] Recognize lea r10, [rip + XX] (#68910)
This instruction is present in memcpy in the latest vcruntime

This PR has been opened for @AndrewDeanMS (a teammate inside Microsoft)
who made the PR to our internal branch.

Co-authored-by: Andrew Dean <Andrew.Dean@microsoft.com>
2023-10-13 08:47:23 -07:00
nicole mazzuca
bc34a83380 [ASan][Windows] Fix rip-relative instruction replacement (#68432)
The old code incorrectly checked what relative offsets were allowed.

The correct check is that the offset from the target to the instruction
pointer should be within $[-2^{31}, 2^{31})$; however, the check that
was originally written was that the offset was within $[0, 2^{31})$.
Negative offsets are certainly allowable (as long as they fit in 32
bits), and this change fixes that.
2023-10-09 14:53:07 -07:00
Alexandre Ganea
2385cf66e2 [compiler-rt] Fix "interception" file name 2023-10-02 12:29:29 -04:00
Alexandre Ganea
262e2886b8 [compiler-rt] Fix MSVC /external detection in cmake scripts
As suggested by https://reviews.llvm.org/D116872#4650507

Differential Revision: https://reviews.llvm.org/D116872
2023-10-02 12:29:28 -04:00
Farzon Lotfi
5a48a824aa [compiler-rt] Fix interception_win.cpp arm64 instruction lengths
Updates GetInstructionSize to account for arm64 instruction sizes.

ARM64 instruction are always 4 bytes long but GetInstructionSize in
interception_win.cpp assumes x86_64 which has mixed sizes.

Fix is for: https://github.com/llvm/llvm-project/issues/64319

Before the changeclang_rt.asan_dynamic-aarch64.dll would crash at:
OverrideFunction -> OverrideFunctionWithHotPatch -> GetInstructionSize:825

After the change:
dllthunkintercept -> dllthunkgetrealaddressordie -> InternalGetProcAddress
2023-09-12 22:43:51 -04:00
Shoaib Meenai
dcafbd0c67 [compiler-rt] Remove explicit Android libatomic linking
The comments date back to NDK r10, which is ancient. libatomic isn't
always needed anymore, and even when it is, it's bundled into
compiler-rt in the NDK so we'll get it automatically. Remove the
unnecessary explicit links.

Reviewed By: srhines

Differential Revision: https://reviews.llvm.org/D158793
2023-08-28 17:34:48 -07:00
Jessica Clarke
7e1afab1b1 [compiler-rt] Use .globl for FreeBSD/NetBSD interceptor wrappers
On FreeBSD and NetBSD we don't use .weak due to differing semantics.
Currently we end up using no directive, which gives a local symbol,
whereas the closer thing to a weak symbol would be a global one. In
particular, both GNU and LLVM toolchains cannot handle a GOT-indirect
reference to a local symbol at a non-zero offset within a section on
AArch64 (see https://github.com/ARM-software/abi-aa/issues/217), and so
interceptors do not work on FreeBSD/arm64, failing to link with LLD.
Switching to .globl both works around this bug and more closely aligns
such non-weak platforms with weak ones.

Fixes https://github.com/llvm/llvm-project/issues/63418

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D158552
2023-08-22 23:38:24 +01:00
Gabor Horvath
8330116ebd Revert "ASan: Add additional wcs* interceptors on Windows" to unbreak build bot
This reverts commit c0c83668f8.
2023-08-21 15:45:51 -07:00
Nicole Mazzuca
c0c83668f8 ASan: Add additional wcs* interceptors on Windows
This adds wcs[n]cat, wcs[n]cmp, wcs[n]cpy, and wcschr functions to the
interception code on Windows; wcs[n]cat was already intercepted, but only on
POSIX.

Differential Revision: https://reviews.llvm.org/D157038
2023-08-21 14:17:42 -07:00
Marco Elver
85d3873a45 Fix "[compiler-rt] Allow 3 simultaneous interceptors on Linux"
Fix inline asm trampoline type. Some architectures will complain:

<inline asm>:8:41: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '%<type>' or "<type>"
    8 | .type  __interceptor_trampoline_malloc, @function

Just use %function instead, which is what is also used in
sanitizer_asm.h
2023-06-09 12:14:45 +02:00
Marco Elver
37445e96d8 [compiler-rt] Allow 3 simultaneous interceptors on Linux
Rework Linux (and *BSD) interceptors to allow for up to 3 (2 for *BSD)
simultaneous interceptors. See code comments for details.

The main motivation is to support new sampling sanitizers (in the spirit
of GWP-ASan), that have to intercept few functions. Unfortunately, the
reality is that there are user interceptors that exist in the wild.

To support foreign user interceptors, foreign dynamic analysis
interceptors, and compiler-rt interceptors all at the same time,
including any combination of them, this change enables up to 3
interceptors on Linux (2 on *BSD).

v2:
* Revert to to the simpler "weak wrapper -(alias)-> __interceptor"
  scheme on architectures that cannot implement a trampoline efficiently
  due to complexities of resolving a preemptible symbol (PowerPC64
  ELFv2 global entry, and i386 PIC).
* Avoid duplicate intercepted functions in gen_dynamic_list.py, due to
  matching __interceptor_X and ___interceptor_X.
* Fix s390 __tls_get_offset.

Reviewed By: dvyukov, MaskRay, vitalybuka

Differential Revision: https://reviews.llvm.org/D151085
2023-06-09 11:30:41 +02:00
Marco Elver
4d927fc035 [compiler-rt] Reformat interception macros
Reformat interception macros to be more readable.

NFC.
2023-06-09 10:43:37 +02:00
Marco Elver
33388d8c0b Revert "[compiler-rt] Allow 3 simultaneous interceptors on Linux"
This reverts commit 57882fe76e.
This reverts commit 74b0ac571b.

Breaks various build bots.
2023-06-07 10:16:24 +02:00
Marco Elver
74b0ac571b [compiler-rt] Allow 3 simultaneous interceptors on Linux
Rework Linux (and *BSD) interceptors to allow for up to 3 (2 for *BSD)
simultaneous interceptors. See code comments for details.

The main motivation is to support new sampling sanitizers (in the spirit
of GWP-ASan), that have to intercept few functions. Unfortunately, the
reality is that there are user interceptors that exist in the wild.

To support foreign user interceptors, foreign dynamic analysis
interceptors, and compiler-rt interceptors all at the same time,
including any combination of them, this change enables up to 3
interceptors on Linux (2 on *BSD).

Reviewed By: dvyukov, MaskRay, vitalybuka

Differential Revision: https://reviews.llvm.org/D151085
2023-06-07 09:06:31 +02:00
Marco Elver
0a71e25e24 [compiler-rt] Avoid memintrinsic calls inserted by the compiler
D135716 introduced -ftrivial-auto-var-init=pattern where supported.
Unfortunately this introduces unwanted memset() for large stack arrays,
as shown by the new tests added for asan and msan (tsan already had this
test).

In general, the problem of compiler-inserted memintrinsic calls
(memset/memcpy/memmove) is not new to compiler-rt, and has been a
problem before.

To avoid introducing unwanted memintrinsic calls, we redefine
memintrinsics as __sanitizer_internal_mem* at the assembly level for
most source files automatically (where sanitizer_common_internal_defs.h
is included).

In few cases, redefining a symbol in this way causes issues for
interceptors, namely the memintrinsic interceptor themselves. For such
source files we have to selectively disable the redefinition.

Other alternatives have been considered, but simply do not work well in
the context of compiler-rt:

	1. Linker --wrap:  this does not work because --wrap only
	   applies to the final link, and would not apply when building
	   sanitizer static libraries.

	2. Changing references to memset() via objcopy:  this may work,
	   but due to the complexities of the build system, introducing
	   such a post-processing step for the right object files (in
	   particular object files defining memset cannot be touched)
	   seems infeasible.

The chosen solution works well (as shown by the tests). Other libraries
have chosen the same solution where nothing else works (see e.g. glibc's
"symbol-hacks.h").

v4:
- Add interface attribute to __sanitizer_internal_mem* declarations as
  well, as otherwise some compilers (MSVC) will complain.
- Add SANITIZER_COMMON_NO_REDEFINE_BUILTINS to source files using
  C++STL, since this could lead to ODR violations (see added comment).

v3:
- Don't use ALIAS() to alias internal_mem*() functions to
  __sanitizer_internal_mem*() functions, but just define them as
  ALWAYS_INLINE functions instead. This will work on darwin and windows.

v2:
- Fix ubsan_minimal build where compiler decides to insert
  memset/memcpy: ubsan_minimal has work without RTSanitizerCommonLibc,
  therefore do not redefine the builtins.
- Fix definition of internal_mem* functions with compilers that want the
  aliased function to already be defined before.
- Fix definition of __sanitizer_internal_mem* functions with compilers
  more pedantic about attribute placement around extern "C".

Reviewed By: vitalybuka, dvyukov

Differential Revision: https://reviews.llvm.org/D151152
2023-06-06 16:10:45 +02:00
Marco Elver
8e54794867 Revert "[compiler-rt] Avoid memintrinsic calls inserted by the compiler"
This reverts commit fc011a7288.
This reverts commit 4ad6a0c9a4.
This reverts commit 4b1eb4cf0e.

Still causes Windows build bots to fail.
2023-06-02 16:37:38 +02:00
Marco Elver
4b1eb4cf0e [compiler-rt] Avoid memintrinsic calls inserted by the compiler
D135716 introduced -ftrivial-auto-var-init=pattern where supported.
Unfortunately this introduces unwanted memset() for large stack arrays,
as shown by the new tests added for asan and msan (tsan already had this
test).

In general, the problem of compiler-inserted memintrinsic calls
(memset/memcpy/memmove) is not new to compiler-rt, and has been a
problem before.

To avoid introducing unwanted memintrinsic calls, we redefine
memintrinsics as __sanitizer_internal_mem* at the assembly level for
most source files automatically (where sanitizer_common_internal_defs.h
is included).

In few cases, redefining a symbol in this way causes issues for
interceptors, namely the memintrinsic interceptor themselves. For such
source files we have to selectively disable the redefinition.

Other alternatives have been considered, but simply do not work well in
the context of compiler-rt:

	1. Linker --wrap:  this does not work because --wrap only
	   applies to the final link, and would not apply when building
	   sanitizer static libraries.

	2. Changing references to memset() via objcopy:  this may work,
	   but due to the complexities of the build system, introducing
	   such a post-processing step for the right object files (in
	   particular object files defining memset cannot be touched)
	   seems infeasible.

The chosen solution works well (as shown by the tests). Other libraries
have chosen the same solution where nothing else works (see e.g. glibc's
"symbol-hacks.h").

v3:
- Don't use ALIAS() to alias internal_mem*() functions to
  __sanitizer_internal_mem*() functions, but just define them as
  ALWAYS_INLINE functions instead. This will work on darwin and windows.

v2:
- Fix ubsan_minimal build where compiler decides to insert
  memset/memcpy: ubsan_minimal has work without RTSanitizerCommonLibc,
  therefore do not redefine the builtins.
- Fix definition of internal_mem* functions with compilers that want the
  aliased function to already be defined before.
- Fix definition of __sanitizer_internal_mem* functions with compilers
  more pedantic about attribute placement around extern "C".

Reviewed By: vitalybuka, dvyukov

Differential Revision: https://reviews.llvm.org/D151152
2023-06-02 15:39:00 +02:00
Marco Elver
8e728adcfe Revert "[compiler-rt] Avoid memintrinsic calls inserted by the compiler"
This reverts commit 4369de7af4.

Fails on Mac OS with "sanitizer_libc.cpp:109:5: error: aliases are not
supported on darwin".
2023-05-31 17:59:11 +02:00
Marco Elver
4369de7af4 [compiler-rt] Avoid memintrinsic calls inserted by the compiler
D135716 introduced -ftrivial-auto-var-init=pattern where supported.
Unfortunately this introduces unwanted memset() for large stack arrays,
as shown by the new tests added for asan and msan (tsan already had this
test).

In general, the problem of compiler-inserted memintrinsic calls
(memset/memcpy/memmove) is not new to compiler-rt, and has been a
problem before.

To avoid introducing unwanted memintrinsic calls, we redefine
memintrinsics as __sanitizer_internal_mem* at the assembly level for
most source files automatically (where sanitizer_common_internal_defs.h
is included).

In few cases, redefining a symbol in this way causes issues for
interceptors, namely the memintrinsic interceptor themselves. For such
source files we have to selectively disable the redefinition.

Other alternatives have been considered, but simply do not work well in
the context of compiler-rt:

	1. Linker --wrap:  this does not work because --wrap only
	   applies to the final link, and would not apply when building
	   sanitizer static libraries.

	2. Changing references to memset() via objcopy:  this may work,
	   but due to the complexities of the build system, introducing
	   such a post-processing step for the right object files (in
	   particular object files defining memset cannot be touched)
	   seems infeasible.

The chosen solution works well (as shown by the tests). Other libraries
have chosen the same solution where nothing else works (see e.g. glibc's
"symbol-hacks.h").

v2:
- Fix ubsan_minimal build where compiler decides to insert
  memset/memcpy: ubsan_minimal has work without RTSanitizerCommonLibc,
  therefore do not redefine the builtins.
- Fix definition of internal_mem* functions with compilers that want the
  aliased function to already be defined before.
- Fix definition of __sanitizer_internal_mem* functions with compilers
  more pedantic about attribute placement around extern "C".

Reviewed By: vitalybuka, dvyukov

Differential Revision: https://reviews.llvm.org/D151152
2023-05-31 16:58:53 +02:00
Marco Elver
26bda9e95a Revert "[compiler-rt] Avoid memintrinsic calls inserted by the compiler"
This reverts commit e614d5667f.

Build bot failures:

| FAILED: lib/clang/17/lib/linux/libclang_rt.ubsan_minimal-i386.so
| : && /usr/bin/clang++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete   -m32 -nodefaultlibs -Wl,-z,text -nostdlib++ -shared -Wl,-soname,libclang_rt.ubsan_minimal-i386.so -o lib/clang/17/lib/linux/libclang_rt.ubsan_minimal-i386.so projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.i386.dir/ubsan_minimal_handlers.cpp.o  -lgcc_s  -lc && :
| /usr/bin/ld: projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.i386.dir/ubsan_minimal_handlers.cpp.o: in function `__ubsan_handle_type_mismatch_minimal':
| /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp:120: undefined reference to `__sanitizer_internal_memcpy'
| /usr/bin/ld: projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.i386.dir/ubsan_minimal_handlers.cpp.o: in function `__ubsan_handle_type_mismatch_minimal_abort':
| /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp:120: undefined reference to `__sanitizer_internal_memcpy'
| /usr/bin/ld: projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.i386.dir/ubsan_minimal_handlers.cpp.o: in function `__ubsan_handle_alignment_assumption_minimal':
| /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp:121: undefined reference to `__sanitizer_internal_memcpy'
| /usr/bin/ld: projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.i386.dir/ubsan_minimal_handlers.cpp.o: in function `__ubsan_handle_alignment_assumption_minimal_abort':
| /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp:121: undefined reference to `__sanitizer_internal_memcpy'
| /usr/bin/ld: projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.i386.dir/ubsan_minimal_handlers.cpp.o: in function `__ubsan_handle_add_overflow_minimal':
| /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp:122: undefined reference to `__sanitizer_internal_memcpy'
| /usr/bin/ld: projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.i386.dir/ubsan_minimal_handlers.cpp.o:/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp:122: more undefined references to `__sanitizer_internal_memcpy' follow

Link: https://lab.llvm.org/buildbot#builders/74/builds/19569
2023-05-31 12:20:19 +02:00
Marco Elver
e614d5667f [compiler-rt] Avoid memintrinsic calls inserted by the compiler
D135716 introduced -ftrivial-auto-var-init=pattern where supported.
Unfortunately this introduces unwanted memset() for large stack arrays,
as shown by the new tests added for asan and msan (tsan already had this
test).

In general, the problem of compiler-inserted memintrinsic calls
(memset/memcpy/memmove) is not new to compiler-rt, and has been a
problem before.

To avoid introducing unwanted memintrinsic calls, we redefine
memintrinsics as __sanitizer_internal_mem* at the assembly level for
most source files automatically (where sanitizer_common_internal_defs.h
is included).

In few cases, redefining a symbol in this way causes issues for
interceptors, namely the memintrinsic interceptor themselves. For such
source files we have to selectively disable the redefinition.

Other alternatives have been considered, but simply do not work well in
the context of compiler-rt:

	1. Linker --wrap:  this does not work because --wrap only
	   applies to the final link, and would not apply when building
	   sanitizer static libraries.

	2. Changing references to memset() via objcopy:  this may work,
	   but due to the complexities of the build system, introducing
	   such a post-processing step for the right object files (in
	   particular object files defining memset cannot be touched)
	   seems infeasible.

The chosen solution works well (as shown by the tests). Other libraries
have chosen the same solution where nothing else works (see e.g. glibc's
"symbol-hacks.h").

Reviewed By: vitalybuka, dvyukov

Differential Revision: https://reviews.llvm.org/D151152
2023-05-31 11:50:13 +02:00
Marco Elver
19b137f0c2 [compiler-rt] Unify Linux and *BSD interceptors more
The Linux and *BSD interceptors are almost identical, except for *BSD,
where the overridden intercepted function is not defined weak due to
some incompliant linker behaviour.

Since most of the interception machinery is shared between Linux and
*BSD (see INTERCEPT_FUNCTION macro), it makes sense to unify interceptor
definition and declarations as much as possible to ease future changes.

NFC.

Reviewed By: dvyukov, vitalybuka

Differential Revision: https://reviews.llvm.org/D151318
2023-05-25 12:01:10 +02:00
Marco Elver
d2ac277602 [compiler-rt] Introduce the notion of an interceptor trampoline
To make the interceptor implementation more flexible, allowing for 2
levels of indirection instead of just 1 in the current scheme (where the
intercepted function aliases the interceptor implementation), introduce
the notion of an interceptor "trampoline".

A trampoline may be a real function (and not just an alias, where
aliases of aliases do not work), which will simply forward to the
interceptor implementation; the intercepted function will then alias the
trampoline:

	func -[alias]-> trampoline -[call]-> interceptor

Make the necessary changes to prepare for introducing real trampolines.

This change does not yet introduce any real trampolines, and so
trampoline == interceptor, and we currently still just have:

	func -[alias]-> interceptor

NFC.

Reviewed By: dvyukov, vitalybuka, MaskRay

Differential Revision: https://reviews.llvm.org/D151316
2023-05-25 12:01:09 +02:00
Marco Elver
175fcd6fd2 [compiler-rt] Simplify ALIAS() attribute macro
Most uses of ALIAS() are in conjunction with WRAPPER_NAME().

Simplify the code and just make ALIAS() turn its argument into a string
(similar to Linux kernel's __alias macro). This in turn allows removing
WRAPPER_NAME().

NFC.

Reviewed By: dvyukov

Differential Revision: https://reviews.llvm.org/D151216
2023-05-24 11:57:17 +02:00
Alvin Wong
1a7a00bdc9 [compiler-rt][interception][win] Add error messages for some errors
Depends on D149002

Differential Revision: https://reviews.llvm.org/D149346
2023-05-04 22:41:27 +08:00
Alvin Wong
0716888d82 [compiler-rt][interception][asan][win] Improve error reporting
Add a callback from interception to allow asan on Windows to produce
better error messages. If an unrecoverable error occured when
intercepting functions, print a message before terminating.

Additionally, when encountering unknown instructions, a more helpful
message containing the address and the bytes of the unknown instruction
is now printed to help identify the issue and make it easier to propose
a fix.

Depends on D149549

Differential Revision: https://reviews.llvm.org/D149002
2023-05-04 22:41:26 +08:00
Alvin Wong
7b5571f3fc [compiler-rt][interception][win] Don't crash on unknown instructions
Do not treat unknown instructions as a fatal error. In most cases,
failure to intercept a function is reported by the caller, though
requires setting verbosity to 1 or higher to be visible.

Better error message reporting for asan will be added in a separate
patch.

Differential Revision: https://reviews.llvm.org/D149549
2023-05-04 22:41:26 +08:00
Alvin Wong
814a75dca7 [compiler-rt][asan][win] Intercept exceptions for i686 MinGW
The i686-w64-windows-gnu target does not use SEH (which MSVC uses),
but DWARF-2 exception handling or possibly sjlj depending on the
toolchain build options. On this target we have to actually intercept
functions in libc++ and libunwind which handles throwing exceptions.
This fixes the `TestCases/intercept-rethrow-exception.cpp` test.

The x86_64-w64-windows-gnu target already works because it uses SEH
which is handled by intercepting RaiseException, so this change does not
affect x86_64.

Depends on https://reviews.llvm.org/D148990

Differential Revision: https://reviews.llvm.org/D148991
2023-05-04 22:41:26 +08:00
Alvin Wong
ca40985ee9 [compiler-rt][interception][win] Add more assembly patterns
These assembly patterns are needed to intercept some libc++ and
libunwind functions built by Clang for i686-w64-windows-gnu target.

Differential Revision: https://reviews.llvm.org/D148990
2023-05-04 22:41:26 +08:00
Alvin Wong
1194e6f3fa [compiler-rt][test] Add --large-address-aware link flag for MinGW
The interception tests rely on the test binary being large address
aware. This has already been set for MSVC builds. Now we do the same for
MinGW.

This fixes the interception unit tests for i686-w64-windows-gnu target.

Differential Revision: https://reviews.llvm.org/D148996
2023-04-25 19:21:49 +08:00
Fangrui Song
a5519b99bc [sanitizer] Don't intercept LFS64 symbols on musl
LFS64 symbols in musl are for glibc-ABI-compat and not intended for linking
(correct usage will not create LFS64 references). The next release 1.2.4 will
disallow linking against LFS64 symbols[1].

For sanitizers, let's just remove LFS64 interceptors. In case of erroneous LFS64
references, asan/tsan will detect fewer problems and msan may have false
positives.

[1]: https://git.musl-libc.org/cgit/musl/commit/?id=246f1c811448f37a44b41cd8df8d0ef9736d95f4

Reviewed By: thesamesam

Differential Revision: https://reviews.llvm.org/D141186
2023-01-09 12:43:23 -08:00
Haowei Wu
beb3fa2d2e Revert "Reland "[compiler-rt][test] Heed COMPILER_RT_DEBUG when compiling unittests""
This reverts commit 255c3e3dcb, which
breaks Msan-x86_64-Test.
2022-12-13 16:38:12 -08:00
Rainer Orth
255c3e3dcb Reland "[compiler-rt][test] Heed COMPILER_RT_DEBUG when compiling unittests"
When trying to debug some `compiler-rt` unittests, I initially had a hard
time because

- even in a `Debug` build one needs to set `COMPILER_RT_DEBUG` to get
  debugging info for some of the code and
- even so the unittests used a hardcoded `-O2` which often makes debugging
  impossible.

This patch addresses this by instead using `-O0` if `COMPILER_RT_DEBUG`.

Changes relative to the previous commit:

- Use `string(APPEND)` for `COMPILER_RT_TEST_COMPILER_CFLAGS`.
- Omit `-O3` from `COMPILER_RT_TEST_COMPILER_CFLAGS` in non-debug builds for now.
- Provide `__sanitizer::integral_constant<bool, true>::value` instantiation
  for `sanitizer_type_traits_test.cpp` in debug builds.
- Disable subtests of `tsan/tests/unit/tsan_trace_test.cpp` that deadlock
  in debug builds.
- `XFAIL` `tsan/Linux/check_memcpy.c` in debug builds.

Tested on `sparcv9-sun-solaris2.11`, `amd64-pc-solaris2.11`, and
`x86_64-pc-linux-gnu`.

Differential Revision: https://reviews.llvm.org/D91620
2022-12-13 10:58:58 +01:00
Markus Böck
78c033b541 [sanitizers][windows] Correctly override functions with backward jmps
To reproduce: Download and run the latest Firefox ASAN build (https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/gecko.v2.mozilla-central.latest.firefox.win64-asan-opt/artifacts/public/build/target.zip) on Windows 11 (version 10.0.22621 Build 22621); it will crash on launch. Note that this doesn't seem to crash on another Windows 11 VM I've tried, so I'm not sure how reproducible it is across machines, but it reproduces on my machine every time.

The problem seems to be that when overriding the memset function in OverrideFunctionWithRedirectJump(), the relative_offset is stored as a uptr. Per the Intel x64 instruction set reference (https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf - warning: large PDF), on page 646 the jmp instruction (specifically the near jump flavors that start with E9, which are the ones the OverrideFunctionWithRedirectJump() considers) treats the offset as a signed displacement. This causes an incorrect value to be stored for REAL(memset) which points to uninitialized memory, and a crash the next time that gets called.

The fix is to simply treat that offset as signed. I have also added a test case.

Fixes https://github.com/llvm/llvm-project/issues/58846

Differential Revision: https://reviews.llvm.org/D137788
2022-12-12 11:45:43 +01:00
Vitaly Buka
68f4ceaf9b Revert "[compiler-rt][test] Heed COMPILER_RT_DEBUG when compiling unittests"
Breaks some bots, details in https://reviews.llvm.org/D91620

This reverts commit 93b1256e38.
2022-10-05 09:59:25 -07:00
Rainer Orth
93b1256e38 [compiler-rt][test] Heed COMPILER_RT_DEBUG when compiling unittests
When trying to debug some `compiler-rt` unittests, I initially had a hard
time because

- even in a `Debug` build one needs to set `COMPILER_RT_DEBUG` to get
  debugging info for some of the code and
- even so the unittests used a hardcoded `-O2` which often makes debugging
  impossible.

This patch addresses this by instead using `-O0` if `COMPILER_RT_DEBUG`.
Two tests in `sanitizer_type_traits_test.cpp` need to be disabled since
they have undefined references to `__sanitizer::integral_constant<bool,
true>::value`.

Tested on `sparcv9-sun-solaris2.11`, `amd64-pc-solaris2.11`, and
`x86_64-pc-linux-gnu`.

Differential Revision: https://reviews.llvm.org/D91620
2022-10-05 09:53:26 +02:00
Petr Hosek
6699f55488 [compiler-rt][CMake] Set --unwindlib=none when using LLVM libunwind
We already link libunwind explicitly so avoid trying to link toolchain's
default libunwind which may be missing. This matches what we already do
for libcxx and libcxxabi.

Differential Revision: https://reviews.llvm.org/D129472
2022-07-15 07:25:38 +00:00
Petr Hosek
ba007f20bb [CMake] Use explicit header path when using in-tree libc++ for tests
This is a follow up to D118200 which applies a similar cleanup to
headers when using in-tree libc++ to avoid accidentally picking up
the system headers.

Differential Revision: https://reviews.llvm.org/D128035
2022-07-09 06:14:29 +00:00
Mariusz Borsa
8246b2e156 [Sanitizers][Darwin] Replace SANITIZER_MAC with SANITIZER_APPLE in source files
This is a follow up to [Sanitizers][Darwin] Rename Apple macro SANITIZER_MAC -> SANITIZER_APPLE (D125816)

Performed a global search/replace as in title against LLVM sources

Differential Revision: https://reviews.llvm.org/D126263
2022-05-24 12:59:27 -07:00
Stella Laurenzo
38151a08c2 Reapply "[cmake] Prefix gtest and gtest_main with "llvm_"."
This reverts commit 7cdda6b8ce.

Differential Revision: https://reviews.llvm.org/D121020
2022-03-04 13:45:43 -08:00