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