]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/MinGW.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / MinGW.cpp
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
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
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
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
121 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
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 }