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