diff options
Diffstat (limited to 'clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index cdd40d2a6a2e..a0b5d9e4b096 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -128,7 +128,7 @@ static void resolveTopLevelMetadata(llvm::Function *Fn, // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes // they are referencing. - for (auto &BB : Fn->getBasicBlockList()) { + for (auto &BB : *Fn) { for (auto &I : BB) { if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) { auto *DILocal = DII->getVariable(); @@ -664,6 +664,12 @@ void CodeGenVTables::addRelativeComponent(ConstantArrayBuilder &builder, proxy->setVisibility(llvm::GlobalValue::HiddenVisibility); proxy->setComdat(module.getOrInsertComdat(rttiProxyName)); } + // Do not instrument the rtti proxies with hwasan to avoid a duplicate + // symbol error. Aliases generated by hwasan will retain the same namebut + // the addresses they are set to may have different tags from different + // compilation units. We don't run into this without hwasan because the + // proxies are in comdat groups, but those aren't propagated to the alias. + RemoveHwasanMetadata(proxy); } target = proxy; } @@ -672,15 +678,23 @@ void CodeGenVTables::addRelativeComponent(ConstantArrayBuilder &builder, /*position=*/vtableAddressPoint); } -bool CodeGenVTables::useRelativeLayout() const { +static bool UseRelativeLayout(const CodeGenModule &CGM) { return CGM.getTarget().getCXXABI().isItaniumFamily() && CGM.getItaniumVTableContext().isRelativeLayout(); } +bool CodeGenVTables::useRelativeLayout() const { + return UseRelativeLayout(CGM); +} + +llvm::Type *CodeGenModule::getVTableComponentType() const { + if (UseRelativeLayout(*this)) + return Int32Ty; + return Int8PtrTy; +} + llvm::Type *CodeGenVTables::getVTableComponentType() const { - if (useRelativeLayout()) - return CGM.Int32Ty; - return CGM.Int8PtrTy; + return CGM.getVTableComponentType(); } static void AddPointerLayoutOffset(const CodeGenModule &CGM, @@ -895,7 +909,7 @@ llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable( if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage) Linkage = llvm::GlobalVariable::InternalLinkage; - unsigned Align = CGM.getDataLayout().getABITypeAlignment(VTType); + llvm::Align Align = CGM.getDataLayout().getABITypeAlign(VTType); // Create the variable that will hold the construction vtable. llvm::GlobalVariable *VTable = @@ -921,12 +935,33 @@ llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable( CGM.EmitVTableTypeMetadata(RD, VTable, *VTLayout.get()); - if (UsingRelativeLayout && !VTable->isDSOLocal()) - GenerateRelativeVTableAlias(VTable, OutName); + if (UsingRelativeLayout) { + RemoveHwasanMetadata(VTable); + if (!VTable->isDSOLocal()) + GenerateRelativeVTableAlias(VTable, OutName); + } return VTable; } +// Ensure this vtable is not instrumented by hwasan. That is, a global alias is +// not generated for it. This is mainly used by the relative-vtables ABI where +// vtables instead contain 32-bit offsets between the vtable and function +// pointers. Hwasan is disabled for these vtables for now because the tag in a +// vtable pointer may fail the overflow check when resolving 32-bit PLT +// relocations. A future alternative for this would be finding which usages of +// the vtable can continue to use the untagged hwasan value without any loss of +// value in hwasan. +void CodeGenVTables::RemoveHwasanMetadata(llvm::GlobalValue *GV) const { + if (CGM.getLangOpts().Sanitize.has(SanitizerKind::HWAddress)) { + llvm::GlobalValue::SanitizerMetadata Meta; + if (GV->hasSanitizerMetadata()) + Meta = GV->getSanitizerMetadata(); + Meta.NoHWAddress = true; + GV->setSanitizerMetadata(Meta); + } +} + // If the VTable is not dso_local, then we will not be able to indicate that // the VTable does not need a relocation and move into rodata. A frequent // time this can occur is for classes that should be made public from a DSO @@ -1254,8 +1289,7 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD, if (!getCodeGenOpts().LTOUnit) return; - CharUnits PointerWidth = - Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); + CharUnits ComponentWidth = GetTargetTypeStoreSize(getVTableComponentType()); typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint; std::vector<AddressPoint> AddressPoints; @@ -1293,7 +1327,7 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD, ArrayRef<VTableComponent> Comps = VTLayout.vtable_components(); for (auto AP : AddressPoints) { // Create type metadata for the address point. - AddVTableTypeMetadata(VTable, PointerWidth * AP.second, AP.first); + AddVTableTypeMetadata(VTable, ComponentWidth * AP.second, AP.first); // The class associated with each address point could also potentially be // used for indirect calls via a member function pointer, so we need to @@ -1306,7 +1340,7 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD, Context.getMemberPointerType( Comps[I].getFunctionDecl()->getType(), Context.getRecordType(AP.first).getTypePtr())); - VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD); + VTable->addTypeMetadata((ComponentWidth * I).getQuantity(), MD); } } |