cl::desc("Record stack frames with tagged allocations "
"in a thread-local ring buffer"),
cl::Hidden, cl::init(true));
-static cl::opt<bool>
- ClCreateFrameDescriptions("hwasan-create-frame-descriptions",
- cl::desc("create static frame descriptions"),
- cl::Hidden, cl::init(true));
-
static cl::opt<bool>
ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics",
cl::desc("instrument memory intrinsics"),
FunctionCallee HWAsanMemmove, HWAsanMemcpy, HWAsanMemset;
FunctionCallee HWAsanHandleVfork;
- // Frame description is a way to pass names/sizes of local variables
- // to the run-time w/o adding extra executable code in every function.
- // We do this by creating a separate section with {PC,Descr} pairs and passing
- // the section beg/end to __hwasan_init_frames() at module init time.
- std::string createFrameString(ArrayRef<AllocaInst*> Allocas);
- void createFrameGlobal(Function &F, const std::string &FrameString);
- // Get the section name for frame descriptions. Currently ELF-only.
- const char *getFrameSection() { return "__hwasan_frames"; }
- const char *getFrameSectionBeg() { return "__start___hwasan_frames"; }
- const char *getFrameSectionEnd() { return "__stop___hwasan_frames"; }
- GlobalVariable *createFrameSectionBound(Module &M, Type *Ty,
- const char *Name) {
- auto GV = new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
- nullptr, Name);
- GV->setVisibility(GlobalValue::HiddenVisibility);
- return GV;
- }
-
/// This struct defines the shadow mapping using the rule:
/// shadow = (mem >> Scale) + Offset.
/// If InGlobal is true, then
Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
Ctor->setComdat(CtorComdat);
appendToGlobalCtors(M, Ctor, 0, Ctor);
-
- IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
- IRBCtor.CreateCall(
- declareSanitizerInitFunction(M, "__hwasan_init_frames",
- {Int8PtrTy, Int8PtrTy}),
- {createFrameSectionBound(M, Int8Ty, getFrameSectionBeg()),
- createFrameSectionBound(M, Int8Ty, getFrameSectionEnd())});
});
-
- // Create a zero-length global in __hwasan_frame so that the linker will
- // always create start and stop symbols.
- //
- // N.B. If we ever start creating associated metadata in this pass this
- // global will need to be associated with the ctor.
- Type *Int8Arr0Ty = ArrayType::get(Int8Ty, 0);
- M.getOrInsertGlobal("__hwasan", Int8Arr0Ty, [&] {
- auto *GV = new GlobalVariable(
- M, Int8Arr0Ty, /*isConstantGlobal=*/true, GlobalValue::PrivateLinkage,
- Constant::getNullValue(Int8Arr0Ty), "__hwasan");
- GV->setSection(getFrameSection());
- Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
- GV->setComdat(CtorComdat);
- appendToCompilerUsed(M, GV);
- return GV;
- });
}
if (!TargetTriple.isAndroid()) {
return nullptr;
}
-// Creates a string with a description of the stack frame (set of Allocas).
-// The string is intended to be human readable.
-// The current form is: Size1 Name1; Size2 Name2; ...
-std::string
-HWAddressSanitizer::createFrameString(ArrayRef<AllocaInst *> Allocas) {
- std::ostringstream Descr;
- for (auto AI : Allocas)
- Descr << getAllocaSizeInBytes(*AI) << " " << AI->getName().str() << "; ";
- return Descr.str();
-}
-
-// Creates a global in the frame section which consists of two pointers:
-// the function PC and the frame string constant.
-void HWAddressSanitizer::createFrameGlobal(Function &F,
- const std::string &FrameString) {
- Module &M = *F.getParent();
- auto DescrGV = createPrivateGlobalForString(M, FrameString, true);
- auto PtrPairTy = StructType::get(F.getType(), DescrGV->getType());
- auto GV = new GlobalVariable(
- M, PtrPairTy, /*isConstantGlobal*/ true, GlobalVariable::PrivateLinkage,
- ConstantStruct::get(PtrPairTy, (Constant *)&F, (Constant *)DescrGV),
- "__hwasan");
- GV->setSection(getFrameSection());
- appendToCompilerUsed(M, GV);
- // Put GV into the F's Comadat so that if F is deleted GV can be deleted too.
- if (auto Comdat =
- GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
- GV->setComdat(Comdat);
-}
-
void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
if (!Mapping.InTls) {
LocalDynamicShadow = getDynamicShadowNonTls(IRB);
if (AllocasToInstrument.empty() && ToInstrument.empty())
return false;
- if (ClCreateFrameDescriptions && !AllocasToInstrument.empty())
- createFrameGlobal(F, createFrameString(AllocasToInstrument));
-
-
assert(!LocalDynamicShadow);
Instruction *InsertPt = &*F.getEntryBlock().begin();