[PATCH] D58102: Support X86 Control-flow Enforcement Technology (CET) in LLD
Xiang Zhang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 01:36:54 PDT 2019
xiangzhangllvm added a comment.
I do this changes in my local:
I do the feature collection work in the GnuPropertySection's Constructor which will be called in createSyntheticSections().
For the SPlt, I keep its generation condition, because the GnuPropertySection's Constructor will set the Config->SPltSectionEnable.
1 diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
2 index 7628df0..d5217bd 100644
3 --- a/ELF/Driver.cpp
4 +++ b/ELF/Driver.cpp
5 @@ -1626,14 +1626,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
6 return S->Name.startswith(".debug") || S->Name.startswith(".zdebug");
7 });
8
9 - // Merge aggregate metadata sections like .note.gnu.property that should be
10 - // found across all relocated files and reproduced once. But Until now, the
11 - // emitAggregateMetadata just deal with the X86Feature1AND info, and only X86_64, i386
12 - // support the X86Feature1AND.
13 - if ((Config->EMachine == EM_X86_64 || Config->EMachine == EM_386)
14 - && (Config->AutoCET || Config->ForceCET))
15 - mergeAggregateMetadata();
16 -
17 Config->EFlags = Target->calcEFlags();
18
19 if (Config->EMachine == EM_ARM) {
20 diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
21 index bb1c5d3..4ed1a72 100644
22 --- a/ELF/SyntheticSections.cpp
23 +++ b/ELF/SyntheticSections.cpp
24 @@ -297,11 +297,11 @@ void GnuPropertySection::writeTo(uint8_t *Buf) {
25 write32(Buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
26 memcpy(Buf + 12, "GNU", 4); // Name string
27
28 - // To Be Dnone
29 + // To Be Done
30 // Now we only supported X86_FEATURE_1_AND in .note.gnu.property, so we fix
31 // the Feature type to GNU_PROPERTY_X86_FEATURE_1_AND, it should be changed
32 // when we try to fix other feature types in .note.gnu.property.
33 - DescBuf = Buf + 16;
34 + uint8_t *DescBuf = Buf + 16;
35 write32(DescBuf, GNU_PROPERTY_X86_FEATURE_1_AND); // Feature type
36 write32(DescBuf + 4, 4); // Feature size
37 write32(DescBuf + 8, Feature1AND); // Feature flags
38 @@ -311,20 +311,17 @@ size_t GnuPropertySection::getSize() const {
39 return 16 + DescSize;
40 }
41
42 -void GnuPropertySection::setDescSize() {
43 - DescSize = getDescSize();
44 +bool GnuPropertySection::empty() const {
45 + uint32_t Feature = getFeature();
46 + return Feature == 0x0;
47 }
48
49 -// To Be Dnone
50 -// Now we only supported X86_FEATURE_1_AND in .note.gnu.property, so we just
51 -// get the feature of GNU_PROPERTY_X86_FEATURE_1_AND property, it should be
52 -// changed when we try to support other feature types in .note.gnu.property.
53 -uint32_t GnuPropertySection::getFeature() {
54 - return Config->X86Feature1AND;
55 +void GnuPropertySection::setDescSize() {
56 + DescSize = getDescSize();
57 }
58
59 void GnuPropertySection::setFeature() {
60 - Feature1AND = getFeature();
61 + Feature1AND = mergeAggregateMetadata();
62 }
63
64 GnuPropertySection::GnuPropertySection()
65 @@ -3054,12 +3051,11 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
66
67 // Get the CFProtection properties from a X86F1AND section. The X86F1AND section
68 // info can refert the comment of function findGNUPropertyX86Feature1AND.
69 -static void readGNUPropertyX86Feature1AND(InputSectionBase *S,
70 - Configuration *Config,
71 - unsigned X86F1ANDDescLoca) {
72 +static uint32_t readGNUPropertyX86Feature1AND(InputSectionBase *S,
73 + Configuration *Config,
74 + unsigned X86F1ANDDescLoca) {
75 auto Data = S->getDataAs<uint32_t>();
76 unsigned &Offset = X86F1ANDDescLoca;
77 -
78 unsigned pr_typeIndex = 0; // Offset of pr_type from start of 'desc'
79 unsigned pr_dataIndex = 2; // Offset of pr_data from start of 'desc'
80
81 @@ -3067,14 +3063,7 @@ static void readGNUPropertyX86Feature1AND(InputSectionBase *S,
82 if (Data[Offset + pr_typeIndex] != GNU_PROPERTY_X86_FEATURE_1_AND)
83 error("There must be GNU_PROPERTY_X86_FEATURE_1_AND note!");
84 uint32_t Flags = Data[Offset + pr_dataIndex];
85 -
86 - // GNU_PROPERTY_X86_FEATURE_1_AND: Its pr_data field contains a 4-byte
87 - // integer. A bit in the output pr_data field is set only if it is set
88 - // in all relocatable input pr_data fields.
89 - Config->X86Feature1AND &= Flags;
90 -
91 - Config->SPltSectionEnable = Config->X86Feature1AND
92 - & GNU_PROPERTY_X86_FEATURE_1_IBT;
93 + return Flags;
94 }
95
96 // Get the position of desc with GNU_PROPERTY_X86_FEATURE_1_AND.
97 @@ -3219,11 +3208,11 @@ static bool findGNUPropertyX86Feature1AND(InputSectionBase *S,
98 // other 'desc' in the .note.gnu.propery section. Here we first find all the
99 // X86Feature1AND info section, then delete them, and finally rebuild the
100 // X86Feature1AND section in the Writer if necessary.
101 -void elf::mergeAggregateMetadata() {
102 +uint32_t elf::mergeAggregateMetadata() {
103 decltype (InputSections) X86F1ANDSections;
104 bool IsAllFileF1AND = true;
105 + uint32_t X86Feature1AND = 0xFFFFFFFF;
106 Config->SPltSectionEnable = true;
107 - Config->X86Feature1AND = 0xFFFFFFFF;
108 for (InputFile *F : ObjectFiles) {
109 unsigned X86F1ANDDescLoca = 0;
110 auto I = llvm::find_if(InputSections, [&](InputSectionBase *S) {
111 @@ -3242,12 +3231,16 @@ void elf::mergeAggregateMetadata() {
112 if (Config->ForceCET)
113 error(toString(F) + "must enable CET when using --force-cet");
114 } else {
115 - readGNUPropertyX86Feature1AND(*I, Config, X86F1ANDDescLoca);
116 + uint32_t Feature = readGNUPropertyX86Feature1AND(*I, Config,
117 + X86F1ANDDescLoca);
118 + X86Feature1AND &= Feature;
119 }
120 }
121 if (!IsAllFileF1AND) {
122 Config->SPltSectionEnable = false;
123 - Config->X86Feature1AND = 0x0;
124 + X86Feature1AND = 0x0;
125 + } else {
126 + Config->SPltSectionEnable = X86Feature1AND & GNU_PROPERTY_X86_FEATURE_1_IBT;
127 }
128
129 // The resulting .note.gnu.property section will be created by the Writer
130 @@ -3269,6 +3262,8 @@ void elf::mergeAggregateMetadata() {
131 else
132 return false;
133 });
134 +
135 + return X86Feature1AND;
136 }
137
138 template <class ELFT> void elf::splitSections() {
139 diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h
140 index f148281..e369ef1 100644
141 --- a/ELF/SyntheticSections.h
142 +++ b/ELF/SyntheticSections.h
143 @@ -149,19 +149,19 @@ public:
144 GnuPropertySection();
145 void writeTo(uint8_t *Buf) override;
146 size_t getSize() const override;
147 + bool empty() const override;
148
149 - // To Be Dnone
150 + // To Be Done
151 // Now we only supported X86_FEATURE_1_AND in .note.gnu.property, so we fix
152 - // the DescSize to one Desciption size, it may be mare than one Desciption
153 + // the DescSize to one Description size, it may be more than one Description
154 // when we try to fix other feature types in .note.gnu.property.
155 - size_t getDescSize() {return 16;}
156 + size_t getDescSize() { return 16; }
157 void setDescSize();
158 - uint32_t getFeature();
159 + uint32_t getFeature() const { return Feature1AND; }
160 void setFeature();
161
162 private:
163 size_t DescSize;
164 - uint8_t *DescBuf;
165 uint32_t Feature1AND;
166 };
167
168 @@ -1033,7 +1033,7 @@ private:
169
170 InputSection *createInterpSection();
171 MergeInputSection *createCommentSection();
172 -void mergeAggregateMetadata();
173 +uint32_t mergeAggregateMetadata();
174 template <class ELFT> void splitSections();
175 void mergeSections();
176
177 diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
178 index 11639e5..0deebb9 100644
179 --- a/ELF/Writer.cpp
180 +++ b/ELF/Writer.cpp
181 @@ -335,6 +335,16 @@ template <class ELFT> static void createSyntheticSections() {
182 Add(Sec);
183 }
184
185 + // Merge aggregate metadata sections like .note.gnu.property that should be
186 + // found across all relocated files and reproduced once. But Until now, the
187 + // emitAggregateMetadata just deal with the X86Feature1AND info, and only
188 + // X86_64, i386 support the X86Feature1AND.
189 + if ((Config->EMachine == EM_X86_64 || Config->EMachine == EM_386)
190 + && (Config->AutoCET || Config->ForceCET)) {
191 + In.GnuProperty = make<GnuPropertySection>();
192 + Add(In.GnuProperty);
193 + }
194 +
195 if (Config->HasDynSymTab) {
196 In.DynSymTab = make<SymbolTableSection<ELFT>>(*In.DynStrTab);
197 Add(In.DynSymTab);
198 @@ -416,16 +426,12 @@ template <class ELFT> static void createSyntheticSections() {
199 Add(In.Plt);
200 In.Iplt = make<PltSection>(true);
201 Add(In.Iplt);
202 +
203 if (Config->SPltSectionEnable) {
204 In.Splt = make<SPltSection>();
205 Add(In.Splt);
206 }
207
208 - if (Config->X86Feature1AND) {
209 - In.GnuProperty = make<GnuPropertySection>();
210 - Add(In.GnuProperty);
211 - }
212 -
213 // .note.GNU-stack is always added when we are creating a re-linkable
214 // object file. Other linkers are using the presence of this marker
215 // section to control the executable-ness of the stack area, but that
Repository:
rLLD LLVM Linker
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D58102/new/
https://reviews.llvm.org/D58102
More information about the llvm-commits
mailing list