WasmObjectFile.cpp 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997
  1. //===- WasmObjectFile.cpp - Wasm object file implementation ---------------===//
  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/ArrayRef.h"
  9. #include "llvm/ADT/DenseSet.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. #include "llvm/ADT/SmallSet.h"
  12. #include "llvm/ADT/StringRef.h"
  13. #include "llvm/ADT/StringSet.h"
  14. #include "llvm/ADT/StringSwitch.h"
  15. #include "llvm/ADT/Triple.h"
  16. #include "llvm/BinaryFormat/Wasm.h"
  17. #include "llvm/MC/SubtargetFeature.h"
  18. #include "llvm/Object/Binary.h"
  19. #include "llvm/Object/Error.h"
  20. #include "llvm/Object/ObjectFile.h"
  21. #include "llvm/Object/SymbolicFile.h"
  22. #include "llvm/Object/Wasm.h"
  23. #include "llvm/Support/Endian.h"
  24. #include "llvm/Support/Error.h"
  25. #include "llvm/Support/ErrorHandling.h"
  26. #include "llvm/Support/LEB128.h"
  27. #include "llvm/Support/ScopedPrinter.h"
  28. #include <algorithm>
  29. #include <cassert>
  30. #include <cstdint>
  31. #include <cstring>
  32. #include <system_error>
  33. #define DEBUG_TYPE "wasm-object"
  34. using namespace llvm;
  35. using namespace object;
  36. void WasmSymbol::print(raw_ostream &Out) const {
  37. Out << "Name=" << Info.Name
  38. << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x"
  39. << Twine::utohexstr(Info.Flags);
  40. if (!isTypeData()) {
  41. Out << ", ElemIndex=" << Info.ElementIndex;
  42. } else if (isDefined()) {
  43. Out << ", Segment=" << Info.DataRef.Segment;
  44. Out << ", Offset=" << Info.DataRef.Offset;
  45. Out << ", Size=" << Info.DataRef.Size;
  46. }
  47. }
  48. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  49. LLVM_DUMP_METHOD void WasmSymbol::dump() const { print(dbgs()); }
  50. #endif
  51. Expected<std::unique_ptr<WasmObjectFile>>
  52. ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) {
  53. Error Err = Error::success();
  54. auto ObjectFile = std::make_unique<WasmObjectFile>(Buffer, Err);
  55. if (Err)
  56. return std::move(Err);
  57. return std::move(ObjectFile);
  58. }
  59. #define VARINT7_MAX ((1 << 7) - 1)
  60. #define VARINT7_MIN (-(1 << 7))
  61. #define VARUINT7_MAX (1 << 7)
  62. #define VARUINT1_MAX (1)
  63. static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx) {
  64. if (Ctx.Ptr == Ctx.End)
  65. report_fatal_error("EOF while reading uint8");
  66. return *Ctx.Ptr++;
  67. }
  68. static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx) {
  69. if (Ctx.Ptr + 4 > Ctx.End)
  70. report_fatal_error("EOF while reading uint32");
  71. uint32_t Result = support::endian::read32le(Ctx.Ptr);
  72. Ctx.Ptr += 4;
  73. return Result;
  74. }
  75. static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx) {
  76. if (Ctx.Ptr + 4 > Ctx.End)
  77. report_fatal_error("EOF while reading float64");
  78. int32_t Result = 0;
  79. memcpy(&Result, Ctx.Ptr, sizeof(Result));
  80. Ctx.Ptr += sizeof(Result);
  81. return Result;
  82. }
  83. static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx) {
  84. if (Ctx.Ptr + 8 > Ctx.End)
  85. report_fatal_error("EOF while reading float64");
  86. int64_t Result = 0;
  87. memcpy(&Result, Ctx.Ptr, sizeof(Result));
  88. Ctx.Ptr += sizeof(Result);
  89. return Result;
  90. }
  91. static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx) {
  92. unsigned Count;
  93. const char *Error = nullptr;
  94. uint64_t Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
  95. if (Error)
  96. report_fatal_error(Error);
  97. Ctx.Ptr += Count;
  98. return Result;
  99. }
  100. static StringRef readString(WasmObjectFile::ReadContext &Ctx) {
  101. uint32_t StringLen = readULEB128(Ctx);
  102. if (Ctx.Ptr + StringLen > Ctx.End)
  103. report_fatal_error("EOF while reading string");
  104. StringRef Return =
  105. StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);
  106. Ctx.Ptr += StringLen;
  107. return Return;
  108. }
  109. static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx) {
  110. unsigned Count;
  111. const char *Error = nullptr;
  112. uint64_t Result = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
  113. if (Error)
  114. report_fatal_error(Error);
  115. Ctx.Ptr += Count;
  116. return Result;
  117. }
  118. static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx) {
  119. int64_t Result = readLEB128(Ctx);
  120. if (Result > VARUINT1_MAX || Result < 0)
  121. report_fatal_error("LEB is outside Varuint1 range");
  122. return Result;
  123. }
  124. static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx) {
  125. int64_t Result = readLEB128(Ctx);
  126. if (Result > INT32_MAX || Result < INT32_MIN)
  127. report_fatal_error("LEB is outside Varint32 range");
  128. return Result;
  129. }
  130. static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx) {
  131. uint64_t Result = readULEB128(Ctx);
  132. if (Result > UINT32_MAX)
  133. report_fatal_error("LEB is outside Varuint32 range");
  134. return Result;
  135. }
  136. static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) {
  137. return readLEB128(Ctx);
  138. }
  139. static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx) {
  140. return readULEB128(Ctx);
  141. }
  142. static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
  143. return readUint8(Ctx);
  144. }
  145. static Error readInitExpr(wasm::WasmInitExpr &Expr,
  146. WasmObjectFile::ReadContext &Ctx) {
  147. Expr.Opcode = readOpcode(Ctx);
  148. switch (Expr.Opcode) {
  149. case wasm::WASM_OPCODE_I32_CONST:
  150. Expr.Value.Int32 = readVarint32(Ctx);
  151. break;
  152. case wasm::WASM_OPCODE_I64_CONST:
  153. Expr.Value.Int64 = readVarint64(Ctx);
  154. break;
  155. case wasm::WASM_OPCODE_F32_CONST:
  156. Expr.Value.Float32 = readFloat32(Ctx);
  157. break;
  158. case wasm::WASM_OPCODE_F64_CONST:
  159. Expr.Value.Float64 = readFloat64(Ctx);
  160. break;
  161. case wasm::WASM_OPCODE_GLOBAL_GET:
  162. Expr.Value.Global = readULEB128(Ctx);
  163. break;
  164. case wasm::WASM_OPCODE_REF_NULL: {
  165. wasm::ValType Ty = static_cast<wasm::ValType>(readULEB128(Ctx));
  166. if (Ty != wasm::ValType::EXTERNREF) {
  167. return make_error<GenericBinaryError>("invalid type for ref.null",
  168. object_error::parse_failed);
  169. }
  170. break;
  171. }
  172. default:
  173. return make_error<GenericBinaryError>("invalid opcode in init_expr",
  174. object_error::parse_failed);
  175. }
  176. uint8_t EndOpcode = readOpcode(Ctx);
  177. if (EndOpcode != wasm::WASM_OPCODE_END) {
  178. return make_error<GenericBinaryError>("invalid init_expr",
  179. object_error::parse_failed);
  180. }
  181. return Error::success();
  182. }
  183. static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
  184. wasm::WasmLimits Result;
  185. Result.Flags = readVaruint32(Ctx);
  186. Result.Minimum = readVaruint64(Ctx);
  187. if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
  188. Result.Maximum = readVaruint64(Ctx);
  189. return Result;
  190. }
  191. static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx) {
  192. wasm::WasmTableType TableType;
  193. TableType.ElemType = readUint8(Ctx);
  194. TableType.Limits = readLimits(Ctx);
  195. return TableType;
  196. }
  197. static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
  198. WasmSectionOrderChecker &Checker) {
  199. Section.Offset = Ctx.Ptr - Ctx.Start;
  200. Section.Type = readUint8(Ctx);
  201. LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");
  202. uint32_t Size = readVaruint32(Ctx);
  203. if (Size == 0)
  204. return make_error<StringError>("zero length section",
  205. object_error::parse_failed);
  206. if (Ctx.Ptr + Size > Ctx.End)
  207. return make_error<StringError>("section too large",
  208. object_error::parse_failed);
  209. if (Section.Type == wasm::WASM_SEC_CUSTOM) {
  210. WasmObjectFile::ReadContext SectionCtx;
  211. SectionCtx.Start = Ctx.Ptr;
  212. SectionCtx.Ptr = Ctx.Ptr;
  213. SectionCtx.End = Ctx.Ptr + Size;
  214. Section.Name = readString(SectionCtx);
  215. uint32_t SectionNameSize = SectionCtx.Ptr - SectionCtx.Start;
  216. Ctx.Ptr += SectionNameSize;
  217. Size -= SectionNameSize;
  218. }
  219. if (!Checker.isValidSectionOrder(Section.Type, Section.Name)) {
  220. return make_error<StringError>("out of order section type: " +
  221. llvm::to_string(Section.Type),
  222. object_error::parse_failed);
  223. }
  224. Section.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
  225. Ctx.Ptr += Size;
  226. return Error::success();
  227. }
  228. WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
  229. : ObjectFile(Binary::ID_Wasm, Buffer) {
  230. ErrorAsOutParameter ErrAsOutParam(&Err);
  231. Header.Magic = getData().substr(0, 4);
  232. if (Header.Magic != StringRef("\0asm", 4)) {
  233. Err = make_error<StringError>("invalid magic number",
  234. object_error::parse_failed);
  235. return;
  236. }
  237. ReadContext Ctx;
  238. Ctx.Start = getData().bytes_begin();
  239. Ctx.Ptr = Ctx.Start + 4;
  240. Ctx.End = Ctx.Start + getData().size();
  241. if (Ctx.Ptr + 4 > Ctx.End) {
  242. Err = make_error<StringError>("missing version number",
  243. object_error::parse_failed);
  244. return;
  245. }
  246. Header.Version = readUint32(Ctx);
  247. if (Header.Version != wasm::WasmVersion) {
  248. Err = make_error<StringError>("invalid version number: " +
  249. Twine(Header.Version),
  250. object_error::parse_failed);
  251. return;
  252. }
  253. WasmSectionOrderChecker Checker;
  254. while (Ctx.Ptr < Ctx.End) {
  255. WasmSection Sec;
  256. if ((Err = readSection(Sec, Ctx, Checker)))
  257. return;
  258. if ((Err = parseSection(Sec)))
  259. return;
  260. Sections.push_back(Sec);
  261. }
  262. }
  263. Error WasmObjectFile::parseSection(WasmSection &Sec) {
  264. ReadContext Ctx;
  265. Ctx.Start = Sec.Content.data();
  266. Ctx.End = Ctx.Start + Sec.Content.size();
  267. Ctx.Ptr = Ctx.Start;
  268. switch (Sec.Type) {
  269. case wasm::WASM_SEC_CUSTOM:
  270. return parseCustomSection(Sec, Ctx);
  271. case wasm::WASM_SEC_TYPE:
  272. return parseTypeSection(Ctx);
  273. case wasm::WASM_SEC_IMPORT:
  274. return parseImportSection(Ctx);
  275. case wasm::WASM_SEC_FUNCTION:
  276. return parseFunctionSection(Ctx);
  277. case wasm::WASM_SEC_TABLE:
  278. return parseTableSection(Ctx);
  279. case wasm::WASM_SEC_MEMORY:
  280. return parseMemorySection(Ctx);
  281. case wasm::WASM_SEC_TAG:
  282. return parseTagSection(Ctx);
  283. case wasm::WASM_SEC_GLOBAL:
  284. return parseGlobalSection(Ctx);
  285. case wasm::WASM_SEC_EXPORT:
  286. return parseExportSection(Ctx);
  287. case wasm::WASM_SEC_START:
  288. return parseStartSection(Ctx);
  289. case wasm::WASM_SEC_ELEM:
  290. return parseElemSection(Ctx);
  291. case wasm::WASM_SEC_CODE:
  292. return parseCodeSection(Ctx);
  293. case wasm::WASM_SEC_DATA:
  294. return parseDataSection(Ctx);
  295. case wasm::WASM_SEC_DATACOUNT:
  296. return parseDataCountSection(Ctx);
  297. default:
  298. return make_error<GenericBinaryError>(
  299. "invalid section type: " + Twine(Sec.Type), object_error::parse_failed);
  300. }
  301. }
  302. Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
  303. // Legacy "dylink" section support.
  304. // See parseDylink0Section for the current "dylink.0" section parsing.
  305. HasDylinkSection = true;
  306. DylinkInfo.MemorySize = readVaruint32(Ctx);
  307. DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
  308. DylinkInfo.TableSize = readVaruint32(Ctx);
  309. DylinkInfo.TableAlignment = readVaruint32(Ctx);
  310. uint32_t Count = readVaruint32(Ctx);
  311. while (Count--) {
  312. DylinkInfo.Needed.push_back(readString(Ctx));
  313. }
  314. if (Ctx.Ptr != Ctx.End)
  315. return make_error<GenericBinaryError>("dylink section ended prematurely",
  316. object_error::parse_failed);
  317. return Error::success();
  318. }
  319. Error WasmObjectFile::parseDylink0Section(ReadContext &Ctx) {
  320. // See
  321. // https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
  322. HasDylinkSection = true;
  323. const uint8_t *OrigEnd = Ctx.End;
  324. while (Ctx.Ptr < OrigEnd) {
  325. Ctx.End = OrigEnd;
  326. uint8_t Type = readUint8(Ctx);
  327. uint32_t Size = readVaruint32(Ctx);
  328. LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
  329. << "\n");
  330. Ctx.End = Ctx.Ptr + Size;
  331. uint32_t Count;
  332. switch (Type) {
  333. case wasm::WASM_DYLINK_MEM_INFO:
  334. DylinkInfo.MemorySize = readVaruint32(Ctx);
  335. DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
  336. DylinkInfo.TableSize = readVaruint32(Ctx);
  337. DylinkInfo.TableAlignment = readVaruint32(Ctx);
  338. break;
  339. case wasm::WASM_DYLINK_NEEDED:
  340. Count = readVaruint32(Ctx);
  341. while (Count--) {
  342. DylinkInfo.Needed.push_back(readString(Ctx));
  343. }
  344. break;
  345. case wasm::WASM_DYLINK_EXPORT_INFO: {
  346. uint32_t Count = readVaruint32(Ctx);
  347. while (Count--) {
  348. DylinkInfo.ExportInfo.push_back({readString(Ctx), readVaruint32(Ctx)});
  349. }
  350. break;
  351. }
  352. case wasm::WASM_DYLINK_IMPORT_INFO: {
  353. uint32_t Count = readVaruint32(Ctx);
  354. while (Count--) {
  355. DylinkInfo.ImportInfo.push_back(
  356. {readString(Ctx), readString(Ctx), readVaruint32(Ctx)});
  357. }
  358. break;
  359. }
  360. default:
  361. LLVM_DEBUG(dbgs() << "unknown dylink.0 sub-section: " << Type << "\n");
  362. Ctx.Ptr += Size;
  363. break;
  364. }
  365. if (Ctx.Ptr != Ctx.End) {
  366. return make_error<GenericBinaryError>(
  367. "dylink.0 sub-section ended prematurely", object_error::parse_failed);
  368. }
  369. }
  370. if (Ctx.Ptr != Ctx.End)
  371. return make_error<GenericBinaryError>("dylink.0 section ended prematurely",
  372. object_error::parse_failed);
  373. return Error::success();
  374. }
  375. Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
  376. llvm::DenseSet<uint64_t> SeenFunctions;
  377. llvm::DenseSet<uint64_t> SeenGlobals;
  378. llvm::DenseSet<uint64_t> SeenSegments;
  379. if (Functions.size() && !SeenCodeSection) {
  380. return make_error<GenericBinaryError>("names must come after code section",
  381. object_error::parse_failed);
  382. }
  383. while (Ctx.Ptr < Ctx.End) {
  384. uint8_t Type = readUint8(Ctx);
  385. uint32_t Size = readVaruint32(Ctx);
  386. const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
  387. switch (Type) {
  388. case wasm::WASM_NAMES_FUNCTION:
  389. case wasm::WASM_NAMES_GLOBAL:
  390. case wasm::WASM_NAMES_DATA_SEGMENT: {
  391. uint32_t Count = readVaruint32(Ctx);
  392. while (Count--) {
  393. uint32_t Index = readVaruint32(Ctx);
  394. StringRef Name = readString(Ctx);
  395. wasm::NameType nameType = wasm::NameType::FUNCTION;
  396. if (Type == wasm::WASM_NAMES_FUNCTION) {
  397. if (!SeenFunctions.insert(Index).second)
  398. return make_error<GenericBinaryError>(
  399. "function named more than once", object_error::parse_failed);
  400. if (!isValidFunctionIndex(Index) || Name.empty())
  401. return make_error<GenericBinaryError>("invalid name entry",
  402. object_error::parse_failed);
  403. if (isDefinedFunctionIndex(Index))
  404. getDefinedFunction(Index).DebugName = Name;
  405. } else if (Type == wasm::WASM_NAMES_GLOBAL) {
  406. nameType = wasm::NameType::GLOBAL;
  407. if (!SeenGlobals.insert(Index).second)
  408. return make_error<GenericBinaryError>("global named more than once",
  409. object_error::parse_failed);
  410. if (!isValidGlobalIndex(Index) || Name.empty())
  411. return make_error<GenericBinaryError>("invalid name entry",
  412. object_error::parse_failed);
  413. } else {
  414. nameType = wasm::NameType::DATA_SEGMENT;
  415. if (!SeenSegments.insert(Index).second)
  416. return make_error<GenericBinaryError>(
  417. "segment named more than once", object_error::parse_failed);
  418. if (Index > DataSegments.size())
  419. return make_error<GenericBinaryError>("invalid named data segment",
  420. object_error::parse_failed);
  421. }
  422. DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
  423. }
  424. break;
  425. }
  426. // Ignore local names for now
  427. case wasm::WASM_NAMES_LOCAL:
  428. default:
  429. Ctx.Ptr += Size;
  430. break;
  431. }
  432. if (Ctx.Ptr != SubSectionEnd)
  433. return make_error<GenericBinaryError>(
  434. "name sub-section ended prematurely", object_error::parse_failed);
  435. }
  436. if (Ctx.Ptr != Ctx.End)
  437. return make_error<GenericBinaryError>("name section ended prematurely",
  438. object_error::parse_failed);
  439. return Error::success();
  440. }
  441. Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
  442. HasLinkingSection = true;
  443. if (Functions.size() && !SeenCodeSection) {
  444. return make_error<GenericBinaryError>(
  445. "linking data must come after code section",
  446. object_error::parse_failed);
  447. }
  448. LinkingData.Version = readVaruint32(Ctx);
  449. if (LinkingData.Version != wasm::WasmMetadataVersion) {
  450. return make_error<GenericBinaryError>(
  451. "unexpected metadata version: " + Twine(LinkingData.Version) +
  452. " (Expected: " + Twine(wasm::WasmMetadataVersion) + ")",
  453. object_error::parse_failed);
  454. }
  455. const uint8_t *OrigEnd = Ctx.End;
  456. while (Ctx.Ptr < OrigEnd) {
  457. Ctx.End = OrigEnd;
  458. uint8_t Type = readUint8(Ctx);
  459. uint32_t Size = readVaruint32(Ctx);
  460. LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
  461. << "\n");
  462. Ctx.End = Ctx.Ptr + Size;
  463. switch (Type) {
  464. case wasm::WASM_SYMBOL_TABLE:
  465. if (Error Err = parseLinkingSectionSymtab(Ctx))
  466. return Err;
  467. break;
  468. case wasm::WASM_SEGMENT_INFO: {
  469. uint32_t Count = readVaruint32(Ctx);
  470. if (Count > DataSegments.size())
  471. return make_error<GenericBinaryError>("too many segment names",
  472. object_error::parse_failed);
  473. for (uint32_t I = 0; I < Count; I++) {
  474. DataSegments[I].Data.Name = readString(Ctx);
  475. DataSegments[I].Data.Alignment = readVaruint32(Ctx);
  476. DataSegments[I].Data.LinkingFlags = readVaruint32(Ctx);
  477. }
  478. break;
  479. }
  480. case wasm::WASM_INIT_FUNCS: {
  481. uint32_t Count = readVaruint32(Ctx);
  482. LinkingData.InitFunctions.reserve(Count);
  483. for (uint32_t I = 0; I < Count; I++) {
  484. wasm::WasmInitFunc Init;
  485. Init.Priority = readVaruint32(Ctx);
  486. Init.Symbol = readVaruint32(Ctx);
  487. if (!isValidFunctionSymbol(Init.Symbol))
  488. return make_error<GenericBinaryError>("invalid function symbol: " +
  489. Twine(Init.Symbol),
  490. object_error::parse_failed);
  491. LinkingData.InitFunctions.emplace_back(Init);
  492. }
  493. break;
  494. }
  495. case wasm::WASM_COMDAT_INFO:
  496. if (Error Err = parseLinkingSectionComdat(Ctx))
  497. return Err;
  498. break;
  499. default:
  500. Ctx.Ptr += Size;
  501. break;
  502. }
  503. if (Ctx.Ptr != Ctx.End)
  504. return make_error<GenericBinaryError>(
  505. "linking sub-section ended prematurely", object_error::parse_failed);
  506. }
  507. if (Ctx.Ptr != OrigEnd)
  508. return make_error<GenericBinaryError>("linking section ended prematurely",
  509. object_error::parse_failed);
  510. return Error::success();
  511. }
  512. Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
  513. uint32_t Count = readVaruint32(Ctx);
  514. LinkingData.SymbolTable.reserve(Count);
  515. Symbols.reserve(Count);
  516. StringSet<> SymbolNames;
  517. std::vector<wasm::WasmImport *> ImportedGlobals;
  518. std::vector<wasm::WasmImport *> ImportedFunctions;
  519. std::vector<wasm::WasmImport *> ImportedTags;
  520. std::vector<wasm::WasmImport *> ImportedTables;
  521. ImportedGlobals.reserve(Imports.size());
  522. ImportedFunctions.reserve(Imports.size());
  523. ImportedTags.reserve(Imports.size());
  524. ImportedTables.reserve(Imports.size());
  525. for (auto &I : Imports) {
  526. if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
  527. ImportedFunctions.emplace_back(&I);
  528. else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
  529. ImportedGlobals.emplace_back(&I);
  530. else if (I.Kind == wasm::WASM_EXTERNAL_TAG)
  531. ImportedTags.emplace_back(&I);
  532. else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
  533. ImportedTables.emplace_back(&I);
  534. }
  535. while (Count--) {
  536. wasm::WasmSymbolInfo Info;
  537. const wasm::WasmSignature *Signature = nullptr;
  538. const wasm::WasmGlobalType *GlobalType = nullptr;
  539. const wasm::WasmTableType *TableType = nullptr;
  540. Info.Kind = readUint8(Ctx);
  541. Info.Flags = readVaruint32(Ctx);
  542. bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
  543. switch (Info.Kind) {
  544. case wasm::WASM_SYMBOL_TYPE_FUNCTION:
  545. Info.ElementIndex = readVaruint32(Ctx);
  546. if (!isValidFunctionIndex(Info.ElementIndex) ||
  547. IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
  548. return make_error<GenericBinaryError>("invalid function symbol index",
  549. object_error::parse_failed);
  550. if (IsDefined) {
  551. Info.Name = readString(Ctx);
  552. unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
  553. wasm::WasmFunction &Function = Functions[FuncIndex];
  554. Signature = &Signatures[Function.SigIndex];
  555. if (Function.SymbolName.empty())
  556. Function.SymbolName = Info.Name;
  557. } else {
  558. wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
  559. if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
  560. Info.Name = readString(Ctx);
  561. Info.ImportName = Import.Field;
  562. } else {
  563. Info.Name = Import.Field;
  564. }
  565. Signature = &Signatures[Import.SigIndex];
  566. if (!Import.Module.empty()) {
  567. Info.ImportModule = Import.Module;
  568. }
  569. }
  570. break;
  571. case wasm::WASM_SYMBOL_TYPE_GLOBAL:
  572. Info.ElementIndex = readVaruint32(Ctx);
  573. if (!isValidGlobalIndex(Info.ElementIndex) ||
  574. IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
  575. return make_error<GenericBinaryError>("invalid global symbol index",
  576. object_error::parse_failed);
  577. if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
  578. wasm::WASM_SYMBOL_BINDING_WEAK)
  579. return make_error<GenericBinaryError>("undefined weak global symbol",
  580. object_error::parse_failed);
  581. if (IsDefined) {
  582. Info.Name = readString(Ctx);
  583. unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
  584. wasm::WasmGlobal &Global = Globals[GlobalIndex];
  585. GlobalType = &Global.Type;
  586. if (Global.SymbolName.empty())
  587. Global.SymbolName = Info.Name;
  588. } else {
  589. wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
  590. if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
  591. Info.Name = readString(Ctx);
  592. Info.ImportName = Import.Field;
  593. } else {
  594. Info.Name = Import.Field;
  595. }
  596. GlobalType = &Import.Global;
  597. if (!Import.Module.empty()) {
  598. Info.ImportModule = Import.Module;
  599. }
  600. }
  601. break;
  602. case wasm::WASM_SYMBOL_TYPE_TABLE:
  603. Info.ElementIndex = readVaruint32(Ctx);
  604. if (!isValidTableNumber(Info.ElementIndex) ||
  605. IsDefined != isDefinedTableNumber(Info.ElementIndex))
  606. return make_error<GenericBinaryError>("invalid table symbol index",
  607. object_error::parse_failed);
  608. if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
  609. wasm::WASM_SYMBOL_BINDING_WEAK)
  610. return make_error<GenericBinaryError>("undefined weak table symbol",
  611. object_error::parse_failed);
  612. if (IsDefined) {
  613. Info.Name = readString(Ctx);
  614. unsigned TableNumber = Info.ElementIndex - NumImportedTables;
  615. wasm::WasmTable &Table = Tables[TableNumber];
  616. TableType = &Table.Type;
  617. if (Table.SymbolName.empty())
  618. Table.SymbolName = Info.Name;
  619. } else {
  620. wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
  621. if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
  622. Info.Name = readString(Ctx);
  623. Info.ImportName = Import.Field;
  624. } else {
  625. Info.Name = Import.Field;
  626. }
  627. TableType = &Import.Table;
  628. if (!Import.Module.empty()) {
  629. Info.ImportModule = Import.Module;
  630. }
  631. }
  632. break;
  633. case wasm::WASM_SYMBOL_TYPE_DATA:
  634. Info.Name = readString(Ctx);
  635. if (IsDefined) {
  636. auto Index = readVaruint32(Ctx);
  637. if (Index >= DataSegments.size())
  638. return make_error<GenericBinaryError>("invalid data symbol index",
  639. object_error::parse_failed);
  640. auto Offset = readVaruint64(Ctx);
  641. auto Size = readVaruint64(Ctx);
  642. size_t SegmentSize = DataSegments[Index].Data.Content.size();
  643. if (Offset > SegmentSize)
  644. return make_error<GenericBinaryError>(
  645. "invalid data symbol offset: `" + Info.Name + "` (offset: " +
  646. Twine(Offset) + " segment size: " + Twine(SegmentSize) + ")",
  647. object_error::parse_failed);
  648. Info.DataRef = wasm::WasmDataReference{Index, Offset, Size};
  649. }
  650. break;
  651. case wasm::WASM_SYMBOL_TYPE_SECTION: {
  652. if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
  653. wasm::WASM_SYMBOL_BINDING_LOCAL)
  654. return make_error<GenericBinaryError>(
  655. "section symbols must have local binding",
  656. object_error::parse_failed);
  657. Info.ElementIndex = readVaruint32(Ctx);
  658. // Use somewhat unique section name as symbol name.
  659. StringRef SectionName = Sections[Info.ElementIndex].Name;
  660. Info.Name = SectionName;
  661. break;
  662. }
  663. case wasm::WASM_SYMBOL_TYPE_TAG: {
  664. Info.ElementIndex = readVaruint32(Ctx);
  665. if (!isValidTagIndex(Info.ElementIndex) ||
  666. IsDefined != isDefinedTagIndex(Info.ElementIndex))
  667. return make_error<GenericBinaryError>("invalid tag symbol index",
  668. object_error::parse_failed);
  669. if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
  670. wasm::WASM_SYMBOL_BINDING_WEAK)
  671. return make_error<GenericBinaryError>("undefined weak global symbol",
  672. object_error::parse_failed);
  673. if (IsDefined) {
  674. Info.Name = readString(Ctx);
  675. unsigned TagIndex = Info.ElementIndex - NumImportedTags;
  676. wasm::WasmTag &Tag = Tags[TagIndex];
  677. Signature = &Signatures[Tag.SigIndex];
  678. if (Tag.SymbolName.empty())
  679. Tag.SymbolName = Info.Name;
  680. } else {
  681. wasm::WasmImport &Import = *ImportedTags[Info.ElementIndex];
  682. if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
  683. Info.Name = readString(Ctx);
  684. Info.ImportName = Import.Field;
  685. } else {
  686. Info.Name = Import.Field;
  687. }
  688. Signature = &Signatures[Import.SigIndex];
  689. if (!Import.Module.empty()) {
  690. Info.ImportModule = Import.Module;
  691. }
  692. }
  693. break;
  694. }
  695. default:
  696. return make_error<GenericBinaryError>("invalid symbol type: " +
  697. Twine(unsigned(Info.Kind)),
  698. object_error::parse_failed);
  699. }
  700. if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
  701. wasm::WASM_SYMBOL_BINDING_LOCAL &&
  702. !SymbolNames.insert(Info.Name).second)
  703. return make_error<GenericBinaryError>("duplicate symbol name " +
  704. Twine(Info.Name),
  705. object_error::parse_failed);
  706. LinkingData.SymbolTable.emplace_back(Info);
  707. Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
  708. Signature);
  709. LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
  710. }
  711. return Error::success();
  712. }
  713. Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
  714. uint32_t ComdatCount = readVaruint32(Ctx);
  715. StringSet<> ComdatSet;
  716. for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
  717. StringRef Name = readString(Ctx);
  718. if (Name.empty() || !ComdatSet.insert(Name).second)
  719. return make_error<GenericBinaryError>("bad/duplicate COMDAT name " +
  720. Twine(Name),
  721. object_error::parse_failed);
  722. LinkingData.Comdats.emplace_back(Name);
  723. uint32_t Flags = readVaruint32(Ctx);
  724. if (Flags != 0)
  725. return make_error<GenericBinaryError>("unsupported COMDAT flags",
  726. object_error::parse_failed);
  727. uint32_t EntryCount = readVaruint32(Ctx);
  728. while (EntryCount--) {
  729. unsigned Kind = readVaruint32(Ctx);
  730. unsigned Index = readVaruint32(Ctx);
  731. switch (Kind) {
  732. default:
  733. return make_error<GenericBinaryError>("invalid COMDAT entry type",
  734. object_error::parse_failed);
  735. case wasm::WASM_COMDAT_DATA:
  736. if (Index >= DataSegments.size())
  737. return make_error<GenericBinaryError>(
  738. "COMDAT data index out of range", object_error::parse_failed);
  739. if (DataSegments[Index].Data.Comdat != UINT32_MAX)
  740. return make_error<GenericBinaryError>("data segment in two COMDATs",
  741. object_error::parse_failed);
  742. DataSegments[Index].Data.Comdat = ComdatIndex;
  743. break;
  744. case wasm::WASM_COMDAT_FUNCTION:
  745. if (!isDefinedFunctionIndex(Index))
  746. return make_error<GenericBinaryError>(
  747. "COMDAT function index out of range", object_error::parse_failed);
  748. if (getDefinedFunction(Index).Comdat != UINT32_MAX)
  749. return make_error<GenericBinaryError>("function in two COMDATs",
  750. object_error::parse_failed);
  751. getDefinedFunction(Index).Comdat = ComdatIndex;
  752. break;
  753. case wasm::WASM_COMDAT_SECTION:
  754. if (Index >= Sections.size())
  755. return make_error<GenericBinaryError>(
  756. "COMDAT section index out of range", object_error::parse_failed);
  757. if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
  758. return make_error<GenericBinaryError>(
  759. "non-custom section in a COMDAT", object_error::parse_failed);
  760. Sections[Index].Comdat = ComdatIndex;
  761. break;
  762. }
  763. }
  764. }
  765. return Error::success();
  766. }
  767. Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
  768. llvm::SmallSet<StringRef, 3> FieldsSeen;
  769. uint32_t Fields = readVaruint32(Ctx);
  770. for (size_t I = 0; I < Fields; ++I) {
  771. StringRef FieldName = readString(Ctx);
  772. if (!FieldsSeen.insert(FieldName).second)
  773. return make_error<GenericBinaryError>(
  774. "producers section does not have unique fields",
  775. object_error::parse_failed);
  776. std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
  777. if (FieldName == "language") {
  778. ProducerVec = &ProducerInfo.Languages;
  779. } else if (FieldName == "processed-by") {
  780. ProducerVec = &ProducerInfo.Tools;
  781. } else if (FieldName == "sdk") {
  782. ProducerVec = &ProducerInfo.SDKs;
  783. } else {
  784. return make_error<GenericBinaryError>(
  785. "producers section field is not named one of language, processed-by, "
  786. "or sdk",
  787. object_error::parse_failed);
  788. }
  789. uint32_t ValueCount = readVaruint32(Ctx);
  790. llvm::SmallSet<StringRef, 8> ProducersSeen;
  791. for (size_t J = 0; J < ValueCount; ++J) {
  792. StringRef Name = readString(Ctx);
  793. StringRef Version = readString(Ctx);
  794. if (!ProducersSeen.insert(Name).second) {
  795. return make_error<GenericBinaryError>(
  796. "producers section contains repeated producer",
  797. object_error::parse_failed);
  798. }
  799. ProducerVec->emplace_back(std::string(Name), std::string(Version));
  800. }
  801. }
  802. if (Ctx.Ptr != Ctx.End)
  803. return make_error<GenericBinaryError>("producers section ended prematurely",
  804. object_error::parse_failed);
  805. return Error::success();
  806. }
  807. Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
  808. llvm::SmallSet<std::string, 8> FeaturesSeen;
  809. uint32_t FeatureCount = readVaruint32(Ctx);
  810. for (size_t I = 0; I < FeatureCount; ++I) {
  811. wasm::WasmFeatureEntry Feature;
  812. Feature.Prefix = readUint8(Ctx);
  813. switch (Feature.Prefix) {
  814. case wasm::WASM_FEATURE_PREFIX_USED:
  815. case wasm::WASM_FEATURE_PREFIX_REQUIRED:
  816. case wasm::WASM_FEATURE_PREFIX_DISALLOWED:
  817. break;
  818. default:
  819. return make_error<GenericBinaryError>("unknown feature policy prefix",
  820. object_error::parse_failed);
  821. }
  822. Feature.Name = std::string(readString(Ctx));
  823. if (!FeaturesSeen.insert(Feature.Name).second)
  824. return make_error<GenericBinaryError>(
  825. "target features section contains repeated feature \"" +
  826. Feature.Name + "\"",
  827. object_error::parse_failed);
  828. TargetFeatures.push_back(Feature);
  829. }
  830. if (Ctx.Ptr != Ctx.End)
  831. return make_error<GenericBinaryError>(
  832. "target features section ended prematurely",
  833. object_error::parse_failed);
  834. return Error::success();
  835. }
  836. Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
  837. uint32_t SectionIndex = readVaruint32(Ctx);
  838. if (SectionIndex >= Sections.size())
  839. return make_error<GenericBinaryError>("invalid section index",
  840. object_error::parse_failed);
  841. WasmSection &Section = Sections[SectionIndex];
  842. uint32_t RelocCount = readVaruint32(Ctx);
  843. uint32_t EndOffset = Section.Content.size();
  844. uint32_t PreviousOffset = 0;
  845. while (RelocCount--) {
  846. wasm::WasmRelocation Reloc = {};
  847. uint32_t type = readVaruint32(Ctx);
  848. Reloc.Type = type;
  849. Reloc.Offset = readVaruint32(Ctx);
  850. if (Reloc.Offset < PreviousOffset)
  851. return make_error<GenericBinaryError>("relocations not in offset order",
  852. object_error::parse_failed);
  853. PreviousOffset = Reloc.Offset;
  854. Reloc.Index = readVaruint32(Ctx);
  855. switch (type) {
  856. case wasm::R_WASM_FUNCTION_INDEX_LEB:
  857. case wasm::R_WASM_TABLE_INDEX_SLEB:
  858. case wasm::R_WASM_TABLE_INDEX_SLEB64:
  859. case wasm::R_WASM_TABLE_INDEX_I32:
  860. case wasm::R_WASM_TABLE_INDEX_I64:
  861. case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
  862. case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
  863. if (!isValidFunctionSymbol(Reloc.Index))
  864. return make_error<GenericBinaryError>(
  865. "invalid relocation function index", object_error::parse_failed);
  866. break;
  867. case wasm::R_WASM_TABLE_NUMBER_LEB:
  868. if (!isValidTableSymbol(Reloc.Index))
  869. return make_error<GenericBinaryError>("invalid relocation table index",
  870. object_error::parse_failed);
  871. break;
  872. case wasm::R_WASM_TYPE_INDEX_LEB:
  873. if (Reloc.Index >= Signatures.size())
  874. return make_error<GenericBinaryError>("invalid relocation type index",
  875. object_error::parse_failed);
  876. break;
  877. case wasm::R_WASM_GLOBAL_INDEX_LEB:
  878. // R_WASM_GLOBAL_INDEX_LEB are can be used against function and data
  879. // symbols to refer to their GOT entries.
  880. if (!isValidGlobalSymbol(Reloc.Index) &&
  881. !isValidDataSymbol(Reloc.Index) &&
  882. !isValidFunctionSymbol(Reloc.Index))
  883. return make_error<GenericBinaryError>("invalid relocation global index",
  884. object_error::parse_failed);
  885. break;
  886. case wasm::R_WASM_GLOBAL_INDEX_I32:
  887. if (!isValidGlobalSymbol(Reloc.Index))
  888. return make_error<GenericBinaryError>("invalid relocation global index",
  889. object_error::parse_failed);
  890. break;
  891. case wasm::R_WASM_TAG_INDEX_LEB:
  892. if (!isValidTagSymbol(Reloc.Index))
  893. return make_error<GenericBinaryError>("invalid relocation tag index",
  894. object_error::parse_failed);
  895. break;
  896. case wasm::R_WASM_MEMORY_ADDR_LEB:
  897. case wasm::R_WASM_MEMORY_ADDR_SLEB:
  898. case wasm::R_WASM_MEMORY_ADDR_I32:
  899. case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
  900. case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
  901. case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
  902. if (!isValidDataSymbol(Reloc.Index))
  903. return make_error<GenericBinaryError>("invalid relocation data index",
  904. object_error::parse_failed);
  905. Reloc.Addend = readVarint32(Ctx);
  906. break;
  907. case wasm::R_WASM_MEMORY_ADDR_LEB64:
  908. case wasm::R_WASM_MEMORY_ADDR_SLEB64:
  909. case wasm::R_WASM_MEMORY_ADDR_I64:
  910. case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
  911. case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
  912. if (!isValidDataSymbol(Reloc.Index))
  913. return make_error<GenericBinaryError>("invalid relocation data index",
  914. object_error::parse_failed);
  915. Reloc.Addend = readVarint64(Ctx);
  916. break;
  917. case wasm::R_WASM_FUNCTION_OFFSET_I32:
  918. if (!isValidFunctionSymbol(Reloc.Index))
  919. return make_error<GenericBinaryError>(
  920. "invalid relocation function index", object_error::parse_failed);
  921. Reloc.Addend = readVarint32(Ctx);
  922. break;
  923. case wasm::R_WASM_FUNCTION_OFFSET_I64:
  924. if (!isValidFunctionSymbol(Reloc.Index))
  925. return make_error<GenericBinaryError>(
  926. "invalid relocation function index", object_error::parse_failed);
  927. Reloc.Addend = readVarint64(Ctx);
  928. break;
  929. case wasm::R_WASM_SECTION_OFFSET_I32:
  930. if (!isValidSectionSymbol(Reloc.Index))
  931. return make_error<GenericBinaryError>(
  932. "invalid relocation section index", object_error::parse_failed);
  933. Reloc.Addend = readVarint32(Ctx);
  934. break;
  935. default:
  936. return make_error<GenericBinaryError>("invalid relocation type: " +
  937. Twine(type),
  938. object_error::parse_failed);
  939. }
  940. // Relocations must fit inside the section, and must appear in order. They
  941. // also shouldn't overlap a function/element boundary, but we don't bother
  942. // to check that.
  943. uint64_t Size = 5;
  944. if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
  945. Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
  946. Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
  947. Size = 10;
  948. if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
  949. Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
  950. Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
  951. Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
  952. Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
  953. Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
  954. Size = 4;
  955. if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
  956. Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
  957. Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
  958. Size = 8;
  959. if (Reloc.Offset + Size > EndOffset)
  960. return make_error<GenericBinaryError>("invalid relocation offset",
  961. object_error::parse_failed);
  962. Section.Relocations.push_back(Reloc);
  963. }
  964. if (Ctx.Ptr != Ctx.End)
  965. return make_error<GenericBinaryError>("reloc section ended prematurely",
  966. object_error::parse_failed);
  967. return Error::success();
  968. }
  969. Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
  970. if (Sec.Name == "dylink") {
  971. if (Error Err = parseDylinkSection(Ctx))
  972. return Err;
  973. } else if (Sec.Name == "dylink.0") {
  974. if (Error Err = parseDylink0Section(Ctx))
  975. return Err;
  976. } else if (Sec.Name == "name") {
  977. if (Error Err = parseNameSection(Ctx))
  978. return Err;
  979. } else if (Sec.Name == "linking") {
  980. if (Error Err = parseLinkingSection(Ctx))
  981. return Err;
  982. } else if (Sec.Name == "producers") {
  983. if (Error Err = parseProducersSection(Ctx))
  984. return Err;
  985. } else if (Sec.Name == "target_features") {
  986. if (Error Err = parseTargetFeaturesSection(Ctx))
  987. return Err;
  988. } else if (Sec.Name.startswith("reloc.")) {
  989. if (Error Err = parseRelocSection(Sec.Name, Ctx))
  990. return Err;
  991. }
  992. return Error::success();
  993. }
  994. Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
  995. uint32_t Count = readVaruint32(Ctx);
  996. Signatures.reserve(Count);
  997. while (Count--) {
  998. wasm::WasmSignature Sig;
  999. uint8_t Form = readUint8(Ctx);
  1000. if (Form != wasm::WASM_TYPE_FUNC) {
  1001. return make_error<GenericBinaryError>("invalid signature type",
  1002. object_error::parse_failed);
  1003. }
  1004. uint32_t ParamCount = readVaruint32(Ctx);
  1005. Sig.Params.reserve(ParamCount);
  1006. while (ParamCount--) {
  1007. uint32_t ParamType = readUint8(Ctx);
  1008. Sig.Params.push_back(wasm::ValType(ParamType));
  1009. }
  1010. uint32_t ReturnCount = readVaruint32(Ctx);
  1011. while (ReturnCount--) {
  1012. uint32_t ReturnType = readUint8(Ctx);
  1013. Sig.Returns.push_back(wasm::ValType(ReturnType));
  1014. }
  1015. Signatures.push_back(std::move(Sig));
  1016. }
  1017. if (Ctx.Ptr != Ctx.End)
  1018. return make_error<GenericBinaryError>("type section ended prematurely",
  1019. object_error::parse_failed);
  1020. return Error::success();
  1021. }
  1022. Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
  1023. uint32_t Count = readVaruint32(Ctx);
  1024. uint32_t NumTypes = Signatures.size();
  1025. Imports.reserve(Count);
  1026. for (uint32_t I = 0; I < Count; I++) {
  1027. wasm::WasmImport Im;
  1028. Im.Module = readString(Ctx);
  1029. Im.Field = readString(Ctx);
  1030. Im.Kind = readUint8(Ctx);
  1031. switch (Im.Kind) {
  1032. case wasm::WASM_EXTERNAL_FUNCTION:
  1033. NumImportedFunctions++;
  1034. Im.SigIndex = readVaruint32(Ctx);
  1035. if (Im.SigIndex >= NumTypes)
  1036. return make_error<GenericBinaryError>("invalid function type",
  1037. object_error::parse_failed);
  1038. break;
  1039. case wasm::WASM_EXTERNAL_GLOBAL:
  1040. NumImportedGlobals++;
  1041. Im.Global.Type = readUint8(Ctx);
  1042. Im.Global.Mutable = readVaruint1(Ctx);
  1043. break;
  1044. case wasm::WASM_EXTERNAL_MEMORY:
  1045. Im.Memory = readLimits(Ctx);
  1046. if (Im.Memory.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
  1047. HasMemory64 = true;
  1048. break;
  1049. case wasm::WASM_EXTERNAL_TABLE: {
  1050. Im.Table = readTableType(Ctx);
  1051. NumImportedTables++;
  1052. auto ElemType = Im.Table.ElemType;
  1053. if (ElemType != wasm::WASM_TYPE_FUNCREF &&
  1054. ElemType != wasm::WASM_TYPE_EXTERNREF)
  1055. return make_error<GenericBinaryError>("invalid table element type",
  1056. object_error::parse_failed);
  1057. break;
  1058. }
  1059. case wasm::WASM_EXTERNAL_TAG:
  1060. NumImportedTags++;
  1061. if (readUint8(Ctx) != 0) // Reserved 'attribute' field
  1062. return make_error<GenericBinaryError>("invalid attribute",
  1063. object_error::parse_failed);
  1064. Im.SigIndex = readVaruint32(Ctx);
  1065. if (Im.SigIndex >= NumTypes)
  1066. return make_error<GenericBinaryError>("invalid tag type",
  1067. object_error::parse_failed);
  1068. break;
  1069. default:
  1070. return make_error<GenericBinaryError>("unexpected import kind",
  1071. object_error::parse_failed);
  1072. }
  1073. Imports.push_back(Im);
  1074. }
  1075. if (Ctx.Ptr != Ctx.End)
  1076. return make_error<GenericBinaryError>("import section ended prematurely",
  1077. object_error::parse_failed);
  1078. return Error::success();
  1079. }
  1080. Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
  1081. uint32_t Count = readVaruint32(Ctx);
  1082. Functions.reserve(Count);
  1083. uint32_t NumTypes = Signatures.size();
  1084. while (Count--) {
  1085. uint32_t Type = readVaruint32(Ctx);
  1086. if (Type >= NumTypes)
  1087. return make_error<GenericBinaryError>("invalid function type",
  1088. object_error::parse_failed);
  1089. wasm::WasmFunction F;
  1090. F.SigIndex = Type;
  1091. Functions.push_back(F);
  1092. }
  1093. if (Ctx.Ptr != Ctx.End)
  1094. return make_error<GenericBinaryError>("function section ended prematurely",
  1095. object_error::parse_failed);
  1096. return Error::success();
  1097. }
  1098. Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
  1099. TableSection = Sections.size();
  1100. uint32_t Count = readVaruint32(Ctx);
  1101. Tables.reserve(Count);
  1102. while (Count--) {
  1103. wasm::WasmTable T;
  1104. T.Type = readTableType(Ctx);
  1105. T.Index = NumImportedTables + Tables.size();
  1106. Tables.push_back(T);
  1107. auto ElemType = Tables.back().Type.ElemType;
  1108. if (ElemType != wasm::WASM_TYPE_FUNCREF &&
  1109. ElemType != wasm::WASM_TYPE_EXTERNREF) {
  1110. return make_error<GenericBinaryError>("invalid table element type",
  1111. object_error::parse_failed);
  1112. }
  1113. }
  1114. if (Ctx.Ptr != Ctx.End)
  1115. return make_error<GenericBinaryError>("table section ended prematurely",
  1116. object_error::parse_failed);
  1117. return Error::success();
  1118. }
  1119. Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
  1120. uint32_t Count = readVaruint32(Ctx);
  1121. Memories.reserve(Count);
  1122. while (Count--) {
  1123. auto Limits = readLimits(Ctx);
  1124. if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
  1125. HasMemory64 = true;
  1126. Memories.push_back(Limits);
  1127. }
  1128. if (Ctx.Ptr != Ctx.End)
  1129. return make_error<GenericBinaryError>("memory section ended prematurely",
  1130. object_error::parse_failed);
  1131. return Error::success();
  1132. }
  1133. Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
  1134. TagSection = Sections.size();
  1135. uint32_t Count = readVaruint32(Ctx);
  1136. Tags.reserve(Count);
  1137. uint32_t NumTypes = Signatures.size();
  1138. while (Count--) {
  1139. if (readUint8(Ctx) != 0) // Reserved 'attribute' field
  1140. return make_error<GenericBinaryError>("invalid attribute",
  1141. object_error::parse_failed);
  1142. uint32_t Type = readVaruint32(Ctx);
  1143. if (Type >= NumTypes)
  1144. return make_error<GenericBinaryError>("invalid tag type",
  1145. object_error::parse_failed);
  1146. wasm::WasmTag Tag;
  1147. Tag.Index = NumImportedTags + Tags.size();
  1148. Tag.SigIndex = Type;
  1149. Tags.push_back(Tag);
  1150. }
  1151. if (Ctx.Ptr != Ctx.End)
  1152. return make_error<GenericBinaryError>("tag section ended prematurely",
  1153. object_error::parse_failed);
  1154. return Error::success();
  1155. }
  1156. Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
  1157. GlobalSection = Sections.size();
  1158. uint32_t Count = readVaruint32(Ctx);
  1159. Globals.reserve(Count);
  1160. while (Count--) {
  1161. wasm::WasmGlobal Global;
  1162. Global.Index = NumImportedGlobals + Globals.size();
  1163. Global.Type.Type = readUint8(Ctx);
  1164. Global.Type.Mutable = readVaruint1(Ctx);
  1165. if (Error Err = readInitExpr(Global.InitExpr, Ctx))
  1166. return Err;
  1167. Globals.push_back(Global);
  1168. }
  1169. if (Ctx.Ptr != Ctx.End)
  1170. return make_error<GenericBinaryError>("global section ended prematurely",
  1171. object_error::parse_failed);
  1172. return Error::success();
  1173. }
  1174. Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
  1175. uint32_t Count = readVaruint32(Ctx);
  1176. Exports.reserve(Count);
  1177. for (uint32_t I = 0; I < Count; I++) {
  1178. wasm::WasmExport Ex;
  1179. Ex.Name = readString(Ctx);
  1180. Ex.Kind = readUint8(Ctx);
  1181. Ex.Index = readVaruint32(Ctx);
  1182. switch (Ex.Kind) {
  1183. case wasm::WASM_EXTERNAL_FUNCTION:
  1184. if (!isDefinedFunctionIndex(Ex.Index))
  1185. return make_error<GenericBinaryError>("invalid function export",
  1186. object_error::parse_failed);
  1187. getDefinedFunction(Ex.Index).ExportName = Ex.Name;
  1188. break;
  1189. case wasm::WASM_EXTERNAL_GLOBAL:
  1190. if (!isValidGlobalIndex(Ex.Index))
  1191. return make_error<GenericBinaryError>("invalid global export",
  1192. object_error::parse_failed);
  1193. break;
  1194. case wasm::WASM_EXTERNAL_TAG:
  1195. if (!isValidTagIndex(Ex.Index))
  1196. return make_error<GenericBinaryError>("invalid tag export",
  1197. object_error::parse_failed);
  1198. break;
  1199. case wasm::WASM_EXTERNAL_MEMORY:
  1200. case wasm::WASM_EXTERNAL_TABLE:
  1201. break;
  1202. default:
  1203. return make_error<GenericBinaryError>("unexpected export kind",
  1204. object_error::parse_failed);
  1205. }
  1206. Exports.push_back(Ex);
  1207. }
  1208. if (Ctx.Ptr != Ctx.End)
  1209. return make_error<GenericBinaryError>("export section ended prematurely",
  1210. object_error::parse_failed);
  1211. return Error::success();
  1212. }
  1213. bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
  1214. return Index < NumImportedFunctions + Functions.size();
  1215. }
  1216. bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
  1217. return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
  1218. }
  1219. bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
  1220. return Index < NumImportedGlobals + Globals.size();
  1221. }
  1222. bool WasmObjectFile::isValidTableNumber(uint32_t Index) const {
  1223. return Index < NumImportedTables + Tables.size();
  1224. }
  1225. bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
  1226. return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
  1227. }
  1228. bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const {
  1229. return Index >= NumImportedTables && isValidTableNumber(Index);
  1230. }
  1231. bool WasmObjectFile::isValidTagIndex(uint32_t Index) const {
  1232. return Index < NumImportedTags + Tags.size();
  1233. }
  1234. bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const {
  1235. return Index >= NumImportedTags && isValidTagIndex(Index);
  1236. }
  1237. bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
  1238. return Index < Symbols.size() && Symbols[Index].isTypeFunction();
  1239. }
  1240. bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
  1241. return Index < Symbols.size() && Symbols[Index].isTypeTable();
  1242. }
  1243. bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
  1244. return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
  1245. }
  1246. bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const {
  1247. return Index < Symbols.size() && Symbols[Index].isTypeTag();
  1248. }
  1249. bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
  1250. return Index < Symbols.size() && Symbols[Index].isTypeData();
  1251. }
  1252. bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
  1253. return Index < Symbols.size() && Symbols[Index].isTypeSection();
  1254. }
  1255. wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
  1256. assert(isDefinedFunctionIndex(Index));
  1257. return Functions[Index - NumImportedFunctions];
  1258. }
  1259. const wasm::WasmFunction &
  1260. WasmObjectFile::getDefinedFunction(uint32_t Index) const {
  1261. assert(isDefinedFunctionIndex(Index));
  1262. return Functions[Index - NumImportedFunctions];
  1263. }
  1264. wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
  1265. assert(isDefinedGlobalIndex(Index));
  1266. return Globals[Index - NumImportedGlobals];
  1267. }
  1268. wasm::WasmTag &WasmObjectFile::getDefinedTag(uint32_t Index) {
  1269. assert(isDefinedTagIndex(Index));
  1270. return Tags[Index - NumImportedTags];
  1271. }
  1272. Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
  1273. StartFunction = readVaruint32(Ctx);
  1274. if (!isValidFunctionIndex(StartFunction))
  1275. return make_error<GenericBinaryError>("invalid start function",
  1276. object_error::parse_failed);
  1277. return Error::success();
  1278. }
  1279. Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
  1280. SeenCodeSection = true;
  1281. CodeSection = Sections.size();
  1282. uint32_t FunctionCount = readVaruint32(Ctx);
  1283. if (FunctionCount != Functions.size()) {
  1284. return make_error<GenericBinaryError>("invalid function count",
  1285. object_error::parse_failed);
  1286. }
  1287. for (uint32_t i = 0; i < FunctionCount; i++) {
  1288. wasm::WasmFunction& Function = Functions[i];
  1289. const uint8_t *FunctionStart = Ctx.Ptr;
  1290. uint32_t Size = readVaruint32(Ctx);
  1291. const uint8_t *FunctionEnd = Ctx.Ptr + Size;
  1292. Function.CodeOffset = Ctx.Ptr - FunctionStart;
  1293. Function.Index = NumImportedFunctions + i;
  1294. Function.CodeSectionOffset = FunctionStart - Ctx.Start;
  1295. Function.Size = FunctionEnd - FunctionStart;
  1296. uint32_t NumLocalDecls = readVaruint32(Ctx);
  1297. Function.Locals.reserve(NumLocalDecls);
  1298. while (NumLocalDecls--) {
  1299. wasm::WasmLocalDecl Decl;
  1300. Decl.Count = readVaruint32(Ctx);
  1301. Decl.Type = readUint8(Ctx);
  1302. Function.Locals.push_back(Decl);
  1303. }
  1304. uint32_t BodySize = FunctionEnd - Ctx.Ptr;
  1305. Function.Body = ArrayRef<uint8_t>(Ctx.Ptr, BodySize);
  1306. // This will be set later when reading in the linking metadata section.
  1307. Function.Comdat = UINT32_MAX;
  1308. Ctx.Ptr += BodySize;
  1309. assert(Ctx.Ptr == FunctionEnd);
  1310. }
  1311. if (Ctx.Ptr != Ctx.End)
  1312. return make_error<GenericBinaryError>("code section ended prematurely",
  1313. object_error::parse_failed);
  1314. return Error::success();
  1315. }
  1316. Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
  1317. uint32_t Count = readVaruint32(Ctx);
  1318. ElemSegments.reserve(Count);
  1319. while (Count--) {
  1320. wasm::WasmElemSegment Segment;
  1321. Segment.Flags = readVaruint32(Ctx);
  1322. uint32_t SupportedFlags = wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER |
  1323. wasm::WASM_ELEM_SEGMENT_IS_PASSIVE |
  1324. wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS;
  1325. if (Segment.Flags & ~SupportedFlags)
  1326. return make_error<GenericBinaryError>(
  1327. "Unsupported flags for element segment", object_error::parse_failed);
  1328. if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER)
  1329. Segment.TableNumber = readVaruint32(Ctx);
  1330. else
  1331. Segment.TableNumber = 0;
  1332. if (!isValidTableNumber(Segment.TableNumber))
  1333. return make_error<GenericBinaryError>("invalid TableNumber",
  1334. object_error::parse_failed);
  1335. if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) {
  1336. Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
  1337. Segment.Offset.Value.Int32 = 0;
  1338. } else {
  1339. if (Error Err = readInitExpr(Segment.Offset, Ctx))
  1340. return Err;
  1341. }
  1342. if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) {
  1343. Segment.ElemKind = readUint8(Ctx);
  1344. if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS) {
  1345. if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) &&
  1346. Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) {
  1347. return make_error<GenericBinaryError>("invalid reference type",
  1348. object_error::parse_failed);
  1349. }
  1350. } else {
  1351. if (Segment.ElemKind != 0)
  1352. return make_error<GenericBinaryError>("invalid elemtype",
  1353. object_error::parse_failed);
  1354. Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
  1355. }
  1356. } else {
  1357. Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
  1358. }
  1359. if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS)
  1360. return make_error<GenericBinaryError>(
  1361. "elem segment init expressions not yet implemented",
  1362. object_error::parse_failed);
  1363. uint32_t NumElems = readVaruint32(Ctx);
  1364. while (NumElems--) {
  1365. Segment.Functions.push_back(readVaruint32(Ctx));
  1366. }
  1367. ElemSegments.push_back(Segment);
  1368. }
  1369. if (Ctx.Ptr != Ctx.End)
  1370. return make_error<GenericBinaryError>("elem section ended prematurely",
  1371. object_error::parse_failed);
  1372. return Error::success();
  1373. }
  1374. Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
  1375. DataSection = Sections.size();
  1376. uint32_t Count = readVaruint32(Ctx);
  1377. if (DataCount && Count != DataCount.getValue())
  1378. return make_error<GenericBinaryError>(
  1379. "number of data segments does not match DataCount section");
  1380. DataSegments.reserve(Count);
  1381. while (Count--) {
  1382. WasmSegment Segment;
  1383. Segment.Data.InitFlags = readVaruint32(Ctx);
  1384. Segment.Data.MemoryIndex =
  1385. (Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
  1386. ? readVaruint32(Ctx)
  1387. : 0;
  1388. if ((Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
  1389. if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
  1390. return Err;
  1391. } else {
  1392. Segment.Data.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
  1393. Segment.Data.Offset.Value.Int32 = 0;
  1394. }
  1395. uint32_t Size = readVaruint32(Ctx);
  1396. if (Size > (size_t)(Ctx.End - Ctx.Ptr))
  1397. return make_error<GenericBinaryError>("invalid segment size",
  1398. object_error::parse_failed);
  1399. Segment.Data.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
  1400. // The rest of these Data fields are set later, when reading in the linking
  1401. // metadata section.
  1402. Segment.Data.Alignment = 0;
  1403. Segment.Data.LinkingFlags = 0;
  1404. Segment.Data.Comdat = UINT32_MAX;
  1405. Segment.SectionOffset = Ctx.Ptr - Ctx.Start;
  1406. Ctx.Ptr += Size;
  1407. DataSegments.push_back(Segment);
  1408. }
  1409. if (Ctx.Ptr != Ctx.End)
  1410. return make_error<GenericBinaryError>("data section ended prematurely",
  1411. object_error::parse_failed);
  1412. return Error::success();
  1413. }
  1414. Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
  1415. DataCount = readVaruint32(Ctx);
  1416. return Error::success();
  1417. }
  1418. const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
  1419. return Header;
  1420. }
  1421. void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.b++; }
  1422. Expected<uint32_t> WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
  1423. uint32_t Result = SymbolRef::SF_None;
  1424. const WasmSymbol &Sym = getWasmSymbol(Symb);
  1425. LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
  1426. if (Sym.isBindingWeak())
  1427. Result |= SymbolRef::SF_Weak;
  1428. if (!Sym.isBindingLocal())
  1429. Result |= SymbolRef::SF_Global;
  1430. if (Sym.isHidden())
  1431. Result |= SymbolRef::SF_Hidden;
  1432. if (!Sym.isDefined())
  1433. Result |= SymbolRef::SF_Undefined;
  1434. if (Sym.isTypeFunction())
  1435. Result |= SymbolRef::SF_Executable;
  1436. return Result;
  1437. }
  1438. basic_symbol_iterator WasmObjectFile::symbol_begin() const {
  1439. DataRefImpl Ref;
  1440. Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
  1441. Ref.d.b = 0; // Symbol index
  1442. return BasicSymbolRef(Ref, this);
  1443. }
  1444. basic_symbol_iterator WasmObjectFile::symbol_end() const {
  1445. DataRefImpl Ref;
  1446. Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
  1447. Ref.d.b = Symbols.size(); // Symbol index
  1448. return BasicSymbolRef(Ref, this);
  1449. }
  1450. const WasmSymbol &WasmObjectFile::getWasmSymbol(const DataRefImpl &Symb) const {
  1451. return Symbols[Symb.d.b];
  1452. }
  1453. const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
  1454. return getWasmSymbol(Symb.getRawDataRefImpl());
  1455. }
  1456. Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
  1457. return getWasmSymbol(Symb).Info.Name;
  1458. }
  1459. Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
  1460. auto &Sym = getWasmSymbol(Symb);
  1461. if (Sym.Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION &&
  1462. isDefinedFunctionIndex(Sym.Info.ElementIndex))
  1463. return getDefinedFunction(Sym.Info.ElementIndex).CodeSectionOffset;
  1464. else
  1465. return getSymbolValue(Symb);
  1466. }
  1467. uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
  1468. switch (Sym.Info.Kind) {
  1469. case wasm::WASM_SYMBOL_TYPE_FUNCTION:
  1470. case wasm::WASM_SYMBOL_TYPE_GLOBAL:
  1471. case wasm::WASM_SYMBOL_TYPE_TAG:
  1472. case wasm::WASM_SYMBOL_TYPE_TABLE:
  1473. return Sym.Info.ElementIndex;
  1474. case wasm::WASM_SYMBOL_TYPE_DATA: {
  1475. // The value of a data symbol is the segment offset, plus the symbol
  1476. // offset within the segment.
  1477. uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
  1478. const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
  1479. if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST) {
  1480. return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
  1481. } else if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST) {
  1482. return Segment.Offset.Value.Int64 + Sym.Info.DataRef.Offset;
  1483. } else {
  1484. llvm_unreachable("unknown init expr opcode");
  1485. }
  1486. }
  1487. case wasm::WASM_SYMBOL_TYPE_SECTION:
  1488. return 0;
  1489. }
  1490. llvm_unreachable("invalid symbol type");
  1491. }
  1492. uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
  1493. return getWasmSymbolValue(getWasmSymbol(Symb));
  1494. }
  1495. uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
  1496. llvm_unreachable("not yet implemented");
  1497. return 0;
  1498. }
  1499. uint64_t WasmObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
  1500. llvm_unreachable("not yet implemented");
  1501. return 0;
  1502. }
  1503. Expected<SymbolRef::Type>
  1504. WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
  1505. const WasmSymbol &Sym = getWasmSymbol(Symb);
  1506. switch (Sym.Info.Kind) {
  1507. case wasm::WASM_SYMBOL_TYPE_FUNCTION:
  1508. return SymbolRef::ST_Function;
  1509. case wasm::WASM_SYMBOL_TYPE_GLOBAL:
  1510. return SymbolRef::ST_Other;
  1511. case wasm::WASM_SYMBOL_TYPE_DATA:
  1512. return SymbolRef::ST_Data;
  1513. case wasm::WASM_SYMBOL_TYPE_SECTION:
  1514. return SymbolRef::ST_Debug;
  1515. case wasm::WASM_SYMBOL_TYPE_TAG:
  1516. return SymbolRef::ST_Other;
  1517. case wasm::WASM_SYMBOL_TYPE_TABLE:
  1518. return SymbolRef::ST_Other;
  1519. }
  1520. llvm_unreachable("unknown WasmSymbol::SymbolType");
  1521. return SymbolRef::ST_Other;
  1522. }
  1523. Expected<section_iterator>
  1524. WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
  1525. const WasmSymbol &Sym = getWasmSymbol(Symb);
  1526. if (Sym.isUndefined())
  1527. return section_end();
  1528. DataRefImpl Ref;
  1529. Ref.d.a = getSymbolSectionIdImpl(Sym);
  1530. return section_iterator(SectionRef(Ref, this));
  1531. }
  1532. uint32_t WasmObjectFile::getSymbolSectionId(SymbolRef Symb) const {
  1533. const WasmSymbol &Sym = getWasmSymbol(Symb);
  1534. return getSymbolSectionIdImpl(Sym);
  1535. }
  1536. uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
  1537. switch (Sym.Info.Kind) {
  1538. case wasm::WASM_SYMBOL_TYPE_FUNCTION:
  1539. return CodeSection;
  1540. case wasm::WASM_SYMBOL_TYPE_GLOBAL:
  1541. return GlobalSection;
  1542. case wasm::WASM_SYMBOL_TYPE_DATA:
  1543. return DataSection;
  1544. case wasm::WASM_SYMBOL_TYPE_SECTION:
  1545. return Sym.Info.ElementIndex;
  1546. case wasm::WASM_SYMBOL_TYPE_TAG:
  1547. return TagSection;
  1548. case wasm::WASM_SYMBOL_TYPE_TABLE:
  1549. return TableSection;
  1550. default:
  1551. llvm_unreachable("unknown WasmSymbol::SymbolType");
  1552. }
  1553. }
  1554. void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
  1555. Expected<StringRef> WasmObjectFile::getSectionName(DataRefImpl Sec) const {
  1556. const WasmSection &S = Sections[Sec.d.a];
  1557. #define ECase(X) \
  1558. case wasm::WASM_SEC_##X: \
  1559. return #X;
  1560. switch (S.Type) {
  1561. ECase(TYPE);
  1562. ECase(IMPORT);
  1563. ECase(FUNCTION);
  1564. ECase(TABLE);
  1565. ECase(MEMORY);
  1566. ECase(GLOBAL);
  1567. ECase(TAG);
  1568. ECase(EXPORT);
  1569. ECase(START);
  1570. ECase(ELEM);
  1571. ECase(CODE);
  1572. ECase(DATA);
  1573. ECase(DATACOUNT);
  1574. case wasm::WASM_SEC_CUSTOM:
  1575. return S.Name;
  1576. default:
  1577. return createStringError(object_error::invalid_section_index, "");
  1578. }
  1579. #undef ECase
  1580. }
  1581. uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }
  1582. uint64_t WasmObjectFile::getSectionIndex(DataRefImpl Sec) const {
  1583. return Sec.d.a;
  1584. }
  1585. uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const {
  1586. const WasmSection &S = Sections[Sec.d.a];
  1587. return S.Content.size();
  1588. }
  1589. Expected<ArrayRef<uint8_t>>
  1590. WasmObjectFile::getSectionContents(DataRefImpl Sec) const {
  1591. const WasmSection &S = Sections[Sec.d.a];
  1592. // This will never fail since wasm sections can never be empty (user-sections
  1593. // must have a name and non-user sections each have a defined structure).
  1594. return S.Content;
  1595. }
  1596. uint64_t WasmObjectFile::getSectionAlignment(DataRefImpl Sec) const {
  1597. return 1;
  1598. }
  1599. bool WasmObjectFile::isSectionCompressed(DataRefImpl Sec) const {
  1600. return false;
  1601. }
  1602. bool WasmObjectFile::isSectionText(DataRefImpl Sec) const {
  1603. return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE;
  1604. }
  1605. bool WasmObjectFile::isSectionData(DataRefImpl Sec) const {
  1606. return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA;
  1607. }
  1608. bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
  1609. bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
  1610. relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Ref) const {
  1611. DataRefImpl RelocRef;
  1612. RelocRef.d.a = Ref.d.a;
  1613. RelocRef.d.b = 0;
  1614. return relocation_iterator(RelocationRef(RelocRef, this));
  1615. }
  1616. relocation_iterator WasmObjectFile::section_rel_end(DataRefImpl Ref) const {
  1617. const WasmSection &Sec = getWasmSection(Ref);
  1618. DataRefImpl RelocRef;
  1619. RelocRef.d.a = Ref.d.a;
  1620. RelocRef.d.b = Sec.Relocations.size();
  1621. return relocation_iterator(RelocationRef(RelocRef, this));
  1622. }
  1623. void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const { Rel.d.b++; }
  1624. uint64_t WasmObjectFile::getRelocationOffset(DataRefImpl Ref) const {
  1625. const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
  1626. return Rel.Offset;
  1627. }
  1628. symbol_iterator WasmObjectFile::getRelocationSymbol(DataRefImpl Ref) const {
  1629. const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
  1630. if (Rel.Type == wasm::R_WASM_TYPE_INDEX_LEB)
  1631. return symbol_end();
  1632. DataRefImpl Sym;
  1633. Sym.d.a = 1;
  1634. Sym.d.b = Rel.Index;
  1635. return symbol_iterator(SymbolRef(Sym, this));
  1636. }
  1637. uint64_t WasmObjectFile::getRelocationType(DataRefImpl Ref) const {
  1638. const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
  1639. return Rel.Type;
  1640. }
  1641. void WasmObjectFile::getRelocationTypeName(
  1642. DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
  1643. const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
  1644. StringRef Res = "Unknown";
  1645. #define WASM_RELOC(name, value) \
  1646. case wasm::name: \
  1647. Res = #name; \
  1648. break;
  1649. switch (Rel.Type) {
  1650. #include "llvm/BinaryFormat/WasmRelocs.def"
  1651. }
  1652. #undef WASM_RELOC
  1653. Result.append(Res.begin(), Res.end());
  1654. }
  1655. section_iterator WasmObjectFile::section_begin() const {
  1656. DataRefImpl Ref;
  1657. Ref.d.a = 0;
  1658. return section_iterator(SectionRef(Ref, this));
  1659. }
  1660. section_iterator WasmObjectFile::section_end() const {
  1661. DataRefImpl Ref;
  1662. Ref.d.a = Sections.size();
  1663. return section_iterator(SectionRef(Ref, this));
  1664. }
  1665. uint8_t WasmObjectFile::getBytesInAddress() const {
  1666. return HasMemory64 ? 8 : 4;
  1667. }
  1668. StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; }
  1669. Triple::ArchType WasmObjectFile::getArch() const {
  1670. return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
  1671. }
  1672. SubtargetFeatures WasmObjectFile::getFeatures() const {
  1673. return SubtargetFeatures();
  1674. }
  1675. bool WasmObjectFile::isRelocatableObject() const { return HasLinkingSection; }
  1676. bool WasmObjectFile::isSharedObject() const { return HasDylinkSection; }
  1677. const WasmSection &WasmObjectFile::getWasmSection(DataRefImpl Ref) const {
  1678. assert(Ref.d.a < Sections.size());
  1679. return Sections[Ref.d.a];
  1680. }
  1681. const WasmSection &
  1682. WasmObjectFile::getWasmSection(const SectionRef &Section) const {
  1683. return getWasmSection(Section.getRawDataRefImpl());
  1684. }
  1685. const wasm::WasmRelocation &
  1686. WasmObjectFile::getWasmRelocation(const RelocationRef &Ref) const {
  1687. return getWasmRelocation(Ref.getRawDataRefImpl());
  1688. }
  1689. const wasm::WasmRelocation &
  1690. WasmObjectFile::getWasmRelocation(DataRefImpl Ref) const {
  1691. assert(Ref.d.a < Sections.size());
  1692. const WasmSection &Sec = Sections[Ref.d.a];
  1693. assert(Ref.d.b < Sec.Relocations.size());
  1694. return Sec.Relocations[Ref.d.b];
  1695. }
  1696. int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
  1697. StringRef CustomSectionName) {
  1698. switch (ID) {
  1699. case wasm::WASM_SEC_CUSTOM:
  1700. return StringSwitch<unsigned>(CustomSectionName)
  1701. .Case("dylink", WASM_SEC_ORDER_DYLINK)
  1702. .Case("dylink.0", WASM_SEC_ORDER_DYLINK)
  1703. .Case("linking", WASM_SEC_ORDER_LINKING)
  1704. .StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
  1705. .Case("name", WASM_SEC_ORDER_NAME)
  1706. .Case("producers", WASM_SEC_ORDER_PRODUCERS)
  1707. .Case("target_features", WASM_SEC_ORDER_TARGET_FEATURES)
  1708. .Default(WASM_SEC_ORDER_NONE);
  1709. case wasm::WASM_SEC_TYPE:
  1710. return WASM_SEC_ORDER_TYPE;
  1711. case wasm::WASM_SEC_IMPORT:
  1712. return WASM_SEC_ORDER_IMPORT;
  1713. case wasm::WASM_SEC_FUNCTION:
  1714. return WASM_SEC_ORDER_FUNCTION;
  1715. case wasm::WASM_SEC_TABLE:
  1716. return WASM_SEC_ORDER_TABLE;
  1717. case wasm::WASM_SEC_MEMORY:
  1718. return WASM_SEC_ORDER_MEMORY;
  1719. case wasm::WASM_SEC_GLOBAL:
  1720. return WASM_SEC_ORDER_GLOBAL;
  1721. case wasm::WASM_SEC_EXPORT:
  1722. return WASM_SEC_ORDER_EXPORT;
  1723. case wasm::WASM_SEC_START:
  1724. return WASM_SEC_ORDER_START;
  1725. case wasm::WASM_SEC_ELEM:
  1726. return WASM_SEC_ORDER_ELEM;
  1727. case wasm::WASM_SEC_CODE:
  1728. return WASM_SEC_ORDER_CODE;
  1729. case wasm::WASM_SEC_DATA:
  1730. return WASM_SEC_ORDER_DATA;
  1731. case wasm::WASM_SEC_DATACOUNT:
  1732. return WASM_SEC_ORDER_DATACOUNT;
  1733. case wasm::WASM_SEC_TAG:
  1734. return WASM_SEC_ORDER_TAG;
  1735. default:
  1736. return WASM_SEC_ORDER_NONE;
  1737. }
  1738. }
  1739. // Represents the edges in a directed graph where any node B reachable from node
  1740. // A is not allowed to appear before A in the section ordering, but may appear
  1741. // afterward.
  1742. int WasmSectionOrderChecker::DisallowedPredecessors
  1743. [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
  1744. // WASM_SEC_ORDER_NONE
  1745. {},
  1746. // WASM_SEC_ORDER_TYPE
  1747. {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
  1748. // WASM_SEC_ORDER_IMPORT
  1749. {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
  1750. // WASM_SEC_ORDER_FUNCTION
  1751. {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
  1752. // WASM_SEC_ORDER_TABLE
  1753. {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
  1754. // WASM_SEC_ORDER_MEMORY
  1755. {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
  1756. // WASM_SEC_ORDER_TAG
  1757. {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
  1758. // WASM_SEC_ORDER_GLOBAL
  1759. {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
  1760. // WASM_SEC_ORDER_EXPORT
  1761. {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
  1762. // WASM_SEC_ORDER_START
  1763. {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
  1764. // WASM_SEC_ORDER_ELEM
  1765. {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
  1766. // WASM_SEC_ORDER_DATACOUNT
  1767. {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
  1768. // WASM_SEC_ORDER_CODE
  1769. {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
  1770. // WASM_SEC_ORDER_DATA
  1771. {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},
  1772. // Custom Sections
  1773. // WASM_SEC_ORDER_DYLINK
  1774. {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
  1775. // WASM_SEC_ORDER_LINKING
  1776. {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
  1777. // WASM_SEC_ORDER_RELOC (can be repeated)
  1778. {},
  1779. // WASM_SEC_ORDER_NAME
  1780. {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
  1781. // WASM_SEC_ORDER_PRODUCERS
  1782. {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
  1783. // WASM_SEC_ORDER_TARGET_FEATURES
  1784. {WASM_SEC_ORDER_TARGET_FEATURES}};
  1785. bool WasmSectionOrderChecker::isValidSectionOrder(unsigned ID,
  1786. StringRef CustomSectionName) {
  1787. int Order = getSectionOrder(ID, CustomSectionName);
  1788. if (Order == WASM_SEC_ORDER_NONE)
  1789. return true;
  1790. // Disallowed predecessors we need to check for
  1791. SmallVector<int, WASM_NUM_SEC_ORDERS> WorkList;
  1792. // Keep track of completed checks to avoid repeating work
  1793. bool Checked[WASM_NUM_SEC_ORDERS] = {};
  1794. int Curr = Order;
  1795. while (true) {
  1796. // Add new disallowed predecessors to work list
  1797. for (size_t I = 0;; ++I) {
  1798. int Next = DisallowedPredecessors[Curr][I];
  1799. if (Next == WASM_SEC_ORDER_NONE)
  1800. break;
  1801. if (Checked[Next])
  1802. continue;
  1803. WorkList.push_back(Next);
  1804. Checked[Next] = true;
  1805. }
  1806. if (WorkList.empty())
  1807. break;
  1808. // Consider next disallowed predecessor
  1809. Curr = WorkList.pop_back_val();
  1810. if (Seen[Curr])
  1811. return false;
  1812. }
  1813. // Have not seen any disallowed predecessors
  1814. Seen[Order] = true;
  1815. return true;
  1816. }