| 510 | namespace WasmEdge::LLVM { |
| 511 | |
| 512 | Expect<void> CodeGen::codegen(Span<const Byte> WasmData, Data D, |
| 513 | std::filesystem::path OutputPath) noexcept { |
| 514 | // CompileFromBuffer skips the loader, so reject empty path here. |
| 515 | if (OutputPath.empty()) { |
| 516 | spdlog::error("output failed: empty output path"sv); |
| 517 | return Unexpect(ErrCode::Value::IllegalPath); |
| 518 | } |
| 519 | |
| 520 | auto LLContext = D.extract().getLLContext(); |
| 521 | auto &LLModule = D.extract().LLModule; |
| 522 | auto &TM = D.extract().TM; |
| 523 | std::filesystem::path LLPath(OutputPath); |
| 524 | LLPath.replace_extension("ll"sv); |
| 525 | |
| 526 | #if WASMEDGE_OS_WINDOWS |
| 527 | { |
| 528 | // create dummy dllmain function |
| 529 | auto FTy = LLVM::Type::getFunctionType(LLContext.getInt32Ty(), {}); |
| 530 | auto F = |
| 531 | LLModule.addFunction(FTy, LLVMExternalLinkage, "_DllMainCRTStartup"); |
| 532 | F.setVisibility(LLVMProtectedVisibility); |
| 533 | F.setDSOLocal(true); |
| 534 | F.addFnAttr( |
| 535 | LLVM::Attribute::createString(LLContext, "no-stack-arg-probe"sv, {})); |
| 536 | F.addFnAttr( |
| 537 | LLVM::Attribute::createEnum(LLContext, LLVM::Core::StrictFP, 0)); |
| 538 | F.addFnAttr(LLVM::Attribute::createEnum(LLContext, LLVM::Core::UWTable, |
| 539 | LLVM::Core::UWTableDefault)); |
| 540 | F.addFnAttr( |
| 541 | LLVM::Attribute::createEnum(LLContext, LLVM::Core::NoReturn, 0)); |
| 542 | LLVM::Builder Builder(LLContext); |
| 543 | Builder.positionAtEnd(LLVM::BasicBlock::create(LLContext, F, "entry")); |
| 544 | Builder.createRet(LLContext.getInt32(1u)); |
| 545 | |
| 546 | auto A = LLModule.addAlias(F.getType(), F, "_fltused"); |
| 547 | A.setLinkage(LLVMExternalLinkage); |
| 548 | A.setVisibility(LLVMProtectedVisibility); |
| 549 | A.setDSOLocal(true); |
| 550 | } |
| 551 | #endif |
| 552 | #if WASMEDGE_OS_MACOS |
| 553 | { |
| 554 | const auto [Major, Minor] = getSDKVersionPair(); |
| 555 | LLModule.addFlag(LLVMModuleFlagBehaviorError, "SDK Version"sv, |
| 556 | LLVM::Value::getConstVector32(LLContext, {Major, Minor})); |
| 557 | } |
| 558 | #endif |
| 559 | |
| 560 | if (Conf.getCompilerConfigure().getOutputFormat() != |
| 561 | CompilerConfigure::OutputFormat::Wasm) { |
| 562 | // create wasm.code and wasm.size |
| 563 | auto Int32Ty = LLContext.getInt32Ty(); |
| 564 | auto Content = LLVM::Value::getConstString( |
| 565 | LLContext, |
| 566 | {reinterpret_cast<const char *>(WasmData.data()), WasmData.size()}, |
| 567 | true); |
| 568 | LLModule.addGlobal(Content.getType(), true, LLVMExternalLinkage, Content, |
| 569 | "wasm.code"); |