23
23
#include < string>
24
24
25
25
namespace lld {
26
+ enum Flavor {
27
+ Invalid,
28
+ Gnu, // -flavor gnu
29
+ MinGW, // -flavor gnu MinGW
30
+ WinLink, // -flavor link
31
+ Darwin, // -flavor darwin
32
+ Wasm, // -flavor wasm
33
+ };
34
+
35
+ using Driver = bool (*)(llvm::ArrayRef<const char *>, llvm::raw_ostream &,
36
+ llvm::raw_ostream &, bool , bool );
37
+
38
+ struct DriverDef {
39
+ Flavor f;
40
+ Driver d;
41
+ };
42
+
43
+ struct Result {
44
+ int retCode;
45
+ bool canRunAgain;
46
+ };
47
+
48
+ Result lldMain (llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
49
+ llvm::raw_ostream &stderrOS, llvm::ArrayRef<DriverDef> drivers);
50
+
26
51
namespace wasm {
27
52
bool link (llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
28
53
llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput);
@@ -51,13 +76,14 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
51
76
llvm::TargetMachine *TargetMachine = Target->createTargetMachine (
52
77
PTU.TheModule ->getTargetTriple (), " " , " " , TO, llvm::Reloc::Model::PIC_);
53
78
PTU.TheModule ->setDataLayout (TargetMachine->createDataLayout ());
54
- std::string OutputFileName = PTU.TheModule ->getName ().str () + " .wasm" ;
79
+ std::string ObjectFileName = PTU.TheModule ->getName ().str () + " .o" ;
80
+ std::string BinaryFileName = PTU.TheModule ->getName ().str () + " .wasm" ;
55
81
56
82
std::error_code Error;
57
- llvm::raw_fd_ostream OutputFile (llvm::StringRef (OutputFileName ), Error);
83
+ llvm::raw_fd_ostream ObjectFileOutput (llvm::StringRef (ObjectFileName ), Error);
58
84
59
85
llvm::legacy::PassManager PM;
60
- if (TargetMachine->addPassesToEmitFile (PM, OutputFile , nullptr ,
86
+ if (TargetMachine->addPassesToEmitFile (PM, ObjectFileOutput , nullptr ,
61
87
llvm::CodeGenFileType::ObjectFile)) {
62
88
return llvm::make_error<llvm::StringError>(
63
89
" Wasm backend cannot produce object." , llvm::inconvertibleErrorCode ());
@@ -69,27 +95,30 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
69
95
llvm::inconvertibleErrorCode ());
70
96
}
71
97
72
- OutputFile .close ();
98
+ ObjectFileOutput .close ();
73
99
74
100
std::vector<const char *> LinkerArgs = {" wasm-ld" ,
75
101
" -shared" ,
76
102
" --import-memory" ,
77
- " --no-entry" ,
78
- " --export-all" ,
79
103
" --experimental-pic" ,
80
104
" --stack-first" ,
81
105
" --allow-undefined" ,
82
- OutputFileName .c_str (),
106
+ ObjectFileName .c_str (),
83
107
" -o" ,
84
- OutputFileName.c_str ()};
85
- int Result =
86
- lld::wasm::link (LinkerArgs, llvm::outs (), llvm::errs (), false , false );
87
- if (!Result)
108
+ BinaryFileName.c_str ()};
109
+
110
+ const lld::DriverDef WasmDriver = {lld::Flavor::Wasm, &lld::wasm::link };
111
+ std::vector<lld::DriverDef> WasmDriverArgs;
112
+ WasmDriverArgs.push_back (WasmDriver);
113
+ lld::Result Result =
114
+ lld::lldMain (LinkerArgs, llvm::outs (), llvm::errs (), WasmDriverArgs);
115
+
116
+ if (Result.retCode )
88
117
return llvm::make_error<llvm::StringError>(
89
118
" Failed to link incremental module" , llvm::inconvertibleErrorCode ());
90
119
91
120
void *LoadedLibModule =
92
- dlopen (OutputFileName .c_str (), RTLD_NOW | RTLD_GLOBAL);
121
+ dlopen (BinaryFileName .c_str (), RTLD_NOW | RTLD_GLOBAL);
93
122
if (LoadedLibModule == nullptr ) {
94
123
llvm::errs () << dlerror () << ' \n ' ;
95
124
return llvm::make_error<llvm::StringError>(
@@ -109,12 +138,12 @@ llvm::Error WasmIncrementalExecutor::runCtors() const {
109
138
return llvm::Error::success ();
110
139
}
111
140
112
- llvm::Error WasmIncrementalExecutor::cleanUp () const {
141
+ llvm::Error WasmIncrementalExecutor::cleanUp () {
113
142
// Can't call cleanUp through IncrementalExecutor as it
114
143
// tries to deinitialize JIT which hasn't been initialized
115
144
return llvm::Error::success ();
116
145
}
117
146
118
147
WasmIncrementalExecutor::~WasmIncrementalExecutor () = default ;
119
148
120
- } // namespace clang
149
+ } // namespace clang
0 commit comments