Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
35269 views
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/SmallVector.h"
10
#include "llvm/ADT/StringRef.h"
11
#include "llvm/ADT/StringSwitch.h"
12
#include "llvm/ADT/Twine.h"
13
#include "llvm/BinaryFormat/MachO.h"
14
#include "llvm/MC/MCContext.h"
15
#include "llvm/MC/MCDirectives.h"
16
#include "llvm/MC/MCParser/MCAsmLexer.h"
17
#include "llvm/MC/MCParser/MCAsmParser.h"
18
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
19
#include "llvm/MC/MCSectionMachO.h"
20
#include "llvm/MC/MCStreamer.h"
21
#include "llvm/MC/MCSymbol.h"
22
#include "llvm/MC/SectionKind.h"
23
#include "llvm/Support/Error.h"
24
#include "llvm/Support/FileSystem.h"
25
#include "llvm/Support/MemoryBuffer.h"
26
#include "llvm/Support/SMLoc.h"
27
#include "llvm/Support/SourceMgr.h"
28
#include "llvm/Support/raw_ostream.h"
29
#include "llvm/TargetParser/Triple.h"
30
#include <cstddef>
31
#include <cstdint>
32
#include <string>
33
#include <system_error>
34
#include <utility>
35
36
using namespace llvm;
37
38
namespace {
39
40
/// Implementation of directive handling which is shared across all
41
/// Darwin targets.
42
class DarwinAsmParser : public MCAsmParserExtension {
43
template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
44
void addDirectiveHandler(StringRef Directive) {
45
MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
46
this, HandleDirective<DarwinAsmParser, HandlerMethod>);
47
getParser().addDirectiveHandler(Directive, Handler);
48
}
49
50
bool parseSectionSwitch(StringRef Segment, StringRef Section,
51
unsigned TAA = 0, unsigned ImplicitAlign = 0,
52
unsigned StubSize = 0);
53
54
SMLoc LastVersionDirective;
55
56
public:
57
DarwinAsmParser() = default;
58
59
void Initialize(MCAsmParser &Parser) override {
60
// Call the base implementation.
61
this->MCAsmParserExtension::Initialize(Parser);
62
63
addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");
64
addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
65
addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
66
".indirect_symbol");
67
addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
68
addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
69
".subsections_via_symbols");
70
addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
71
addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
72
addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
73
addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
74
".pushsection");
75
addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
76
".popsection");
77
addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
78
addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
79
".secure_log_unique");
80
addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
81
".secure_log_reset");
82
addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
83
addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");
84
85
addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
86
".data_region");
87
addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
88
".end_data_region");
89
90
// Special section directives.
91
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
92
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
93
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
94
".const_data");
95
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
96
".constructor");
97
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
98
".cstring");
99
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
100
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
101
".destructor");
102
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
103
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
104
".fvmlib_init0");
105
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
106
".fvmlib_init1");
107
addDirectiveHandler<
108
&DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
109
".lazy_symbol_pointer");
110
addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
111
".linker_option");
112
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
113
".literal16");
114
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
115
".literal4");
116
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
117
".literal8");
118
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
119
".mod_init_func");
120
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
121
".mod_term_func");
122
addDirectiveHandler<
123
&DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
124
".non_lazy_symbol_pointer");
125
addDirectiveHandler<
126
&DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(
127
".thread_local_variable_pointer");
128
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
129
".objc_cat_cls_meth");
130
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
131
".objc_cat_inst_meth");
132
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
133
".objc_category");
134
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
135
".objc_class");
136
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
137
".objc_class_names");
138
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
139
".objc_class_vars");
140
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
141
".objc_cls_meth");
142
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
143
".objc_cls_refs");
144
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
145
".objc_inst_meth");
146
addDirectiveHandler<
147
&DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
148
".objc_instance_vars");
149
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
150
".objc_message_refs");
151
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
152
".objc_meta_class");
153
addDirectiveHandler<
154
&DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
155
".objc_meth_var_names");
156
addDirectiveHandler<
157
&DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
158
".objc_meth_var_types");
159
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
160
".objc_module_info");
161
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
162
".objc_protocol");
163
addDirectiveHandler<
164
&DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
165
".objc_selector_strs");
166
addDirectiveHandler<
167
&DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
168
".objc_string_object");
169
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
170
".objc_symbols");
171
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
172
".picsymbol_stub");
173
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
174
".static_const");
175
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
176
".static_data");
177
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
178
".symbol_stub");
179
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
180
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
181
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
182
".thread_init_func");
183
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
184
185
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
186
addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(
187
".watchos_version_min");
188
addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(
189
".tvos_version_min");
190
addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(
191
".ios_version_min");
192
addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(
193
".macosx_version_min");
194
addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");
195
addDirectiveHandler<&DarwinAsmParser::parseDirectiveCGProfile>(
196
".cg_profile");
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
bool parseDirectiveCGProfile(StringRef Directive, SMLoc Loc);
470
};
471
472
} // end anonymous namespace
473
474
bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section,
475
unsigned TAA, unsigned Alignment,
476
unsigned StubSize) {
477
if (getLexer().isNot(AsmToken::EndOfStatement))
478
return TokError("unexpected token in section switching directive");
479
Lex();
480
481
// FIXME: Arch specific.
482
bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;
483
getStreamer().switchSection(getContext().getMachOSection(
484
Segment, Section, TAA, StubSize,
485
isText ? SectionKind::getText() : SectionKind::getData()));
486
487
// Set the implicit alignment, if any.
488
//
489
// FIXME: This isn't really what 'as' does; I think it just uses the implicit
490
// alignment on the section (e.g., if one manually inserts bytes into the
491
// section, then just issuing the section switch directive will not realign
492
// the section. However, this is arguably more reasonable behavior, and there
493
// is no good reason for someone to intentionally emit incorrectly sized
494
// values into the implicitly aligned sections.
495
if (Alignment)
496
getStreamer().emitValueToAlignment(Align(Alignment));
497
498
return false;
499
}
500
501
/// parseDirectiveAltEntry
502
/// ::= .alt_entry identifier
503
bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) {
504
StringRef Name;
505
if (getParser().parseIdentifier(Name))
506
return TokError("expected identifier in directive");
507
508
// Look up symbol.
509
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
510
511
if (Sym->isDefined())
512
return TokError(".alt_entry must preceed symbol definition");
513
514
if (!getStreamer().emitSymbolAttribute(Sym, MCSA_AltEntry))
515
return TokError("unable to emit symbol attribute");
516
517
Lex();
518
return false;
519
}
520
521
/// parseDirectiveDesc
522
/// ::= .desc identifier , expression
523
bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
524
StringRef Name;
525
if (getParser().parseIdentifier(Name))
526
return TokError("expected identifier in directive");
527
528
// Handle the identifier as the key symbol.
529
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
530
531
if (getLexer().isNot(AsmToken::Comma))
532
return TokError("unexpected token in '.desc' directive");
533
Lex();
534
535
int64_t DescValue;
536
if (getParser().parseAbsoluteExpression(DescValue))
537
return true;
538
539
if (getLexer().isNot(AsmToken::EndOfStatement))
540
return TokError("unexpected token in '.desc' directive");
541
542
Lex();
543
544
// Set the n_desc field of this Symbol to this DescValue
545
getStreamer().emitSymbolDesc(Sym, DescValue);
546
547
return false;
548
}
549
550
/// parseDirectiveIndirectSymbol
551
/// ::= .indirect_symbol identifier
552
bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
553
const MCSectionMachO *Current = static_cast<const MCSectionMachO *>(
554
getStreamer().getCurrentSectionOnly());
555
MachO::SectionType SectionType = Current->getType();
556
if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
557
SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
558
SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
559
SectionType != MachO::S_SYMBOL_STUBS)
560
return Error(Loc, "indirect symbol not in a symbol pointer or stub "
561
"section");
562
563
StringRef Name;
564
if (getParser().parseIdentifier(Name))
565
return TokError("expected identifier in .indirect_symbol directive");
566
567
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
568
569
// Assembler local symbols don't make any sense here. Complain loudly.
570
if (Sym->isTemporary())
571
return TokError("non-local symbol required in directive");
572
573
if (!getStreamer().emitSymbolAttribute(Sym, MCSA_IndirectSymbol))
574
return TokError("unable to emit indirect symbol attribute for: " + Name);
575
576
if (getLexer().isNot(AsmToken::EndOfStatement))
577
return TokError("unexpected token in '.indirect_symbol' directive");
578
579
Lex();
580
581
return false;
582
}
583
584
/// parseDirectiveDumpOrLoad
585
/// ::= ( .dump | .load ) "filename"
586
bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
587
SMLoc IDLoc) {
588
bool IsDump = Directive == ".dump";
589
if (getLexer().isNot(AsmToken::String))
590
return TokError("expected string in '.dump' or '.load' directive");
591
592
Lex();
593
594
if (getLexer().isNot(AsmToken::EndOfStatement))
595
return TokError("unexpected token in '.dump' or '.load' directive");
596
597
Lex();
598
599
// FIXME: If/when .dump and .load are implemented they will be done in the
600
// the assembly parser and not have any need for an MCStreamer API.
601
if (IsDump)
602
return Warning(IDLoc, "ignoring directive .dump for now");
603
else
604
return Warning(IDLoc, "ignoring directive .load for now");
605
}
606
607
/// ParseDirectiveLinkerOption
608
/// ::= .linker_option "string" ( , "string" )*
609
bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
610
SmallVector<std::string, 4> Args;
611
while (true) {
612
if (getLexer().isNot(AsmToken::String))
613
return TokError("expected string in '" + Twine(IDVal) + "' directive");
614
615
std::string Data;
616
if (getParser().parseEscapedString(Data))
617
return true;
618
619
Args.push_back(Data);
620
621
if (getLexer().is(AsmToken::EndOfStatement))
622
break;
623
624
if (getLexer().isNot(AsmToken::Comma))
625
return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
626
Lex();
627
}
628
629
getStreamer().emitLinkerOptions(Args);
630
return false;
631
}
632
633
/// parseDirectiveLsym
634
/// ::= .lsym identifier , expression
635
bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {
636
StringRef Name;
637
if (getParser().parseIdentifier(Name))
638
return TokError("expected identifier in directive");
639
640
// Handle the identifier as the key symbol.
641
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
642
643
if (getLexer().isNot(AsmToken::Comma))
644
return TokError("unexpected token in '.lsym' directive");
645
Lex();
646
647
const MCExpr *Value;
648
if (getParser().parseExpression(Value))
649
return true;
650
651
if (getLexer().isNot(AsmToken::EndOfStatement))
652
return TokError("unexpected token in '.lsym' directive");
653
654
Lex();
655
656
// We don't currently support this directive.
657
//
658
// FIXME: Diagnostic location!
659
(void) Sym;
660
return TokError("directive '.lsym' is unsupported");
661
}
662
663
/// parseDirectiveSection:
664
/// ::= .section identifier (',' identifier)*
665
bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
666
SMLoc Loc = getLexer().getLoc();
667
668
StringRef SectionName;
669
if (getParser().parseIdentifier(SectionName))
670
return Error(Loc, "expected identifier after '.section' directive");
671
672
// Verify there is a following comma.
673
if (!getLexer().is(AsmToken::Comma))
674
return TokError("unexpected token in '.section' directive");
675
676
std::string SectionSpec = std::string(SectionName);
677
SectionSpec += ",";
678
679
// Add all the tokens until the end of the line, ParseSectionSpecifier will
680
// handle this.
681
StringRef EOL = getLexer().LexUntilEndOfStatement();
682
SectionSpec.append(EOL.begin(), EOL.end());
683
684
Lex();
685
if (getLexer().isNot(AsmToken::EndOfStatement))
686
return TokError("unexpected token in '.section' directive");
687
Lex();
688
689
StringRef Segment, Section;
690
unsigned StubSize;
691
unsigned TAA;
692
bool TAAParsed;
693
if (class Error E = MCSectionMachO::ParseSectionSpecifier(
694
SectionSpec, Segment, Section, TAA, TAAParsed, StubSize))
695
return Error(Loc, toString(std::move(E)));
696
697
// Issue a warning if the target is not powerpc and Section is a *coal* section.
698
Triple TT = getParser().getContext().getTargetTriple();
699
Triple::ArchType ArchTy = TT.getArch();
700
701
if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) {
702
StringRef NonCoalSection = StringSwitch<StringRef>(Section)
703
.Case("__textcoal_nt", "__text")
704
.Case("__const_coal", "__const")
705
.Case("__datacoal_nt", "__data")
706
.Default(Section);
707
708
if (Section != NonCoalSection) {
709
StringRef SectionVal(Loc.getPointer());
710
size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B);
711
SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B);
712
SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E);
713
getParser().Warning(Loc, "section \"" + Section + "\" is deprecated",
714
SMRange(BLoc, ELoc));
715
getParser().Note(Loc, "change section name to \"" + NonCoalSection +
716
"\"", SMRange(BLoc, ELoc));
717
}
718
}
719
720
// FIXME: Arch specific.
721
bool isText = Segment == "__TEXT"; // FIXME: Hack.
722
getStreamer().switchSection(getContext().getMachOSection(
723
Segment, Section, TAA, StubSize,
724
isText ? SectionKind::getText() : SectionKind::getData()));
725
return false;
726
}
727
728
/// ParseDirectivePushSection:
729
/// ::= .pushsection identifier (',' identifier)*
730
bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {
731
getStreamer().pushSection();
732
733
if (parseDirectiveSection(S, Loc)) {
734
getStreamer().popSection();
735
return true;
736
}
737
738
return false;
739
}
740
741
/// ParseDirectivePopSection:
742
/// ::= .popsection
743
bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
744
if (!getStreamer().popSection())
745
return TokError(".popsection without corresponding .pushsection");
746
return false;
747
}
748
749
/// ParseDirectivePrevious:
750
/// ::= .previous
751
bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
752
MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
753
if (!PreviousSection.first)
754
return TokError(".previous without corresponding .section");
755
getStreamer().switchSection(PreviousSection.first, PreviousSection.second);
756
return false;
757
}
758
759
/// ParseDirectiveSecureLogUnique
760
/// ::= .secure_log_unique ... message ...
761
bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
762
StringRef LogMessage = getParser().parseStringToEndOfStatement();
763
if (getLexer().isNot(AsmToken::EndOfStatement))
764
return TokError("unexpected token in '.secure_log_unique' directive");
765
766
if (getContext().getSecureLogUsed())
767
return Error(IDLoc, ".secure_log_unique specified multiple times");
768
769
// Get the secure log path.
770
StringRef SecureLogFile = getContext().getSecureLogFile();
771
if (SecureLogFile.empty())
772
return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
773
"environment variable unset.");
774
775
// Open the secure log file if we haven't already.
776
raw_fd_ostream *OS = getContext().getSecureLog();
777
if (!OS) {
778
std::error_code EC;
779
auto NewOS = std::make_unique<raw_fd_ostream>(
780
SecureLogFile, EC, sys::fs::OF_Append | sys::fs::OF_TextWithCRLF);
781
if (EC)
782
return Error(IDLoc, Twine("can't open secure log file: ") +
783
SecureLogFile + " (" + EC.message() + ")");
784
OS = NewOS.get();
785
getContext().setSecureLog(std::move(NewOS));
786
}
787
788
// Write the message.
789
unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
790
*OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
791
<< ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
792
<< LogMessage + "\n";
793
794
getContext().setSecureLogUsed(true);
795
796
return false;
797
}
798
799
/// ParseDirectiveSecureLogReset
800
/// ::= .secure_log_reset
801
bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
802
if (getLexer().isNot(AsmToken::EndOfStatement))
803
return TokError("unexpected token in '.secure_log_reset' directive");
804
805
Lex();
806
807
getContext().setSecureLogUsed(false);
808
809
return false;
810
}
811
812
/// parseDirectiveSubsectionsViaSymbols
813
/// ::= .subsections_via_symbols
814
bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
815
if (getLexer().isNot(AsmToken::EndOfStatement))
816
return TokError("unexpected token in '.subsections_via_symbols' directive");
817
818
Lex();
819
820
getStreamer().emitAssemblerFlag(MCAF_SubsectionsViaSymbols);
821
822
return false;
823
}
824
825
/// ParseDirectiveTBSS
826
/// ::= .tbss identifier, size, align
827
bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
828
SMLoc IDLoc = getLexer().getLoc();
829
StringRef Name;
830
if (getParser().parseIdentifier(Name))
831
return TokError("expected identifier in directive");
832
833
// Handle the identifier as the key symbol.
834
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
835
836
if (getLexer().isNot(AsmToken::Comma))
837
return TokError("unexpected token in directive");
838
Lex();
839
840
int64_t Size;
841
SMLoc SizeLoc = getLexer().getLoc();
842
if (getParser().parseAbsoluteExpression(Size))
843
return true;
844
845
int64_t Pow2Alignment = 0;
846
SMLoc Pow2AlignmentLoc;
847
if (getLexer().is(AsmToken::Comma)) {
848
Lex();
849
Pow2AlignmentLoc = getLexer().getLoc();
850
if (getParser().parseAbsoluteExpression(Pow2Alignment))
851
return true;
852
}
853
854
if (getLexer().isNot(AsmToken::EndOfStatement))
855
return TokError("unexpected token in '.tbss' directive");
856
857
Lex();
858
859
if (Size < 0)
860
return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
861
"zero");
862
863
// FIXME: Diagnose overflow.
864
if (Pow2Alignment < 0)
865
return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
866
"than zero");
867
868
if (!Sym->isUndefined())
869
return Error(IDLoc, "invalid symbol redefinition");
870
871
getStreamer().emitTBSSSymbol(
872
getContext().getMachOSection("__DATA", "__thread_bss",
873
MachO::S_THREAD_LOCAL_ZEROFILL, 0,
874
SectionKind::getThreadBSS()),
875
Sym, Size, Align(1ULL << Pow2Alignment));
876
877
return false;
878
}
879
880
/// ParseDirectiveZerofill
881
/// ::= .zerofill segname , sectname [, identifier , size_expression [
882
/// , align_expression ]]
883
bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
884
StringRef Segment;
885
if (getParser().parseIdentifier(Segment))
886
return TokError("expected segment name after '.zerofill' directive");
887
888
if (getLexer().isNot(AsmToken::Comma))
889
return TokError("unexpected token in directive");
890
Lex();
891
892
StringRef Section;
893
SMLoc SectionLoc = getLexer().getLoc();
894
if (getParser().parseIdentifier(Section))
895
return TokError("expected section name after comma in '.zerofill' "
896
"directive");
897
898
// If this is the end of the line all that was wanted was to create the
899
// the section but with no symbol.
900
if (getLexer().is(AsmToken::EndOfStatement)) {
901
// Create the zerofill section but no symbol
902
getStreamer().emitZerofill(
903
getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
904
SectionKind::getBSS()),
905
/*Symbol=*/nullptr, /*Size=*/0, Align(1), SectionLoc);
906
return false;
907
}
908
909
if (getLexer().isNot(AsmToken::Comma))
910
return TokError("unexpected token in directive");
911
Lex();
912
913
SMLoc IDLoc = getLexer().getLoc();
914
StringRef IDStr;
915
if (getParser().parseIdentifier(IDStr))
916
return TokError("expected identifier in directive");
917
918
// handle the identifier as the key symbol.
919
MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr);
920
921
if (getLexer().isNot(AsmToken::Comma))
922
return TokError("unexpected token in directive");
923
Lex();
924
925
int64_t Size;
926
SMLoc SizeLoc = getLexer().getLoc();
927
if (getParser().parseAbsoluteExpression(Size))
928
return true;
929
930
int64_t Pow2Alignment = 0;
931
SMLoc Pow2AlignmentLoc;
932
if (getLexer().is(AsmToken::Comma)) {
933
Lex();
934
Pow2AlignmentLoc = getLexer().getLoc();
935
if (getParser().parseAbsoluteExpression(Pow2Alignment))
936
return true;
937
}
938
939
if (getLexer().isNot(AsmToken::EndOfStatement))
940
return TokError("unexpected token in '.zerofill' directive");
941
942
Lex();
943
944
if (Size < 0)
945
return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
946
"than zero");
947
948
// NOTE: The alignment in the directive is a power of 2 value, the assembler
949
// may internally end up wanting an alignment in bytes.
950
// FIXME: Diagnose overflow.
951
if (Pow2Alignment < 0)
952
return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
953
"can't be less than zero");
954
955
if (!Sym->isUndefined())
956
return Error(IDLoc, "invalid symbol redefinition");
957
958
// Create the zerofill Symbol with Size and Pow2Alignment
959
//
960
// FIXME: Arch specific.
961
getStreamer().emitZerofill(
962
getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
963
SectionKind::getBSS()),
964
Sym, Size, Align(1ULL << Pow2Alignment), SectionLoc);
965
966
return false;
967
}
968
969
/// ParseDirectiveDataRegion
970
/// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
971
bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
972
if (getLexer().is(AsmToken::EndOfStatement)) {
973
Lex();
974
getStreamer().emitDataRegion(MCDR_DataRegion);
975
return false;
976
}
977
StringRef RegionType;
978
SMLoc Loc = getParser().getTok().getLoc();
979
if (getParser().parseIdentifier(RegionType))
980
return TokError("expected region type after '.data_region' directive");
981
int Kind = StringSwitch<int>(RegionType)
982
.Case("jt8", MCDR_DataRegionJT8)
983
.Case("jt16", MCDR_DataRegionJT16)
984
.Case("jt32", MCDR_DataRegionJT32)
985
.Default(-1);
986
if (Kind == -1)
987
return Error(Loc, "unknown region type in '.data_region' directive");
988
Lex();
989
990
getStreamer().emitDataRegion((MCDataRegionType)Kind);
991
return false;
992
}
993
994
/// ParseDirectiveDataRegionEnd
995
/// ::= .end_data_region
996
bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
997
if (getLexer().isNot(AsmToken::EndOfStatement))
998
return TokError("unexpected token in '.end_data_region' directive");
999
1000
Lex();
1001
getStreamer().emitDataRegion(MCDR_DataRegionEnd);
1002
return false;
1003
}
1004
1005
static bool isSDKVersionToken(const AsmToken &Tok) {
1006
return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version";
1007
}
1008
1009
/// parseMajorMinorVersionComponent ::= major, minor
1010
bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major,
1011
unsigned *Minor,
1012
const char *VersionName) {
1013
// Get the major version number.
1014
if (getLexer().isNot(AsmToken::Integer))
1015
return TokError(Twine("invalid ") + VersionName +
1016
" major version number, integer expected");
1017
int64_t MajorVal = getLexer().getTok().getIntVal();
1018
if (MajorVal > 65535 || MajorVal <= 0)
1019
return TokError(Twine("invalid ") + VersionName + " major version number");
1020
*Major = (unsigned)MajorVal;
1021
Lex();
1022
if (getLexer().isNot(AsmToken::Comma))
1023
return TokError(Twine(VersionName) +
1024
" minor version number required, comma expected");
1025
Lex();
1026
// Get the minor version number.
1027
if (getLexer().isNot(AsmToken::Integer))
1028
return TokError(Twine("invalid ") + VersionName +
1029
" minor version number, integer expected");
1030
int64_t MinorVal = getLexer().getTok().getIntVal();
1031
if (MinorVal > 255 || MinorVal < 0)
1032
return TokError(Twine("invalid ") + VersionName + " minor version number");
1033
*Minor = MinorVal;
1034
Lex();
1035
return false;
1036
}
1037
1038
/// parseOptionalTrailingVersionComponent ::= , version_number
1039
bool DarwinAsmParser::parseOptionalTrailingVersionComponent(
1040
unsigned *Component, const char *ComponentName) {
1041
assert(getLexer().is(AsmToken::Comma) && "comma expected");
1042
Lex();
1043
if (getLexer().isNot(AsmToken::Integer))
1044
return TokError(Twine("invalid ") + ComponentName +
1045
" version number, integer expected");
1046
int64_t Val = getLexer().getTok().getIntVal();
1047
if (Val > 255 || Val < 0)
1048
return TokError(Twine("invalid ") + ComponentName + " version number");
1049
*Component = Val;
1050
Lex();
1051
return false;
1052
}
1053
1054
/// parseVersion ::= parseMajorMinorVersionComponent
1055
/// parseOptionalTrailingVersionComponent
1056
bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
1057
unsigned *Update) {
1058
if (parseMajorMinorVersionComponent(Major, Minor, "OS"))
1059
return true;
1060
1061
// Get the update level, if specified
1062
*Update = 0;
1063
if (getLexer().is(AsmToken::EndOfStatement) ||
1064
isSDKVersionToken(getLexer().getTok()))
1065
return false;
1066
if (getLexer().isNot(AsmToken::Comma))
1067
return TokError("invalid OS update specifier, comma expected");
1068
if (parseOptionalTrailingVersionComponent(Update, "OS update"))
1069
return true;
1070
return false;
1071
}
1072
1073
bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) {
1074
assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");
1075
Lex();
1076
unsigned Major, Minor;
1077
if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK"))
1078
return true;
1079
SDKVersion = VersionTuple(Major, Minor);
1080
1081
// Get the subminor version, if specified.
1082
if (getLexer().is(AsmToken::Comma)) {
1083
unsigned Subminor;
1084
if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor"))
1085
return true;
1086
SDKVersion = VersionTuple(Major, Minor, Subminor);
1087
}
1088
return false;
1089
}
1090
1091
void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,
1092
SMLoc Loc, Triple::OSType ExpectedOS) {
1093
const Triple &Target = getContext().getTargetTriple();
1094
if (Target.getOS() != ExpectedOS)
1095
Warning(Loc, Twine(Directive) +
1096
(Arg.empty() ? Twine() : Twine(' ') + Arg) +
1097
" used while targeting " + Target.getOSName());
1098
1099
if (LastVersionDirective.isValid()) {
1100
Warning(Loc, "overriding previous version directive");
1101
Note(LastVersionDirective, "previous definition is here");
1102
}
1103
LastVersionDirective = Loc;
1104
}
1105
1106
static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {
1107
switch (Type) {
1108
case MCVM_WatchOSVersionMin: return Triple::WatchOS;
1109
case MCVM_TvOSVersionMin: return Triple::TvOS;
1110
case MCVM_IOSVersionMin: return Triple::IOS;
1111
case MCVM_OSXVersionMin: return Triple::MacOSX;
1112
}
1113
llvm_unreachable("Invalid mc version min type");
1114
}
1115
1116
/// parseVersionMin
1117
/// ::= .ios_version_min parseVersion parseSDKVersion
1118
/// | .macosx_version_min parseVersion parseSDKVersion
1119
/// | .tvos_version_min parseVersion parseSDKVersion
1120
/// | .watchos_version_min parseVersion parseSDKVersion
1121
bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,
1122
MCVersionMinType Type) {
1123
unsigned Major;
1124
unsigned Minor;
1125
unsigned Update;
1126
if (parseVersion(&Major, &Minor, &Update))
1127
return true;
1128
1129
VersionTuple SDKVersion;
1130
if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
1131
return true;
1132
1133
if (parseEOL())
1134
return addErrorSuffix(Twine(" in '") + Directive + "' directive");
1135
1136
Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);
1137
checkVersion(Directive, StringRef(), Loc, ExpectedOS);
1138
getStreamer().emitVersionMin(Type, Major, Minor, Update, SDKVersion);
1139
return false;
1140
}
1141
1142
static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {
1143
switch (Type) {
1144
case MachO::PLATFORM_UNKNOWN: /* silence warning */
1145
break;
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_XROS: return Triple::XROS;
1151
case MachO::PLATFORM_BRIDGEOS: /* silence warning */ break;
1152
case MachO::PLATFORM_DRIVERKIT:
1153
return Triple::DriverKit;
1154
case MachO::PLATFORM_MACCATALYST: return Triple::IOS;
1155
case MachO::PLATFORM_IOSSIMULATOR: /* silence warning */ break;
1156
case MachO::PLATFORM_TVOSSIMULATOR: /* silence warning */ break;
1157
case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break;
1158
case MachO::PLATFORM_XROS_SIMULATOR: /* silence warning */ break;
1159
}
1160
llvm_unreachable("Invalid mach-o platform type");
1161
}
1162
1163
/// parseBuildVersion
1164
/// ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion
1165
bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
1166
StringRef PlatformName;
1167
SMLoc PlatformLoc = getTok().getLoc();
1168
if (getParser().parseIdentifier(PlatformName))
1169
return TokError("platform name expected");
1170
1171
unsigned Platform = StringSwitch<unsigned>(PlatformName)
1172
#define PLATFORM(platform, id, name, build_name, target, tapi_target, \
1173
marketing) \
1174
.Case(#build_name, MachO::PLATFORM_##platform)
1175
#include "llvm/BinaryFormat/MachO.def"
1176
.Default(MachO::PLATFORM_UNKNOWN);
1177
1178
if (Platform == MachO::PLATFORM_UNKNOWN)
1179
return Error(PlatformLoc, "unknown platform name");
1180
1181
if (getLexer().isNot(AsmToken::Comma))
1182
return TokError("version number required, comma expected");
1183
Lex();
1184
1185
unsigned Major;
1186
unsigned Minor;
1187
unsigned Update;
1188
if (parseVersion(&Major, &Minor, &Update))
1189
return true;
1190
1191
VersionTuple SDKVersion;
1192
if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
1193
return true;
1194
1195
if (parseEOL())
1196
return addErrorSuffix(" in '.build_version' directive");
1197
1198
Triple::OSType ExpectedOS
1199
= getOSTypeFromPlatform((MachO::PlatformType)Platform);
1200
checkVersion(Directive, PlatformName, Loc, ExpectedOS);
1201
getStreamer().emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
1202
return false;
1203
}
1204
1205
/// parseDirectiveCGProfile
1206
/// ::= .cg_profile from, to, count
1207
bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
1208
return MCAsmParserExtension::ParseDirectiveCGProfile(S, Loc);
1209
}
1210
1211
namespace llvm {
1212
1213
MCAsmParserExtension *createDarwinAsmParser() {
1214
return new DarwinAsmParser;
1215
}
1216
1217
} // end llvm namespace
1218
1219