1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
//===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This contains code dealing with C++ code generation of virtual tables.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H
#define LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H
#include "clang/AST/BaseSubobject.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/VTableBuilder.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/GlobalVariable.h"
namespace clang {
class CXXRecordDecl;
namespace CodeGen {
class CodeGenModule;
class ConstantArrayBuilder;
class ConstantStructBuilder;
class CodeGenVTables {
CodeGenModule &CGM;
VTableContextBase *VTContext;
/// VTableAddressPointsMapTy - Address points for a single vtable.
typedef VTableLayout::AddressPointsMapTy VTableAddressPointsMapTy;
typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
/// SubVTTIndicies - Contains indices into the various sub-VTTs.
SubVTTIndiciesMapTy SubVTTIndicies;
typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t>
SecondaryVirtualPointerIndicesMapTy;
/// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
/// indices.
SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
/// Cache for the pure virtual member call function.
llvm::Constant *PureVirtualFn = nullptr;
/// Cache for the deleted virtual member call function.
llvm::Constant *DeletedVirtualFn = nullptr;
/// Get the address of a thunk and emit it if necessary.
llvm::Constant *maybeEmitThunk(GlobalDecl GD,
const ThunkInfo &ThunkAdjustments,
bool ForVTable);
void addVTableComponent(ConstantArrayBuilder &builder,
const VTableLayout &layout, unsigned componentIndex,
llvm::Constant *rtti, unsigned &nextVTableThunkIndex,
unsigned vtableAddressPoint,
bool vtableHasLocalLinkage);
/// Add a 32-bit offset to a component relative to the vtable when using the
/// relative vtables ABI. The array builder points to the start of the vtable.
void addRelativeComponent(ConstantArrayBuilder &builder,
llvm::Constant *component,
unsigned vtableAddressPoint,
bool vtableHasLocalLinkage,
bool isCompleteDtor) const;
/// Create a dso_local stub that will be used for a relative reference in the
/// relative vtable layout. This stub will just be a tail call to the original
/// function and propagate any function attributes from the original. If the
/// original function is already dso_local, the original is returned instead
/// and a stub is not created.
llvm::Function *
getOrCreateRelativeStub(llvm::Function *func,
llvm::GlobalValue::LinkageTypes stubLinkage,
bool isCompleteDtor) const;
bool useRelativeLayout() const;
llvm::Type *getVTableComponentType() const;
public:
/// Add vtable components for the given vtable layout to the given
/// global initializer.
void createVTableInitializer(ConstantStructBuilder &builder,
const VTableLayout &layout, llvm::Constant *rtti,
bool vtableHasLocalLinkage);
CodeGenVTables(CodeGenModule &CGM);
ItaniumVTableContext &getItaniumVTableContext() {
return *cast<ItaniumVTableContext>(VTContext);
}
const ItaniumVTableContext &getItaniumVTableContext() const {
return *cast<ItaniumVTableContext>(VTContext);
}
MicrosoftVTableContext &getMicrosoftVTableContext() {
return *cast<MicrosoftVTableContext>(VTContext);
}
/// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
/// given record decl.
uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
/// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
/// virtual pointer for the given subobject is located.
uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
BaseSubobject Base);
/// GenerateConstructionVTable - Generate a construction vtable for the given
/// base subobject.
llvm::GlobalVariable *
GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
bool BaseIsVirtual,
llvm::GlobalVariable::LinkageTypes Linkage,
VTableAddressPointsMapTy& AddressPoints);
/// GetAddrOfVTT - Get the address of the VTT for the given record decl.
llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
/// EmitVTTDefinition - Emit the definition of the given vtable.
void EmitVTTDefinition(llvm::GlobalVariable *VTT,
llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD);
/// EmitThunks - Emit the associated thunks for the given global decl.
void EmitThunks(GlobalDecl GD);
/// GenerateClassData - Generate all the class data required to be
/// generated upon definition of a KeyFunction. This includes the
/// vtable, the RTTI data structure (if RTTI is enabled) and the VTT
/// (if the class has virtual bases).
void GenerateClassData(const CXXRecordDecl *RD);
bool isVTableExternal(const CXXRecordDecl *RD);
/// Returns the type of a vtable with the given layout. Normally a struct of
/// arrays of pointers, with one struct element for each vtable in the vtable
/// group.
llvm::Type *getVTableType(const VTableLayout &layout);
/// Generate a public facing alias for the vtable and make the vtable either
/// hidden or private. The alias will have the original linkage and visibility
/// of the vtable. This is used for cases under the relative vtables ABI
/// when a vtable may not be dso_local.
void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable,
llvm::StringRef AliasNameRef);
/// Specify a global should not be instrumented with hwasan.
void RemoveHwasanMetadata(llvm::GlobalValue *GV) const;
};
} // end namespace CodeGen
} // end namespace clang
#endif
|