diff --git a/compiler-rt/lib/objsan/include/obj_encoding.h b/compiler-rt/lib/objsan/include/obj_encoding.h index 61936385707df..560a0f7a620d2 100644 --- a/compiler-rt/lib/objsan/include/obj_encoding.h +++ b/compiler-rt/lib/objsan/include/obj_encoding.h @@ -457,19 +457,17 @@ using SmallObjectsTy = BucketSchemeTy; using LargeObjectsTy = LedgerSchemeTy; -extern SmallObjectsTy *SmallObjects; -extern LargeObjectsTy *LargeObjects; +extern SmallObjectsTy &SmallObjects; +extern LargeObjectsTy &LargeObjects; +SmallObjectsTy &getOrConstructSmallObjects(); static inline SmallObjectsTy &getSmallObjects() { - if (!SmallObjects) [[unlikely]] - SmallObjects = new SmallObjectsTy(); - return *SmallObjects; + return SmallObjects; } +LargeObjectsTy &getOrConstructLargeObjects(); static inline LargeObjectsTy &getLargeObjects() { - if (!LargeObjects) [[unlikely]] - LargeObjects = new LargeObjectsTy(); - return *LargeObjects; + return LargeObjects; } } // namespace __objsan diff --git a/compiler-rt/lib/objsan/objsan_ir_rt.cpp b/compiler-rt/lib/objsan/objsan_ir_rt.cpp index 7f1f88c7dff1d..c6de21d781bc2 100644 --- a/compiler-rt/lib/objsan/objsan_ir_rt.cpp +++ b/compiler-rt/lib/objsan/objsan_ir_rt.cpp @@ -94,6 +94,15 @@ char *__objsan_post_alloca(char *MPtr, int64_t ObjSize, return __objsan_register_object(MPtr, ObjSize, RequiresTemporalCheck); } +OBJSAN_BIG_API_ATTRS +void __objsan_pre_module(char *module_name, char *name, int32_t id) { + getOrConstructLargeObjects(); + getOrConstructSmallObjects(); +} + +OBJSAN_SMALL_API_ATTRS +void __objsan_post_module(char *module_name, char *name, int32_t id) {} + // OBJSAN_BIG_API_ATTRS __attribute__((optnone, noinline)) char * __objsan_pre_global(char *MPtr, int32_t ObjSize, int8_t IsDefinition, diff --git a/compiler-rt/lib/objsan/objsan_rt.cpp b/compiler-rt/lib/objsan/objsan_rt.cpp index 010a9050d051a..cc545e1eb797d 100644 --- a/compiler-rt/lib/objsan/objsan_rt.cpp +++ b/compiler-rt/lib/objsan/objsan_rt.cpp @@ -1,30 +1,51 @@ #include "include/obj_encoding.h" -namespace __objsan { +#include -template class ObjectDeallocator { - T *&ObjectPtr; +namespace __objsan { -public: - ObjectDeallocator(T *&Ptr) : ObjectPtr(Ptr) {} - ~ObjectDeallocator() { - if (ObjectPtr == nullptr) - delete ObjectPtr; +template struct LazyConstruction { + static bool Init; + LazyConstruction() {} + ~LazyConstruction() { + if (Init) + V.~T(); + } + template void construct(ArgsTy &&...Args) { + if (!Init) { + new (&V) T(std::forward(Args)...); + Init = true; + } } + union { + T V; + }; }; -__attribute__((visibility("default"))) SmallObjectsTy *SmallObjects = nullptr; -__attribute__((visibility("default"))) LargeObjectsTy *LargeObjects = nullptr; +static LazyConstruction LazySmallObjects; +static LazyConstruction LazyLargeObjects; +template <> bool LazyConstruction::Init = false; +template <> bool LazyConstruction::Init = false; -// These will ensure the objects are deallocated when the program ends. -ObjectDeallocator SODeallocator(SmallObjects); -ObjectDeallocator LODeallocator(LargeObjects); +__attribute__((visibility("default"))) SmallObjectsTy &SmallObjects = + LazySmallObjects.V; +__attribute__((visibility("default"))) LargeObjectsTy &LargeObjects = + LazyLargeObjects.V; + +SmallObjectsTy &getOrConstructSmallObjects() { + LazySmallObjects.construct(); + return SmallObjects; +} +LargeObjectsTy &getOrConstructLargeObjects() { + LazyLargeObjects.construct(); + return LargeObjects; +} __attribute((constructor)) void initialize() { // Ensure the globals are constructed before the program begins. If it is // multithreaded, we do not want multiple threads to initialize the objects. - getSmallObjects(); - getLargeObjects(); + getOrConstructSmallObjects(); + getOrConstructLargeObjects(); } } // namespace __objsan diff --git a/llvm/lib/Transforms/IPO/LightSan.cpp b/llvm/lib/Transforms/IPO/LightSan.cpp index 720ec4588cb23..e50fd8b526e7f 100644 --- a/llvm/lib/Transforms/IPO/LightSan.cpp +++ b/llvm/lib/Transforms/IPO/LightSan.cpp @@ -2690,7 +2690,7 @@ void LightSanInstrumentationConfig::populate(InstrumentorIRBuilderTy &IIRB) { ExtendedICmpIO::populate(*this, IIRB); ExtendedVAArgIO::populate(*this, IIRB); AllocatorCallIO::populate(*this, IIRB); - // ModuleIO::populate(*this, IIRB.Ctx); + ModuleIO::populate(*this, IIRB.Ctx); PtrToIntIO::ConfigTy PostP2IIOConfig(/*Enable=*/false); PostP2IIOConfig.set(PtrToIntIO::PassPointer);