DarwinAsmParser.cpp 44 KB

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