summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/lsan/lsan_common_linux.cc12
-rw-r--r--compiler-rt/lib/lsan/lsan_flags.inc4
-rw-r--r--compiler-rt/test/lsan/TestCases/use_tls_dynamic.cc2
3 files changed, 13 insertions, 5 deletions
diff --git a/compiler-rt/lib/lsan/lsan_common_linux.cc b/compiler-rt/lib/lsan/lsan_common_linux.cc
index 1dc0561dab7..09f1502c6c5 100644
--- a/compiler-rt/lib/lsan/lsan_common_linux.cc
+++ b/compiler-rt/lib/lsan/lsan_common_linux.cc
@@ -100,6 +100,7 @@ static uptr GetCallerPC(u32 stack_id, StackDepotReverseMap *map) {
struct ProcessPlatformAllocParam {
Frontier *frontier;
StackDepotReverseMap *stack_depot_reverse_map;
+ bool skip_linker_allocations;
};
// ForEachChunk callback. Identifies unreachable chunks which must be treated as
@@ -117,7 +118,8 @@ static void ProcessPlatformSpecificAllocationsCb(uptr chunk, void *arg) {
caller_pc = GetCallerPC(stack_id, param->stack_depot_reverse_map);
// If caller_pc is unknown, this chunk may be allocated in a coroutine. Mark
// it as reachable, as we can't properly report its allocation stack anyway.
- if (caller_pc == 0 || linker->containsAddress(caller_pc)) {
+ if (caller_pc == 0 || (param->skip_linker_allocations &&
+ linker->containsAddress(caller_pc))) {
m.set_tag(kReachable);
param->frontier->push_back(chunk);
}
@@ -142,10 +144,12 @@ static void ProcessPlatformSpecificAllocationsCb(uptr chunk, void *arg) {
// guaranteed to include all dynamic TLS blocks (and possibly other allocations
// which we don't care about).
void ProcessPlatformSpecificAllocations(Frontier *frontier) {
- if (!flags()->use_tls) return;
- if (!linker) return;
StackDepotReverseMap stack_depot_reverse_map;
- ProcessPlatformAllocParam arg = {frontier, &stack_depot_reverse_map};
+ ProcessPlatformAllocParam arg;
+ arg.frontier = frontier;
+ arg.stack_depot_reverse_map = &stack_depot_reverse_map;
+ arg.skip_linker_allocations =
+ flags()->use_tls && flags()->use_ld_allocations && linker != nullptr;
ForEachChunk(ProcessPlatformSpecificAllocationsCb, &arg);
}
diff --git a/compiler-rt/lib/lsan/lsan_flags.inc b/compiler-rt/lib/lsan/lsan_flags.inc
index c405005deed..e390e2ae5a1 100644
--- a/compiler-rt/lib/lsan/lsan_flags.inc
+++ b/compiler-rt/lib/lsan/lsan_flags.inc
@@ -34,6 +34,10 @@ LSAN_FLAG(bool, use_tls, true,
"Root set: include TLS and thread-specific storage")
LSAN_FLAG(bool, use_root_regions, true,
"Root set: include regions added via __lsan_register_root_region().")
+LSAN_FLAG(bool, use_ld_allocations, true,
+ "Root set: mark as reachable all allocations made from dynamic "
+ "linker. This was the old way to handle dynamic TLS, and will "
+ "be removed soon. Do not use this flag.")
LSAN_FLAG(bool, use_unaligned, false, "Consider unaligned pointers valid.")
LSAN_FLAG(bool, use_poisoned, false,
diff --git a/compiler-rt/test/lsan/TestCases/use_tls_dynamic.cc b/compiler-rt/test/lsan/TestCases/use_tls_dynamic.cc
index 860db041ae4..207894b0fff 100644
--- a/compiler-rt/test/lsan/TestCases/use_tls_dynamic.cc
+++ b/compiler-rt/test/lsan/TestCases/use_tls_dynamic.cc
@@ -1,5 +1,5 @@
// Test that dynamically allocated TLS space is included in the root set.
-// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0"
+// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0:use_ld_allocations=0"
// RUN: %clangxx %s -DBUILD_DSO -fPIC -shared -o %t-so.so
// RUN: %clangxx_lsan %s -o %t
// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s
OpenPOWER on IntegriCloud