1 //===- MinGW.cpp ----------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 #include "COFFLinkerContext.h"
12 #include "InputFiles.h"
13 #include "SymbolTable.h"
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/DenseSet.h"
16 #include "llvm/Object/COFF.h"
17 #include "llvm/Support/Parallel.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/Support/raw_ostream.h"
22 using namespace llvm::COFF
;
24 using namespace lld::coff
;
26 AutoExporter::AutoExporter() {
37 "libclang_rt.builtins",
38 "libclang_rt.builtins-aarch64",
39 "libclang_rt.builtins-arm",
40 "libclang_rt.builtins-i386",
41 "libclang_rt.builtins-x86_64",
42 "libclang_rt.profile",
43 "libclang_rt.profile-aarch64",
44 "libclang_rt.profile-arm",
45 "libclang_rt.profile-i386",
46 "libclang_rt.profile-x86_64",
55 "crt0.o", "crt1.o", "crt1u.o", "crt2.o", "crt2u.o", "dllcrt1.o",
56 "dllcrt2.o", "gcrt0.o", "gcrt1.o", "gcrt2.o", "crtbegin.o", "crtend.o",
59 excludeSymbolPrefixes
= {
62 "__IMPORT_DESCRIPTOR_",
63 // Extra import symbols from GNU import libraries
68 // Artificial symbols such as .refptr
70 // profile generate symbols
76 excludeSymbolSuffixes
= {
81 if (config
->machine
== I386
) {
83 "__NULL_IMPORT_DESCRIPTOR",
84 "__pei386_runtime_relocator",
91 // These are the MinGW names that differ from the standard
92 // ones (lacking an extra underscore).
95 "_DllMainCRTStartup@12",
97 excludeSymbolPrefixes
.insert("__head_");
100 "__NULL_IMPORT_DESCRIPTOR",
101 "_pei386_runtime_relocator",
108 // These are the MinGW names that differ from the standard
109 // ones (lacking an extra underscore).
114 excludeSymbolPrefixes
.insert("_head_");
118 void AutoExporter::addWholeArchive(StringRef path
) {
119 StringRef libName
= sys::path::filename(path
);
120 // Drop the file extension, to match the processing below.
121 libName
= libName
.substr(0, libName
.rfind('.'));
122 excludeLibs
.erase(libName
);
125 bool AutoExporter::shouldExport(const COFFLinkerContext
&ctx
,
126 Defined
*sym
) const {
127 if (!sym
|| !sym
->getChunk())
130 // Only allow the symbol kinds that make sense to export; in particular,
131 // disallow import symbols.
132 if (!isa
<DefinedRegular
>(sym
) && !isa
<DefinedCommon
>(sym
))
134 if (excludeSymbols
.count(sym
->getName()))
137 for (StringRef prefix
: excludeSymbolPrefixes
.keys())
138 if (sym
->getName().startswith(prefix
))
140 for (StringRef suffix
: excludeSymbolSuffixes
.keys())
141 if (sym
->getName().endswith(suffix
))
144 // If a corresponding __imp_ symbol exists and is defined, don't export it.
145 if (ctx
.symtab
.find(("__imp_" + sym
->getName()).str()))
148 // Check that file is non-null before dereferencing it, symbols not
149 // originating in regular object files probably shouldn't be exported.
153 StringRef libName
= sys::path::filename(sym
->getFile()->parentName
);
155 // Drop the file extension.
156 libName
= libName
.substr(0, libName
.rfind('.'));
157 if (!libName
.empty())
158 return !excludeLibs
.count(libName
);
160 StringRef fileName
= sys::path::filename(sym
->getFile()->getName());
161 return !excludeObjects
.count(fileName
);
164 void lld::coff::writeDefFile(StringRef name
) {
166 raw_fd_ostream
os(name
, ec
, sys::fs::OF_None
);
168 fatal("cannot open " + name
+ ": " + ec
.message());
171 for (Export
&e
: config
->exports
) {
172 os
<< " " << e
.exportName
<< " "
174 if (auto *def
= dyn_cast_or_null
<Defined
>(e
.sym
)) {
175 if (def
&& def
->getChunk() &&
176 !(def
->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE
))
183 static StringRef
mangle(Twine sym
) {
184 assert(config
->machine
!= IMAGE_FILE_MACHINE_UNKNOWN
);
185 if (config
->machine
== I386
)
186 return saver().save("_" + sym
);
187 return saver().save(sym
);
190 // Handles -wrap option.
192 // This function instantiates wrapper symbols. At this point, they seem
193 // like they are not being used at all, so we explicitly set some flags so
194 // that LTO won't eliminate them.
195 std::vector
<WrappedSymbol
>
196 lld::coff::addWrappedSymbols(COFFLinkerContext
&ctx
, opt::InputArgList
&args
) {
197 std::vector
<WrappedSymbol
> v
;
198 DenseSet
<StringRef
> seen
;
200 for (auto *arg
: args
.filtered(OPT_wrap
)) {
201 StringRef name
= arg
->getValue();
202 if (!seen
.insert(name
).second
)
205 Symbol
*sym
= ctx
.symtab
.findUnderscore(name
);
209 Symbol
*real
= ctx
.symtab
.addUndefined(mangle("__real_" + name
));
210 Symbol
*wrap
= ctx
.symtab
.addUndefined(mangle("__wrap_" + name
));
211 v
.push_back({sym
, real
, wrap
});
213 // These symbols may seem undefined initially, but don't bail out
214 // at symtab.reportUnresolvable() due to them, but let wrapSymbols
215 // below sort things out before checking finally with
216 // symtab.resolveRemainingUndefines().
217 sym
->deferUndefined
= true;
218 real
->deferUndefined
= true;
219 // We want to tell LTO not to inline symbols to be overwritten
220 // because LTO doesn't know the final symbol contents after renaming.
221 real
->canInline
= false;
222 sym
->canInline
= false;
224 // Tell LTO not to eliminate these symbols.
225 sym
->isUsedInRegularObj
= true;
226 if (!isa
<Undefined
>(wrap
))
227 wrap
->isUsedInRegularObj
= true;
232 // Do renaming for -wrap by updating pointers to symbols.
234 // When this function is executed, only InputFiles and symbol table
235 // contain pointers to symbol objects. We visit them to replace pointers,
236 // so that wrapped symbols are swapped as instructed by the command line.
237 void lld::coff::wrapSymbols(COFFLinkerContext
&ctx
,
238 ArrayRef
<WrappedSymbol
> wrapped
) {
239 DenseMap
<Symbol
*, Symbol
*> map
;
240 for (const WrappedSymbol
&w
: wrapped
) {
243 if (Defined
*d
= dyn_cast
<Defined
>(w
.wrap
)) {
244 Symbol
*imp
= ctx
.symtab
.find(("__imp_" + w
.sym
->getName()).str());
245 // Create a new defined local import for the wrap symbol. If
246 // no imp prefixed symbol existed, there's no need for it.
247 // (We can't easily distinguish whether any object file actually
248 // referenced it or not, though.)
250 DefinedLocalImport
*wrapimp
= make
<DefinedLocalImport
>(
251 saver().save("__imp_" + w
.wrap
->getName()), d
);
252 ctx
.symtab
.localImportChunks
.push_back(wrapimp
->getChunk());
258 // Update pointers in input files.
259 parallelForEach(ctx
.objFileInstances
, [&](ObjFile
*file
) {
260 MutableArrayRef
<Symbol
*> syms
= file
->getMutableSymbols();
261 for (size_t i
= 0, e
= syms
.size(); i
!= e
; ++i
)
262 if (Symbol
*s
= map
.lookup(syms
[i
]))