All platforms return the main executable as the first dl_phdr_info.
FreeBSD, NetBSD, Solaris, and Linux-musl place the executable name
in the dlpi_name field of this entry. It appears that only Linux-glibc
uses the empty string.
To make this work generically on all platforms, unconditionally skip the first
object (like is currently done for FreeBSD and NetBSD). This fixes first DSO
detection on Linux-musl with clang -shared-libsan/-shared-libasan and GCC's
default. It also would likely fix detection on Solaris/Illumos if it were to
gain PIE support (since dlpi_addr would not be NULL).
Additionally, only skip the Linux VDSO on linux.
Finally, use the empty string as the "seen first dl_phdr_info"
marker rather than (char *)-1. If there was no other object, we
would try to dereference it for a string comparison.
Reviewed By: MaskRay, vitalybuka
Differential Revision: https://reviews.llvm.org/D119515
An infinite loop without any effects is illegal C++ and can be optimized
away by the compiler.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D119575
This is a follow up to 4f3f4d6722
("sanitizer_common: fix __sanitizer_get_module_and_offset_for_pc signature mismatch")
which fixes a similar problem for msan build.
I am getting the following error compiling a unit test for code that
uses sanitizer_common headers and googletest transitively includes
sanitizer interface headers:
In file included from third_party/gwp_sanitizers/singlestep_test.cpp:3:
In file included from sanitizer_common/sanitizer_common.h:19:
sanitizer_interface_internal.h:41:5: error: typedef redefinition with different types
('struct __sanitizer_sandbox_arguments' vs 'struct __sanitizer_sandbox_arguments')
} __sanitizer_sandbox_arguments;
common_interface_defs.h:39:3: note: previous definition is here
} __sanitizer_sandbox_arguments;
Reviewed By: melver
Differential Revision: https://reviews.llvm.org/D119546
Summary:
This is neccessary to support solaris/sparc9 where some userspace
addresses have all top bits set, as well as, potentially, kernel memory
on aarch64.
This change does not update the compiler side (HWASan IR pass) which
needs to be done separately for the affected targets.
Reviewers: ro, vitalybuka
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D91827
D116208 may cause a macro clash on older versions of linux, where
fs.h defines a READ macro. This is resolved by switching to a more
typical casing style for non-macro symbols.
Reapplying with changes to the symbol names in various platform
specific code, which I missed previously.
Differential Revision: https://reviews.llvm.org/D118783
D116208 may cause a macro clash on older versions of linux, where
fs.h defines a READ macro. This is resolved by switching to a more
typical casing style for non-macro symbols.
Differential Revision: https://reviews.llvm.org/D118783
Enabling `sanitizer_common` tests on Solaris (D91606
<https://reviews.llvm.org/D91606>) and SPARC (D91608
<https://reviews.llvm.org/D91608>) uncovered a sparcv9 failure
SanitizerCommon-Unit :: ./Sanitizer-sparcv9-Test/CompactRingBuffer.int64
like this:
[ RUN ] CompactRingBuffer.int64
==24576==ERROR: SanitizerTool failed to deallocate 0x2000 (8192) bytes at address 0xffffffff7f59b000
==24576==Sanitizer CHECK failed: /vol/llvm/src/llvm-project/local/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp:61 (("unable to unmap" && 0)) != (0) (0, 0)
The problem is that the original allocation via
`MmapAlignedOrDieOnFatalError` is for 4 kB, but the Solaris/sparcv9
pagesize is 8 kB. So the initial allocation is for 12 kB, rounded to a
multiple of the pagesize. Afterwards, the unneeded rest is unmapped again,
but this fails since the address is not pagesize-aligned.
This patch avoids this by aligning the end of the mapping to the pagesize.
With D91827 <https://reviews.llvm.org/D91827> added, the test `PASS`es on
`sparcv9-sun-solaris2.11`.
Differential Revision: https://reviews.llvm.org/D91615
As described in Issue #53523, the
`DenseMapCustomTest.DefaultMinReservedSizeTest` test FAILs on Solaris/SPARC
(both 32 and 64-bit):
/vol/llvm/src/llvm-project/local/compiler-rt/lib/sanitizer_common/tests/sanitizer_dense_map_test.cpp:399:
Failure
Expected: (MemorySize) != (Map.getMemorySize()), actual: 8192 vs 8192
This happens because SPARC, unlike many other CPUs, uses an 8 kB pagesize.
Fixed by incorporating the pagesize into the calculations of
`ExpectedInitialBucketCount` and derived values.
Tested on `sparcv9-sun-solaris2.11`, `amd64-pc-solaris2.11`, and
`x86_64-pc-linux-gnu`.
Differential Revision: https://reviews.llvm.org/D118771
The SANITIZER_GO code path reports an undefined symbol error for dlsym.
```
FAILED: projects/compiler-rt/lib/tsan/rtl/CMakeFiles/GotsanRuntimeCheck /tmp/RelA/projects/compiler-rt/lib/tsan/rtl/CMakeFiles/GotsanRuntimeCheck
```
This symbol has been exported (as an internal GLIBC_PRIVATE symbol) from libc.so.6 starting with glibc 2.34. glibc uses it internally for its libthread_db implementation to enable thread debugging on GDB, so it is unlikely to go away for now.
Fixes#52989.
Reviewed By: #sanitizers, MaskRay, vitalybuka
Differential Revision: https://reviews.llvm.org/D119007
This patch updates the MachO platform (both the ORC MachOPlatform class and the
ORC-Runtime macho_platform.* files) to use allocation actions, rather than EPC
calls, to transfer the initializer information scraped from each linked object.
Interactions between the ORC and ORC-Runtime sides of the platform are
substantially redesigned to accomodate the change.
The high-level changes in this patch are:
1. The MachOPlatform::setupJITDylib method now calls into the runtime to set up
a dylib name <-> header mapping, and a dylib state object (JITDylibState).
2. The MachOPlatformPlugin builds an allocation action that calls the
__orc_rt_macho_register_object_platform_sections and
__orc_rt_macho_deregister_object_platform_sections functions in the runtime
to register the address ranges for all "interesting" sections in the object
being allocated (TLS data sections, initializers, language runtime metadata
sections, etc.).
3. The MachOPlatform::rt_getInitializers method (the entry point in the
controller for requests from the runtime for initializer information) is
replaced by MachOPlatform::rt_pushInitializers. The former returned a data
structure containing the "interesting" section address ranges, but these are
now handled by __orc_rt_macho_register_object_platform_sections. The new
rt_pushInitializers method first issues a lookup to trigger materialization
of the "interesting" sections, then returns the dylib dependence tree rooted
at the requested dylib for dlopen to consume. (The dylib dependence tree is
returned by rt_pushInitializers, rather than being handled by some dedicated
call, because rt_pushInitializers can alter the dependence tree).
The advantage of these changes (beyond the performance advantages of using
allocation actions) is that it moves more information about the materialized
portions of the JITDylib into the executor. This tends to make the runtime
easier to reason about, e.g. the implementation of dlopen in the runtime is now
recursive, rather than relying on recursive calls in the controller to build a
linear data structure for consumption by the runtime. This change can also make
some operations more efficient, e.g. JITDylibs can be dlclosed and then
re-dlopened without having to pull all initializers over from the controller
again.
In addition to the high-level changes, there are some low-level changes to ORC
and the runtime:
* In ORC, at ExecutionSession teardown time JITDylibs are now destroyed in
reverse creation order. This is on the assumption that the ORC runtime will be
loaded into an earlier dylib that will be used by later JITDylibs. This is a
short-term solution to crashes that arose during testing when the runtime was
torn down before its users. Longer term we will likely destroy dylibs in
dependence order.
* toSPSSerializable(Expected<T> E) is updated to explicitly initialize the T
value, allowing it to be used by Ts that have explicit constructors.
* The ORC runtime now (1) attempts to track ref-counts, and (2) distinguishes
not-yet-processed "interesting" sections from previously processed ones. (1)
is necessary for standard dlopen/dlclose emulation. (2) is intended as a step
towards better REPL support -- it should enable future runtime calls that
run only newly registered initializers ("dlopen_more", "dlopen_additions",
...?).
Adds construction from std::string, an ostream &operator<< and std::hash
specialization. Also adds unit tests for each of these operations, as well as
tests for copy construction and assignment.
These new operations will be used in upcoming macho_platform patches.
Aligned new does not require size to be a multiple of alignment, so
memalign is the correct choice instead of aligned_alloc.
Fixes false reports for unaligned sizes.
Reviewed By: eugenis
Differential Revision: https://reviews.llvm.org/D119161
Similar to 60cc1d3218 for NetBSD, add aliases and interceptors for the
following pthread related functions:
- pthread_cond_init(3)
- pthread_cond_destroy(3)
- pthread_cond_signal(3)
- pthread_cond_broadcast(3)
- pthread_cond_wait(3)
- pthread_mutex_init(3)
- pthread_mutex_destroy(3)
- pthread_mutex_lock(3)
- pthread_mutex_trylock(3)
- pthread_mutex_unlock(3)
- pthread_rwlock_init(3)
- pthread_rwlock_destroy(3)
- pthread_rwlock_rdlock(3)
- pthread_rwlock_tryrdlock(3)
- pthread_rwlock_wrlock(3)
- pthread_rwlock_trywrlock(3)
- pthread_rwlock_unlock(3)
- pthread_once(3)
- pthread_sigmask(3)
In FreeBSD's libc, a number of internal aliases of the pthread functions
are invoked, typically with an additional prefixed underscore, e.g.
_pthread_cond_init() and so on.
ThreadSanitizer needs to intercept these aliases too, otherwise some
false positive reports about data races might be produced.
Reviewed By: dvyukov
Differential Revision: https://reviews.llvm.org/D119034
Fixes segfaults on x86_64 caused by instrumented code running before
shadow is set up.
Reviewed By: pcc
Differential Revision: https://reviews.llvm.org/D118171
This fixes the following error:
sanitizer_interface_internal.h:77:7: error: conflicting types for
'__sanitizer_get_module_and_offset_for_pc'
int __sanitizer_get_module_and_offset_for_pc(
common_interface_defs.h:349:5: note: previous declaration is here
int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
I am getting it on a code that uses sanitizer_common (includes internal headers),
but also transitively gets includes of the public headers in tests
via an internal version of gtest.
Reviewed By: melver
Differential Revision: https://reviews.llvm.org/D118910
Instead of calling asan_report.* directly from assembly code they have been replaced with corresponding asan_report.*_asm function, which call asan_report.*. All asan_report.* are now undefined weak symbols, which allows DSOs to link when z defs is used.
Reviewed By: MaskRay, morehouse
Differential Revision: https://reviews.llvm.org/D118813
Unfortunately, the `sanitizer_common` tests are disabled on many targets
that are supported by `sanitizer_common`, making it easy to miss issues
with that support. This patch enables SPARC testing.
Beside the enabling proper, the patch fixes (together with D91607
<https://reviews.llvm.org/D91607>) the failures of the `symbolize_pc.cpp`,
`symbolize_pc_demangle.cpp`, and `symbolize_pc_inline.cpp` tests. They
lack calls to `__builtin_extract_return_addr`. When those are added, they
`PASS` when compiled with `gcc`. `clang` incorrectly doesn't implement a
non-default `__builtin_extract_return_addr` on several targets, SPARC
included.
Because `__builtin_extract_return_addr(__builtin_return_addr(0))` is quite
a mouthful and I'm uncertain if the code needs to compile with msvc which
appparently has it's own `_ReturnAddress`, I've introduced
`__sanitizer_return_addr` to hide the difference and complexity. Because
on 32-bit SPARC `__builtin_extract_return_addr` differs when the calling
function returns a struct, I've added a testcase for that.
There are a couple more tests failing on SPARC that I will deal with
separately.
Tested on `sparcv9-sun-solaris2.11`, `amd64-pc-solaris2.11`, and
`x86_64-pc-linux-gnu`.
Differential Revision: https://reviews.llvm.org/D91608
The definition of the MemInfoBlock is shared between the memprof
compiler-rt runtime and llvm/lib/ProfileData/. This change removes the
memprof_meminfoblock header and moves the struct to the shared include
file. To enable this sharing, the Print method is moved to the
memprof_allocator (the only place it is used) and the remaining uses are
updated to refer to the MemInfoBlock defined in the MemProfData.inc
file.
Also a couple of other minor changes which improve usability of the
types in MemProfData.inc.
* Update the PACKED macro to handle commas.
* Add constructors and equality operators.
* Don't initialize the buildid field.
Differential Revision: https://reviews.llvm.org/D116780
`__builtin_c[tl]z` accepts `unsigned int` argument that is not always the
same as uint32_t. For example, `unsigned int` is uint16_t on MSP430.
Reviewed By: aykevl
Differential Revision: https://reviews.llvm.org/D86547
Use s[iu]_int instead of `(unsigned) int` and d[ui]_int instead of
`(unsigned) long long` for LibCall arguments.
Note: the `*vfp` LibCall versions were NOT touched.
Reviewed By: aykevl
Differential Revision: https://reviews.llvm.org/D86546
As discussed in D118021 <https://reviews.llvm.org/D118021>, `clang -m32` on
Solaris/sparcv9 currently incorrectly doesn't inline atomics on 8-byte
operands, unlike `gcc`. With the workaround in that patch in place, we're
left with may undefined references to `__sync_val_compare_and_swap_8`,
which isn't provided by `libatomic`. This reference is due to the use of
`__sync_val_compare_and_swap` in `sanitizer_atomic_clang.h`'s
`atomic_compare_exchange_strong`. As is already done in
`scudo/standalone/atomic_helpers.h`, using `__atomic_compare_exchange`
instead avoids this problem.
Tested on `sparcv9-sun-solaris2.11`, `amd64-pc-solaris2.11`, and
`x86_64-pc-linux-gnu`.
Differential Revision: https://reviews.llvm.org/D118024
In glibc before 2.33, include/sys/stat.h defines fstat/fstat64 to
`__fxstat/__fxstat64` and provides `__fxstat/__fxstat64` in libc_nonshared.a.
The symbols are glibc specific and not needed on other systems.
Reviewed By: vitalybuka, #sanitizers
Differential Revision: https://reviews.llvm.org/D118423
Fixes a false positive that occurs when a user-implemented memmove is
instrumented by HWASan.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D118180
Use the llvm flag `-pgo-function-entry-coverage` to create single byte "counters" to track functions coverage. This mode has significantly less size overhead in both code and data because
* We mark a function as "covered" with a store instead of an increment which generally requires fewer assembly instructions
* We use a single byte per function rather than 8 bytes per block
The trade off of course is that this mode only tells you if a function has been covered. This is useful, for example, to detect dead code.
When combined with debug info correlation [0] we are able to create an instrumented Clang binary that is only 150M (the vanilla Clang binary is 143M). That is an overhead of 7M (4.9%) compared to the default instrumentation (without value profiling) which has an overhead of 31M (21.7%).
[0] https://groups.google.com/g/llvm-dev/c/r03Z6JoN7d4
Reviewed By: kyulee
Differential Revision: https://reviews.llvm.org/D116180
The "asan/asan_mapping.h" header relies on sanitizer_platform.h
macros, but doesn't directly include the header. All the existing
uses until recently happened to be in places where some other header
had indirectly included sanitizer_platform.h first. The addition of
asan_rtl_x86_64.S was the first place to use "asan/asan_mapping.h"
alone. It so happens that its uses of the macros make having no
macros defined equivalent to SANITIZER_LINUX, so this did not affect
Linux builds. But the assembly constants in asan_rtl_x86_64.S were
wrong for Fuchsia when SANITIZER_FUCHSIA was not properly defined.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D118296
When using the in-tree libc++, we should be using the full path to
ensure that we're using the right library and not accidentally pick up
the system library.
Differential Revision: https://reviews.llvm.org/D118200
`_vfork` moved from libsystem_kernel.dylib to libsystem_c.dylib as part
of the below changes. The iOS simulator does not actually have
libsystem_kernel.dylib of its own, it only has the host Mac's. The
umbrella-nature of Libsystem makes this movement transparent to
everyone; except the simulator! So when we "back deploy", i.e., use the
current version of TSan with an older simulator runtime then this symbol
is now missing, when we run on the latest OS (but an older simulator
runtime).
Note we use `SANITIZER_IOS` because usage of vfork is forbidden on iOS
and the API is completely unavailable on watchOS and tvOS, even if this
problem is specific to the iOS simulator.
Caused by:
rdar://74818691 (Shim vfork() to fork syscall on iOS)
rdar://76762076 (Shim vfork() to fork syscall on macOS)
Radar-Id: rdar://8634734
https://reviews.llvm.org/D116179 introduced some changes to
`InstrProfData.inc` which broke some downstream builds. This commit
reverts those changes since they only changes two field names.
Reviewed By: phosek
Differential Revision: https://reviews.llvm.org/D117631
The kern.elf64.aslr.pie_enable and kern.elf32.aslr.pie_enable sysctls
control the default setting for PIE binary address randomization, but
it is possible to enable or disable ASLR on a per-process basis. So,
use procctl(2) to query whether ASLR is enabled.
(Note that with ASLR enabled but sysctl kern.elf64.aslr.pie_enable=0
a PIE binary will in effect have randomization disabled, and would be
functional with msan. This is not intended as as a user-facing control
though; proccontrol(1) should be used to disable aslr for the process.)
Reviewed By: devnexen
Differential Revision: https://reviews.llvm.org/D117521
089acf2522 updated WrapperFunctionCall to carry arbitrary argument payloads
(rather than plain address ranges). This commit implements the corresponding
update for the ORC runtime.
Fixes:
[2587/4073] Building CXX object projects\compiler-rt\lib\sanitizer_common\CMakeFiles\RTSanitizerCommon.x86_64.dir\sanitizer_stoptheworld_win.cpp.obj
D:\git\llvm-project\compiler-rt\lib\sanitizer_common\sanitizer_stoptheworld_win.cpp(125,33): warning: comparison of integers of different signs: 'DWORD' (aka 'unsigned long') and 'int' [-Wsign-compare]
if (SuspendThread(thread) == -1) {
~~~~~~~~~~~~~~~~~~~~~ ^ ~~
1 warning generated.
In C++20 compound assignment to volatile (here `LocalData[I]++`) is
deprecated, so `mutex_test.cpp` fails to compile.
Simply changing it to `LocalData[I] = LocalData[I] + 1` fixes it.
Differential Revision: https://reviews.llvm.org/D117359
Existing code tended to assume that counters had type `uint64_t` and
computed size from the number of counters. Fix this code to directly
compute the counters size in number of bytes where possible. When the
number of counters is needed, use `__llvm_profile_counter_entry_size()`
or `getCounterTypeSize()`. In a later diff these functions will depend
on the profile mode.
Change the meaning of `DataSize` and `CountersSize` to make them more clear.
* `DataSize` (`CountersSize`) - the size of the data (counter) section in bytes.
* `NumData` (`NumCounters`) - the number of data (counter) entries.
Reviewed By: kyulee
Differential Revision: https://reviews.llvm.org/D116179