DarwinAsmParser.cpp 44 KB

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