blob: 7fda7ac5e150bd08fa24cf81020b0a0310fd1063 [file] [log] [blame]
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +00001//===- 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/MC/MCParser/MCAsmParserExtension.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000011#include "llvm/ADT/StringRef.h"
12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/ADT/Twine.h"
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000014#include "llvm/MC/MCContext.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000015#include "llvm/MC/MCParser/MCAsmLexer.h"
16#include "llvm/MC/MCParser/MCAsmParser.h"
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000017#include "llvm/MC/MCSectionMachO.h"
18#include "llvm/MC/MCStreamer.h"
19#include "llvm/MC/MCSymbol.h"
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000020#include "llvm/Support/MemoryBuffer.h"
21#include "llvm/Support/SourceMgr.h"
22using namespace llvm;
23
24namespace {
25
26/// \brief Implementation of directive handling which is shared across all
27/// Darwin targets.
28class DarwinAsmParser : public MCAsmParserExtension {
Eli Bendersky171192f2013-01-16 00:50:52 +000029 template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000030 void AddDirectiveHandler(StringRef Directive) {
Eli Bendersky171192f2013-01-16 00:50:52 +000031 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
32 this, HandleDirective<DarwinAsmParser, HandlerMethod>);
33 getParser().AddDirectiveHandler(Directive, Handler);
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000034 }
35
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000036 bool ParseSectionSwitch(const char *Segment, const char *Section,
37 unsigned TAA = 0, unsigned ImplicitAlign = 0,
38 unsigned StubSize = 0);
39
40public:
41 DarwinAsmParser() {}
42
43 virtual void Initialize(MCAsmParser &Parser) {
44 // Call the base implementation.
45 this->MCAsmParserExtension::Initialize(Parser);
46
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000047 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
48 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
49 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
50 ".subsections_via_symbols");
51 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
52 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
53 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000054 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(
55 ".pushsection");
56 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(
57 ".popsection");
Bill Wendlingef920552012-08-08 06:30:30 +000058 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000059 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
60 ".secure_log_unique");
61 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
62 ".secure_log_reset");
63 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
64 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000065
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000066 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(
67 ".data_region");
68 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(
69 ".end_data_region");
Jim Grosbach3e965312012-05-18 19:12:01 +000070
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000071 // Special section directives.
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000072 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000073 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(
74 ".const_data");
75 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(
76 ".constructor");
77 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(
78 ".cstring");
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000079 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000080 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(
81 ".destructor");
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000082 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
Daniel Dunbar9b6a4472013-01-18 01:25:25 +000083 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(
84 ".fvmlib_init0");
85 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(
86 ".fvmlib_init1");
87 AddDirectiveHandler<
88 &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(
89 ".lazy_symbol_pointer");
90 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(
91 ".literal16");
92 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(
93 ".literal4");
94 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(
95 ".literal8");
96 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(
97 ".mod_init_func");
98 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(
99 ".mod_term_func");
100 AddDirectiveHandler<
101 &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(
102 ".non_lazy_symbol_pointer");
103 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(
104 ".objc_cat_cls_meth");
105 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(
106 ".objc_cat_inst_meth");
107 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(
108 ".objc_category");
109 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(
110 ".objc_class");
111 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(
112 ".objc_class_names");
113 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(
114 ".objc_class_vars");
115 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(
116 ".objc_cls_meth");
117 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(
118 ".objc_cls_refs");
119 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(
120 ".objc_inst_meth");
121 AddDirectiveHandler<
122 &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(
123 ".objc_instance_vars");
124 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(
125 ".objc_message_refs");
126 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(
127 ".objc_meta_class");
128 AddDirectiveHandler<
129 &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(
130 ".objc_meth_var_names");
131 AddDirectiveHandler<
132 &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(
133 ".objc_meth_var_types");
134 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(
135 ".objc_module_info");
136 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(
137 ".objc_protocol");
138 AddDirectiveHandler<
139 &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(
140 ".objc_selector_strs");
141 AddDirectiveHandler<
142 &DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(
143 ".objc_string_object");
144 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(
145 ".objc_symbols");
146 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(
147 ".picsymbol_stub");
148 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(
149 ".static_const");
150 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(
151 ".static_data");
152 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(
153 ".symbol_stub");
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +0000154 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
155 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
Daniel Dunbar9b6a4472013-01-18 01:25:25 +0000156 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(
157 ".thread_init_func");
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +0000158 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
Jim Grosbach8270da82011-03-08 19:17:19 +0000159
160 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000161 }
162
163 bool ParseDirectiveDesc(StringRef, SMLoc);
164 bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
165 bool ParseDirectiveLsym(StringRef, SMLoc);
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +0000166 bool ParseDirectiveSection(StringRef, SMLoc);
Bill Wendlingef920552012-08-08 06:30:30 +0000167 bool ParseDirectivePushSection(StringRef, SMLoc);
168 bool ParseDirectivePopSection(StringRef, SMLoc);
169 bool ParseDirectivePrevious(StringRef, SMLoc);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000170 bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
171 bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
172 bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
173 bool ParseDirectiveTBSS(StringRef, SMLoc);
174 bool ParseDirectiveZerofill(StringRef, SMLoc);
Jim Grosbach3e965312012-05-18 19:12:01 +0000175 bool ParseDirectiveDataRegion(StringRef, SMLoc);
176 bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000177
178 // Named Section Directive
179 bool ParseSectionDirectiveConst(StringRef, SMLoc) {
180 return ParseSectionSwitch("__TEXT", "__const");
181 }
182 bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
183 return ParseSectionSwitch("__TEXT", "__static_const");
184 }
185 bool ParseSectionDirectiveCString(StringRef, SMLoc) {
186 return ParseSectionSwitch("__TEXT","__cstring",
187 MCSectionMachO::S_CSTRING_LITERALS);
188 }
189 bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
190 return ParseSectionSwitch("__TEXT", "__literal4",
191 MCSectionMachO::S_4BYTE_LITERALS, 4);
192 }
193 bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
194 return ParseSectionSwitch("__TEXT", "__literal8",
195 MCSectionMachO::S_8BYTE_LITERALS, 8);
196 }
197 bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
198 return ParseSectionSwitch("__TEXT","__literal16",
199 MCSectionMachO::S_16BYTE_LITERALS, 16);
200 }
201 bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
202 return ParseSectionSwitch("__TEXT","__constructor");
203 }
204 bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
205 return ParseSectionSwitch("__TEXT","__destructor");
206 }
207 bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
208 return ParseSectionSwitch("__TEXT","__fvmlib_init0");
209 }
210 bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
211 return ParseSectionSwitch("__TEXT","__fvmlib_init1");
212 }
213 bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
214 return ParseSectionSwitch("__TEXT","__symbol_stub",
215 MCSectionMachO::S_SYMBOL_STUBS |
216 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
217 // FIXME: Different on PPC and ARM.
218 0, 16);
219 }
220 bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
221 return ParseSectionSwitch("__TEXT","__picsymbol_stub",
222 MCSectionMachO::S_SYMBOL_STUBS |
223 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
224 }
225 bool ParseSectionDirectiveData(StringRef, SMLoc) {
226 return ParseSectionSwitch("__DATA", "__data");
227 }
228 bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
229 return ParseSectionSwitch("__DATA", "__static_data");
230 }
231 bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
232 return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
233 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
234 }
235 bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
236 return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
237 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
238 }
239 bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
240 return ParseSectionSwitch("__DATA", "__dyld");
241 }
242 bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
243 return ParseSectionSwitch("__DATA", "__mod_init_func",
244 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
245 }
246 bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
247 return ParseSectionSwitch("__DATA", "__mod_term_func",
248 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
249 }
250 bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
251 return ParseSectionSwitch("__DATA", "__const");
252 }
253 bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
254 return ParseSectionSwitch("__OBJC", "__class",
255 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
256 }
257 bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
258 return ParseSectionSwitch("__OBJC", "__meta_class",
259 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
260 }
261 bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
262 return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
263 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
264 }
265 bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
266 return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
267 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
268 }
269 bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
270 return ParseSectionSwitch("__OBJC", "__protocol",
271 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
272 }
273 bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
274 return ParseSectionSwitch("__OBJC", "__string_object",
275 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
276 }
277 bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
278 return ParseSectionSwitch("__OBJC", "__cls_meth",
279 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
280 }
281 bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
282 return ParseSectionSwitch("__OBJC", "__inst_meth",
283 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
284 }
285 bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
286 return ParseSectionSwitch("__OBJC", "__cls_refs",
287 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
288 MCSectionMachO::S_LITERAL_POINTERS, 4);
289 }
290 bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
291 return ParseSectionSwitch("__OBJC", "__message_refs",
292 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
293 MCSectionMachO::S_LITERAL_POINTERS, 4);
294 }
295 bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
296 return ParseSectionSwitch("__OBJC", "__symbols",
297 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
298 }
299 bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
300 return ParseSectionSwitch("__OBJC", "__category",
301 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
302 }
303 bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
304 return ParseSectionSwitch("__OBJC", "__class_vars",
305 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
306 }
307 bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
308 return ParseSectionSwitch("__OBJC", "__instance_vars",
309 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
310 }
311 bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
312 return ParseSectionSwitch("__OBJC", "__module_info",
313 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
314 }
315 bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
316 return ParseSectionSwitch("__TEXT", "__cstring",
317 MCSectionMachO::S_CSTRING_LITERALS);
318 }
319 bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
320 return ParseSectionSwitch("__TEXT", "__cstring",
321 MCSectionMachO::S_CSTRING_LITERALS);
322 }
323 bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
324 return ParseSectionSwitch("__TEXT", "__cstring",
325 MCSectionMachO::S_CSTRING_LITERALS);
326 }
327 bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
328 return ParseSectionSwitch("__OBJC", "__selector_strs",
329 MCSectionMachO::S_CSTRING_LITERALS);
330 }
331 bool ParseSectionDirectiveTData(StringRef, SMLoc) {
332 return ParseSectionSwitch("__DATA", "__thread_data",
333 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
334 }
335 bool ParseSectionDirectiveText(StringRef, SMLoc) {
336 return ParseSectionSwitch("__TEXT", "__text",
337 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
338 }
339 bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
340 return ParseSectionSwitch("__DATA", "__thread_vars",
341 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
342 }
Jim Grosbach8270da82011-03-08 19:17:19 +0000343 bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
344 // Darwin silently ignores the .ident directive.
345 getParser().EatToEndOfStatement();
346 return false;
347 }
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000348 bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
349 return ParseSectionSwitch("__DATA", "__thread_init",
350 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
351 }
352
353};
354
Bill Wendlingef920552012-08-08 06:30:30 +0000355} // end anonymous namespace
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000356
357bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
358 const char *Section,
359 unsigned TAA, unsigned Align,
360 unsigned StubSize) {
361 if (getLexer().isNot(AsmToken::EndOfStatement))
362 return TokError("unexpected token in section switching directive");
363 Lex();
364
365 // FIXME: Arch specific.
Tim Northover1c2b2f92012-12-17 17:59:32 +0000366 bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000367 getStreamer().SwitchSection(getContext().getMachOSection(
368 Segment, Section, TAA, StubSize,
369 isText ? SectionKind::getText()
370 : SectionKind::getDataRel()));
371
372 // Set the implicit alignment, if any.
373 //
374 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
375 // alignment on the section (e.g., if one manually inserts bytes into the
Bill Wendlingcf2561d2010-10-19 10:18:23 +0000376 // section, then just issuing the section switch directive will not realign
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000377 // the section. However, this is arguably more reasonable behavior, and there
378 // is no good reason for someone to intentionally emit incorrectly sized
379 // values into the implicitly aligned sections.
380 if (Align)
381 getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
382
383 return false;
384}
385
386/// ParseDirectiveDesc
387/// ::= .desc identifier , expression
388bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
389 StringRef Name;
390 if (getParser().ParseIdentifier(Name))
391 return TokError("expected identifier in directive");
392
393 // Handle the identifier as the key symbol.
394 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
395
396 if (getLexer().isNot(AsmToken::Comma))
397 return TokError("unexpected token in '.desc' directive");
398 Lex();
399
400 int64_t DescValue;
401 if (getParser().ParseAbsoluteExpression(DescValue))
402 return true;
403
404 if (getLexer().isNot(AsmToken::EndOfStatement))
405 return TokError("unexpected token in '.desc' directive");
406
407 Lex();
408
409 // Set the n_desc field of this Symbol to this DescValue
410 getStreamer().EmitSymbolDesc(Sym, DescValue);
411
412 return false;
413}
414
415/// ParseDirectiveDumpOrLoad
416/// ::= ( .dump | .load ) "filename"
417bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
418 SMLoc IDLoc) {
419 bool IsDump = Directive == ".dump";
420 if (getLexer().isNot(AsmToken::String))
421 return TokError("expected string in '.dump' or '.load' directive");
422
423 Lex();
424
425 if (getLexer().isNot(AsmToken::EndOfStatement))
426 return TokError("unexpected token in '.dump' or '.load' directive");
427
428 Lex();
429
430 // FIXME: If/when .dump and .load are implemented they will be done in the
431 // the assembly parser and not have any need for an MCStreamer API.
432 if (IsDump)
Joerg Sonnenbergerf8cd7082011-05-19 18:00:13 +0000433 return Warning(IDLoc, "ignoring directive .dump for now");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000434 else
Joerg Sonnenbergerf8cd7082011-05-19 18:00:13 +0000435 return Warning(IDLoc, "ignoring directive .load for now");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000436}
437
438/// ParseDirectiveLsym
439/// ::= .lsym identifier , expression
440bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
441 StringRef Name;
442 if (getParser().ParseIdentifier(Name))
443 return TokError("expected identifier in directive");
444
445 // Handle the identifier as the key symbol.
446 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
447
448 if (getLexer().isNot(AsmToken::Comma))
449 return TokError("unexpected token in '.lsym' directive");
450 Lex();
451
452 const MCExpr *Value;
453 if (getParser().ParseExpression(Value))
454 return true;
455
456 if (getLexer().isNot(AsmToken::EndOfStatement))
457 return TokError("unexpected token in '.lsym' directive");
458
459 Lex();
460
461 // We don't currently support this directive.
462 //
463 // FIXME: Diagnostic location!
464 (void) Sym;
465 return TokError("directive '.lsym' is unsupported");
466}
467
468/// ParseDirectiveSection:
469/// ::= .section identifier (',' identifier)*
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +0000470bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000471 SMLoc Loc = getLexer().getLoc();
472
473 StringRef SectionName;
474 if (getParser().ParseIdentifier(SectionName))
475 return Error(Loc, "expected identifier after '.section' directive");
476
477 // Verify there is a following comma.
478 if (!getLexer().is(AsmToken::Comma))
479 return TokError("unexpected token in '.section' directive");
480
481 std::string SectionSpec = SectionName;
482 SectionSpec += ",";
483
484 // Add all the tokens until the end of the line, ParseSectionSpecifier will
485 // handle this.
486 StringRef EOL = getLexer().LexUntilEndOfStatement();
487 SectionSpec.append(EOL.begin(), EOL.end());
488
489 Lex();
490 if (getLexer().isNot(AsmToken::EndOfStatement))
491 return TokError("unexpected token in '.section' directive");
492 Lex();
493
494
495 StringRef Segment, Section;
Daniel Dunbar8d06ffc2011-03-17 16:25:24 +0000496 unsigned StubSize;
Stuart Hastings65c8bca2011-03-19 02:42:31 +0000497 unsigned TAA;
498 bool TAAParsed;
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000499 std::string ErrorStr =
500 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
Stuart Hastings65c8bca2011-03-19 02:42:31 +0000501 TAA, TAAParsed, StubSize);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000502
503 if (!ErrorStr.empty())
504 return Error(Loc, ErrorStr.c_str());
505
506 // FIXME: Arch specific.
507 bool isText = Segment == "__TEXT"; // FIXME: Hack.
508 getStreamer().SwitchSection(getContext().getMachOSection(
509 Segment, Section, TAA, StubSize,
510 isText ? SectionKind::getText()
511 : SectionKind::getDataRel()));
512 return false;
513}
514
Bill Wendlingef920552012-08-08 06:30:30 +0000515/// ParseDirectivePushSection:
516/// ::= .pushsection identifier (',' identifier)*
517bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
518 getStreamer().PushSection();
519
520 if (ParseDirectiveSection(S, Loc)) {
521 getStreamer().PopSection();
522 return true;
523 }
524
525 return false;
526}
527
528/// ParseDirectivePopSection:
529/// ::= .popsection
530bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
531 if (!getStreamer().PopSection())
532 return TokError(".popsection without corresponding .pushsection");
533 return false;
534}
535
536/// ParseDirectivePrevious:
537/// ::= .previous
538bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
539 const MCSection *PreviousSection = getStreamer().getPreviousSection();
540 if (PreviousSection == NULL)
541 return TokError(".previous without corresponding .section");
542 getStreamer().SwitchSection(PreviousSection);
543 return false;
544}
545
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000546/// ParseDirectiveSecureLogUnique
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000547/// ::= .secure_log_unique ... message ...
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000548bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000549 StringRef LogMessage = getParser().ParseStringToEndOfStatement();
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000550 if (getLexer().isNot(AsmToken::EndOfStatement))
551 return TokError("unexpected token in '.secure_log_unique' directive");
552
553 if (getContext().getSecureLogUsed() != false)
554 return Error(IDLoc, ".secure_log_unique specified multiple times");
555
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000556 // Get the secure log path.
557 const char *SecureLogFile = getContext().getSecureLogFile();
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000558 if (SecureLogFile == NULL)
559 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
560 "environment variable unset.");
561
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000562 // Open the secure log file if we haven't already.
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000563 raw_ostream *OS = getContext().getSecureLog();
564 if (OS == NULL) {
565 std::string Err;
566 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
567 if (!Err.empty()) {
568 delete OS;
569 return Error(IDLoc, Twine("can't open secure log file: ") +
570 SecureLogFile + " (" + Err + ")");
571 }
572 getContext().setSecureLog(OS);
573 }
574
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000575 // Write the message.
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000576 int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
577 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
578 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
579 << LogMessage + "\n";
580
581 getContext().setSecureLogUsed(true);
582
583 return false;
584}
585
586/// ParseDirectiveSecureLogReset
587/// ::= .secure_log_reset
588bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
589 if (getLexer().isNot(AsmToken::EndOfStatement))
590 return TokError("unexpected token in '.secure_log_reset' directive");
591
592 Lex();
593
594 getContext().setSecureLogUsed(false);
595
596 return false;
597}
598
599/// ParseDirectiveSubsectionsViaSymbols
600/// ::= .subsections_via_symbols
601bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
602 if (getLexer().isNot(AsmToken::EndOfStatement))
603 return TokError("unexpected token in '.subsections_via_symbols' directive");
604
605 Lex();
606
607 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
608
609 return false;
610}
611
612/// ParseDirectiveTBSS
613/// ::= .tbss identifier, size, align
614bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
615 SMLoc IDLoc = getLexer().getLoc();
616 StringRef Name;
617 if (getParser().ParseIdentifier(Name))
618 return TokError("expected identifier in directive");
619
620 // Handle the identifier as the key symbol.
621 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
622
623 if (getLexer().isNot(AsmToken::Comma))
624 return TokError("unexpected token in directive");
625 Lex();
626
627 int64_t Size;
628 SMLoc SizeLoc = getLexer().getLoc();
629 if (getParser().ParseAbsoluteExpression(Size))
630 return true;
631
632 int64_t Pow2Alignment = 0;
633 SMLoc Pow2AlignmentLoc;
634 if (getLexer().is(AsmToken::Comma)) {
635 Lex();
636 Pow2AlignmentLoc = getLexer().getLoc();
637 if (getParser().ParseAbsoluteExpression(Pow2Alignment))
638 return true;
639 }
640
641 if (getLexer().isNot(AsmToken::EndOfStatement))
642 return TokError("unexpected token in '.tbss' directive");
643
644 Lex();
645
646 if (Size < 0)
647 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
648 "zero");
649
650 // FIXME: Diagnose overflow.
651 if (Pow2Alignment < 0)
652 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
653 "than zero");
654
655 if (!Sym->isUndefined())
656 return Error(IDLoc, "invalid symbol redefinition");
657
658 getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
659 "__DATA", "__thread_bss",
660 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
661 0, SectionKind::getThreadBSS()),
662 Sym, Size, 1 << Pow2Alignment);
663
664 return false;
665}
666
667/// ParseDirectiveZerofill
668/// ::= .zerofill segname , sectname [, identifier , size_expression [
669/// , align_expression ]]
670bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
671 StringRef Segment;
672 if (getParser().ParseIdentifier(Segment))
673 return TokError("expected segment name after '.zerofill' directive");
674
675 if (getLexer().isNot(AsmToken::Comma))
676 return TokError("unexpected token in directive");
677 Lex();
678
679 StringRef Section;
680 if (getParser().ParseIdentifier(Section))
681 return TokError("expected section name after comma in '.zerofill' "
682 "directive");
683
684 // If this is the end of the line all that was wanted was to create the
685 // the section but with no symbol.
686 if (getLexer().is(AsmToken::EndOfStatement)) {
687 // Create the zerofill section but no symbol
688 getStreamer().EmitZerofill(getContext().getMachOSection(
689 Segment, Section, MCSectionMachO::S_ZEROFILL,
690 0, SectionKind::getBSS()));
691 return false;
692 }
693
694 if (getLexer().isNot(AsmToken::Comma))
695 return TokError("unexpected token in directive");
696 Lex();
697
698 SMLoc IDLoc = getLexer().getLoc();
699 StringRef IDStr;
700 if (getParser().ParseIdentifier(IDStr))
701 return TokError("expected identifier in directive");
702
703 // handle the identifier as the key symbol.
704 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
705
706 if (getLexer().isNot(AsmToken::Comma))
707 return TokError("unexpected token in directive");
708 Lex();
709
710 int64_t Size;
711 SMLoc SizeLoc = getLexer().getLoc();
712 if (getParser().ParseAbsoluteExpression(Size))
713 return true;
714
715 int64_t Pow2Alignment = 0;
716 SMLoc Pow2AlignmentLoc;
717 if (getLexer().is(AsmToken::Comma)) {
718 Lex();
719 Pow2AlignmentLoc = getLexer().getLoc();
720 if (getParser().ParseAbsoluteExpression(Pow2Alignment))
721 return true;
722 }
723
724 if (getLexer().isNot(AsmToken::EndOfStatement))
725 return TokError("unexpected token in '.zerofill' directive");
726
727 Lex();
728
729 if (Size < 0)
730 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
731 "than zero");
732
733 // NOTE: The alignment in the directive is a power of 2 value, the assembler
734 // may internally end up wanting an alignment in bytes.
735 // FIXME: Diagnose overflow.
736 if (Pow2Alignment < 0)
737 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
738 "can't be less than zero");
739
740 if (!Sym->isUndefined())
741 return Error(IDLoc, "invalid symbol redefinition");
742
743 // Create the zerofill Symbol with Size and Pow2Alignment
744 //
745 // FIXME: Arch specific.
746 getStreamer().EmitZerofill(getContext().getMachOSection(
747 Segment, Section, MCSectionMachO::S_ZEROFILL,
748 0, SectionKind::getBSS()),
749 Sym, Size, 1 << Pow2Alignment);
750
751 return false;
752}
753
Jim Grosbach3e965312012-05-18 19:12:01 +0000754/// ParseDirectiveDataRegion
755/// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
756bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
757 if (getLexer().is(AsmToken::EndOfStatement)) {
758 Lex();
759 getStreamer().EmitDataRegion(MCDR_DataRegion);
760 return false;
761 }
762 StringRef RegionType;
763 SMLoc Loc = getParser().getTok().getLoc();
764 if (getParser().ParseIdentifier(RegionType))
765 return TokError("expected region type after '.data_region' directive");
766 int Kind = StringSwitch<int>(RegionType)
767 .Case("jt8", MCDR_DataRegionJT8)
768 .Case("jt16", MCDR_DataRegionJT16)
769 .Case("jt32", MCDR_DataRegionJT32)
770 .Default(-1);
771 if (Kind == -1)
772 return Error(Loc, "unknown region type in '.data_region' directive");
773 Lex();
774
775 getStreamer().EmitDataRegion((MCDataRegionType)Kind);
776 return false;
777}
778
779/// ParseDirectiveDataRegionEnd
780/// ::= .end_data_region
781bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
782 if (getLexer().isNot(AsmToken::EndOfStatement))
783 return TokError("unexpected token in '.end_data_region' directive");
784
785 Lex();
786 getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
787 return false;
788}
789
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000790namespace llvm {
791
792MCAsmParserExtension *createDarwinAsmParser() {
793 return new DarwinAsmParser;
794}
795
Bill Wendlingef920552012-08-08 06:30:30 +0000796} // end llvm namespace