1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | #include "llvm/MC/MCParser/MCAsmParserExtension.h" |
11 | #include "llvm/ADT/STLExtras.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/MC/MCContext.h" |
17 | #include "llvm/MC/MCObjectFileInfo.h" |
18 | #include "llvm/MC/MCParser/MCAsmLexer.h" |
19 | #include "llvm/MC/MCParser/MCAsmParser.h" |
20 | #include "llvm/MC/MCSectionMachO.h" |
21 | #include "llvm/MC/MCStreamer.h" |
22 | #include "llvm/MC/MCSymbol.h" |
23 | #include "llvm/Support/FileSystem.h" |
24 | #include "llvm/Support/MemoryBuffer.h" |
25 | #include "llvm/Support/SourceMgr.h" |
26 | using namespace llvm; |
27 | |
28 | namespace { |
29 | |
30 | |
31 | |
32 | class DarwinAsmParser : public MCAsmParserExtension { |
33 | template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)> |
34 | void addDirectiveHandler(StringRef Directive) { |
35 | MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( |
36 | this, HandleDirective<DarwinAsmParser, HandlerMethod>); |
37 | getParser().addDirectiveHandler(Directive, Handler); |
38 | } |
39 | |
40 | bool parseSectionSwitch(StringRef Segment, StringRef Section, |
41 | unsigned TAA = 0, unsigned ImplicitAlign = 0, |
42 | unsigned StubSize = 0); |
43 | |
44 | SMLoc LastVersionMinDirective; |
45 | |
46 | public: |
47 | DarwinAsmParser() {} |
48 | |
49 | void Initialize(MCAsmParser &Parser) override { |
50 | |
51 | this->MCAsmParserExtension::Initialize(Parser); |
52 | |
53 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry"); |
54 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc"); |
55 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>( |
56 | ".indirect_symbol"); |
57 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym"); |
58 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>( |
59 | ".subsections_via_symbols"); |
60 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump"); |
61 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load"); |
62 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section"); |
63 | addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>( |
64 | ".pushsection"); |
65 | addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>( |
66 | ".popsection"); |
67 | addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous"); |
68 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>( |
69 | ".secure_log_unique"); |
70 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>( |
71 | ".secure_log_reset"); |
72 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss"); |
73 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill"); |
74 | |
75 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>( |
76 | ".data_region"); |
77 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>( |
78 | ".end_data_region"); |
79 | |
80 | |
81 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss"); |
82 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const"); |
83 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>( |
84 | ".const_data"); |
85 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>( |
86 | ".constructor"); |
87 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>( |
88 | ".cstring"); |
89 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data"); |
90 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>( |
91 | ".destructor"); |
92 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld"); |
93 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>( |
94 | ".fvmlib_init0"); |
95 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>( |
96 | ".fvmlib_init1"); |
97 | addDirectiveHandler< |
98 | &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>( |
99 | ".lazy_symbol_pointer"); |
100 | addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>( |
101 | ".linker_option"); |
102 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>( |
103 | ".literal16"); |
104 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>( |
105 | ".literal4"); |
106 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>( |
107 | ".literal8"); |
108 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>( |
109 | ".mod_init_func"); |
110 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>( |
111 | ".mod_term_func"); |
112 | addDirectiveHandler< |
113 | &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>( |
114 | ".non_lazy_symbol_pointer"); |
115 | addDirectiveHandler< |
116 | &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>( |
117 | ".thread_local_variable_pointer"); |
118 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>( |
119 | ".objc_cat_cls_meth"); |
120 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>( |
121 | ".objc_cat_inst_meth"); |
122 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>( |
123 | ".objc_category"); |
124 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>( |
125 | ".objc_class"); |
126 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>( |
127 | ".objc_class_names"); |
128 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>( |
129 | ".objc_class_vars"); |
130 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>( |
131 | ".objc_cls_meth"); |
132 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>( |
133 | ".objc_cls_refs"); |
134 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>( |
135 | ".objc_inst_meth"); |
136 | addDirectiveHandler< |
137 | &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>( |
138 | ".objc_instance_vars"); |
139 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>( |
140 | ".objc_message_refs"); |
141 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>( |
142 | ".objc_meta_class"); |
143 | addDirectiveHandler< |
144 | &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>( |
145 | ".objc_meth_var_names"); |
146 | addDirectiveHandler< |
147 | &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>( |
148 | ".objc_meth_var_types"); |
149 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>( |
150 | ".objc_module_info"); |
151 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>( |
152 | ".objc_protocol"); |
153 | addDirectiveHandler< |
154 | &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>( |
155 | ".objc_selector_strs"); |
156 | addDirectiveHandler< |
157 | &DarwinAsmParser::parseSectionDirectiveObjCStringObject>( |
158 | ".objc_string_object"); |
159 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>( |
160 | ".objc_symbols"); |
161 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>( |
162 | ".picsymbol_stub"); |
163 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>( |
164 | ".static_const"); |
165 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>( |
166 | ".static_data"); |
167 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>( |
168 | ".symbol_stub"); |
169 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata"); |
170 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text"); |
171 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>( |
172 | ".thread_init_func"); |
173 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv"); |
174 | |
175 | addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident"); |
176 | addDirectiveHandler<&DarwinAsmParser::parseVersionMin>( |
177 | ".watchos_version_min"); |
178 | addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".tvos_version_min"); |
179 | addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min"); |
180 | addDirectiveHandler<&DarwinAsmParser::parseVersionMin>( |
181 | ".macosx_version_min"); |
182 | |
183 | LastVersionMinDirective = SMLoc(); |
184 | } |
185 | |
186 | bool parseDirectiveAltEntry(StringRef, SMLoc); |
187 | bool parseDirectiveDesc(StringRef, SMLoc); |
188 | bool parseDirectiveIndirectSymbol(StringRef, SMLoc); |
189 | bool parseDirectiveDumpOrLoad(StringRef, SMLoc); |
190 | bool parseDirectiveLsym(StringRef, SMLoc); |
191 | bool parseDirectiveLinkerOption(StringRef, SMLoc); |
192 | bool parseDirectiveSection(StringRef, SMLoc); |
193 | bool parseDirectivePushSection(StringRef, SMLoc); |
194 | bool parseDirectivePopSection(StringRef, SMLoc); |
195 | bool parseDirectivePrevious(StringRef, SMLoc); |
196 | bool parseDirectiveSecureLogReset(StringRef, SMLoc); |
197 | bool parseDirectiveSecureLogUnique(StringRef, SMLoc); |
198 | bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); |
199 | bool parseDirectiveTBSS(StringRef, SMLoc); |
200 | bool parseDirectiveZerofill(StringRef, SMLoc); |
201 | bool parseDirectiveDataRegion(StringRef, SMLoc); |
202 | bool parseDirectiveDataRegionEnd(StringRef, SMLoc); |
203 | |
204 | |
205 | bool parseSectionDirectiveBss(StringRef, SMLoc) { |
206 | return parseSectionSwitch("__DATA", "__bss"); |
207 | } |
208 | |
209 | bool parseSectionDirectiveConst(StringRef, SMLoc) { |
210 | return parseSectionSwitch("__TEXT", "__const"); |
211 | } |
212 | bool parseSectionDirectiveStaticConst(StringRef, SMLoc) { |
213 | return parseSectionSwitch("__TEXT", "__static_const"); |
214 | } |
215 | bool parseSectionDirectiveCString(StringRef, SMLoc) { |
216 | return parseSectionSwitch("__TEXT","__cstring", |
217 | MachO::S_CSTRING_LITERALS); |
218 | } |
219 | bool parseSectionDirectiveLiteral4(StringRef, SMLoc) { |
220 | return parseSectionSwitch("__TEXT", "__literal4", |
221 | MachO::S_4BYTE_LITERALS, 4); |
222 | } |
223 | bool parseSectionDirectiveLiteral8(StringRef, SMLoc) { |
224 | return parseSectionSwitch("__TEXT", "__literal8", |
225 | MachO::S_8BYTE_LITERALS, 8); |
226 | } |
227 | bool parseSectionDirectiveLiteral16(StringRef, SMLoc) { |
228 | return parseSectionSwitch("__TEXT","__literal16", |
229 | MachO::S_16BYTE_LITERALS, 16); |
230 | } |
231 | bool parseSectionDirectiveConstructor(StringRef, SMLoc) { |
232 | return parseSectionSwitch("__TEXT","__constructor"); |
233 | } |
234 | bool parseSectionDirectiveDestructor(StringRef, SMLoc) { |
235 | return parseSectionSwitch("__TEXT","__destructor"); |
236 | } |
237 | bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) { |
238 | return parseSectionSwitch("__TEXT","__fvmlib_init0"); |
239 | } |
240 | bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) { |
241 | return parseSectionSwitch("__TEXT","__fvmlib_init1"); |
242 | } |
243 | bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) { |
244 | return parseSectionSwitch("__TEXT","__symbol_stub", |
245 | MachO::S_SYMBOL_STUBS | |
246 | MachO::S_ATTR_PURE_INSTRUCTIONS, |
247 | |
248 | 0, 16); |
249 | } |
250 | bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) { |
251 | return parseSectionSwitch("__TEXT","__picsymbol_stub", |
252 | MachO::S_SYMBOL_STUBS | |
253 | MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26); |
254 | } |
255 | bool parseSectionDirectiveData(StringRef, SMLoc) { |
256 | return parseSectionSwitch("__DATA", "__data"); |
257 | } |
258 | bool parseSectionDirectiveStaticData(StringRef, SMLoc) { |
259 | return parseSectionSwitch("__DATA", "__static_data"); |
260 | } |
261 | bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) { |
262 | return parseSectionSwitch("__DATA", "__nl_symbol_ptr", |
263 | MachO::S_NON_LAZY_SYMBOL_POINTERS, 4); |
264 | } |
265 | bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) { |
266 | return parseSectionSwitch("__DATA", "__la_symbol_ptr", |
267 | MachO::S_LAZY_SYMBOL_POINTERS, 4); |
268 | } |
269 | bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) { |
270 | return parseSectionSwitch("__DATA", "__thread_ptr", |
271 | MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4); |
272 | } |
273 | bool parseSectionDirectiveDyld(StringRef, SMLoc) { |
274 | return parseSectionSwitch("__DATA", "__dyld"); |
275 | } |
276 | bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) { |
277 | return parseSectionSwitch("__DATA", "__mod_init_func", |
278 | MachO::S_MOD_INIT_FUNC_POINTERS, 4); |
279 | } |
280 | bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) { |
281 | return parseSectionSwitch("__DATA", "__mod_term_func", |
282 | MachO::S_MOD_TERM_FUNC_POINTERS, 4); |
283 | } |
284 | bool parseSectionDirectiveConstData(StringRef, SMLoc) { |
285 | return parseSectionSwitch("__DATA", "__const"); |
286 | } |
287 | bool parseSectionDirectiveObjCClass(StringRef, SMLoc) { |
288 | return parseSectionSwitch("__OBJC", "__class", |
289 | MachO::S_ATTR_NO_DEAD_STRIP); |
290 | } |
291 | bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) { |
292 | return parseSectionSwitch("__OBJC", "__meta_class", |
293 | MachO::S_ATTR_NO_DEAD_STRIP); |
294 | } |
295 | bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) { |
296 | return parseSectionSwitch("__OBJC", "__cat_cls_meth", |
297 | MachO::S_ATTR_NO_DEAD_STRIP); |
298 | } |
299 | bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) { |
300 | return parseSectionSwitch("__OBJC", "__cat_inst_meth", |
301 | MachO::S_ATTR_NO_DEAD_STRIP); |
302 | } |
303 | bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) { |
304 | return parseSectionSwitch("__OBJC", "__protocol", |
305 | MachO::S_ATTR_NO_DEAD_STRIP); |
306 | } |
307 | bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) { |
308 | return parseSectionSwitch("__OBJC", "__string_object", |
309 | MachO::S_ATTR_NO_DEAD_STRIP); |
310 | } |
311 | bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) { |
312 | return parseSectionSwitch("__OBJC", "__cls_meth", |
313 | MachO::S_ATTR_NO_DEAD_STRIP); |
314 | } |
315 | bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) { |
316 | return parseSectionSwitch("__OBJC", "__inst_meth", |
317 | MachO::S_ATTR_NO_DEAD_STRIP); |
318 | } |
319 | bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) { |
320 | return parseSectionSwitch("__OBJC", "__cls_refs", |
321 | MachO::S_ATTR_NO_DEAD_STRIP | |
322 | MachO::S_LITERAL_POINTERS, 4); |
323 | } |
324 | bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) { |
325 | return parseSectionSwitch("__OBJC", "__message_refs", |
326 | MachO::S_ATTR_NO_DEAD_STRIP | |
327 | MachO::S_LITERAL_POINTERS, 4); |
328 | } |
329 | bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) { |
330 | return parseSectionSwitch("__OBJC", "__symbols", |
331 | MachO::S_ATTR_NO_DEAD_STRIP); |
332 | } |
333 | bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) { |
334 | return parseSectionSwitch("__OBJC", "__category", |
335 | MachO::S_ATTR_NO_DEAD_STRIP); |
336 | } |
337 | bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) { |
338 | return parseSectionSwitch("__OBJC", "__class_vars", |
339 | MachO::S_ATTR_NO_DEAD_STRIP); |
340 | } |
341 | bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) { |
342 | return parseSectionSwitch("__OBJC", "__instance_vars", |
343 | MachO::S_ATTR_NO_DEAD_STRIP); |
344 | } |
345 | bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) { |
346 | return parseSectionSwitch("__OBJC", "__module_info", |
347 | MachO::S_ATTR_NO_DEAD_STRIP); |
348 | } |
349 | bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) { |
350 | return parseSectionSwitch("__TEXT", "__cstring", |
351 | MachO::S_CSTRING_LITERALS); |
352 | } |
353 | bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) { |
354 | return parseSectionSwitch("__TEXT", "__cstring", |
355 | MachO::S_CSTRING_LITERALS); |
356 | } |
357 | bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) { |
358 | return parseSectionSwitch("__TEXT", "__cstring", |
359 | MachO::S_CSTRING_LITERALS); |
360 | } |
361 | bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) { |
362 | return parseSectionSwitch("__OBJC", "__selector_strs", |
363 | MachO::S_CSTRING_LITERALS); |
364 | } |
365 | bool parseSectionDirectiveTData(StringRef, SMLoc) { |
366 | return parseSectionSwitch("__DATA", "__thread_data", |
367 | MachO::S_THREAD_LOCAL_REGULAR); |
368 | } |
369 | bool parseSectionDirectiveText(StringRef, SMLoc) { |
370 | return parseSectionSwitch("__TEXT", "__text", |
371 | MachO::S_ATTR_PURE_INSTRUCTIONS); |
372 | } |
373 | bool parseSectionDirectiveTLV(StringRef, SMLoc) { |
374 | return parseSectionSwitch("__DATA", "__thread_vars", |
375 | MachO::S_THREAD_LOCAL_VARIABLES); |
376 | } |
377 | bool parseSectionDirectiveIdent(StringRef, SMLoc) { |
378 | |
379 | getParser().eatToEndOfStatement(); |
380 | return false; |
381 | } |
382 | bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) { |
383 | return parseSectionSwitch("__DATA", "__thread_init", |
384 | MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); |
385 | } |
386 | bool parseVersionMin(StringRef, SMLoc); |
387 | |
388 | }; |
389 | |
390 | } |
391 | |
392 | bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section, |
393 | unsigned TAA, unsigned Align, |
394 | unsigned StubSize) { |
395 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
396 | return TokError("unexpected token in section switching directive"); |
397 | Lex(); |
398 | |
399 | |
400 | bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS; |
401 | getStreamer().SwitchSection(getContext().getMachOSection( |
402 | Segment, Section, TAA, StubSize, |
403 | isText ? SectionKind::getText() : SectionKind::getData())); |
404 | |
405 | |
406 | |
407 | |
408 | |
409 | |
410 | |
411 | |
412 | |
413 | if (Align) |
414 | getStreamer().EmitValueToAlignment(Align); |
415 | |
416 | return false; |
417 | } |
418 | |
419 | |
420 | |
421 | bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) { |
422 | StringRef Name; |
423 | if (getParser().parseIdentifier(Name)) |
424 | return TokError("expected identifier in directive"); |
425 | |
426 | |
427 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); |
428 | |
429 | if (Sym->isDefined()) |
430 | return TokError(".alt_entry must preceed symbol definition"); |
431 | |
432 | if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_AltEntry)) |
433 | return TokError("unable to emit symbol attribute"); |
434 | |
435 | Lex(); |
436 | return false; |
437 | } |
438 | |
439 | |
440 | |
441 | bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) { |
442 | StringRef Name; |
443 | if (getParser().parseIdentifier(Name)) |
444 | return TokError("expected identifier in directive"); |
445 | |
446 | |
447 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); |
448 | |
449 | if (getLexer().isNot(AsmToken::Comma)) |
450 | return TokError("unexpected token in '.desc' directive"); |
451 | Lex(); |
452 | |
453 | int64_t DescValue; |
454 | if (getParser().parseAbsoluteExpression(DescValue)) |
455 | return true; |
456 | |
457 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
458 | return TokError("unexpected token in '.desc' directive"); |
459 | |
460 | Lex(); |
461 | |
462 | |
463 | getStreamer().EmitSymbolDesc(Sym, DescValue); |
464 | |
465 | return false; |
466 | } |
467 | |
468 | |
469 | |
470 | bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { |
471 | const MCSectionMachO *Current = static_cast<const MCSectionMachO*>( |
| 1 | 'Current' initialized to a null pointer value | |
|
472 | getStreamer().getCurrentSection().first); |
473 | MachO::SectionType SectionType = Current->getType(); |
| 2 | | Called C++ object pointer is null |
|
474 | if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && |
475 | SectionType != MachO::S_LAZY_SYMBOL_POINTERS && |
476 | SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS && |
477 | SectionType != MachO::S_SYMBOL_STUBS) |
478 | return Error(Loc, "indirect symbol not in a symbol pointer or stub " |
479 | "section"); |
480 | |
481 | StringRef Name; |
482 | if (getParser().parseIdentifier(Name)) |
483 | return TokError("expected identifier in .indirect_symbol directive"); |
484 | |
485 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); |
486 | |
487 | |
488 | if (Sym->isTemporary()) |
489 | return TokError("non-local symbol required in directive"); |
490 | |
491 | if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol)) |
492 | return TokError("unable to emit indirect symbol attribute for: " + Name); |
493 | |
494 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
495 | return TokError("unexpected token in '.indirect_symbol' directive"); |
496 | |
497 | Lex(); |
498 | |
499 | return false; |
500 | } |
501 | |
502 | |
503 | |
504 | bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive, |
505 | SMLoc IDLoc) { |
506 | bool IsDump = Directive == ".dump"; |
507 | if (getLexer().isNot(AsmToken::String)) |
508 | return TokError("expected string in '.dump' or '.load' directive"); |
509 | |
510 | Lex(); |
511 | |
512 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
513 | return TokError("unexpected token in '.dump' or '.load' directive"); |
514 | |
515 | Lex(); |
516 | |
517 | |
518 | |
519 | if (IsDump) |
520 | return Warning(IDLoc, "ignoring directive .dump for now"); |
521 | else |
522 | return Warning(IDLoc, "ignoring directive .load for now"); |
523 | } |
524 | |
525 | |
526 | |
527 | bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) { |
528 | SmallVector<std::string, 4> Args; |
529 | for (;;) { |
530 | if (getLexer().isNot(AsmToken::String)) |
531 | return TokError("expected string in '" + Twine(IDVal) + "' directive"); |
532 | |
533 | std::string Data; |
534 | if (getParser().parseEscapedString(Data)) |
535 | return true; |
536 | |
537 | Args.push_back(Data); |
538 | |
539 | if (getLexer().is(AsmToken::EndOfStatement)) |
540 | break; |
541 | |
542 | if (getLexer().isNot(AsmToken::Comma)) |
543 | return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); |
544 | Lex(); |
545 | } |
546 | |
547 | getStreamer().EmitLinkerOptions(Args); |
548 | return false; |
549 | } |
550 | |
551 | |
552 | |
553 | bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) { |
554 | StringRef Name; |
555 | if (getParser().parseIdentifier(Name)) |
556 | return TokError("expected identifier in directive"); |
557 | |
558 | |
559 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); |
560 | |
561 | if (getLexer().isNot(AsmToken::Comma)) |
562 | return TokError("unexpected token in '.lsym' directive"); |
563 | Lex(); |
564 | |
565 | const MCExpr *Value; |
566 | if (getParser().parseExpression(Value)) |
567 | return true; |
568 | |
569 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
570 | return TokError("unexpected token in '.lsym' directive"); |
571 | |
572 | Lex(); |
573 | |
574 | |
575 | |
576 | |
577 | (void) Sym; |
578 | return TokError("directive '.lsym' is unsupported"); |
579 | } |
580 | |
581 | |
582 | |
583 | bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) { |
584 | SMLoc Loc = getLexer().getLoc(); |
585 | |
586 | StringRef SectionName; |
587 | if (getParser().parseIdentifier(SectionName)) |
588 | return Error(Loc, "expected identifier after '.section' directive"); |
589 | |
590 | |
591 | if (!getLexer().is(AsmToken::Comma)) |
592 | return TokError("unexpected token in '.section' directive"); |
593 | |
594 | std::string SectionSpec = SectionName; |
595 | SectionSpec += ","; |
596 | |
597 | |
598 | |
599 | StringRef EOL = getLexer().LexUntilEndOfStatement(); |
600 | SectionSpec.append(EOL.begin(), EOL.end()); |
601 | |
602 | Lex(); |
603 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
604 | return TokError("unexpected token in '.section' directive"); |
605 | Lex(); |
606 | |
607 | |
608 | StringRef Segment, Section; |
609 | unsigned StubSize; |
610 | unsigned TAA; |
611 | bool TAAParsed; |
612 | std::string ErrorStr = |
613 | MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, |
614 | TAA, TAAParsed, StubSize); |
615 | |
616 | if (!ErrorStr.empty()) |
617 | return Error(Loc, ErrorStr.c_str()); |
618 | |
619 | |
620 | Triple TT = getParser().getContext().getObjectFileInfo()->getTargetTriple(); |
621 | Triple::ArchType ArchTy = TT.getArch(); |
622 | |
623 | if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) { |
624 | StringRef NonCoalSection = StringSwitch<StringRef>(Section) |
625 | .Case("__textcoal_nt", "__text") |
626 | .Case("__const_coal", "__const") |
627 | .Case("__datacoal_nt", "__data") |
628 | .Default(Section); |
629 | |
630 | if (!Section.equals(NonCoalSection)) { |
631 | StringRef SectionVal(Loc.getPointer()); |
632 | size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B); |
633 | SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B); |
634 | SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E); |
635 | getParser().Warning(Loc, "section \"" + Section + "\" is deprecated", |
636 | SMRange(BLoc, ELoc)); |
637 | getParser().Note(Loc, "change section name to \"" + NonCoalSection + |
638 | "\"", SMRange(BLoc, ELoc)); |
639 | } |
640 | } |
641 | |
642 | |
643 | bool isText = Segment == "__TEXT"; |
644 | getStreamer().SwitchSection(getContext().getMachOSection( |
645 | Segment, Section, TAA, StubSize, |
646 | isText ? SectionKind::getText() : SectionKind::getData())); |
647 | return false; |
648 | } |
649 | |
650 | |
651 | |
652 | bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) { |
653 | getStreamer().PushSection(); |
654 | |
655 | if (parseDirectiveSection(S, Loc)) { |
656 | getStreamer().PopSection(); |
657 | return true; |
658 | } |
659 | |
660 | return false; |
661 | } |
662 | |
663 | |
664 | |
665 | bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) { |
666 | if (!getStreamer().PopSection()) |
667 | return TokError(".popsection without corresponding .pushsection"); |
668 | return false; |
669 | } |
670 | |
671 | |
672 | |
673 | bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { |
674 | MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); |
675 | if (!PreviousSection.first) |
676 | return TokError(".previous without corresponding .section"); |
677 | getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); |
678 | return false; |
679 | } |
680 | |
681 | |
682 | |
683 | bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { |
684 | StringRef LogMessage = getParser().parseStringToEndOfStatement(); |
685 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
686 | return TokError("unexpected token in '.secure_log_unique' directive"); |
687 | |
688 | if (getContext().getSecureLogUsed()) |
689 | return Error(IDLoc, ".secure_log_unique specified multiple times"); |
690 | |
691 | |
692 | const char *SecureLogFile = getContext().getSecureLogFile(); |
693 | if (!SecureLogFile) |
694 | return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " |
695 | "environment variable unset."); |
696 | |
697 | |
698 | raw_fd_ostream *OS = getContext().getSecureLog(); |
699 | if (!OS) { |
700 | std::error_code EC; |
701 | auto NewOS = llvm::make_unique<raw_fd_ostream>( |
702 | StringRef(SecureLogFile), EC, sys::fs::F_Append | sys::fs::F_Text); |
703 | if (EC) |
704 | return Error(IDLoc, Twine("can't open secure log file: ") + |
705 | SecureLogFile + " (" + EC.message() + ")"); |
706 | OS = NewOS.get(); |
707 | getContext().setSecureLog(std::move(NewOS)); |
708 | } |
709 | |
710 | |
711 | unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); |
712 | *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier() |
713 | << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":" |
714 | << LogMessage + "\n"; |
715 | |
716 | getContext().setSecureLogUsed(true); |
717 | |
718 | return false; |
719 | } |
720 | |
721 | |
722 | |
723 | bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { |
724 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
725 | return TokError("unexpected token in '.secure_log_reset' directive"); |
726 | |
727 | Lex(); |
728 | |
729 | getContext().setSecureLogUsed(false); |
730 | |
731 | return false; |
732 | } |
733 | |
734 | |
735 | |
736 | bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { |
737 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
738 | return TokError("unexpected token in '.subsections_via_symbols' directive"); |
739 | |
740 | Lex(); |
741 | |
742 | getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); |
743 | |
744 | return false; |
745 | } |
746 | |
747 | |
748 | |
749 | bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) { |
750 | SMLoc IDLoc = getLexer().getLoc(); |
751 | StringRef Name; |
752 | if (getParser().parseIdentifier(Name)) |
753 | return TokError("expected identifier in directive"); |
754 | |
755 | |
756 | MCSymbol *Sym = getContext().getOrCreateSymbol(Name); |
757 | |
758 | if (getLexer().isNot(AsmToken::Comma)) |
759 | return TokError("unexpected token in directive"); |
760 | Lex(); |
761 | |
762 | int64_t Size; |
763 | SMLoc SizeLoc = getLexer().getLoc(); |
764 | if (getParser().parseAbsoluteExpression(Size)) |
765 | return true; |
766 | |
767 | int64_t Pow2Alignment = 0; |
768 | SMLoc Pow2AlignmentLoc; |
769 | if (getLexer().is(AsmToken::Comma)) { |
770 | Lex(); |
771 | Pow2AlignmentLoc = getLexer().getLoc(); |
772 | if (getParser().parseAbsoluteExpression(Pow2Alignment)) |
773 | return true; |
774 | } |
775 | |
776 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
777 | return TokError("unexpected token in '.tbss' directive"); |
778 | |
779 | Lex(); |
780 | |
781 | if (Size < 0) |
782 | return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" |
783 | "zero"); |
784 | |
785 | |
786 | if (Pow2Alignment < 0) |
787 | return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" |
788 | "than zero"); |
789 | |
790 | if (!Sym->isUndefined()) |
791 | return Error(IDLoc, "invalid symbol redefinition"); |
792 | |
793 | getStreamer().EmitTBSSSymbol(getContext().getMachOSection( |
794 | "__DATA", "__thread_bss", |
795 | MachO::S_THREAD_LOCAL_ZEROFILL, |
796 | 0, SectionKind::getThreadBSS()), |
797 | Sym, Size, 1 << Pow2Alignment); |
798 | |
799 | return false; |
800 | } |
801 | |
802 | |
803 | |
804 | |
805 | bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) { |
806 | StringRef Segment; |
807 | if (getParser().parseIdentifier(Segment)) |
808 | return TokError("expected segment name after '.zerofill' directive"); |
809 | |
810 | if (getLexer().isNot(AsmToken::Comma)) |
811 | return TokError("unexpected token in directive"); |
812 | Lex(); |
813 | |
814 | StringRef Section; |
815 | if (getParser().parseIdentifier(Section)) |
816 | return TokError("expected section name after comma in '.zerofill' " |
817 | "directive"); |
818 | |
819 | |
820 | |
821 | if (getLexer().is(AsmToken::EndOfStatement)) { |
822 | |
823 | getStreamer().EmitZerofill(getContext().getMachOSection( |
824 | Segment, Section, MachO::S_ZEROFILL, |
825 | 0, SectionKind::getBSS())); |
826 | return false; |
827 | } |
828 | |
829 | if (getLexer().isNot(AsmToken::Comma)) |
830 | return TokError("unexpected token in directive"); |
831 | Lex(); |
832 | |
833 | SMLoc IDLoc = getLexer().getLoc(); |
834 | StringRef IDStr; |
835 | if (getParser().parseIdentifier(IDStr)) |
836 | return TokError("expected identifier in directive"); |
837 | |
838 | |
839 | MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr); |
840 | |
841 | if (getLexer().isNot(AsmToken::Comma)) |
842 | return TokError("unexpected token in directive"); |
843 | Lex(); |
844 | |
845 | int64_t Size; |
846 | SMLoc SizeLoc = getLexer().getLoc(); |
847 | if (getParser().parseAbsoluteExpression(Size)) |
848 | return true; |
849 | |
850 | int64_t Pow2Alignment = 0; |
851 | SMLoc Pow2AlignmentLoc; |
852 | if (getLexer().is(AsmToken::Comma)) { |
853 | Lex(); |
854 | Pow2AlignmentLoc = getLexer().getLoc(); |
855 | if (getParser().parseAbsoluteExpression(Pow2Alignment)) |
856 | return true; |
857 | } |
858 | |
859 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
860 | return TokError("unexpected token in '.zerofill' directive"); |
861 | |
862 | Lex(); |
863 | |
864 | if (Size < 0) |
865 | return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " |
866 | "than zero"); |
867 | |
868 | |
869 | |
870 | |
871 | if (Pow2Alignment < 0) |
872 | return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " |
873 | "can't be less than zero"); |
874 | |
875 | if (!Sym->isUndefined()) |
876 | return Error(IDLoc, "invalid symbol redefinition"); |
877 | |
878 | |
879 | |
880 | |
881 | getStreamer().EmitZerofill(getContext().getMachOSection( |
882 | Segment, Section, MachO::S_ZEROFILL, |
883 | 0, SectionKind::getBSS()), |
884 | Sym, Size, 1 << Pow2Alignment); |
885 | |
886 | return false; |
887 | } |
888 | |
889 | |
890 | |
891 | bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) { |
892 | if (getLexer().is(AsmToken::EndOfStatement)) { |
893 | Lex(); |
894 | getStreamer().EmitDataRegion(MCDR_DataRegion); |
895 | return false; |
896 | } |
897 | StringRef RegionType; |
898 | SMLoc Loc = getParser().getTok().getLoc(); |
899 | if (getParser().parseIdentifier(RegionType)) |
900 | return TokError("expected region type after '.data_region' directive"); |
901 | int Kind = StringSwitch<int>(RegionType) |
902 | .Case("jt8", MCDR_DataRegionJT8) |
903 | .Case("jt16", MCDR_DataRegionJT16) |
904 | .Case("jt32", MCDR_DataRegionJT32) |
905 | .Default(-1); |
906 | if (Kind == -1) |
907 | return Error(Loc, "unknown region type in '.data_region' directive"); |
908 | Lex(); |
909 | |
910 | getStreamer().EmitDataRegion((MCDataRegionType)Kind); |
911 | return false; |
912 | } |
913 | |
914 | |
915 | |
916 | bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) { |
917 | if (getLexer().isNot(AsmToken::EndOfStatement)) |
918 | return TokError("unexpected token in '.end_data_region' directive"); |
919 | |
920 | Lex(); |
921 | getStreamer().EmitDataRegion(MCDR_DataRegionEnd); |
922 | return false; |
923 | } |
924 | |
925 | |
926 | |
927 | |
928 | bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc) { |
929 | int64_t Major = 0, Minor = 0, Update = 0; |
930 | int Kind = StringSwitch<int>(Directive) |
931 | .Case(".watchos_version_min", MCVM_WatchOSVersionMin) |
932 | .Case(".tvos_version_min", MCVM_TvOSVersionMin) |
933 | .Case(".ios_version_min", MCVM_IOSVersionMin) |
934 | .Case(".macosx_version_min", MCVM_OSXVersionMin); |
935 | |
936 | if (getLexer().isNot(AsmToken::Integer)) |
937 | return TokError("invalid OS major version number"); |
938 | Major = getLexer().getTok().getIntVal(); |
939 | if (Major > 65535 || Major <= 0) |
940 | return TokError("invalid OS major version number"); |
941 | Lex(); |
942 | if (getLexer().isNot(AsmToken::Comma)) |
943 | return TokError("minor OS version number required, comma expected"); |
944 | Lex(); |
945 | |
946 | if (getLexer().isNot(AsmToken::Integer)) |
947 | return TokError("invalid OS minor version number"); |
948 | Minor = getLexer().getTok().getIntVal(); |
949 | if (Minor > 255 || Minor < 0) |
950 | return TokError("invalid OS minor version number"); |
951 | Lex(); |
952 | |
953 | if (getLexer().isNot(AsmToken::EndOfStatement)) { |
954 | if (getLexer().isNot(AsmToken::Comma)) |
955 | return TokError("invalid update specifier, comma expected"); |
956 | Lex(); |
957 | if (getLexer().isNot(AsmToken::Integer)) |
958 | return TokError("invalid OS update number"); |
959 | Update = getLexer().getTok().getIntVal(); |
960 | if (Update > 255 || Update < 0) |
961 | return TokError("invalid OS update number"); |
962 | Lex(); |
963 | } |
964 | |
965 | const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); |
966 | Triple::OSType ExpectedOS = Triple::UnknownOS; |
967 | switch ((MCVersionMinType)Kind) { |
968 | case MCVM_WatchOSVersionMin: ExpectedOS = Triple::WatchOS; break; |
969 | case MCVM_TvOSVersionMin: ExpectedOS = Triple::TvOS; break; |
970 | case MCVM_IOSVersionMin: ExpectedOS = Triple::IOS; break; |
971 | case MCVM_OSXVersionMin: ExpectedOS = Triple::MacOSX; break; |
972 | } |
973 | if (T.getOS() != ExpectedOS) |
974 | Warning(Loc, Directive + " should only be used for " + |
975 | Triple::getOSTypeName(ExpectedOS) + " targets"); |
976 | |
977 | if (LastVersionMinDirective.isValid()) { |
978 | Warning(Loc, "overriding previous version_min directive"); |
979 | Note(LastVersionMinDirective, "previous definition is here"); |
980 | } |
981 | LastVersionMinDirective = Loc; |
982 | |
983 | |
984 | getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update); |
985 | |
986 | return false; |
987 | } |
988 | |
989 | namespace llvm { |
990 | |
991 | MCAsmParserExtension *createDarwinAsmParser() { |
992 | return new DarwinAsmParser; |
993 | } |
994 | |
995 | } |