DarwinAsmParser.cpp 43 KB

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