1 //===- MinGW.cpp ----------------------------------------------------------===//
2 //
3 // The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MinGW.h"
11 #include "SymbolTable.h"
12 #include "lld/Common/ErrorHandler.h"
13 #include "llvm/Object/COFF.h"
14 #include "llvm/Support/Path.h"
15 #include "llvm/Support/raw_ostream.h"
16
17 using namespace lld;
18 using namespace lld::coff;
19 using namespace llvm;
20 using namespace llvm::COFF;
21
initSymbolExcludes()22 void AutoExporter::initSymbolExcludes() {
23 ExcludeSymbolPrefixes = {
24 // Import symbols
25 "__imp_",
26 "__IMPORT_DESCRIPTOR_",
27 // Extra import symbols from GNU import libraries
28 "__nm_",
29 // C++ symbols
30 "__rtti_",
31 "__builtin_",
32 // Artifical symbols such as .refptr
33 ".",
34 };
35 ExcludeSymbolSuffixes = {
36 "_iname",
37 "_NULL_THUNK_DATA",
38 };
39 if (Config->Machine == I386) {
40 ExcludeSymbols = {
41 "__NULL_IMPORT_DESCRIPTOR",
42 "__pei386_runtime_relocator",
43 "_do_pseudo_reloc",
44 "_impure_ptr",
45 "__impure_ptr",
46 "__fmode",
47 "_environ",
48 "___dso_handle",
49 // These are the MinGW names that differ from the standard
50 // ones (lacking an extra underscore).
51 "_DllMain@12",
52 "_DllEntryPoint@12",
53 "_DllMainCRTStartup@12",
54 };
55 ExcludeSymbolPrefixes.insert("__head_");
56 } else {
57 ExcludeSymbols = {
58 "__NULL_IMPORT_DESCRIPTOR",
59 "_pei386_runtime_relocator",
60 "do_pseudo_reloc",
61 "impure_ptr",
62 "_impure_ptr",
63 "_fmode",
64 "environ",
65 "__dso_handle",
66 // These are the MinGW names that differ from the standard
67 // ones (lacking an extra underscore).
68 "DllMain",
69 "DllEntryPoint",
70 "DllMainCRTStartup",
71 };
72 ExcludeSymbolPrefixes.insert("_head_");
73 }
74 }
75
AutoExporter()76 AutoExporter::AutoExporter() {
77 ExcludeLibs = {
78 "libgcc",
79 "libgcc_s",
80 "libstdc++",
81 "libmingw32",
82 "libmingwex",
83 "libg2c",
84 "libsupc++",
85 "libobjc",
86 "libgcj",
87 "libclang_rt.builtins",
88 "libclang_rt.builtins-aarch64",
89 "libclang_rt.builtins-arm",
90 "libclang_rt.builtins-i386",
91 "libclang_rt.builtins-x86_64",
92 "libc++",
93 "libc++abi",
94 "libunwind",
95 "libmsvcrt",
96 "libucrtbase",
97 };
98 ExcludeObjects = {
99 "crt0.o",
100 "crt1.o",
101 "crt1u.o",
102 "crt2.o",
103 "crt2u.o",
104 "dllcrt1.o",
105 "dllcrt2.o",
106 "gcrt0.o",
107 "gcrt1.o",
108 "gcrt2.o",
109 "crtbegin.o",
110 "crtend.o",
111 };
112 }
113
addWholeArchive(StringRef Path)114 void AutoExporter::addWholeArchive(StringRef Path) {
115 StringRef LibName = sys::path::filename(Path);
116 // Drop the file extension, to match the processing below.
117 LibName = LibName.substr(0, LibName.rfind('.'));
118 ExcludeLibs.erase(LibName);
119 }
120
shouldExport(Defined * Sym) const121 bool AutoExporter::shouldExport(Defined *Sym) const {
122 if (!Sym || !Sym->isLive() || !Sym->getChunk())
123 return false;
124
125 // Only allow the symbol kinds that make sense to export; in particular,
126 // disallow import symbols.
127 if (!isa<DefinedRegular>(Sym) && !isa<DefinedCommon>(Sym))
128 return false;
129 if (ExcludeSymbols.count(Sym->getName()))
130 return false;
131
132 for (StringRef Prefix : ExcludeSymbolPrefixes.keys())
133 if (Sym->getName().startswith(Prefix))
134 return false;
135 for (StringRef Suffix : ExcludeSymbolSuffixes.keys())
136 if (Sym->getName().endswith(Suffix))
137 return false;
138
139 // If a corresponding __imp_ symbol exists and is defined, don't export it.
140 if (Symtab->find(("__imp_" + Sym->getName()).str()))
141 return false;
142
143 // Check that file is non-null before dereferencing it, symbols not
144 // originating in regular object files probably shouldn't be exported.
145 if (!Sym->getFile())
146 return false;
147
148 StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
149
150 // Drop the file extension.
151 LibName = LibName.substr(0, LibName.rfind('.'));
152 if (!LibName.empty())
153 return !ExcludeLibs.count(LibName);
154
155 StringRef FileName = sys::path::filename(Sym->getFile()->getName());
156 return !ExcludeObjects.count(FileName);
157 }
158
writeDefFile(StringRef Name)159 void coff::writeDefFile(StringRef Name) {
160 std::error_code EC;
161 raw_fd_ostream OS(Name, EC, sys::fs::F_None);
162 if (EC)
163 fatal("cannot open " + Name + ": " + EC.message());
164
165 OS << "EXPORTS\n";
166 for (Export &E : Config->Exports) {
167 OS << " " << E.ExportName << " "
168 << "@" << E.Ordinal;
169 if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) {
170 if (Def && Def->getChunk() &&
171 !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
172 OS << " DATA";
173 }
174 OS << "\n";
175 }
176 }
177