forked from OSchip/llvm-project
[Msan] Generalize instrumentation code to support FreeBSD mapping
Differential Revision: http://reviews.llvm.org/D6666 llvm-svn: 224514
This commit is contained in:
parent
3a623dbd2a
commit
b4ffb5d5e9
|
@ -120,10 +120,6 @@ using namespace llvm;
|
||||||
|
|
||||||
#define DEBUG_TYPE "msan"
|
#define DEBUG_TYPE "msan"
|
||||||
|
|
||||||
static const uint64_t kShadowMask32 = 1ULL << 31;
|
|
||||||
static const uint64_t kShadowMask64 = 1ULL << 46;
|
|
||||||
static const uint64_t kOriginOffset32 = 1ULL << 30;
|
|
||||||
static const uint64_t kOriginOffset64 = 1ULL << 45;
|
|
||||||
static const unsigned kMinOriginAlignment = 4;
|
static const unsigned kMinOriginAlignment = 4;
|
||||||
static const unsigned kShadowTLSAlignment = 8;
|
static const unsigned kShadowTLSAlignment = 8;
|
||||||
|
|
||||||
|
@ -196,6 +192,64 @@ static cl::opt<bool> ClCheckConstantShadow("msan-check-constant-shadow",
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Memory map parameters used in application-to-shadow address calculation.
|
||||||
|
// Offset = (Addr & ~AndMask) ^ XorMask
|
||||||
|
// Shadow = ShadowBase + Offset
|
||||||
|
// Origin = OriginBase + Offset
|
||||||
|
struct MemoryMapParams {
|
||||||
|
uint64_t AndMask;
|
||||||
|
uint64_t XorMask;
|
||||||
|
uint64_t ShadowBase;
|
||||||
|
uint64_t OriginBase;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlatformMemoryMapParams {
|
||||||
|
const MemoryMapParams *bits32;
|
||||||
|
const MemoryMapParams *bits64;
|
||||||
|
};
|
||||||
|
|
||||||
|
// i386 Linux
|
||||||
|
static const MemoryMapParams LinuxMemoryMapParams32 = {
|
||||||
|
0x000080000000, // AndMask
|
||||||
|
0, // XorMask (not used)
|
||||||
|
0, // ShadowBase (not used)
|
||||||
|
0x000040000000, // OriginBase
|
||||||
|
};
|
||||||
|
|
||||||
|
// x86_64 Linux
|
||||||
|
static const MemoryMapParams LinuxMemoryMapParams64 = {
|
||||||
|
0x400000000000, // AndMask
|
||||||
|
0, // XorMask (not used)
|
||||||
|
0, // ShadowBase (not used)
|
||||||
|
0x200000000000, // OriginBase
|
||||||
|
};
|
||||||
|
|
||||||
|
// i386 FreeBSD
|
||||||
|
static const MemoryMapParams FreeBSDMemoryMapParams32 = {
|
||||||
|
0x000180000000, // AndMask
|
||||||
|
0x000040000000, // XorMask
|
||||||
|
0x000020000000, // ShadowBase
|
||||||
|
0x000700000000, // OriginBase
|
||||||
|
};
|
||||||
|
|
||||||
|
// x86_64 FreeBSD
|
||||||
|
static const MemoryMapParams FreeBSDMemoryMapParams64 = {
|
||||||
|
0xc00000000000, // AndMask
|
||||||
|
0x200000000000, // XorMask
|
||||||
|
0x100000000000, // ShadowBase
|
||||||
|
0x380000000000, // OriginBase
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PlatformMemoryMapParams LinuxMemoryMapParams = {
|
||||||
|
&LinuxMemoryMapParams32,
|
||||||
|
&LinuxMemoryMapParams64,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PlatformMemoryMapParams FreeBSDMemoryMapParams = {
|
||||||
|
&FreeBSDMemoryMapParams32,
|
||||||
|
&FreeBSDMemoryMapParams64,
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief An instrumentation pass implementing detection of uninitialized
|
/// \brief An instrumentation pass implementing detection of uninitialized
|
||||||
/// reads.
|
/// reads.
|
||||||
///
|
///
|
||||||
|
@ -258,13 +312,9 @@ class MemorySanitizer : public FunctionPass {
|
||||||
/// \brief MSan runtime replacements for memmove, memcpy and memset.
|
/// \brief MSan runtime replacements for memmove, memcpy and memset.
|
||||||
Value *MemmoveFn, *MemcpyFn, *MemsetFn;
|
Value *MemmoveFn, *MemcpyFn, *MemsetFn;
|
||||||
|
|
||||||
/// \brief Address mask used in application-to-shadow address calculation.
|
/// \brief Memory map parameters used in application-to-shadow calculation.
|
||||||
/// ShadowAddr is computed as ApplicationAddr & ~ShadowMask.
|
const MemoryMapParams *MapParams;
|
||||||
uint64_t ShadowMask;
|
|
||||||
/// \brief Offset of the origin shadow from the "normal" shadow.
|
|
||||||
/// OriginAddr is computed as (ShadowAddr + OriginOffset) & ~3ULL
|
|
||||||
uint64_t OriginOffset;
|
|
||||||
/// \brief Branch weights for error reporting.
|
|
||||||
MDNode *ColdCallWeights;
|
MDNode *ColdCallWeights;
|
||||||
/// \brief Branch weights for origin store.
|
/// \brief Branch weights for origin store.
|
||||||
MDNode *OriginStoreWeights;
|
MDNode *OriginStoreWeights;
|
||||||
|
@ -389,16 +439,21 @@ bool MemorySanitizer::doInitialization(Module &M) {
|
||||||
report_fatal_error("data layout missing");
|
report_fatal_error("data layout missing");
|
||||||
DL = &DLP->getDataLayout();
|
DL = &DLP->getDataLayout();
|
||||||
|
|
||||||
|
Triple TargetTriple(M.getTargetTriple());
|
||||||
|
const PlatformMemoryMapParams *PlatformMapParams;
|
||||||
|
if (TargetTriple.getOS() == Triple::FreeBSD)
|
||||||
|
PlatformMapParams = &FreeBSDMemoryMapParams;
|
||||||
|
else
|
||||||
|
PlatformMapParams = &LinuxMemoryMapParams;
|
||||||
|
|
||||||
C = &(M.getContext());
|
C = &(M.getContext());
|
||||||
unsigned PtrSize = DL->getPointerSizeInBits(/* AddressSpace */0);
|
unsigned PtrSize = DL->getPointerSizeInBits(/* AddressSpace */0);
|
||||||
switch (PtrSize) {
|
switch (PtrSize) {
|
||||||
case 64:
|
case 64:
|
||||||
ShadowMask = kShadowMask64;
|
MapParams = PlatformMapParams->bits64;
|
||||||
OriginOffset = kOriginOffset64;
|
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
ShadowMask = kShadowMask32;
|
MapParams = PlatformMapParams->bits32;
|
||||||
OriginOffset = kOriginOffset32;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
report_fatal_error("unsupported pointer size");
|
report_fatal_error("unsupported pointer size");
|
||||||
|
@ -724,33 +779,57 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||||
return IRB.CreateBitCast(V, NoVecTy);
|
return IRB.CreateBitCast(V, NoVecTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Compute the integer shadow offset that corresponds to a given
|
||||||
|
/// application address.
|
||||||
|
///
|
||||||
|
/// Offset = (Addr & ~AndMask) ^ XorMask
|
||||||
|
Value *getShadowPtrOffset(Value *Addr, IRBuilder<> &IRB) {
|
||||||
|
uint64_t AndMask = MS.MapParams->AndMask;
|
||||||
|
assert(AndMask != 0 && "AndMask shall be specified");
|
||||||
|
Value *OffsetLong =
|
||||||
|
IRB.CreateAnd(IRB.CreatePointerCast(Addr, MS.IntptrTy),
|
||||||
|
ConstantInt::get(MS.IntptrTy, ~AndMask));
|
||||||
|
|
||||||
|
uint64_t XorMask = MS.MapParams->XorMask;
|
||||||
|
if (XorMask != 0)
|
||||||
|
OffsetLong = IRB.CreateXor(OffsetLong,
|
||||||
|
ConstantInt::get(MS.IntptrTy, XorMask));
|
||||||
|
return OffsetLong;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Compute the shadow address that corresponds to a given application
|
/// \brief Compute the shadow address that corresponds to a given application
|
||||||
/// address.
|
/// address.
|
||||||
///
|
///
|
||||||
/// Shadow = Addr & ~ShadowMask.
|
/// Shadow = ShadowBase + Offset
|
||||||
Value *getShadowPtr(Value *Addr, Type *ShadowTy,
|
Value *getShadowPtr(Value *Addr, Type *ShadowTy,
|
||||||
IRBuilder<> &IRB) {
|
IRBuilder<> &IRB) {
|
||||||
Value *ShadowLong =
|
Value *ShadowLong = getShadowPtrOffset(Addr, IRB);
|
||||||
IRB.CreateAnd(IRB.CreatePointerCast(Addr, MS.IntptrTy),
|
uint64_t ShadowBase = MS.MapParams->ShadowBase;
|
||||||
ConstantInt::get(MS.IntptrTy, ~MS.ShadowMask));
|
if (ShadowBase != 0)
|
||||||
|
ShadowLong =
|
||||||
|
IRB.CreateAdd(ShadowLong,
|
||||||
|
ConstantInt::get(MS.IntptrTy, ShadowBase));
|
||||||
return IRB.CreateIntToPtr(ShadowLong, PointerType::get(ShadowTy, 0));
|
return IRB.CreateIntToPtr(ShadowLong, PointerType::get(ShadowTy, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Compute the origin address that corresponds to a given application
|
/// \brief Compute the origin address that corresponds to a given application
|
||||||
/// address.
|
/// address.
|
||||||
///
|
///
|
||||||
/// OriginAddr = (ShadowAddr + OriginOffset) & ~3ULL
|
/// OriginAddr = (OriginBase + Offset) & ~3ULL
|
||||||
Value *getOriginPtr(Value *Addr, IRBuilder<> &IRB, unsigned Alignment) {
|
Value *getOriginPtr(Value *Addr, IRBuilder<> &IRB, unsigned Alignment) {
|
||||||
Value *ShadowLong =
|
Value *OriginLong = getShadowPtrOffset(Addr, IRB);
|
||||||
IRB.CreateAnd(IRB.CreatePointerCast(Addr, MS.IntptrTy),
|
uint64_t OriginBase = MS.MapParams->OriginBase;
|
||||||
ConstantInt::get(MS.IntptrTy, ~MS.ShadowMask));
|
if (OriginBase != 0)
|
||||||
Value *Origin = IRB.CreateAdd(
|
OriginLong =
|
||||||
ShadowLong, ConstantInt::get(MS.IntptrTy, MS.OriginOffset));
|
IRB.CreateAdd(OriginLong,
|
||||||
|
ConstantInt::get(MS.IntptrTy, OriginBase));
|
||||||
if (Alignment < kMinOriginAlignment) {
|
if (Alignment < kMinOriginAlignment) {
|
||||||
uint64_t Mask = kMinOriginAlignment - 1;
|
uint64_t Mask = kMinOriginAlignment - 1;
|
||||||
Origin = IRB.CreateAnd(Origin, ConstantInt::get(MS.IntptrTy, ~Mask));
|
OriginLong = IRB.CreateAnd(OriginLong,
|
||||||
|
ConstantInt::get(MS.IntptrTy, ~Mask));
|
||||||
}
|
}
|
||||||
return IRB.CreateIntToPtr(Origin, PointerType::get(IRB.getInt32Ty(), 0));
|
return IRB.CreateIntToPtr(OriginLong,
|
||||||
|
PointerType::get(IRB.getInt32Ty(), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Compute the shadow address for a given function argument.
|
/// \brief Compute the shadow address for a given function argument.
|
||||||
|
|
Loading…
Reference in New Issue