Skip to content

Commit

Permalink
Revert r267784, r267824 and r267830.
Browse files Browse the repository at this point in the history
It makes compiler-rt tests fail if the gold plugin is enabled.

Revert "Rework interface for bitset-using features to use a notion of LTO visibility."
Revert "Driver: only produce CFI -fvisibility= error when compiling."
Revert "clang/test/CodeGenCXX/cfi-blacklist.cpp: Exclude ms targets. They would be non-cfi."

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@267871 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
d0k committed Apr 28, 2016
1 parent 0b3d630 commit ce850d4
Show file tree
Hide file tree
Showing 35 changed files with 209 additions and 435 deletions.
36 changes: 13 additions & 23 deletions docs/ControlFlowIntegrity.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,13 @@ As currently implemented, all schemes rely on link-time optimization (LTO);
so it is required to specify ``-flto``, and the linker used must support LTO,
for example via the `gold plugin`_.

To allow the checks to be implemented efficiently, the program must
be structured such that certain object files are compiled with CFI
To allow the checks to be implemented efficiently, the program must be
structured such that certain object files are compiled with CFI
enabled, and are statically linked into the program. This may preclude
the use of shared libraries in some cases.

The compiler will only produce CFI checks for a class if it can infer hidden
LTO visibility for that class. LTO visibility is a property of a class that
is inferred from flags and attributes. For more details, see the documentation
for :doc:`LTO visibility <LTOVisibility>`.

The ``-fsanitize=cfi-{vcall,nvcall,derived-cast,unrelated-cast}`` flags
require that a ``-fvisibility=`` flag also be specified. This is because the
default visibility setting is ``-fvisibility=default``, which would disable
CFI checks for classes without visibility attributes. Most users will want
to specify ``-fvisibility=hidden``, which enables CFI checks for such classes.

Experimental support for :ref:`cross-DSO control flow integrity
<cfi-cross-dso>` exists that does not require classes to have hidden LTO
visibility. This cross-DSO support has unstable ABI at this time.
the use of shared libraries in some cases. Experimental support for
:ref:`cross-DSO control flow integrity <cfi-cross-dso>` exists that
does not have these requirements. This cross-DSO support has unstable
ABI at this time.

.. _gold plugin: http://llvm.org/docs/GoldPlugin.html

Expand Down Expand Up @@ -245,6 +233,11 @@ A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain
source files, functions and types using the ``src``, ``fun`` and ``type``
entity types.

In addition, if a type has a ``uuid`` attribute and the blacklist contains
the type entry ``attr:uuid``, CFI checks are suppressed for that type. This
allows all COM types to be easily blacklisted, which is useful as COM types
are typically defined outside of the linked program.

.. code-block:: bash
# Suppress checking for code in a file.
Expand All @@ -254,6 +247,8 @@ entity types.
fun:*MyFooBar*
# Ignore all types in the standard library.
type:std::*
# Ignore all types with a uuid attribute.
type:attr:uuid
.. _cfi-cross-dso:

Expand All @@ -265,11 +260,6 @@ flow integrity mode, which allows all CFI schemes listed above to
apply across DSO boundaries. As in the regular CFI, each DSO must be
built with ``-flto``.

Normally, CFI checks will only be performed for classes that have hidden LTO
visibility. With this flag enabled, the compiler will emit cross-DSO CFI
checks for all classes, except for those which appear in the CFI blacklist
or which use a ``no_sanitize`` attribute.

Design
======

Expand Down
111 changes: 0 additions & 111 deletions docs/LTOVisibility.rst

This file was deleted.

13 changes: 11 additions & 2 deletions docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1056,8 +1056,17 @@ are listed below.
.. option:: -fwhole-program-vtables

Enable whole-program vtable optimizations, such as single-implementation
devirtualization and virtual constant propagation, for classes with
:doc:`hidden LTO visibility <LTOVisibility>`. Requires ``-flto``.
devirtualization and virtual constant propagation. Requires ``-flto``.

By default, the compiler will assume that all type hierarchies are
closed except those in the ``std`` namespace, the ``stdext`` namespace
and classes with the ``__declspec(uuid())`` attribute.

.. option:: -fwhole-program-vtables-blacklist=path

Allows the user to specify the path to a list of additional classes to
blacklist from whole-program vtable optimizations. This list is in the
:ref:`CFI blacklist <cfi-blacklist>` format.

.. option:: -fno-assume-sane-operator-new

Expand Down
1 change: 0 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Using Clang as a Compiler
SanitizerStats
SanitizerSpecialCaseList
ControlFlowIntegrity
LTOVisibility
SafeStack
Modules
MSVCCompatibility
Expand Down
6 changes: 0 additions & 6 deletions include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1611,12 +1611,6 @@ def WeakRef : InheritableAttr {
let Documentation = [Undocumented];
}

def LTOVisibilityPublic : InheritableAttr {
let Spellings = [CXX11<"clang", "lto_visibility_public">];
let Subjects = SubjectList<[Record]>;
let Documentation = [LTOVisibilityDocs];
}

def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
// NOTE: If you add any additional spellings, ARMInterrupt's,
// MSP430Interrupt's and MipsInterrupt's spellings must match.
Expand Down
7 changes: 0 additions & 7 deletions include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -2380,10 +2380,3 @@ The ``ifunc`` attribute may only be used on a function declaration. A function
Not all targets support this attribute. ELF targets support this attribute when using binutils v2.20.1 or higher and glibc v2.11.1 or higher. Non-ELF targets currently do not support this attribute.
}];
}

def LTOVisibilityDocs : Documentation {
let Category = DocCatType;
let Content = [{
See :doc:`LTOVisibility`.
}];
}
3 changes: 0 additions & 3 deletions include/clang/Driver/CC1Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,6 @@ def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">,
def fprofile_instrument_use_path_EQ :
Joined<["-"], "fprofile-instrument-use-path=">,
HelpText<"Specify the profile path in PGO use compilation">;
def flto_visibility_public_std:
Flag<["-"], "flto-visibility-public-std">,
HelpText<"Use public LTO visibility for classes in std and stdext namespaces">;

//===----------------------------------------------------------------------===//
// Dependency Output Options
Expand Down
3 changes: 3 additions & 0 deletions include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,9 @@ def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Grou
Flags<[CC1Option]>,
HelpText<"Enables whole-program vtable optimization. Requires -flto">;
def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>;
def fwhole_program_vtables_blacklist_EQ : Joined<["-"], "fwhole-program-vtables-blacklist=">,
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Path to a blacklist file for whole-program vtable optimization">;
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Treat signed integer overflow as two's complement">;
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>,
Expand Down
4 changes: 0 additions & 4 deletions include/clang/Frontend/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,6 @@ CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
CODEGENOPT(WholeProgramVTables, 1, 0) ///< Whether to apply whole-program
/// vtable optimization.

/// Whether to use public LTO visibility for entities in std and stdext
/// namespaces. This is enabled by clang-cl's /MT and /MTd flags.
CODEGENOPT(LTOVisibilityPublicStd, 1, 0)

/// The user specified number of registers to be used for integral arguments,
/// or 0 if unspecified.
VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)
Expand Down
3 changes: 3 additions & 0 deletions include/clang/Frontend/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// \brief A list of all -fno-builtin-* function names (e.g., memset).
std::vector<std::string> NoBuiltinFuncs;

/// List of blacklist files for the whole-program vtable optimization feature.
std::vector<std::string> WholeProgramVTablesBlacklistFiles;

public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
Expand Down
9 changes: 2 additions & 7 deletions lib/CodeGen/CGClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2489,7 +2489,7 @@ void CodeGenFunction::EmitBitSetCodeForVCall(const CXXRecordDecl *RD,
llvm::Value *VTable,
SourceLocation Loc) {
if (CGM.getCodeGenOpts().WholeProgramVTables &&
CGM.HasHiddenLTOVisibility(RD)) {
!CGM.IsBitSetBlacklistedRecord(RD)) {
llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
llvm::Value *BitSetName =
Expand Down Expand Up @@ -2565,12 +2565,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
llvm::Value *VTable,
CFITypeCheckKind TCK,
SourceLocation Loc) {
if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
!CGM.HasHiddenLTOVisibility(RD))
return;

std::string TypeName = RD->getQualifiedNameAsString();
if (getContext().getSanitizerBlacklist().isBlacklistedType(TypeName))
if (CGM.IsBitSetBlacklistedRecord(RD))
return;

SanitizerScope SanScope(this);
Expand Down
57 changes: 26 additions & 31 deletions lib/CodeGen/CGVTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,43 +902,34 @@ void CodeGenModule::EmitDeferredVTables() {
DeferredVTables.clear();
}

bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
LinkageInfo LV = RD->getLinkageAndVisibility();
if (!isExternallyVisible(LV.getLinkage()))
return true;

if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>())
return false;
bool CodeGenModule::NeedVTableBitSets() {
return getCodeGenOpts().WholeProgramVTables ||
getLangOpts().Sanitize.has(SanitizerKind::CFIVCall) ||
getLangOpts().Sanitize.has(SanitizerKind::CFINVCall) ||
getLangOpts().Sanitize.has(SanitizerKind::CFIDerivedCast) ||
getLangOpts().Sanitize.has(SanitizerKind::CFIUnrelatedCast);
}

if (getTriple().isOSBinFormatCOFF()) {
if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>())
return false;
} else {
if (LV.getVisibility() != HiddenVisibility)
return false;
}
bool CodeGenModule::IsBitSetBlacklistedRecord(const CXXRecordDecl *RD) {
std::string TypeName = RD->getQualifiedNameAsString();
auto isInBlacklist = [&](const SanitizerBlacklist &BL) {
if (RD->hasAttr<UuidAttr>() && BL.isBlacklistedType("attr:uuid"))
return true;

if (getCodeGenOpts().LTOVisibilityPublicStd) {
const DeclContext *DC = RD;
while (1) {
auto *D = cast<Decl>(DC);
DC = DC->getParent();
if (isa<TranslationUnitDecl>(DC->getRedeclContext())) {
if (auto *ND = dyn_cast<NamespaceDecl>(D))
if (const IdentifierInfo *II = ND->getIdentifier())
if (II->isStr("std") || II->isStr("stdext"))
return false;
break;
}
}
}
return BL.isBlacklistedType(TypeName);
};

return true;
return isInBlacklist(WholeProgramVTablesBlacklist) ||
((LangOpts.Sanitize.has(SanitizerKind::CFIVCall) ||
LangOpts.Sanitize.has(SanitizerKind::CFINVCall) ||
LangOpts.Sanitize.has(SanitizerKind::CFIDerivedCast) ||
LangOpts.Sanitize.has(SanitizerKind::CFIUnrelatedCast)) &&
isInBlacklist(getContext().getSanitizerBlacklist()));
}

void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
const VTableLayout &VTLayout) {
if (!getCodeGenOpts().PrepareForLTO)
if (!NeedVTableBitSets())
return;

CharUnits PointerWidth =
Expand All @@ -947,8 +938,12 @@ void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
typedef std::pair<const CXXRecordDecl *, unsigned> BSEntry;
std::vector<BSEntry> BitsetEntries;
// Create a bit set entry for each address point.
for (auto &&AP : VTLayout.getAddressPoints())
for (auto &&AP : VTLayout.getAddressPoints()) {
if (IsBitSetBlacklistedRecord(AP.first.getBase()))
continue;

BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second));
}

// Sort the bit set entries for determinism.
std::sort(BitsetEntries.begin(), BitsetEntries.end(),
Expand Down
4 changes: 3 additions & 1 deletion lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
VMContext(M.getContext()), Types(*this), VTables(*this),
SanitizerMD(new SanitizerMetadata(*this)) {
SanitizerMD(new SanitizerMetadata(*this)),
WholeProgramVTablesBlacklist(CGO.WholeProgramVTablesBlacklistFiles,
C.getSourceManager()) {

// Initialize the type cache.
llvm::LLVMContext &LLVMContext = M.getContext();
Expand Down
Loading

0 comments on commit ce850d4

Please sign in to comment.