blob: c4974e57f7916bae48efd636a3b5da35bfe4445a [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");
Bill Wendlingef920552012-08-08 06:30:30 +000054 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(".pushsection");
55 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection");
56 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000057 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
58 ".secure_log_unique");
59 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
60 ".secure_log_reset");
61 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
62 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000063
Jim Grosbach3e965312012-05-18 19:12:01 +000064 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(".data_region");
65 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(".end_data_region");
66
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +000067 // Special section directives.
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +000068 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
69 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(".const_data");
70 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(".constructor");
71 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(".cstring");
72 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
73 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(".destructor");
74 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
75 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(".fvmlib_init0");
76 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(".fvmlib_init1");
77 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(".lazy_symbol_pointer");
78 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(".literal16");
79 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(".literal4");
80 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(".literal8");
81 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(".mod_init_func");
82 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(".mod_term_func");
83 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(".non_lazy_symbol_pointer");
84 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(".objc_cat_cls_meth");
85 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(".objc_cat_inst_meth");
86 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(".objc_category");
87 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(".objc_class");
88 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(".objc_class_names");
89 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(".objc_class_vars");
90 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(".objc_cls_meth");
91 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(".objc_cls_refs");
92 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(".objc_inst_meth");
93 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(".objc_instance_vars");
94 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(".objc_message_refs");
95 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(".objc_meta_class");
96 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(".objc_meth_var_names");
97 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(".objc_meth_var_types");
98 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(".objc_module_info");
99 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(".objc_protocol");
100 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(".objc_selector_strs");
101 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(".objc_string_object");
102 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(".objc_symbols");
103 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(".picsymbol_stub");
104 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(".static_const");
105 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(".static_data");
106 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(".symbol_stub");
107 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
108 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
109 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(".thread_init_func");
110 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
Jim Grosbach8270da82011-03-08 19:17:19 +0000111
112 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000113 }
114
115 bool ParseDirectiveDesc(StringRef, SMLoc);
116 bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
117 bool ParseDirectiveLsym(StringRef, SMLoc);
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +0000118 bool ParseDirectiveSection(StringRef, SMLoc);
Bill Wendlingef920552012-08-08 06:30:30 +0000119 bool ParseDirectivePushSection(StringRef, SMLoc);
120 bool ParseDirectivePopSection(StringRef, SMLoc);
121 bool ParseDirectivePrevious(StringRef, SMLoc);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000122 bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
123 bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
124 bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
125 bool ParseDirectiveTBSS(StringRef, SMLoc);
126 bool ParseDirectiveZerofill(StringRef, SMLoc);
Jim Grosbach3e965312012-05-18 19:12:01 +0000127 bool ParseDirectiveDataRegion(StringRef, SMLoc);
128 bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000129
130 // Named Section Directive
131 bool ParseSectionDirectiveConst(StringRef, SMLoc) {
132 return ParseSectionSwitch("__TEXT", "__const");
133 }
134 bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
135 return ParseSectionSwitch("__TEXT", "__static_const");
136 }
137 bool ParseSectionDirectiveCString(StringRef, SMLoc) {
138 return ParseSectionSwitch("__TEXT","__cstring",
139 MCSectionMachO::S_CSTRING_LITERALS);
140 }
141 bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
142 return ParseSectionSwitch("__TEXT", "__literal4",
143 MCSectionMachO::S_4BYTE_LITERALS, 4);
144 }
145 bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
146 return ParseSectionSwitch("__TEXT", "__literal8",
147 MCSectionMachO::S_8BYTE_LITERALS, 8);
148 }
149 bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
150 return ParseSectionSwitch("__TEXT","__literal16",
151 MCSectionMachO::S_16BYTE_LITERALS, 16);
152 }
153 bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
154 return ParseSectionSwitch("__TEXT","__constructor");
155 }
156 bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
157 return ParseSectionSwitch("__TEXT","__destructor");
158 }
159 bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
160 return ParseSectionSwitch("__TEXT","__fvmlib_init0");
161 }
162 bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
163 return ParseSectionSwitch("__TEXT","__fvmlib_init1");
164 }
165 bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
166 return ParseSectionSwitch("__TEXT","__symbol_stub",
167 MCSectionMachO::S_SYMBOL_STUBS |
168 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
169 // FIXME: Different on PPC and ARM.
170 0, 16);
171 }
172 bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
173 return ParseSectionSwitch("__TEXT","__picsymbol_stub",
174 MCSectionMachO::S_SYMBOL_STUBS |
175 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
176 }
177 bool ParseSectionDirectiveData(StringRef, SMLoc) {
178 return ParseSectionSwitch("__DATA", "__data");
179 }
180 bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
181 return ParseSectionSwitch("__DATA", "__static_data");
182 }
183 bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
184 return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
185 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
186 }
187 bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
188 return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
189 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
190 }
191 bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
192 return ParseSectionSwitch("__DATA", "__dyld");
193 }
194 bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
195 return ParseSectionSwitch("__DATA", "__mod_init_func",
196 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
197 }
198 bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
199 return ParseSectionSwitch("__DATA", "__mod_term_func",
200 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
201 }
202 bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
203 return ParseSectionSwitch("__DATA", "__const");
204 }
205 bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
206 return ParseSectionSwitch("__OBJC", "__class",
207 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
208 }
209 bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
210 return ParseSectionSwitch("__OBJC", "__meta_class",
211 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
212 }
213 bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
214 return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
215 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
216 }
217 bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
218 return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
219 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
220 }
221 bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
222 return ParseSectionSwitch("__OBJC", "__protocol",
223 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
224 }
225 bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
226 return ParseSectionSwitch("__OBJC", "__string_object",
227 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
228 }
229 bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
230 return ParseSectionSwitch("__OBJC", "__cls_meth",
231 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
232 }
233 bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
234 return ParseSectionSwitch("__OBJC", "__inst_meth",
235 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
236 }
237 bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
238 return ParseSectionSwitch("__OBJC", "__cls_refs",
239 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
240 MCSectionMachO::S_LITERAL_POINTERS, 4);
241 }
242 bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
243 return ParseSectionSwitch("__OBJC", "__message_refs",
244 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
245 MCSectionMachO::S_LITERAL_POINTERS, 4);
246 }
247 bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
248 return ParseSectionSwitch("__OBJC", "__symbols",
249 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
250 }
251 bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
252 return ParseSectionSwitch("__OBJC", "__category",
253 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
254 }
255 bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
256 return ParseSectionSwitch("__OBJC", "__class_vars",
257 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
258 }
259 bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
260 return ParseSectionSwitch("__OBJC", "__instance_vars",
261 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
262 }
263 bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
264 return ParseSectionSwitch("__OBJC", "__module_info",
265 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
266 }
267 bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
268 return ParseSectionSwitch("__TEXT", "__cstring",
269 MCSectionMachO::S_CSTRING_LITERALS);
270 }
271 bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
272 return ParseSectionSwitch("__TEXT", "__cstring",
273 MCSectionMachO::S_CSTRING_LITERALS);
274 }
275 bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
276 return ParseSectionSwitch("__TEXT", "__cstring",
277 MCSectionMachO::S_CSTRING_LITERALS);
278 }
279 bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
280 return ParseSectionSwitch("__OBJC", "__selector_strs",
281 MCSectionMachO::S_CSTRING_LITERALS);
282 }
283 bool ParseSectionDirectiveTData(StringRef, SMLoc) {
284 return ParseSectionSwitch("__DATA", "__thread_data",
285 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
286 }
287 bool ParseSectionDirectiveText(StringRef, SMLoc) {
288 return ParseSectionSwitch("__TEXT", "__text",
289 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
290 }
291 bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
292 return ParseSectionSwitch("__DATA", "__thread_vars",
293 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
294 }
Jim Grosbach8270da82011-03-08 19:17:19 +0000295 bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
296 // Darwin silently ignores the .ident directive.
297 getParser().EatToEndOfStatement();
298 return false;
299 }
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000300 bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
301 return ParseSectionSwitch("__DATA", "__thread_init",
302 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
303 }
304
305};
306
Bill Wendlingef920552012-08-08 06:30:30 +0000307} // end anonymous namespace
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000308
309bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
310 const char *Section,
311 unsigned TAA, unsigned Align,
312 unsigned StubSize) {
313 if (getLexer().isNot(AsmToken::EndOfStatement))
314 return TokError("unexpected token in section switching directive");
315 Lex();
316
317 // FIXME: Arch specific.
Tim Northover1c2b2f92012-12-17 17:59:32 +0000318 bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000319 getStreamer().SwitchSection(getContext().getMachOSection(
320 Segment, Section, TAA, StubSize,
321 isText ? SectionKind::getText()
322 : SectionKind::getDataRel()));
323
324 // Set the implicit alignment, if any.
325 //
326 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
327 // alignment on the section (e.g., if one manually inserts bytes into the
Bill Wendlingcf2561d2010-10-19 10:18:23 +0000328 // section, then just issuing the section switch directive will not realign
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000329 // the section. However, this is arguably more reasonable behavior, and there
330 // is no good reason for someone to intentionally emit incorrectly sized
331 // values into the implicitly aligned sections.
332 if (Align)
333 getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
334
335 return false;
336}
337
338/// ParseDirectiveDesc
339/// ::= .desc identifier , expression
340bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
341 StringRef Name;
342 if (getParser().ParseIdentifier(Name))
343 return TokError("expected identifier in directive");
344
345 // Handle the identifier as the key symbol.
346 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
347
348 if (getLexer().isNot(AsmToken::Comma))
349 return TokError("unexpected token in '.desc' directive");
350 Lex();
351
352 int64_t DescValue;
353 if (getParser().ParseAbsoluteExpression(DescValue))
354 return true;
355
356 if (getLexer().isNot(AsmToken::EndOfStatement))
357 return TokError("unexpected token in '.desc' directive");
358
359 Lex();
360
361 // Set the n_desc field of this Symbol to this DescValue
362 getStreamer().EmitSymbolDesc(Sym, DescValue);
363
364 return false;
365}
366
367/// ParseDirectiveDumpOrLoad
368/// ::= ( .dump | .load ) "filename"
369bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
370 SMLoc IDLoc) {
371 bool IsDump = Directive == ".dump";
372 if (getLexer().isNot(AsmToken::String))
373 return TokError("expected string in '.dump' or '.load' directive");
374
375 Lex();
376
377 if (getLexer().isNot(AsmToken::EndOfStatement))
378 return TokError("unexpected token in '.dump' or '.load' directive");
379
380 Lex();
381
382 // FIXME: If/when .dump and .load are implemented they will be done in the
383 // the assembly parser and not have any need for an MCStreamer API.
384 if (IsDump)
Joerg Sonnenbergerf8cd7082011-05-19 18:00:13 +0000385 return Warning(IDLoc, "ignoring directive .dump for now");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000386 else
Joerg Sonnenbergerf8cd7082011-05-19 18:00:13 +0000387 return Warning(IDLoc, "ignoring directive .load for now");
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000388}
389
390/// ParseDirectiveLsym
391/// ::= .lsym identifier , expression
392bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
393 StringRef Name;
394 if (getParser().ParseIdentifier(Name))
395 return TokError("expected identifier in directive");
396
397 // Handle the identifier as the key symbol.
398 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
399
400 if (getLexer().isNot(AsmToken::Comma))
401 return TokError("unexpected token in '.lsym' directive");
402 Lex();
403
404 const MCExpr *Value;
405 if (getParser().ParseExpression(Value))
406 return true;
407
408 if (getLexer().isNot(AsmToken::EndOfStatement))
409 return TokError("unexpected token in '.lsym' directive");
410
411 Lex();
412
413 // We don't currently support this directive.
414 //
415 // FIXME: Diagnostic location!
416 (void) Sym;
417 return TokError("directive '.lsym' is unsupported");
418}
419
420/// ParseDirectiveSection:
421/// ::= .section identifier (',' identifier)*
Daniel Dunbar1edf6ca2010-07-18 22:22:07 +0000422bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000423 SMLoc Loc = getLexer().getLoc();
424
425 StringRef SectionName;
426 if (getParser().ParseIdentifier(SectionName))
427 return Error(Loc, "expected identifier after '.section' directive");
428
429 // Verify there is a following comma.
430 if (!getLexer().is(AsmToken::Comma))
431 return TokError("unexpected token in '.section' directive");
432
433 std::string SectionSpec = SectionName;
434 SectionSpec += ",";
435
436 // Add all the tokens until the end of the line, ParseSectionSpecifier will
437 // handle this.
438 StringRef EOL = getLexer().LexUntilEndOfStatement();
439 SectionSpec.append(EOL.begin(), EOL.end());
440
441 Lex();
442 if (getLexer().isNot(AsmToken::EndOfStatement))
443 return TokError("unexpected token in '.section' directive");
444 Lex();
445
446
447 StringRef Segment, Section;
Daniel Dunbar8d06ffc2011-03-17 16:25:24 +0000448 unsigned StubSize;
Stuart Hastings65c8bca2011-03-19 02:42:31 +0000449 unsigned TAA;
450 bool TAAParsed;
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000451 std::string ErrorStr =
452 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
Stuart Hastings65c8bca2011-03-19 02:42:31 +0000453 TAA, TAAParsed, StubSize);
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000454
455 if (!ErrorStr.empty())
456 return Error(Loc, ErrorStr.c_str());
457
458 // FIXME: Arch specific.
459 bool isText = Segment == "__TEXT"; // FIXME: Hack.
460 getStreamer().SwitchSection(getContext().getMachOSection(
461 Segment, Section, TAA, StubSize,
462 isText ? SectionKind::getText()
463 : SectionKind::getDataRel()));
464 return false;
465}
466
Bill Wendlingef920552012-08-08 06:30:30 +0000467/// ParseDirectivePushSection:
468/// ::= .pushsection identifier (',' identifier)*
469bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
470 getStreamer().PushSection();
471
472 if (ParseDirectiveSection(S, Loc)) {
473 getStreamer().PopSection();
474 return true;
475 }
476
477 return false;
478}
479
480/// ParseDirectivePopSection:
481/// ::= .popsection
482bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
483 if (!getStreamer().PopSection())
484 return TokError(".popsection without corresponding .pushsection");
485 return false;
486}
487
488/// ParseDirectivePrevious:
489/// ::= .previous
490bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
491 const MCSection *PreviousSection = getStreamer().getPreviousSection();
492 if (PreviousSection == NULL)
493 return TokError(".previous without corresponding .section");
494 getStreamer().SwitchSection(PreviousSection);
495 return false;
496}
497
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000498/// ParseDirectiveSecureLogUnique
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000499/// ::= .secure_log_unique ... message ...
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000500bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000501 StringRef LogMessage = getParser().ParseStringToEndOfStatement();
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000502 if (getLexer().isNot(AsmToken::EndOfStatement))
503 return TokError("unexpected token in '.secure_log_unique' directive");
504
505 if (getContext().getSecureLogUsed() != false)
506 return Error(IDLoc, ".secure_log_unique specified multiple times");
507
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000508 // Get the secure log path.
509 const char *SecureLogFile = getContext().getSecureLogFile();
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000510 if (SecureLogFile == NULL)
511 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
512 "environment variable unset.");
513
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000514 // Open the secure log file if we haven't already.
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000515 raw_ostream *OS = getContext().getSecureLog();
516 if (OS == NULL) {
517 std::string Err;
518 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
519 if (!Err.empty()) {
520 delete OS;
521 return Error(IDLoc, Twine("can't open secure log file: ") +
522 SecureLogFile + " (" + Err + ")");
523 }
524 getContext().setSecureLog(OS);
525 }
526
Daniel Dunbar6a46d572010-07-18 20:15:59 +0000527 // Write the message.
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000528 int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
529 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
530 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
531 << LogMessage + "\n";
532
533 getContext().setSecureLogUsed(true);
534
535 return false;
536}
537
538/// ParseDirectiveSecureLogReset
539/// ::= .secure_log_reset
540bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
541 if (getLexer().isNot(AsmToken::EndOfStatement))
542 return TokError("unexpected token in '.secure_log_reset' directive");
543
544 Lex();
545
546 getContext().setSecureLogUsed(false);
547
548 return false;
549}
550
551/// ParseDirectiveSubsectionsViaSymbols
552/// ::= .subsections_via_symbols
553bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
554 if (getLexer().isNot(AsmToken::EndOfStatement))
555 return TokError("unexpected token in '.subsections_via_symbols' directive");
556
557 Lex();
558
559 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
560
561 return false;
562}
563
564/// ParseDirectiveTBSS
565/// ::= .tbss identifier, size, align
566bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
567 SMLoc IDLoc = getLexer().getLoc();
568 StringRef Name;
569 if (getParser().ParseIdentifier(Name))
570 return TokError("expected identifier in directive");
571
572 // Handle the identifier as the key symbol.
573 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
574
575 if (getLexer().isNot(AsmToken::Comma))
576 return TokError("unexpected token in directive");
577 Lex();
578
579 int64_t Size;
580 SMLoc SizeLoc = getLexer().getLoc();
581 if (getParser().ParseAbsoluteExpression(Size))
582 return true;
583
584 int64_t Pow2Alignment = 0;
585 SMLoc Pow2AlignmentLoc;
586 if (getLexer().is(AsmToken::Comma)) {
587 Lex();
588 Pow2AlignmentLoc = getLexer().getLoc();
589 if (getParser().ParseAbsoluteExpression(Pow2Alignment))
590 return true;
591 }
592
593 if (getLexer().isNot(AsmToken::EndOfStatement))
594 return TokError("unexpected token in '.tbss' directive");
595
596 Lex();
597
598 if (Size < 0)
599 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
600 "zero");
601
602 // FIXME: Diagnose overflow.
603 if (Pow2Alignment < 0)
604 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
605 "than zero");
606
607 if (!Sym->isUndefined())
608 return Error(IDLoc, "invalid symbol redefinition");
609
610 getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
611 "__DATA", "__thread_bss",
612 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
613 0, SectionKind::getThreadBSS()),
614 Sym, Size, 1 << Pow2Alignment);
615
616 return false;
617}
618
619/// ParseDirectiveZerofill
620/// ::= .zerofill segname , sectname [, identifier , size_expression [
621/// , align_expression ]]
622bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
623 StringRef Segment;
624 if (getParser().ParseIdentifier(Segment))
625 return TokError("expected segment name after '.zerofill' directive");
626
627 if (getLexer().isNot(AsmToken::Comma))
628 return TokError("unexpected token in directive");
629 Lex();
630
631 StringRef Section;
632 if (getParser().ParseIdentifier(Section))
633 return TokError("expected section name after comma in '.zerofill' "
634 "directive");
635
636 // If this is the end of the line all that was wanted was to create the
637 // the section but with no symbol.
638 if (getLexer().is(AsmToken::EndOfStatement)) {
639 // Create the zerofill section but no symbol
640 getStreamer().EmitZerofill(getContext().getMachOSection(
641 Segment, Section, MCSectionMachO::S_ZEROFILL,
642 0, SectionKind::getBSS()));
643 return false;
644 }
645
646 if (getLexer().isNot(AsmToken::Comma))
647 return TokError("unexpected token in directive");
648 Lex();
649
650 SMLoc IDLoc = getLexer().getLoc();
651 StringRef IDStr;
652 if (getParser().ParseIdentifier(IDStr))
653 return TokError("expected identifier in directive");
654
655 // handle the identifier as the key symbol.
656 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
657
658 if (getLexer().isNot(AsmToken::Comma))
659 return TokError("unexpected token in directive");
660 Lex();
661
662 int64_t Size;
663 SMLoc SizeLoc = getLexer().getLoc();
664 if (getParser().ParseAbsoluteExpression(Size))
665 return true;
666
667 int64_t Pow2Alignment = 0;
668 SMLoc Pow2AlignmentLoc;
669 if (getLexer().is(AsmToken::Comma)) {
670 Lex();
671 Pow2AlignmentLoc = getLexer().getLoc();
672 if (getParser().ParseAbsoluteExpression(Pow2Alignment))
673 return true;
674 }
675
676 if (getLexer().isNot(AsmToken::EndOfStatement))
677 return TokError("unexpected token in '.zerofill' directive");
678
679 Lex();
680
681 if (Size < 0)
682 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
683 "than zero");
684
685 // NOTE: The alignment in the directive is a power of 2 value, the assembler
686 // may internally end up wanting an alignment in bytes.
687 // FIXME: Diagnose overflow.
688 if (Pow2Alignment < 0)
689 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
690 "can't be less than zero");
691
692 if (!Sym->isUndefined())
693 return Error(IDLoc, "invalid symbol redefinition");
694
695 // Create the zerofill Symbol with Size and Pow2Alignment
696 //
697 // FIXME: Arch specific.
698 getStreamer().EmitZerofill(getContext().getMachOSection(
699 Segment, Section, MCSectionMachO::S_ZEROFILL,
700 0, SectionKind::getBSS()),
701 Sym, Size, 1 << Pow2Alignment);
702
703 return false;
704}
705
Jim Grosbach3e965312012-05-18 19:12:01 +0000706/// ParseDirectiveDataRegion
707/// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
708bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
709 if (getLexer().is(AsmToken::EndOfStatement)) {
710 Lex();
711 getStreamer().EmitDataRegion(MCDR_DataRegion);
712 return false;
713 }
714 StringRef RegionType;
715 SMLoc Loc = getParser().getTok().getLoc();
716 if (getParser().ParseIdentifier(RegionType))
717 return TokError("expected region type after '.data_region' directive");
718 int Kind = StringSwitch<int>(RegionType)
719 .Case("jt8", MCDR_DataRegionJT8)
720 .Case("jt16", MCDR_DataRegionJT16)
721 .Case("jt32", MCDR_DataRegionJT32)
722 .Default(-1);
723 if (Kind == -1)
724 return Error(Loc, "unknown region type in '.data_region' directive");
725 Lex();
726
727 getStreamer().EmitDataRegion((MCDataRegionType)Kind);
728 return false;
729}
730
731/// ParseDirectiveDataRegionEnd
732/// ::= .end_data_region
733bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
734 if (getLexer().isNot(AsmToken::EndOfStatement))
735 return TokError("unexpected token in '.end_data_region' directive");
736
737 Lex();
738 getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
739 return false;
740}
741
Daniel Dunbar9c23d7f2010-07-12 20:51:51 +0000742namespace llvm {
743
744MCAsmParserExtension *createDarwinAsmParser() {
745 return new DarwinAsmParser;
746}
747
Bill Wendlingef920552012-08-08 06:30:30 +0000748} // end llvm namespace