Skip to content

Commit 3afb266

Browse files
committed
Re-apply r267784, r267824 and r267830.
I have updated the compiler-rt tests. llvm-svn: 267903
1 parent f730de6 commit 3afb266

35 files changed

+435
-209
lines changed

clang/docs/ControlFlowIntegrity.rst

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,25 @@ As currently implemented, all schemes rely on link-time optimization (LTO);
2525
so it is required to specify ``-flto``, and the linker used must support LTO,
2626
for example via the `gold plugin`_.
2727

28-
To allow the checks to be implemented efficiently, the program must be
29-
structured such that certain object files are compiled with CFI
28+
To allow the checks to be implemented efficiently, the program must
29+
be structured such that certain object files are compiled with CFI
3030
enabled, and are statically linked into the program. This may preclude
31-
the use of shared libraries in some cases. Experimental support for
32-
:ref:`cross-DSO control flow integrity <cfi-cross-dso>` exists that
33-
does not have these requirements. This cross-DSO support has unstable
34-
ABI at this time.
31+
the use of shared libraries in some cases.
32+
33+
The compiler will only produce CFI checks for a class if it can infer hidden
34+
LTO visibility for that class. LTO visibility is a property of a class that
35+
is inferred from flags and attributes. For more details, see the documentation
36+
for :doc:`LTO visibility <LTOVisibility>`.
37+
38+
The ``-fsanitize=cfi-{vcall,nvcall,derived-cast,unrelated-cast}`` flags
39+
require that a ``-fvisibility=`` flag also be specified. This is because the
40+
default visibility setting is ``-fvisibility=default``, which would disable
41+
CFI checks for classes without visibility attributes. Most users will want
42+
to specify ``-fvisibility=hidden``, which enables CFI checks for such classes.
43+
44+
Experimental support for :ref:`cross-DSO control flow integrity
45+
<cfi-cross-dso>` exists that does not require classes to have hidden LTO
46+
visibility. This cross-DSO support has unstable ABI at this time.
3547

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

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

236-
In addition, if a type has a ``uuid`` attribute and the blacklist contains
237-
the type entry ``attr:uuid``, CFI checks are suppressed for that type. This
238-
allows all COM types to be easily blacklisted, which is useful as COM types
239-
are typically defined outside of the linked program.
240-
241248
.. code-block:: bash
242249
243250
# Suppress checking for code in a file.
@@ -247,8 +254,6 @@ are typically defined outside of the linked program.
247254
fun:*MyFooBar*
248255
# Ignore all types in the standard library.
249256
type:std::*
250-
# Ignore all types with a uuid attribute.
251-
type:attr:uuid
252257
253258
.. _cfi-cross-dso:
254259

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

268+
Normally, CFI checks will only be performed for classes that have hidden LTO
269+
visibility. With this flag enabled, the compiler will emit cross-DSO CFI
270+
checks for all classes, except for those which appear in the CFI blacklist
271+
or which use a ``no_sanitize`` attribute.
272+
263273
Design
264274
======
265275

clang/docs/LTOVisibility.rst

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
==============
2+
LTO Visibility
3+
==============
4+
5+
*LTO visibility* is a property of an entity that specifies whether it can be
6+
referenced from outside the current LTO unit. A *linkage unit* is a set of
7+
translation units linked together into an executable or DSO, and a linkage
8+
unit's *LTO unit* is the subset of the linkage unit that is linked together
9+
using link-time optimization; in the case where LTO is not being used, the
10+
linkage unit's LTO unit is empty. Each linkage unit has only a single LTO unit.
11+
12+
The LTO visibility of a class is used by the compiler to determine which
13+
classes the virtual function call optimization and control flow integrity
14+
features apply to. These features use whole-program information, so they
15+
require the entire class hierarchy to be visible in order to work correctly.
16+
17+
If any translation unit in the program uses either of the virtual function
18+
call optimization or control flow integrity features, it is effectively an
19+
ODR violation to define a class with hidden LTO visibility in multiple linkage
20+
units. A class with public LTO visibility may be defined in multiple linkage
21+
units, but the tradeoff is that the virtual function call optimization and
22+
control flow integrity features can only be applied to classes with hidden LTO
23+
visibility. A class's LTO visibility is treated as an ODR-relevant property
24+
of its definition, so it must be consistent between translation units.
25+
26+
In translation units built with LTO, LTO visibility is based on symbol
27+
visibility or, on the Windows platform, the dllimport and dllexport
28+
attributes. When targeting non-Windows platforms, classes with a visibility
29+
other than hidden visibility receive public LTO visibility. When targeting
30+
Windows, classes with dllimport or dllexport attributes receive public LTO
31+
visibility. All other classes receive hidden LTO visibility. Classes with
32+
internal linkage (e.g. classes declared in unnamed namespaces) also receive
33+
hidden LTO visibility.
34+
35+
A class defined in a translation unit built without LTO receives public
36+
LTO visibility regardless of its object file visibility, linkage or other
37+
attributes.
38+
39+
This mechanism will produce the correct result in most cases, but there are
40+
two cases where it may wrongly infer hidden LTO visibility.
41+
42+
1. As a corollary of the above rules, if a linkage unit is produced from a
43+
combination of LTO object files and non-LTO object files, any hidden
44+
visibility class defined in both a translation unit built with LTO and
45+
a translation unit built without LTO must be defined with public LTO
46+
visibility in order to avoid an ODR violation.
47+
48+
2. Some ABIs provide the ability to define an abstract base class without
49+
visibility attributes in multiple linkage units and have virtual calls
50+
to derived classes in other linkage units work correctly. One example of
51+
this is COM on Windows platforms. If the ABI allows this, any base class
52+
used in this way must be defined with public LTO visibility.
53+
54+
Classes that fall into either of these categories can be marked up with the
55+
``[[clang::lto_visibility_public]]`` attribute. To specifically handle the
56+
COM case, classes with the ``__declspec(uuid())`` attribute receive public
57+
LTO visibility. On Windows platforms, clang-cl's ``/MT`` and ``/MTd``
58+
flags statically link the program against a prebuilt standard library;
59+
these flags imply public LTO visibility for every class declared in the
60+
``std`` and ``stdext`` namespaces.
61+
62+
Example
63+
=======
64+
65+
The following example shows how LTO visibility works in practice in several
66+
cases involving two linkage units, ``main`` and ``dso.so``.
67+
68+
.. code-block:: none
69+
70+
+-----------------------------------------------------------+ +----------------------------------------------------+
71+
| main (clang++ -fvisibility=hidden): | | dso.so (clang++ -fvisibility=hidden): |
72+
| | | |
73+
| +-----------------------------------------------------+ | | struct __attribute__((visibility("default"))) C { |
74+
| | LTO unit (clang++ -fvisibility=hidden -flto): | | | virtual void f(); |
75+
| | | | | } |
76+
| | struct A { ... }; | | | void C::f() {} |
77+
| | struct [[clang::lto_visibility_public]] B { ... }; | | | struct D { |
78+
| | struct __attribute__((visibility("default"))) C { | | | virtual void g() = 0; |
79+
| | virtual void f(); | | | }; |
80+
| | }; | | | struct E : D { |
81+
| | struct [[clang::lto_visibility_public]] D { | | | virtual void g() { ... } |
82+
| | virtual void g() = 0; | | | }; |
83+
| | }; | | | __attribute__(visibility("default"))) D *mkE() { |
84+
| | | | | return new E; |
85+
| +-----------------------------------------------------+ | | } |
86+
| | | |
87+
| struct B { ... }; | +----------------------------------------------------+
88+
| |
89+
+-----------------------------------------------------------+
90+
91+
We will now describe the LTO visibility of each of the classes defined in
92+
these linkage units.
93+
94+
Class ``A`` is not defined outside of ``main``'s LTO unit, so it can have
95+
hidden LTO visibility. This is inferred from the object file visibility
96+
specified on the command line.
97+
98+
Class ``B`` is defined in ``main``, both inside and outside its LTO unit. The
99+
definition outside the LTO unit has public LTO visibility, so the definition
100+
inside the LTO unit must also have public LTO visibility in order to avoid
101+
an ODR violation.
102+
103+
Class ``C`` is defined in both ``main`` and ``dso.so`` and therefore must
104+
have public LTO visibility. This is correctly inferred from the ``visibility``
105+
attribute.
106+
107+
Class ``D`` is an abstract base class with a derived class ``E`` defined
108+
in ``dso.so``. This is an example of the COM scenario; the definition of
109+
``D`` in ``main``'s LTO unit must have public LTO visibility in order to be
110+
compatible with the definition of ``D`` in ``dso.so``, which is observable
111+
by calling the function ``mkE``.

clang/docs/UsersManual.rst

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,17 +1056,8 @@ are listed below.
10561056
.. option:: -fwhole-program-vtables
10571057

10581058
Enable whole-program vtable optimizations, such as single-implementation
1059-
devirtualization and virtual constant propagation. Requires ``-flto``.
1060-
1061-
By default, the compiler will assume that all type hierarchies are
1062-
closed except those in the ``std`` namespace, the ``stdext`` namespace
1063-
and classes with the ``__declspec(uuid())`` attribute.
1064-
1065-
.. option:: -fwhole-program-vtables-blacklist=path
1066-
1067-
Allows the user to specify the path to a list of additional classes to
1068-
blacklist from whole-program vtable optimizations. This list is in the
1069-
:ref:`CFI blacklist <cfi-blacklist>` format.
1059+
devirtualization and virtual constant propagation, for classes with
1060+
:doc:`hidden LTO visibility <LTOVisibility>`. Requires ``-flto``.
10701061

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

clang/docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Using Clang as a Compiler
3131
SanitizerStats
3232
SanitizerSpecialCaseList
3333
ControlFlowIntegrity
34+
LTOVisibility
3435
SafeStack
3536
Modules
3637
MSVCCompatibility

clang/include/clang/Basic/Attr.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,12 @@ def WeakRef : InheritableAttr {
16111611
let Documentation = [Undocumented];
16121612
}
16131613

1614+
def LTOVisibilityPublic : InheritableAttr {
1615+
let Spellings = [CXX11<"clang", "lto_visibility_public">];
1616+
let Subjects = SubjectList<[Record]>;
1617+
let Documentation = [LTOVisibilityDocs];
1618+
}
1619+
16141620
def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
16151621
// NOTE: If you add any additional spellings, ARMInterrupt's,
16161622
// MSP430Interrupt's and MipsInterrupt's spellings must match.

clang/include/clang/Basic/AttrDocs.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,3 +2380,10 @@ The ``ifunc`` attribute may only be used on a function declaration. A function
23802380
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.
23812381
}];
23822382
}
2383+
2384+
def LTOVisibilityDocs : Documentation {
2385+
let Category = DocCatType;
2386+
let Content = [{
2387+
See :doc:`LTOVisibility`.
2388+
}];
2389+
}

clang/include/clang/Driver/CC1Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,9 @@ def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">,
282282
def fprofile_instrument_use_path_EQ :
283283
Joined<["-"], "fprofile-instrument-use-path=">,
284284
HelpText<"Specify the profile path in PGO use compilation">;
285+
def flto_visibility_public_std:
286+
Flag<["-"], "flto-visibility-public-std">,
287+
HelpText<"Use public LTO visibility for classes in std and stdext namespaces">;
285288

286289
//===----------------------------------------------------------------------===//
287290
// Dependency Output Options

clang/include/clang/Driver/Options.td

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,9 +1152,6 @@ def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Grou
11521152
Flags<[CC1Option]>,
11531153
HelpText<"Enables whole-program vtable optimization. Requires -flto">;
11541154
def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>;
1155-
def fwhole_program_vtables_blacklist_EQ : Joined<["-"], "fwhole-program-vtables-blacklist=">,
1156-
Group<f_Group>, Flags<[CC1Option]>,
1157-
HelpText<"Path to a blacklist file for whole-program vtable optimization">;
11581155
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>,
11591156
HelpText<"Treat signed integer overflow as two's complement">;
11601157
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>,

clang/include/clang/Frontend/CodeGenOptions.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
187187
CODEGENOPT(WholeProgramVTables, 1, 0) ///< Whether to apply whole-program
188188
/// vtable optimization.
189189

190+
/// Whether to use public LTO visibility for entities in std and stdext
191+
/// namespaces. This is enabled by clang-cl's /MT and /MTd flags.
192+
CODEGENOPT(LTOVisibilityPublicStd, 1, 0)
193+
190194
/// The user specified number of registers to be used for integral arguments,
191195
/// or 0 if unspecified.
192196
VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)

clang/include/clang/Frontend/CodeGenOptions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,6 @@ class CodeGenOptions : public CodeGenOptionsBase {
199199
/// \brief A list of all -fno-builtin-* function names (e.g., memset).
200200
std::vector<std::string> NoBuiltinFuncs;
201201

202-
/// List of blacklist files for the whole-program vtable optimization feature.
203-
std::vector<std::string> WholeProgramVTablesBlacklistFiles;
204-
205202
public:
206203
// Define accessors/mutators for code generation options of enumeration type.
207204
#define CODEGENOPT(Name, Bits, Default)

0 commit comments

Comments
 (0)