forked from OSchip/llvm-project
Revert "[DFSan] Cleanup code for platforms other than Linux x86_64."
This reverts commit 8441b993bd
.
Buildbot failures.
This commit is contained in:
parent
76d0747e08
commit
39295e92f7
|
@ -88,8 +88,72 @@ int __dfsan_get_track_origins() {
|
|||
// 45-46 are cleared to bring the address into the range
|
||||
// [0x100000008000,0x200000000000). See the function shadow_for below.
|
||||
//
|
||||
// On Linux/MIPS64, memory is laid out as follows:
|
||||
//
|
||||
// +--------------------+ 0x10000000000 (top of memory)
|
||||
// | application memory |
|
||||
// +--------------------+ 0xF000008000 (kAppAddr)
|
||||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x2000000000 (kUnusedAddr)
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x1000008000 (kShadowAddr)
|
||||
// | unused |
|
||||
// +--------------------+ 0x0000010000
|
||||
// | reserved by kernel |
|
||||
// +--------------------+ 0x0000000000
|
||||
|
||||
// On Linux/AArch64 (39-bit VMA), memory is laid out as follow:
|
||||
//
|
||||
// +--------------------+ 0x8000000000 (top of memory)
|
||||
// | application memory |
|
||||
// +--------------------+ 0x7000008000 (kAppAddr)
|
||||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x1000000000 (kUnusedAddr)
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x0000010000 (kShadowAddr)
|
||||
// | reserved by kernel |
|
||||
// +--------------------+ 0x0000000000
|
||||
|
||||
// On Linux/AArch64 (42-bit VMA), memory is laid out as follow:
|
||||
//
|
||||
// +--------------------+ 0x40000000000 (top of memory)
|
||||
// | application memory |
|
||||
// +--------------------+ 0x3ff00008000 (kAppAddr)
|
||||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x8000000000 (kUnusedAddr)
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x0000010000 (kShadowAddr)
|
||||
// | reserved by kernel |
|
||||
// +--------------------+ 0x0000000000
|
||||
|
||||
// On Linux/AArch64 (48-bit VMA), memory is laid out as follow:
|
||||
//
|
||||
// +--------------------+ 0x1000000000000 (top of memory)
|
||||
// | application memory |
|
||||
// +--------------------+ 0xffff00008000 (kAppAddr)
|
||||
// | unused |
|
||||
// +--------------------+ 0xaaaab0000000 (top of PIE address)
|
||||
// | application PIE |
|
||||
// +--------------------+ 0xaaaaa0000000 (top of PIE address)
|
||||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x8000000000 (kUnusedAddr)
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x0000010000 (kShadowAddr)
|
||||
// | reserved by kernel |
|
||||
// +--------------------+ 0x0000000000
|
||||
|
||||
#ifdef DFSAN_RUNTIME_VMA
|
||||
// Runtime detected VMA size.
|
||||
int __dfsan::vmaSize;
|
||||
#endif
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
dfsan_label __dfsan_union_load(const dfsan_label *ls, uptr n) {
|
||||
|
@ -835,6 +899,22 @@ void dfsan_clear_thread_local_state() {
|
|||
}
|
||||
}
|
||||
|
||||
static void InitializePlatformEarly() {
|
||||
AvoidCVE_2016_2143();
|
||||
#ifdef DFSAN_RUNTIME_VMA
|
||||
__dfsan::vmaSize =
|
||||
(MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
|
||||
if (__dfsan::vmaSize == 39 || __dfsan::vmaSize == 42 ||
|
||||
__dfsan::vmaSize == 48) {
|
||||
__dfsan_shadow_ptr_mask = ShadowMask();
|
||||
} else {
|
||||
Printf("FATAL: DataFlowSanitizer: unsupported VMA range\n");
|
||||
Printf("FATAL: Found %d - Supported 39, 42, and 48\n", __dfsan::vmaSize);
|
||||
Die();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void dfsan_flush() {
|
||||
if (!MmapFixedSuperNoReserve(ShadowAddr(), UnusedAddr() - ShadowAddr()))
|
||||
Die();
|
||||
|
@ -847,10 +927,10 @@ static void DFsanInit(int argc, char **argv, char **envp) {
|
|||
dfsan_init_is_running = true;
|
||||
SanitizerToolName = "DataflowSanitizer";
|
||||
|
||||
AvoidCVE_2016_2143();
|
||||
|
||||
InitializeFlags();
|
||||
|
||||
::InitializePlatformEarly();
|
||||
|
||||
dfsan_flush();
|
||||
if (common_flags()->use_madv_dontdump)
|
||||
DontDumpShadowMemory(ShadowAddr(), UnusedAddr() - ShadowAddr());
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace __dfsan {
|
|||
|
||||
using __sanitizer::uptr;
|
||||
|
||||
#if defined(__x86_64__)
|
||||
struct Mapping {
|
||||
static const uptr kShadowAddr = 0x100000008000;
|
||||
static const uptr kOriginAddr = 0x200000008000;
|
||||
|
@ -27,10 +28,46 @@ struct Mapping {
|
|||
static const uptr kAppAddr = 0x700000008000;
|
||||
static const uptr kShadowMask = ~0x600000000000;
|
||||
};
|
||||
#elif defined(__mips64)
|
||||
struct Mapping {
|
||||
static const uptr kShadowAddr = 0x1000008000;
|
||||
static const uptr kUnusedAddr = 0x2000000000;
|
||||
static const uptr kAppAddr = 0xF000008000;
|
||||
static const uptr kShadowMask = ~0xE000000000;
|
||||
};
|
||||
#elif defined(__aarch64__)
|
||||
struct Mapping39 {
|
||||
static const uptr kShadowAddr = 0x10000;
|
||||
static const uptr kUnusedAddr = 0x1000000000;
|
||||
static const uptr kAppAddr = 0x7000008000;
|
||||
static const uptr kShadowMask = ~0x7800000000;
|
||||
};
|
||||
|
||||
struct Mapping42 {
|
||||
static const uptr kShadowAddr = 0x10000;
|
||||
static const uptr kUnusedAddr = 0x8000000000;
|
||||
static const uptr kAppAddr = 0x3ff00008000;
|
||||
static const uptr kShadowMask = ~0x3c000000000;
|
||||
};
|
||||
|
||||
struct Mapping48 {
|
||||
static const uptr kShadowAddr = 0x10000;
|
||||
static const uptr kUnusedAddr = 0x8000000000;
|
||||
static const uptr kAppAddr = 0xffff00008000;
|
||||
static const uptr kShadowMask = ~0xfffff0000000;
|
||||
};
|
||||
|
||||
extern int vmaSize;
|
||||
# define DFSAN_RUNTIME_VMA 1
|
||||
#else
|
||||
# error "DFSan not supported for this platform!"
|
||||
#endif
|
||||
|
||||
enum MappingType {
|
||||
MAPPING_SHADOW_ADDR,
|
||||
#if defined(__x86_64__)
|
||||
MAPPING_ORIGIN_ADDR,
|
||||
#endif
|
||||
MAPPING_UNUSED_ADDR,
|
||||
MAPPING_APP_ADDR,
|
||||
MAPPING_SHADOW_MASK
|
||||
|
@ -53,7 +90,17 @@ uptr MappingImpl(void) {
|
|||
|
||||
template<int Type>
|
||||
uptr MappingArchImpl(void) {
|
||||
#ifdef __aarch64__
|
||||
switch (vmaSize) {
|
||||
case 39: return MappingImpl<Mapping39, Type>();
|
||||
case 42: return MappingImpl<Mapping42, Type>();
|
||||
case 48: return MappingImpl<Mapping48, Type>();
|
||||
}
|
||||
DCHECK(0);
|
||||
return 0;
|
||||
#else
|
||||
return MappingImpl<Mapping, Type>();
|
||||
#endif
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
|
@ -63,7 +110,11 @@ uptr ShadowAddr() {
|
|||
|
||||
ALWAYS_INLINE
|
||||
uptr OriginAddr() {
|
||||
#if defined(__x86_64__)
|
||||
return MappingArchImpl<MAPPING_ORIGIN_ADDR>();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
|
|
|
@ -123,6 +123,11 @@ static const Align MinOriginAlignment = Align(4);
|
|||
static const unsigned ArgTLSSize = 800;
|
||||
static const unsigned RetvalTLSSize = 800;
|
||||
|
||||
// External symbol to be used when generating the shadow address for
|
||||
// architectures with multiple VMAs. Instead of using a constant integer
|
||||
// the runtime will set the external mask based on the VMA range.
|
||||
const char DFSanExternShadowPtrMask[] = "__dfsan_shadow_ptr_mask";
|
||||
|
||||
// The -dfsan-preserve-alignment flag controls whether this pass assumes that
|
||||
// alignment requirements provided by the input IR are correct. For example,
|
||||
// if the input IR contains a load with alignment 8, this flag will cause
|
||||
|
@ -398,6 +403,7 @@ class DataFlowSanitizer {
|
|||
Constant *ArgOriginTLS;
|
||||
Constant *RetvalTLS;
|
||||
Constant *RetvalOriginTLS;
|
||||
Constant *ExternalShadowMask;
|
||||
FunctionType *DFSanUnionLoadFnTy;
|
||||
FunctionType *DFSanLoadLabelAndOriginFnTy;
|
||||
FunctionType *DFSanUnimplementedFnTy;
|
||||
|
@ -431,6 +437,7 @@ class DataFlowSanitizer {
|
|||
DFSanABIList ABIList;
|
||||
DenseMap<Value *, Function *> UnwrappedFnMap;
|
||||
AttrBuilder ReadOnlyNoneAttrs;
|
||||
bool DFSanRuntimeShadowMask = false;
|
||||
|
||||
Value *getShadowOffset(Value *Addr, IRBuilder<> &IRB);
|
||||
Value *getShadowAddress(Value *Addr, Instruction *Pos);
|
||||
|
@ -1006,11 +1013,6 @@ bool DataFlowSanitizer::init(Module &M) {
|
|||
Triple TargetTriple(M.getTargetTriple());
|
||||
const DataLayout &DL = M.getDataLayout();
|
||||
|
||||
if (TargetTriple.getOS() != Triple::Linux)
|
||||
report_fatal_error("unsupported operating system");
|
||||
if (TargetTriple.getArch() != Triple::x86_64)
|
||||
report_fatal_error("unsupported architecture");
|
||||
|
||||
Mod = &M;
|
||||
Ctx = &M.getContext();
|
||||
Int8Ptr = Type::getInt8PtrTy(*Ctx);
|
||||
|
@ -1022,9 +1024,27 @@ bool DataFlowSanitizer::init(Module &M) {
|
|||
ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0);
|
||||
ZeroOrigin = ConstantInt::getSigned(OriginTy, 0);
|
||||
|
||||
// TODO: these should be platform-specific and set in the switch-stmt below.
|
||||
ShadowBase = ConstantInt::get(IntptrTy, 0x100000008000LL);
|
||||
OriginBase = ConstantInt::get(IntptrTy, 0x200000008000LL);
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x600000000000LL);
|
||||
|
||||
switch (TargetTriple.getArch()) {
|
||||
case Triple::x86_64:
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x600000000000LL);
|
||||
break;
|
||||
case Triple::mips64:
|
||||
case Triple::mips64el:
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0xE000000000LL);
|
||||
break;
|
||||
case Triple::aarch64:
|
||||
case Triple::aarch64_be:
|
||||
// AArch64 supports multiple VMAs and the shadow mask is set at runtime.
|
||||
DFSanRuntimeShadowMask = true;
|
||||
break;
|
||||
default:
|
||||
report_fatal_error("unsupported triple");
|
||||
}
|
||||
|
||||
Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
|
||||
DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
|
||||
/*isVarArg=*/false);
|
||||
|
@ -1370,6 +1390,9 @@ bool DataFlowSanitizer::runImpl(Module &M) {
|
|||
|
||||
injectMetadataGlobals(M);
|
||||
|
||||
ExternalShadowMask =
|
||||
Mod->getOrInsertGlobal(DFSanExternShadowPtrMask, IntptrTy);
|
||||
|
||||
initializeCallbackFunctions(M);
|
||||
initializeRuntimeFunctions(M);
|
||||
|
||||
|
@ -1718,8 +1741,13 @@ void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
|
|||
Value *DataFlowSanitizer::getShadowOffset(Value *Addr, IRBuilder<> &IRB) {
|
||||
// Returns Addr & shadow_mask
|
||||
assert(Addr != RetvalTLS && "Reinstrumenting?");
|
||||
Value *ShadowPtrMaskValue;
|
||||
if (DFSanRuntimeShadowMask)
|
||||
ShadowPtrMaskValue = IRB.CreateLoad(IntptrTy, ExternalShadowMask);
|
||||
else
|
||||
ShadowPtrMaskValue = ShadowPtrMask;
|
||||
return IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy),
|
||||
IRB.CreatePtrToInt(ShadowPtrMask, IntptrTy));
|
||||
IRB.CreatePtrToInt(ShadowPtrMaskValue, IntptrTy));
|
||||
}
|
||||
|
||||
std::pair<Value *, Value *>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s
|
||||
target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
|
||||
target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
define i32 @test(i32 %a, i32* nocapture readonly %b) #0 {
|
||||
; CHECK: @"dfs$test"
|
||||
; CHECK: %[[RV:.*]] load{{.*}}__dfsan_shadow_ptr_mask
|
||||
; CHECK: ptrtoint i32* {{.*}} to i64
|
||||
; CHECK: and {{.*}}%[[RV:.*]]
|
||||
%1 = load i32, i32* %b, align 4
|
||||
%2 = add nsw i32 %1, %a
|
||||
ret i32 %2
|
||||
}
|
Loading…
Reference in New Issue