File: | lib/MC/MCParser/DarwinAsmParser.cpp |
Warning: | line 1081, column 16 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | ||||
9 | #include "llvm/ADT/STLExtras.h" | |||
10 | #include "llvm/ADT/SmallVector.h" | |||
11 | #include "llvm/ADT/StringRef.h" | |||
12 | #include "llvm/ADT/StringSwitch.h" | |||
13 | #include "llvm/ADT/Triple.h" | |||
14 | #include "llvm/ADT/Twine.h" | |||
15 | #include "llvm/BinaryFormat/MachO.h" | |||
16 | #include "llvm/MC/MCContext.h" | |||
17 | #include "llvm/MC/MCDirectives.h" | |||
18 | #include "llvm/MC/MCObjectFileInfo.h" | |||
19 | #include "llvm/MC/MCParser/MCAsmLexer.h" | |||
20 | #include "llvm/MC/MCParser/MCAsmParser.h" | |||
21 | #include "llvm/MC/MCParser/MCAsmParserExtension.h" | |||
22 | #include "llvm/MC/MCSectionMachO.h" | |||
23 | #include "llvm/MC/MCStreamer.h" | |||
24 | #include "llvm/MC/MCSymbol.h" | |||
25 | #include "llvm/MC/SectionKind.h" | |||
26 | #include "llvm/Support/FileSystem.h" | |||
27 | #include "llvm/Support/MemoryBuffer.h" | |||
28 | #include "llvm/Support/SMLoc.h" | |||
29 | #include "llvm/Support/SourceMgr.h" | |||
30 | #include "llvm/Support/raw_ostream.h" | |||
31 | #include <algorithm> | |||
32 | #include <cstddef> | |||
33 | #include <cstdint> | |||
34 | #include <string> | |||
35 | #include <system_error> | |||
36 | #include <utility> | |||
37 | ||||
38 | using namespace llvm; | |||
39 | ||||
40 | namespace { | |||
41 | ||||
42 | /// Implementation of directive handling which is shared across all | |||
43 | /// Darwin targets. | |||
44 | class DarwinAsmParser : public MCAsmParserExtension { | |||
45 | template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)> | |||
46 | void addDirectiveHandler(StringRef Directive) { | |||
47 | MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( | |||
48 | this, HandleDirective<DarwinAsmParser, HandlerMethod>); | |||
49 | getParser().addDirectiveHandler(Directive, Handler); | |||
50 | } | |||
51 | ||||
52 | bool parseSectionSwitch(StringRef Segment, StringRef Section, | |||
53 | unsigned TAA = 0, unsigned ImplicitAlign = 0, | |||
54 | unsigned StubSize = 0); | |||
55 | ||||
56 | SMLoc LastVersionDirective; | |||
57 | ||||
58 | public: | |||
59 | DarwinAsmParser() = default; | |||
60 | ||||
61 | void Initialize(MCAsmParser &Parser) override { | |||
62 | // Call the base implementation. | |||
63 | this->MCAsmParserExtension::Initialize(Parser); | |||
64 | ||||
65 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry"); | |||
66 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc"); | |||
67 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>( | |||
68 | ".indirect_symbol"); | |||
69 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym"); | |||
70 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>( | |||
71 | ".subsections_via_symbols"); | |||
72 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump"); | |||
73 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load"); | |||
74 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section"); | |||
75 | addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>( | |||
76 | ".pushsection"); | |||
77 | addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>( | |||
78 | ".popsection"); | |||
79 | addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous"); | |||
80 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>( | |||
81 | ".secure_log_unique"); | |||
82 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>( | |||
83 | ".secure_log_reset"); | |||
84 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss"); | |||
85 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill"); | |||
86 | ||||
87 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>( | |||
88 | ".data_region"); | |||
89 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>( | |||
90 | ".end_data_region"); | |||
91 | ||||
92 | // Special section directives. | |||
93 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss"); | |||
94 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const"); | |||
95 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>( | |||
96 | ".const_data"); | |||
97 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>( | |||
98 | ".constructor"); | |||
99 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>( | |||
100 | ".cstring"); | |||
101 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data"); | |||
102 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>( | |||
103 | ".destructor"); | |||
104 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld"); | |||
105 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>( | |||
106 | ".fvmlib_init0"); | |||
107 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>( | |||
108 | ".fvmlib_init1"); | |||
109 | addDirectiveHandler< | |||
110 | &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>( | |||
111 | ".lazy_symbol_pointer"); | |||
112 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>( | |||
113 | ".linker_option"); | |||
114 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>( | |||
115 | ".literal16"); | |||
116 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>( | |||
117 | ".literal4"); | |||
118 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>( | |||
119 | ".literal8"); | |||
120 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>( | |||
121 | ".mod_init_func"); | |||
122 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>( | |||
123 | ".mod_term_func"); | |||
124 | addDirectiveHandler< | |||
125 | &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>( | |||
126 | ".non_lazy_symbol_pointer"); | |||
127 | addDirectiveHandler< | |||
128 | &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>( | |||
129 | ".thread_local_variable_pointer"); | |||
130 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>( | |||
131 | ".objc_cat_cls_meth"); | |||
132 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>( | |||
133 | ".objc_cat_inst_meth"); | |||
134 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>( | |||
135 | ".objc_category"); | |||
136 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>( | |||
137 | ".objc_class"); | |||
138 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>( | |||
139 | ".objc_class_names"); | |||
140 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>( | |||
141 | ".objc_class_vars"); | |||
142 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>( | |||
143 | ".objc_cls_meth"); | |||
144 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>( | |||
145 | ".objc_cls_refs"); | |||
146 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>( | |||
147 | ".objc_inst_meth"); | |||
148 | addDirectiveHandler< | |||
149 | &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>( | |||
150 | ".objc_instance_vars"); | |||
151 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>( | |||
152 | ".objc_message_refs"); | |||
153 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>( | |||
154 | ".objc_meta_class"); | |||
155 | addDirectiveHandler< | |||
156 | &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>( | |||
157 | ".objc_meth_var_names"); | |||
158 | addDirectiveHandler< | |||
159 | &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>( | |||
160 | ".objc_meth_var_types"); | |||
161 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>( | |||
162 | ".objc_module_info"); | |||
163 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>( | |||
164 | ".objc_protocol"); | |||
165 | addDirectiveHandler< | |||
166 | &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>( | |||
167 | ".objc_selector_strs"); | |||
168 | addDirectiveHandler< | |||
169 | &DarwinAsmParser::parseSectionDirectiveObjCStringObject>( | |||
170 | ".objc_string_object"); | |||
171 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>( | |||
172 | ".objc_symbols"); | |||
173 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>( | |||
174 | ".picsymbol_stub"); | |||
175 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>( | |||
176 | ".static_const"); | |||
177 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>( | |||
178 | ".static_data"); | |||
179 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>( | |||
180 | ".symbol_stub"); | |||
181 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata"); | |||
182 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text"); | |||
183 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>( | |||
184 | ".thread_init_func"); | |||
185 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv"); | |||
186 | ||||
187 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident"); | |||
188 | addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>( | |||
189 | ".watchos_version_min"); | |||
190 | addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>( | |||
191 | ".tvos_version_min"); | |||
192 | addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>( | |||
193 | ".ios_version_min"); | |||
194 | addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>( | |||
195 | ".macosx_version_min"); | |||
196 | addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version"); | |||
197 | ||||
198 | LastVersionDirective = SMLoc(); | |||
199 | } | |||
200 | ||||
201 | bool parseDirectiveAltEntry(StringRef, SMLoc); | |||
202 | bool parseDirectiveDesc(StringRef, SMLoc); | |||
203 | bool parseDirectiveIndirectSymbol(StringRef, SMLoc); | |||
204 | bool parseDirectiveDumpOrLoad(StringRef, SMLoc); | |||
205 | bool parseDirectiveLsym(StringRef, SMLoc); | |||
206 | bool parseDirectiveLinkerOption(StringRef, SMLoc); | |||
207 | bool parseDirectiveSection(StringRef, SMLoc); | |||
208 | bool parseDirectivePushSection(StringRef, SMLoc); | |||
209 | bool parseDirectivePopSection(StringRef, SMLoc); | |||
210 | bool parseDirectivePrevious(StringRef, SMLoc); | |||
211 | bool parseDirectiveSecureLogReset(StringRef, SMLoc); | |||
212 | bool parseDirectiveSecureLogUnique(StringRef, SMLoc); | |||
213 | bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); | |||
214 | bool parseDirectiveTBSS(StringRef, SMLoc); | |||
215 | bool parseDirectiveZerofill(StringRef, SMLoc); | |||
216 | bool parseDirectiveDataRegion(StringRef, SMLoc); | |||
217 | bool parseDirectiveDataRegionEnd(StringRef, SMLoc); | |||
218 | ||||
219 | // Named Section Directive | |||
220 | bool parseSectionDirectiveBss(StringRef, SMLoc) { | |||
221 | return parseSectionSwitch("__DATA", "__bss"); | |||
222 | } | |||
223 | ||||
224 | bool parseSectionDirectiveConst(StringRef, SMLoc) { | |||
225 | return parseSectionSwitch("__TEXT", "__const"); | |||
226 | } | |||
227 | ||||
228 | bool parseSectionDirectiveStaticConst(StringRef, SMLoc) { | |||
229 | return parseSectionSwitch("__TEXT", "__static_const"); | |||
230 | } | |||
231 | ||||
232 | bool parseSectionDirectiveCString(StringRef, SMLoc) { | |||
233 | return parseSectionSwitch("__TEXT","__cstring", | |||
234 | MachO::S_CSTRING_LITERALS); | |||
235 | } | |||
236 | ||||
237 | bool parseSectionDirectiveLiteral4(StringRef, SMLoc) { | |||
238 | return parseSectionSwitch("__TEXT", "__literal4", | |||
239 | MachO::S_4BYTE_LITERALS, 4); | |||
240 | } | |||
241 | ||||
242 | bool parseSectionDirectiveLiteral8(StringRef, SMLoc) { | |||
243 | return parseSectionSwitch("__TEXT", "__literal8", | |||
244 | MachO::S_8BYTE_LITERALS, 8); | |||
245 | } | |||
246 | ||||
247 | bool parseSectionDirectiveLiteral16(StringRef, SMLoc) { | |||
248 | return parseSectionSwitch("__TEXT","__literal16", | |||
249 | MachO::S_16BYTE_LITERALS, 16); | |||
250 | } | |||
251 | ||||
252 | bool parseSectionDirectiveConstructor(StringRef, SMLoc) { | |||
253 | return parseSectionSwitch("__TEXT","__constructor"); | |||
254 | } | |||
255 | ||||
256 | bool parseSectionDirectiveDestructor(StringRef, SMLoc) { | |||
257 | return parseSectionSwitch("__TEXT","__destructor"); | |||
258 | } | |||
259 | ||||
260 | bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) { | |||
261 | return parseSectionSwitch("__TEXT","__fvmlib_init0"); | |||
262 | } | |||
263 | ||||
264 | bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) { | |||
265 | return parseSectionSwitch("__TEXT","__fvmlib_init1"); | |||
266 | } | |||
267 | ||||
268 | bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) { | |||
269 | return parseSectionSwitch("__TEXT","__symbol_stub", | |||
270 | MachO::S_SYMBOL_STUBS | | |||
271 | MachO::S_ATTR_PURE_INSTRUCTIONS, | |||
272 | // FIXME: Different on PPC and ARM. | |||
273 | 0, 16); | |||
274 | } | |||
275 | ||||
276 | bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) { | |||
277 | return parseSectionSwitch("__TEXT","__picsymbol_stub", | |||
278 | MachO::S_SYMBOL_STUBS | | |||
279 | MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26); | |||
280 | } | |||
281 | ||||
282 | bool parseSectionDirectiveData(StringRef, SMLoc) { | |||
283 | return parseSectionSwitch("__DATA", "__data"); | |||
284 | } | |||
285 | ||||
286 | bool parseSectionDirectiveStaticData(StringRef, SMLoc) { | |||
287 | return parseSectionSwitch("__DATA", "__static_data"); | |||
288 | } | |||
289 | ||||
290 | bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) { | |||
291 | return parseSectionSwitch("__DATA", "__nl_symbol_ptr", | |||
292 | MachO::S_NON_LAZY_SYMBOL_POINTERS, 4); | |||
293 | } | |||
294 | ||||
295 | bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) { | |||
296 | return parseSectionSwitch("__DATA", "__la_symbol_ptr", | |||
297 | MachO::S_LAZY_SYMBOL_POINTERS, 4); | |||
298 | } | |||
299 | ||||
300 | bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) { | |||
301 | return parseSectionSwitch("__DATA", "__thread_ptr", | |||
302 | MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4); | |||
303 | } | |||
304 | ||||
305 | bool parseSectionDirectiveDyld(StringRef, SMLoc) { | |||
306 | return parseSectionSwitch("__DATA", "__dyld"); | |||
307 | } | |||
308 | ||||
309 | bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) { | |||
310 | return parseSectionSwitch("__DATA", "__mod_init_func", | |||
311 | MachO::S_MOD_INIT_FUNC_POINTERS, 4); | |||
312 | } | |||
313 | ||||
314 | bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) { | |||
315 | return parseSectionSwitch("__DATA", "__mod_term_func", | |||
316 | MachO::S_MOD_TERM_FUNC_POINTERS, 4); | |||
317 | } | |||
318 | ||||
319 | bool parseSectionDirectiveConstData(StringRef, SMLoc) { | |||
320 | return parseSectionSwitch("__DATA", "__const"); | |||
321 | } | |||
322 | ||||
323 | bool parseSectionDirectiveObjCClass(StringRef, SMLoc) { | |||
324 | return parseSectionSwitch("__OBJC", "__class", | |||
325 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
326 | } | |||
327 | ||||
328 | bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) { | |||
329 | return parseSectionSwitch("__OBJC", "__meta_class", | |||
330 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
331 | } | |||
332 | ||||
333 | bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) { | |||
334 | return parseSectionSwitch("__OBJC", "__cat_cls_meth", | |||
335 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
336 | } | |||
337 | ||||
338 | bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) { | |||
339 | return parseSectionSwitch("__OBJC", "__cat_inst_meth", | |||
340 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
341 | } | |||
342 | ||||
343 | bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) { | |||
344 | return parseSectionSwitch("__OBJC", "__protocol", | |||
345 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
346 | } | |||
347 | ||||
348 | bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) { | |||
349 | return parseSectionSwitch("__OBJC", "__string_object", | |||
350 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
351 | } | |||
352 | ||||
353 | bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) { | |||
354 | return parseSectionSwitch("__OBJC", "__cls_meth", | |||
355 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
356 | } | |||
357 | ||||
358 | bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) { | |||
359 | return parseSectionSwitch("__OBJC", "__inst_meth", | |||
360 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
361 | } | |||
362 | ||||
363 | bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) { | |||
364 | return parseSectionSwitch("__OBJC", "__cls_refs", | |||
365 | MachO::S_ATTR_NO_DEAD_STRIP | | |||
366 | MachO::S_LITERAL_POINTERS, 4); | |||
367 | } | |||
368 | ||||
369 | bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) { | |||
370 | return parseSectionSwitch("__OBJC", "__message_refs", | |||
371 | MachO::S_ATTR_NO_DEAD_STRIP | | |||
372 | MachO::S_LITERAL_POINTERS, 4); | |||
373 | } | |||
374 | ||||
375 | bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) { | |||
376 | return parseSectionSwitch("__OBJC", "__symbols", | |||
377 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
378 | } | |||
379 | ||||
380 | bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) { | |||
381 | return parseSectionSwitch("__OBJC", "__category", | |||
382 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
383 | } | |||
384 | ||||
385 | bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) { | |||
386 | return parseSectionSwitch("__OBJC", "__class_vars", | |||
387 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
388 | } | |||
389 | ||||
390 | bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) { | |||
391 | return parseSectionSwitch("__OBJC", "__instance_vars", | |||
392 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
393 | } | |||
394 | ||||
395 | bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) { | |||
396 | return parseSectionSwitch("__OBJC", "__module_info", | |||
397 | MachO::S_ATTR_NO_DEAD_STRIP); | |||
398 | } | |||
399 | ||||
400 | bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) { | |||
401 | return parseSectionSwitch("__TEXT", "__cstring", | |||
402 | MachO::S_CSTRING_LITERALS); | |||
403 | } | |||
404 | ||||
405 | bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) { | |||
406 | return parseSectionSwitch("__TEXT", "__cstring", | |||
407 | MachO::S_CSTRING_LITERALS); | |||
408 | } | |||
409 | ||||
410 | bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) { | |||
411 | return parseSectionSwitch("__TEXT", "__cstring", | |||
412 | MachO::S_CSTRING_LITERALS); | |||
413 | } | |||
414 | ||||
415 | bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) { | |||
416 | return parseSectionSwitch("__OBJC", "__selector_strs", | |||
417 | MachO::S_CSTRING_LITERALS); | |||
418 | } | |||
419 | ||||
420 | bool parseSectionDirectiveTData(StringRef, SMLoc) { | |||
421 | return parseSectionSwitch("__DATA", "__thread_data", | |||
422 | MachO::S_THREAD_LOCAL_REGULAR); | |||
423 | } | |||
424 | ||||
425 | bool parseSectionDirectiveText(StringRef, SMLoc) { | |||
426 | return parseSectionSwitch("__TEXT", "__text", | |||
427 | MachO::S_ATTR_PURE_INSTRUCTIONS); | |||
428 | } | |||
429 | ||||
430 | bool parseSectionDirectiveTLV(StringRef, SMLoc) { | |||
431 | return parseSectionSwitch("__DATA", "__thread_vars", | |||
432 | MachO::S_THREAD_LOCAL_VARIABLES); | |||
433 | } | |||
434 | ||||
435 | bool parseSectionDirectiveIdent(StringRef, SMLoc) { | |||
436 | // Darwin silently ignores the .ident directive. | |||
437 | getParser().eatToEndOfStatement(); | |||
438 | return false; | |||
439 | } | |||
440 | ||||
441 | bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) { | |||
442 | return parseSectionSwitch("__DATA", "__thread_init", | |||
443 | MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); | |||
444 | } | |||
445 | ||||
446 | bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) { | |||
447 | return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin); | |||
448 | } | |||
449 | bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) { | |||
450 | return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin); | |||
451 | } | |||
452 | bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) { | |||
453 | return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin); | |||
454 | } | |||
455 | bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) { | |||
456 | return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin); | |||
| ||||
457 | } | |||
458 | ||||
459 | bool parseBuildVersion(StringRef Directive, SMLoc Loc); | |||
460 | bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type); | |||
461 | bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor, | |||
462 | const char *VersionName); | |||
463 | bool parseOptionalTrailingVersionComponent(unsigned *Component, | |||
464 | const char *ComponentName); | |||
465 | bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update); | |||
466 | bool parseSDKVersion(VersionTuple &SDKVersion); | |||
467 | void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc, | |||
468 | Triple::OSType ExpectedOS); | |||
469 | }; | |||
470 | ||||
471 | } // end anonymous namespace | |||
472 | ||||
473 | bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section, | |||
474 | unsigned TAA, unsigned Align, | |||
475 | unsigned StubSize) { | |||
476 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
477 | return TokError("unexpected token in section switching directive"); | |||
478 | Lex(); | |||
479 | ||||
480 | // FIXME: Arch specific. | |||
481 | bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS; | |||
482 | getStreamer().SwitchSection(getContext().getMachOSection( | |||
483 | Segment, Section, TAA, StubSize, | |||
484 | isText ? SectionKind::getText() : SectionKind::getData())); | |||
485 | ||||
486 | // Set the implicit alignment, if any. | |||
487 | // | |||
488 | // FIXME: This isn't really what 'as' does; I think it just uses the implicit | |||
489 | // alignment on the section (e.g., if one manually inserts bytes into the | |||
490 | // section, then just issuing the section switch directive will not realign | |||
491 | // the section. However, this is arguably more reasonable behavior, and there | |||
492 | // is no good reason for someone to intentionally emit incorrectly sized | |||
493 | // values into the implicitly aligned sections. | |||
494 | if (Align) | |||
495 | getStreamer().EmitValueToAlignment(Align); | |||
496 | ||||
497 | return false; | |||
498 | } | |||
499 | ||||
500 | /// parseDirectiveAltEntry | |||
501 | /// ::= .alt_entry identifier | |||
502 | bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) { | |||
503 | StringRef Name; | |||
504 | if (getParser().parseIdentifier(Name)) | |||
505 | return TokError("expected identifier in directive"); | |||
506 | ||||
507 | // Look up symbol. | |||
508 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); | |||
509 | ||||
510 | if (Sym->isDefined()) | |||
511 | return TokError(".alt_entry must preceed symbol definition"); | |||
512 | ||||
513 | if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_AltEntry)) | |||
514 | return TokError("unable to emit symbol attribute"); | |||
515 | ||||
516 | Lex(); | |||
517 | return false; | |||
518 | } | |||
519 | ||||
520 | /// parseDirectiveDesc | |||
521 | /// ::= .desc identifier , expression | |||
522 | bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) { | |||
523 | StringRef Name; | |||
524 | if (getParser().parseIdentifier(Name)) | |||
525 | return TokError("expected identifier in directive"); | |||
526 | ||||
527 | // Handle the identifier as the key symbol. | |||
528 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); | |||
529 | ||||
530 | if (getLexer().isNot(AsmToken::Comma)) | |||
531 | return TokError("unexpected token in '.desc' directive"); | |||
532 | Lex(); | |||
533 | ||||
534 | int64_t DescValue; | |||
535 | if (getParser().parseAbsoluteExpression(DescValue)) | |||
536 | return true; | |||
537 | ||||
538 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
539 | return TokError("unexpected token in '.desc' directive"); | |||
540 | ||||
541 | Lex(); | |||
542 | ||||
543 | // Set the n_desc field of this Symbol to this DescValue | |||
544 | getStreamer().EmitSymbolDesc(Sym, DescValue); | |||
545 | ||||
546 | return false; | |||
547 | } | |||
548 | ||||
549 | /// parseDirectiveIndirectSymbol | |||
550 | /// ::= .indirect_symbol identifier | |||
551 | bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { | |||
552 | const MCSectionMachO *Current = static_cast<const MCSectionMachO *>( | |||
553 | getStreamer().getCurrentSectionOnly()); | |||
554 | MachO::SectionType SectionType = Current->getType(); | |||
555 | if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && | |||
556 | SectionType != MachO::S_LAZY_SYMBOL_POINTERS && | |||
557 | SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS && | |||
558 | SectionType != MachO::S_SYMBOL_STUBS) | |||
559 | return Error(Loc, "indirect symbol not in a symbol pointer or stub " | |||
560 | "section"); | |||
561 | ||||
562 | StringRef Name; | |||
563 | if (getParser().parseIdentifier(Name)) | |||
564 | return TokError("expected identifier in .indirect_symbol directive"); | |||
565 | ||||
566 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); | |||
567 | ||||
568 | // Assembler local symbols don't make any sense here. Complain loudly. | |||
569 | if (Sym->isTemporary()) | |||
570 | return TokError("non-local symbol required in directive"); | |||
571 | ||||
572 | if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol)) | |||
573 | return TokError("unable to emit indirect symbol attribute for: " + Name); | |||
574 | ||||
575 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
576 | return TokError("unexpected token in '.indirect_symbol' directive"); | |||
577 | ||||
578 | Lex(); | |||
579 | ||||
580 | return false; | |||
581 | } | |||
582 | ||||
583 | /// parseDirectiveDumpOrLoad | |||
584 | /// ::= ( .dump | .load ) "filename" | |||
585 | bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive, | |||
586 | SMLoc IDLoc) { | |||
587 | bool IsDump = Directive == ".dump"; | |||
588 | if (getLexer().isNot(AsmToken::String)) | |||
589 | return TokError("expected string in '.dump' or '.load' directive"); | |||
590 | ||||
591 | Lex(); | |||
592 | ||||
593 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
594 | return TokError("unexpected token in '.dump' or '.load' directive"); | |||
595 | ||||
596 | Lex(); | |||
597 | ||||
598 | // FIXME: If/when .dump and .load are implemented they will be done in the | |||
599 | // the assembly parser and not have any need for an MCStreamer API. | |||
600 | if (IsDump) | |||
601 | return Warning(IDLoc, "ignoring directive .dump for now"); | |||
602 | else | |||
603 | return Warning(IDLoc, "ignoring directive .load for now"); | |||
604 | } | |||
605 | ||||
606 | /// ParseDirectiveLinkerOption | |||
607 | /// ::= .linker_option "string" ( , "string" )* | |||
608 | bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) { | |||
609 | SmallVector<std::string, 4> Args; | |||
610 | while (true) { | |||
611 | if (getLexer().isNot(AsmToken::String)) | |||
612 | return TokError("expected string in '" + Twine(IDVal) + "' directive"); | |||
613 | ||||
614 | std::string Data; | |||
615 | if (getParser().parseEscapedString(Data)) | |||
616 | return true; | |||
617 | ||||
618 | Args.push_back(Data); | |||
619 | ||||
620 | if (getLexer().is(AsmToken::EndOfStatement)) | |||
621 | break; | |||
622 | ||||
623 | if (getLexer().isNot(AsmToken::Comma)) | |||
624 | return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); | |||
625 | Lex(); | |||
626 | } | |||
627 | ||||
628 | getStreamer().EmitLinkerOptions(Args); | |||
629 | return false; | |||
630 | } | |||
631 | ||||
632 | /// parseDirectiveLsym | |||
633 | /// ::= .lsym identifier , expression | |||
634 | bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) { | |||
635 | StringRef Name; | |||
636 | if (getParser().parseIdentifier(Name)) | |||
637 | return TokError("expected identifier in directive"); | |||
638 | ||||
639 | // Handle the identifier as the key symbol. | |||
640 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); | |||
641 | ||||
642 | if (getLexer().isNot(AsmToken::Comma)) | |||
643 | return TokError("unexpected token in '.lsym' directive"); | |||
644 | Lex(); | |||
645 | ||||
646 | const MCExpr *Value; | |||
647 | if (getParser().parseExpression(Value)) | |||
648 | return true; | |||
649 | ||||
650 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
651 | return TokError("unexpected token in '.lsym' directive"); | |||
652 | ||||
653 | Lex(); | |||
654 | ||||
655 | // We don't currently support this directive. | |||
656 | // | |||
657 | // FIXME: Diagnostic location! | |||
658 | (void) Sym; | |||
659 | return TokError("directive '.lsym' is unsupported"); | |||
660 | } | |||
661 | ||||
662 | /// parseDirectiveSection: | |||
663 | /// ::= .section identifier (',' identifier)* | |||
664 | bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) { | |||
665 | SMLoc Loc = getLexer().getLoc(); | |||
666 | ||||
667 | StringRef SectionName; | |||
668 | if (getParser().parseIdentifier(SectionName)) | |||
669 | return Error(Loc, "expected identifier after '.section' directive"); | |||
670 | ||||
671 | // Verify there is a following comma. | |||
672 | if (!getLexer().is(AsmToken::Comma)) | |||
673 | return TokError("unexpected token in '.section' directive"); | |||
674 | ||||
675 | std::string SectionSpec = SectionName; | |||
676 | SectionSpec += ","; | |||
677 | ||||
678 | // Add all the tokens until the end of the line, ParseSectionSpecifier will | |||
679 | // handle this. | |||
680 | StringRef EOL = getLexer().LexUntilEndOfStatement(); | |||
681 | SectionSpec.append(EOL.begin(), EOL.end()); | |||
682 | ||||
683 | Lex(); | |||
684 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
685 | return TokError("unexpected token in '.section' directive"); | |||
686 | Lex(); | |||
687 | ||||
688 | StringRef Segment, Section; | |||
689 | unsigned StubSize; | |||
690 | unsigned TAA; | |||
691 | bool TAAParsed; | |||
692 | std::string ErrorStr = | |||
693 | MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, | |||
694 | TAA, TAAParsed, StubSize); | |||
695 | ||||
696 | if (!ErrorStr.empty()) | |||
697 | return Error(Loc, ErrorStr); | |||
698 | ||||
699 | // Issue a warning if the target is not powerpc and Section is a *coal* section. | |||
700 | Triple TT = getParser().getContext().getObjectFileInfo()->getTargetTriple(); | |||
701 | Triple::ArchType ArchTy = TT.getArch(); | |||
702 | ||||
703 | if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) { | |||
704 | StringRef NonCoalSection = StringSwitch<StringRef>(Section) | |||
705 | .Case("__textcoal_nt", "__text") | |||
706 | .Case("__const_coal", "__const") | |||
707 | .Case("__datacoal_nt", "__data") | |||
708 | .Default(Section); | |||
709 | ||||
710 | if (!Section.equals(NonCoalSection)) { | |||
711 | StringRef SectionVal(Loc.getPointer()); | |||
712 | size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B); | |||
713 | SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B); | |||
714 | SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E); | |||
715 | getParser().Warning(Loc, "section \"" + Section + "\" is deprecated", | |||
716 | SMRange(BLoc, ELoc)); | |||
717 | getParser().Note(Loc, "change section name to \"" + NonCoalSection + | |||
718 | "\"", SMRange(BLoc, ELoc)); | |||
719 | } | |||
720 | } | |||
721 | ||||
722 | // FIXME: Arch specific. | |||
723 | bool isText = Segment == "__TEXT"; // FIXME: Hack. | |||
724 | getStreamer().SwitchSection(getContext().getMachOSection( | |||
725 | Segment, Section, TAA, StubSize, | |||
726 | isText ? SectionKind::getText() : SectionKind::getData())); | |||
727 | return false; | |||
728 | } | |||
729 | ||||
730 | /// ParseDirectivePushSection: | |||
731 | /// ::= .pushsection identifier (',' identifier)* | |||
732 | bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) { | |||
733 | getStreamer().PushSection(); | |||
734 | ||||
735 | if (parseDirectiveSection(S, Loc)) { | |||
736 | getStreamer().PopSection(); | |||
737 | return true; | |||
738 | } | |||
739 | ||||
740 | return false; | |||
741 | } | |||
742 | ||||
743 | /// ParseDirectivePopSection: | |||
744 | /// ::= .popsection | |||
745 | bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) { | |||
746 | if (!getStreamer().PopSection()) | |||
747 | return TokError(".popsection without corresponding .pushsection"); | |||
748 | return false; | |||
749 | } | |||
750 | ||||
751 | /// ParseDirectivePrevious: | |||
752 | /// ::= .previous | |||
753 | bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { | |||
754 | MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); | |||
755 | if (!PreviousSection.first) | |||
756 | return TokError(".previous without corresponding .section"); | |||
757 | getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); | |||
758 | return false; | |||
759 | } | |||
760 | ||||
761 | /// ParseDirectiveSecureLogUnique | |||
762 | /// ::= .secure_log_unique ... message ... | |||
763 | bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { | |||
764 | StringRef LogMessage = getParser().parseStringToEndOfStatement(); | |||
765 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
766 | return TokError("unexpected token in '.secure_log_unique' directive"); | |||
767 | ||||
768 | if (getContext().getSecureLogUsed()) | |||
769 | return Error(IDLoc, ".secure_log_unique specified multiple times"); | |||
770 | ||||
771 | // Get the secure log path. | |||
772 | const char *SecureLogFile = getContext().getSecureLogFile(); | |||
773 | if (!SecureLogFile) | |||
774 | return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " | |||
775 | "environment variable unset."); | |||
776 | ||||
777 | // Open the secure log file if we haven't already. | |||
778 | raw_fd_ostream *OS = getContext().getSecureLog(); | |||
779 | if (!OS) { | |||
780 | std::error_code EC; | |||
781 | auto NewOS = llvm::make_unique<raw_fd_ostream>( | |||
782 | StringRef(SecureLogFile), EC, sys::fs::F_Append | sys::fs::F_Text); | |||
783 | if (EC) | |||
784 | return Error(IDLoc, Twine("can't open secure log file: ") + | |||
785 | SecureLogFile + " (" + EC.message() + ")"); | |||
786 | OS = NewOS.get(); | |||
787 | getContext().setSecureLog(std::move(NewOS)); | |||
788 | } | |||
789 | ||||
790 | // Write the message. | |||
791 | unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); | |||
792 | *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier() | |||
793 | << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":" | |||
794 | << LogMessage + "\n"; | |||
795 | ||||
796 | getContext().setSecureLogUsed(true); | |||
797 | ||||
798 | return false; | |||
799 | } | |||
800 | ||||
801 | /// ParseDirectiveSecureLogReset | |||
802 | /// ::= .secure_log_reset | |||
803 | bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { | |||
804 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
805 | return TokError("unexpected token in '.secure_log_reset' directive"); | |||
806 | ||||
807 | Lex(); | |||
808 | ||||
809 | getContext().setSecureLogUsed(false); | |||
810 | ||||
811 | return false; | |||
812 | } | |||
813 | ||||
814 | /// parseDirectiveSubsectionsViaSymbols | |||
815 | /// ::= .subsections_via_symbols | |||
816 | bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { | |||
817 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
818 | return TokError("unexpected token in '.subsections_via_symbols' directive"); | |||
819 | ||||
820 | Lex(); | |||
821 | ||||
822 | getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); | |||
823 | ||||
824 | return false; | |||
825 | } | |||
826 | ||||
827 | /// ParseDirectiveTBSS | |||
828 | /// ::= .tbss identifier, size, align | |||
829 | bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) { | |||
830 | SMLoc IDLoc = getLexer().getLoc(); | |||
831 | StringRef Name; | |||
832 | if (getParser().parseIdentifier(Name)) | |||
833 | return TokError("expected identifier in directive"); | |||
834 | ||||
835 | // Handle the identifier as the key symbol. | |||
836 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); | |||
837 | ||||
838 | if (getLexer().isNot(AsmToken::Comma)) | |||
839 | return TokError("unexpected token in directive"); | |||
840 | Lex(); | |||
841 | ||||
842 | int64_t Size; | |||
843 | SMLoc SizeLoc = getLexer().getLoc(); | |||
844 | if (getParser().parseAbsoluteExpression(Size)) | |||
845 | return true; | |||
846 | ||||
847 | int64_t Pow2Alignment = 0; | |||
848 | SMLoc Pow2AlignmentLoc; | |||
849 | if (getLexer().is(AsmToken::Comma)) { | |||
850 | Lex(); | |||
851 | Pow2AlignmentLoc = getLexer().getLoc(); | |||
852 | if (getParser().parseAbsoluteExpression(Pow2Alignment)) | |||
853 | return true; | |||
854 | } | |||
855 | ||||
856 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
857 | return TokError("unexpected token in '.tbss' directive"); | |||
858 | ||||
859 | Lex(); | |||
860 | ||||
861 | if (Size < 0) | |||
862 | return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" | |||
863 | "zero"); | |||
864 | ||||
865 | // FIXME: Diagnose overflow. | |||
866 | if (Pow2Alignment < 0) | |||
867 | return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" | |||
868 | "than zero"); | |||
869 | ||||
870 | if (!Sym->isUndefined()) | |||
871 | return Error(IDLoc, "invalid symbol redefinition"); | |||
872 | ||||
873 | getStreamer().EmitTBSSSymbol(getContext().getMachOSection( | |||
874 | "__DATA", "__thread_bss", | |||
875 | MachO::S_THREAD_LOCAL_ZEROFILL, | |||
876 | 0, SectionKind::getThreadBSS()), | |||
877 | Sym, Size, 1 << Pow2Alignment); | |||
878 | ||||
879 | return false; | |||
880 | } | |||
881 | ||||
882 | /// ParseDirectiveZerofill | |||
883 | /// ::= .zerofill segname , sectname [, identifier , size_expression [ | |||
884 | /// , align_expression ]] | |||
885 | bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) { | |||
886 | StringRef Segment; | |||
887 | if (getParser().parseIdentifier(Segment)) | |||
888 | return TokError("expected segment name after '.zerofill' directive"); | |||
889 | ||||
890 | if (getLexer().isNot(AsmToken::Comma)) | |||
891 | return TokError("unexpected token in directive"); | |||
892 | Lex(); | |||
893 | ||||
894 | StringRef Section; | |||
895 | SMLoc SectionLoc = getLexer().getLoc(); | |||
896 | if (getParser().parseIdentifier(Section)) | |||
897 | return TokError("expected section name after comma in '.zerofill' " | |||
898 | "directive"); | |||
899 | ||||
900 | // If this is the end of the line all that was wanted was to create the | |||
901 | // the section but with no symbol. | |||
902 | if (getLexer().is(AsmToken::EndOfStatement)) { | |||
903 | // Create the zerofill section but no symbol | |||
904 | getStreamer().EmitZerofill( | |||
905 | getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0, | |||
906 | SectionKind::getBSS()), | |||
907 | /*Symbol=*/nullptr, /*Size=*/0, /*ByteAlignment=*/0, SectionLoc); | |||
908 | return false; | |||
909 | } | |||
910 | ||||
911 | if (getLexer().isNot(AsmToken::Comma)) | |||
912 | return TokError("unexpected token in directive"); | |||
913 | Lex(); | |||
914 | ||||
915 | SMLoc IDLoc = getLexer().getLoc(); | |||
916 | StringRef IDStr; | |||
917 | if (getParser().parseIdentifier(IDStr)) | |||
918 | return TokError("expected identifier in directive"); | |||
919 | ||||
920 | // handle the identifier as the key symbol. | |||
921 | MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr); | |||
922 | ||||
923 | if (getLexer().isNot(AsmToken::Comma)) | |||
924 | return TokError("unexpected token in directive"); | |||
925 | Lex(); | |||
926 | ||||
927 | int64_t Size; | |||
928 | SMLoc SizeLoc = getLexer().getLoc(); | |||
929 | if (getParser().parseAbsoluteExpression(Size)) | |||
930 | return true; | |||
931 | ||||
932 | int64_t Pow2Alignment = 0; | |||
933 | SMLoc Pow2AlignmentLoc; | |||
934 | if (getLexer().is(AsmToken::Comma)) { | |||
935 | Lex(); | |||
936 | Pow2AlignmentLoc = getLexer().getLoc(); | |||
937 | if (getParser().parseAbsoluteExpression(Pow2Alignment)) | |||
938 | return true; | |||
939 | } | |||
940 | ||||
941 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
942 | return TokError("unexpected token in '.zerofill' directive"); | |||
943 | ||||
944 | Lex(); | |||
945 | ||||
946 | if (Size < 0) | |||
947 | return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " | |||
948 | "than zero"); | |||
949 | ||||
950 | // NOTE: The alignment in the directive is a power of 2 value, the assembler | |||
951 | // may internally end up wanting an alignment in bytes. | |||
952 | // FIXME: Diagnose overflow. | |||
953 | if (Pow2Alignment < 0) | |||
954 | return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " | |||
955 | "can't be less than zero"); | |||
956 | ||||
957 | if (!Sym->isUndefined()) | |||
958 | return Error(IDLoc, "invalid symbol redefinition"); | |||
959 | ||||
960 | // Create the zerofill Symbol with Size and Pow2Alignment | |||
961 | // | |||
962 | // FIXME: Arch specific. | |||
963 | getStreamer().EmitZerofill(getContext().getMachOSection( | |||
964 | Segment, Section, MachO::S_ZEROFILL, | |||
965 | 0, SectionKind::getBSS()), | |||
966 | Sym, Size, 1 << Pow2Alignment, SectionLoc); | |||
967 | ||||
968 | return false; | |||
969 | } | |||
970 | ||||
971 | /// ParseDirectiveDataRegion | |||
972 | /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ] | |||
973 | bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) { | |||
974 | if (getLexer().is(AsmToken::EndOfStatement)) { | |||
975 | Lex(); | |||
976 | getStreamer().EmitDataRegion(MCDR_DataRegion); | |||
977 | return false; | |||
978 | } | |||
979 | StringRef RegionType; | |||
980 | SMLoc Loc = getParser().getTok().getLoc(); | |||
981 | if (getParser().parseIdentifier(RegionType)) | |||
982 | return TokError("expected region type after '.data_region' directive"); | |||
983 | int Kind = StringSwitch<int>(RegionType) | |||
984 | .Case("jt8", MCDR_DataRegionJT8) | |||
985 | .Case("jt16", MCDR_DataRegionJT16) | |||
986 | .Case("jt32", MCDR_DataRegionJT32) | |||
987 | .Default(-1); | |||
988 | if (Kind == -1) | |||
989 | return Error(Loc, "unknown region type in '.data_region' directive"); | |||
990 | Lex(); | |||
991 | ||||
992 | getStreamer().EmitDataRegion((MCDataRegionType)Kind); | |||
993 | return false; | |||
994 | } | |||
995 | ||||
996 | /// ParseDirectiveDataRegionEnd | |||
997 | /// ::= .end_data_region | |||
998 | bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) { | |||
999 | if (getLexer().isNot(AsmToken::EndOfStatement)) | |||
1000 | return TokError("unexpected token in '.end_data_region' directive"); | |||
1001 | ||||
1002 | Lex(); | |||
1003 | getStreamer().EmitDataRegion(MCDR_DataRegionEnd); | |||
1004 | return false; | |||
1005 | } | |||
1006 | ||||
1007 | static bool isSDKVersionToken(const AsmToken &Tok) { | |||
1008 | return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version"; | |||
1009 | } | |||
1010 | ||||
1011 | /// parseMajorMinorVersionComponent ::= major, minor | |||
1012 | bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major, | |||
1013 | unsigned *Minor, | |||
1014 | const char *VersionName) { | |||
1015 | // Get the major version number. | |||
1016 | if (getLexer().isNot(AsmToken::Integer)) | |||
1017 | return TokError(Twine("invalid ") + VersionName + | |||
1018 | " major version number, integer expected"); | |||
1019 | int64_t MajorVal = getLexer().getTok().getIntVal(); | |||
1020 | if (MajorVal > 65535 || MajorVal <= 0) | |||
1021 | return TokError(Twine("invalid ") + VersionName + " major version number"); | |||
1022 | *Major = (unsigned)MajorVal; | |||
1023 | Lex(); | |||
1024 | if (getLexer().isNot(AsmToken::Comma)) | |||
1025 | return TokError(Twine(VersionName) + | |||
1026 | " minor version number required, comma expected"); | |||
1027 | Lex(); | |||
1028 | // Get the minor version number. | |||
1029 | if (getLexer().isNot(AsmToken::Integer)) | |||
1030 | return TokError(Twine("invalid ") + VersionName + | |||
1031 | " minor version number, integer expected"); | |||
1032 | int64_t MinorVal = getLexer().getTok().getIntVal(); | |||
1033 | if (MinorVal > 255 || MinorVal < 0) | |||
1034 | return TokError(Twine("invalid ") + VersionName + " minor version number"); | |||
1035 | *Minor = MinorVal; | |||
1036 | Lex(); | |||
1037 | return false; | |||
1038 | } | |||
1039 | ||||
1040 | /// parseOptionalTrailingVersionComponent ::= , version_number | |||
1041 | bool DarwinAsmParser::parseOptionalTrailingVersionComponent( | |||
1042 | unsigned *Component, const char *ComponentName) { | |||
1043 | assert(getLexer().is(AsmToken::Comma) && "comma expected")((getLexer().is(AsmToken::Comma) && "comma expected") ? static_cast<void> (0) : __assert_fail ("getLexer().is(AsmToken::Comma) && \"comma expected\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/MC/MCParser/DarwinAsmParser.cpp" , 1043, __PRETTY_FUNCTION__)); | |||
1044 | Lex(); | |||
1045 | if (getLexer().isNot(AsmToken::Integer)) | |||
1046 | return TokError(Twine("invalid ") + ComponentName + | |||
1047 | " version number, integer expected"); | |||
1048 | int64_t Val = getLexer().getTok().getIntVal(); | |||
1049 | if (Val > 255 || Val < 0) | |||
1050 | return TokError(Twine("invalid ") + ComponentName + " version number"); | |||
1051 | *Component = Val; | |||
1052 | Lex(); | |||
1053 | return false; | |||
1054 | } | |||
1055 | ||||
1056 | /// parseVersion ::= parseMajorMinorVersionComponent | |||
1057 | /// parseOptionalTrailingVersionComponent | |||
1058 | bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor, | |||
1059 | unsigned *Update) { | |||
1060 | if (parseMajorMinorVersionComponent(Major, Minor, "OS")) | |||
1061 | return true; | |||
1062 | ||||
1063 | // Get the update level, if specified | |||
1064 | *Update = 0; | |||
1065 | if (getLexer().is(AsmToken::EndOfStatement) || | |||
1066 | isSDKVersionToken(getLexer().getTok())) | |||
1067 | return false; | |||
1068 | if (getLexer().isNot(AsmToken::Comma)) | |||
1069 | return TokError("invalid OS update specifier, comma expected"); | |||
1070 | if (parseOptionalTrailingVersionComponent(Update, "OS update")) | |||
1071 | return true; | |||
1072 | return false; | |||
1073 | } | |||
1074 | ||||
1075 | bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) { | |||
1076 | assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version")((isSDKVersionToken(getLexer().getTok()) && "expected sdk_version" ) ? static_cast<void> (0) : __assert_fail ("isSDKVersionToken(getLexer().getTok()) && \"expected sdk_version\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/MC/MCParser/DarwinAsmParser.cpp" , 1076, __PRETTY_FUNCTION__)); | |||
1077 | Lex(); | |||
1078 | unsigned Major, Minor; | |||
1079 | if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK")) | |||
1080 | return true; | |||
1081 | SDKVersion = VersionTuple(Major, Minor); | |||
| ||||
1082 | ||||
1083 | // Get the subminor version, if specified. | |||
1084 | if (getLexer().is(AsmToken::Comma)) { | |||
1085 | unsigned Subminor; | |||
1086 | if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor")) | |||
1087 | return true; | |||
1088 | SDKVersion = VersionTuple(Major, Minor, Subminor); | |||
1089 | } | |||
1090 | return false; | |||
1091 | } | |||
1092 | ||||
1093 | void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg, | |||
1094 | SMLoc Loc, Triple::OSType ExpectedOS) { | |||
1095 | const Triple &Target = getContext().getObjectFileInfo()->getTargetTriple(); | |||
1096 | if (Target.getOS() != ExpectedOS) | |||
1097 | Warning(Loc, Twine(Directive) + | |||
1098 | (Arg.empty() ? Twine() : Twine(' ') + Arg) + | |||
1099 | " used while targeting " + Target.getOSName()); | |||
1100 | ||||
1101 | if (LastVersionDirective.isValid()) { | |||
1102 | Warning(Loc, "overriding previous version directive"); | |||
1103 | Note(LastVersionDirective, "previous definition is here"); | |||
1104 | } | |||
1105 | LastVersionDirective = Loc; | |||
1106 | } | |||
1107 | ||||
1108 | static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) { | |||
1109 | switch (Type) { | |||
1110 | case MCVM_WatchOSVersionMin: return Triple::WatchOS; | |||
1111 | case MCVM_TvOSVersionMin: return Triple::TvOS; | |||
1112 | case MCVM_IOSVersionMin: return Triple::IOS; | |||
1113 | case MCVM_OSXVersionMin: return Triple::MacOSX; | |||
1114 | } | |||
1115 | llvm_unreachable("Invalid mc version min type")::llvm::llvm_unreachable_internal("Invalid mc version min type" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/MC/MCParser/DarwinAsmParser.cpp" , 1115); | |||
1116 | } | |||
1117 | ||||
1118 | /// parseVersionMin | |||
1119 | /// ::= .ios_version_min parseVersion parseSDKVersion | |||
1120 | /// | .macosx_version_min parseVersion parseSDKVersion | |||
1121 | /// | .tvos_version_min parseVersion parseSDKVersion | |||
1122 | /// | .watchos_version_min parseVersion parseSDKVersion | |||
1123 | bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc, | |||
1124 | MCVersionMinType Type) { | |||
1125 | unsigned Major; | |||
1126 | unsigned Minor; | |||
1127 | unsigned Update; | |||
1128 | if (parseVersion(&Major, &Minor, &Update)) | |||
1129 | return true; | |||
1130 | ||||
1131 | VersionTuple SDKVersion; | |||
1132 | if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion)) | |||
1133 | return true; | |||
1134 | ||||
1135 | if (parseToken(AsmToken::EndOfStatement)) | |||
1136 | return addErrorSuffix(Twine(" in '") + Directive + "' directive"); | |||
1137 | ||||
1138 | Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type); | |||
1139 | checkVersion(Directive, StringRef(), Loc, ExpectedOS); | |||
1140 | getStreamer().EmitVersionMin(Type, Major, Minor, Update, SDKVersion); | |||
1141 | return false; | |||
1142 | } | |||
1143 | ||||
1144 | static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) { | |||
1145 | switch (Type) { | |||
1146 | case MachO::PLATFORM_MACOS: return Triple::MacOSX; | |||
1147 | case MachO::PLATFORM_IOS: return Triple::IOS; | |||
1148 | case MachO::PLATFORM_TVOS: return Triple::TvOS; | |||
1149 | case MachO::PLATFORM_WATCHOS: return Triple::WatchOS; | |||
1150 | case MachO::PLATFORM_BRIDGEOS: /* silence warning */ break; | |||
1151 | case MachO::PLATFORM_IOSSIMULATOR: /* silence warning */ break; | |||
1152 | case MachO::PLATFORM_TVOSSIMULATOR: /* silence warning */ break; | |||
1153 | case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break; | |||
1154 | } | |||
1155 | llvm_unreachable("Invalid mach-o platform type")::llvm::llvm_unreachable_internal("Invalid mach-o platform type" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/MC/MCParser/DarwinAsmParser.cpp" , 1155); | |||
1156 | } | |||
1157 | ||||
1158 | /// parseBuildVersion | |||
1159 | /// ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion | |||
1160 | bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) { | |||
1161 | StringRef PlatformName; | |||
1162 | SMLoc PlatformLoc = getTok().getLoc(); | |||
1163 | if (getParser().parseIdentifier(PlatformName)) | |||
1164 | return TokError("platform name expected"); | |||
1165 | ||||
1166 | unsigned Platform = StringSwitch<unsigned>(PlatformName) | |||
1167 | .Case("macos", MachO::PLATFORM_MACOS) | |||
1168 | .Case("ios", MachO::PLATFORM_IOS) | |||
1169 | .Case("tvos", MachO::PLATFORM_TVOS) | |||
1170 | .Case("watchos", MachO::PLATFORM_WATCHOS) | |||
1171 | .Default(0); | |||
1172 | if (Platform == 0) | |||
1173 | return Error(PlatformLoc, "unknown platform name"); | |||
1174 | ||||
1175 | if (getLexer().isNot(AsmToken::Comma)) | |||
1176 | return TokError("version number required, comma expected"); | |||
1177 | Lex(); | |||
1178 | ||||
1179 | unsigned Major; | |||
1180 | unsigned Minor; | |||
1181 | unsigned Update; | |||
1182 | if (parseVersion(&Major, &Minor, &Update)) | |||
1183 | return true; | |||
1184 | ||||
1185 | VersionTuple SDKVersion; | |||
1186 | if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion)) | |||
1187 | return true; | |||
1188 | ||||
1189 | if (parseToken(AsmToken::EndOfStatement)) | |||
1190 | return addErrorSuffix(" in '.build_version' directive"); | |||
1191 | ||||
1192 | Triple::OSType ExpectedOS | |||
1193 | = getOSTypeFromPlatform((MachO::PlatformType)Platform); | |||
1194 | checkVersion(Directive, PlatformName, Loc, ExpectedOS); | |||
1195 | getStreamer().EmitBuildVersion(Platform, Major, Minor, Update, SDKVersion); | |||
1196 | return false; | |||
1197 | } | |||
1198 | ||||
1199 | ||||
1200 | namespace llvm { | |||
1201 | ||||
1202 | MCAsmParserExtension *createDarwinAsmParser() { | |||
1203 | return new DarwinAsmParser; | |||
1204 | } | |||
1205 | ||||
1206 | } // end llvm namespace |