Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* 'main' of https://github.com/llvm/llvm-project:
  [RISCV] Improve hasAllNBitUsers for users of SLLI.
  [RISCV] Invert if conditions in the switch in RISCVDAGToDAGISel::hasAllNBitUsers. NFC
  [Transforms] Construct SmallVector with ArrayRef (NFC) (llvm#101851)
  [RISCV] Capitalize some variable names. NFC
  [sanitizer_common] Fix UnwindFast on SPARC (llvm#101634)
  [builtins] Fix divtc3.c etc. compilation on Solaris/SPARC with gcc (llvm#101662)
  [NFC][asan] Track current dynamic init module (llvm#101597)
  [libc] enable most of the entrypoints on aarch64 (llvm#101797)
  [SandboxIR][Tracker] Track InsertIntoBB (llvm#101595)
  [SCEV] Use const SCEV * explicitly in more places.
  [ELF] Move outputSections into Ctx. NFC
  [ELF] Move ElfSym into Ctx. NFC
  [ELF] Move Out into Ctx. NFC
  [test][asan] Fix the test checks
  [NFC][asan] Switch from list to DynInitGlobalsByModule (llvm#101596)

Signed-off-by: Edwiin Kusuma Jaya <kutemeikito0905@gmail.com>
  • Loading branch information
kutemeikito committed Aug 4, 2024
2 parents c7cd574 + c03bf2c commit 6b6ccd8
Show file tree
Hide file tree
Showing 60 changed files with 737 additions and 515 deletions.
108 changes: 80 additions & 28 deletions compiler-rt/lib/asan/asan_globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ struct DynInitGlobal {
bool initialized = false;
DynInitGlobal *next = nullptr;
};
typedef IntrusiveList<DynInitGlobal> DynInitGlobals;
static DynInitGlobals dynamic_init_globals SANITIZER_GUARDED_BY(mu_for_globals);

// We want to remember where a certain range of globals was registered.
struct GlobalRegistrationSite {
Expand All @@ -72,6 +70,25 @@ static ListOfGlobals &GlobalsByIndicator(uptr odr_indicator)
return (*globals_by_indicator)[odr_indicator];
}

static const char *current_dynamic_init_module_name
SANITIZER_GUARDED_BY(mu_for_globals) = nullptr;

using DynInitGlobalsByModule =
DenseMap<const char *, IntrusiveList<DynInitGlobal>>;

// TODO: Add a NoDestroy helper, this patter is very common in sanitizers.
static DynInitGlobalsByModule &DynInitGlobals()
SANITIZER_REQUIRES(mu_for_globals) {
static DynInitGlobalsByModule *globals_by_module = nullptr;
if (!globals_by_module) {
alignas(alignof(DynInitGlobalsByModule)) static char
placeholder[sizeof(DynInitGlobalsByModule)];
globals_by_module = new (placeholder) DynInitGlobalsByModule();
}

return *globals_by_module;
}

ALWAYS_INLINE void PoisonShadowForGlobal(const Global *g, u8 value) {
FastPoisonShadow(g->beg, g->size_with_redzone, value);
}
Expand All @@ -94,6 +111,31 @@ static void AddGlobalToList(ListOfGlobals &list, const Global *g) {
list.push_front(new (GetGlobalLowLevelAllocator()) GlobalListNode{g});
}

static void UnpoisonDynamicGlobals(IntrusiveList<DynInitGlobal> &dyn_globals,
bool mark_initialized) {
for (auto &dyn_g : dyn_globals) {
const Global *g = &dyn_g.g;
if (dyn_g.initialized)
continue;
// Unpoison the whole global.
PoisonShadowForGlobal(g, 0);
// Poison redzones back.
PoisonRedZones(*g);
if (mark_initialized)
dyn_g.initialized = true;
}
}

static void PoisonDynamicGlobals(
const IntrusiveList<DynInitGlobal> &dyn_globals) {
for (auto &dyn_g : dyn_globals) {
const Global *g = &dyn_g.g;
if (dyn_g.initialized)
continue;
PoisonShadowForGlobal(g, kAsanInitializationOrderMagic);
}
}

static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false;
if (addr >= g.beg + g.size_with_redzone) return false;
Expand Down Expand Up @@ -257,8 +299,8 @@ static void RegisterGlobal(const Global *g) SANITIZER_REQUIRES(mu_for_globals) {
AddGlobalToList(list_of_all_globals, g);

if (g->has_dynamic_init) {
dynamic_init_globals.push_back(new (GetGlobalLowLevelAllocator())
DynInitGlobal{*g, false});
DynInitGlobals()[g->module_name].push_back(
new (GetGlobalLowLevelAllocator()) DynInitGlobal{*g, false});
}
}

Expand Down Expand Up @@ -289,13 +331,10 @@ void StopInitOrderChecking() {
return;
Lock lock(&mu_for_globals);
flags()->check_initialization_order = false;
for (const DynInitGlobal &dyn_g : dynamic_init_globals) {
const Global *g = &dyn_g.g;
// Unpoison the whole global.
PoisonShadowForGlobal(g, 0);
// Poison redzones back.
PoisonRedZones(*g);
}
DynInitGlobals().forEach([&](auto &kv) {
UnpoisonDynamicGlobals(kv.second, /*mark_initialized=*/false);
return true;
});
}

static bool IsASCII(unsigned char c) { return /*0x00 <= c &&*/ c <= 0x7F; }
Expand Down Expand Up @@ -456,17 +495,29 @@ void __asan_before_dynamic_init(const char *module_name) {
CHECK(module_name);
CHECK(AsanInited());
Lock lock(&mu_for_globals);
if (current_dynamic_init_module_name == module_name)
return;
if (flags()->report_globals >= 3)
Printf("DynInitPoison module: %s\n", module_name);
for (DynInitGlobal &dyn_g : dynamic_init_globals) {
const Global *g = &dyn_g.g;
if (dyn_g.initialized)
continue;
if (g->module_name != module_name)
PoisonShadowForGlobal(g, kAsanInitializationOrderMagic);
else if (!strict_init_order)
dyn_g.initialized = true;

if (current_dynamic_init_module_name == nullptr) {
// First call, poison all globals from other modules.
DynInitGlobals().forEach([&](auto &kv) {
if (kv.first != module_name) {
PoisonDynamicGlobals(kv.second);
} else {
UnpoisonDynamicGlobals(kv.second,
/*mark_initialized=*/!strict_init_order);
}
return true;
});
} else {
// Module changed.
PoisonDynamicGlobals(DynInitGlobals()[current_dynamic_init_module_name]);
UnpoisonDynamicGlobals(DynInitGlobals()[module_name],
/*mark_initialized=*/!strict_init_order);
}
current_dynamic_init_module_name = module_name;
}

// This method runs immediately after dynamic initialization in each TU, when
Expand All @@ -477,15 +528,16 @@ void __asan_after_dynamic_init() {
return;
CHECK(AsanInited());
Lock lock(&mu_for_globals);
if (!current_dynamic_init_module_name)
return;

if (flags()->report_globals >= 3)
Printf("DynInitUnpoison\n");
for (const DynInitGlobal &dyn_g : dynamic_init_globals) {
const Global *g = &dyn_g.g;
if (!dyn_g.initialized) {
// Unpoison the whole global.
PoisonShadowForGlobal(g, 0);
// Poison redzones back.
PoisonRedZones(*g);
}
}

DynInitGlobals().forEach([&](auto &kv) {
UnpoisonDynamicGlobals(kv.second, /*mark_initialized=*/false);
return true;
});

current_dynamic_init_module_name = nullptr;
}
2 changes: 1 addition & 1 deletion compiler-rt/lib/builtins/divtc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#define QUAD_PRECISION
#include "fp_lib.h"

#if defined(CRT_HAS_F128)
#if defined(CRT_HAS_128BIT) && defined(CRT_HAS_F128)

// Returns: the quotient of (a + ib) / (c + id)

Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/builtins/multc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "int_lib.h"
#include "int_math.h"

#if defined(CRT_HAS_F128)
#if defined(CRT_HAS_128BIT) && defined(CRT_HAS_F128)

// Returns: the product of a + ib and c + id

Expand Down
11 changes: 5 additions & 6 deletions compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,16 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
// Avoid infinite loop when frame == frame[0] by using frame > prev_frame.
while (IsValidFrame(bp, stack_top, bottom) && IsAligned(bp, sizeof(uhwptr)) &&
size < max_depth) {
uhwptr pc1 = ((uhwptr *)bp)[15];
// %o7 contains the address of the call instruction and not the
// return address, so we need to compensate.
uhwptr pc1 = GetNextInstructionPc(((uhwptr *)bp)[15]);
// Let's assume that any pointer in the 0th page is invalid and
// stop unwinding here. If we're adding support for a platform
// where this isn't true, we need to reconsider this check.
if (pc1 < kPageSize)
break;
if (pc1 != pc) {
// %o7 contains the address of the call instruction and not the
// return address, so we need to compensate.
trace_buffer[size++] = GetNextInstructionPc((uptr)pc1);
}
if (pc1 != pc)
trace_buffer[size++] = pc1;
bottom = bp;
bp = (uptr)((uhwptr *)bp)[14] + STACK_BIAS;
}
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/asan/TestCases/initialization-nobug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ int getStructWithDtorValue() { return struct_with_dtor.value; }

int main() { return 0; }

// CHECK: DynInitPoison module: {{.*}}initialization-nobug.cpp
// CHECK: DynInitPoison
// CHECK: DynInitUnpoison
// CHECK: DynInitPoison module: {{.*}}initialization-nobug-extra.cpp
// CHECK: DynInitPoison
// CHECK: DynInitUnpoison
6 changes: 5 additions & 1 deletion libc/cmake/modules/LLVMLibCTestRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ function(get_object_files_for_test result skipped_entrypoints_list)
foreach(dep IN LISTS unchecked_list)
if (NOT TARGET ${dep})
# Skip tests with undefined dependencies.
list(APPEND skipped_list ${dep})
# Compiler-RT targets are added only if they are enabled. However, such targets may not be defined
# at the time of the libc build. We should skip checking such targets.
if (NOT ${dep} MATCHES "^RTScudo.*|^RTGwp.*")
list(APPEND skipped_list ${dep})
endif()
continue()
endif()
get_target_property(aliased_target ${dep} "ALIASED_TARGET")
Expand Down
Loading

0 comments on commit 6b6ccd8

Please sign in to comment.