//===- AArch64GlobalsTagging.cpp - Global tagging in IR -------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// #include "AArch64.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Constants.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <set> usingnamespacellvm; static const Align kTagGranuleSize = …; static bool shouldTagGlobal(GlobalVariable &G) { … } // Technically, due to ELF symbol interposition semantics, we can't change the // alignment or size of symbols. If we increase the alignment or size of a // symbol, the compiler may make optimisations based on this new alignment or // size. If the symbol is interposed, this optimisation could lead to // alignment-related or OOB read/write crashes. // // This is handled in the linker. When the linker sees multiple declarations of // a global variable, and some are tagged, and some are untagged, it resolves it // to be an untagged definition - but preserves the tag-granule-rounded size and // tag-granule-alignment. This should prevent these kind of crashes intra-DSO. // For cross-DSO, it's been a reasonable contract that if you're interposing a // sanitizer-instrumented global, then the interposer also needs to be // sanitizer-instrumented. // // FIXME: In theory, this can be fixed by splitting the size/alignment of // globals into two uses: an "output alignment" that's emitted to the ELF file, // and an "optimisation alignment" that's used for optimisation. Thus, we could // adjust the output alignment only, and still optimise based on the pessimistic // pre-tagging size/alignment. static void tagGlobalDefinition(Module &M, GlobalVariable *G) { … } namespace { class AArch64GlobalsTagging : public ModulePass { … }; } // anonymous namespace char AArch64GlobalsTagging::ID = …; bool AArch64GlobalsTagging::runOnModule(Module &M) { … } INITIALIZE_PASS_BEGIN(AArch64GlobalsTagging, "aarch64-globals-tagging", "AArch64 Globals Tagging Pass", false, false) INITIALIZE_PASS_END(AArch64GlobalsTagging, "aarch64-globals-tagging", "AArch64 Globals Tagging Pass", false, false) ModulePass *llvm::createAArch64GlobalsTaggingPass() { … }