]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/MinGW.cpp
Merge clang 7.0.1 and several follow-up changes
[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 AutoExporter::AutoExporter() {
23   if (Config->Machine == I386) {
24     ExcludeSymbols = {
25         "__NULL_IMPORT_DESCRIPTOR",
26         "__pei386_runtime_relocator",
27         "_do_pseudo_reloc",
28         "_impure_ptr",
29         "__impure_ptr",
30         "__fmode",
31         "_environ",
32         "___dso_handle",
33         // These are the MinGW names that differ from the standard
34         // ones (lacking an extra underscore).
35         "_DllMain@12",
36         "_DllEntryPoint@12",
37         "_DllMainCRTStartup@12",
38     };
39   } else {
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",
52         "DllEntryPoint",
53         "DllMainCRTStartup",
54     };
55   }
56
57   ExcludeLibs = {
58       "libgcc",
59       "libgcc_s",
60       "libstdc++",
61       "libmingw32",
62       "libmingwex",
63       "libg2c",
64       "libsupc++",
65       "libobjc",
66       "libgcj",
67       "libclang_rt.builtins-aarch64",
68       "libclang_rt.builtins-arm",
69       "libclang_rt.builtins-i386",
70       "libclang_rt.builtins-x86_64",
71       "libc++",
72       "libc++abi",
73       "libunwind",
74       "libmsvcrt",
75       "libucrtbase",
76   };
77   ExcludeObjects = {
78       "crt0.o",
79       "crt1.o",
80       "crt1u.o",
81       "crt2.o",
82       "crt2u.o",
83       "dllcrt1.o",
84       "dllcrt2.o",
85       "gcrt0.o",
86       "gcrt1.o",
87       "gcrt2.o",
88       "crtbegin.o",
89       "crtend.o",
90   };
91 }
92
93 bool AutoExporter::shouldExport(Defined *Sym) const {
94   if (!Sym || !Sym->isLive() || !Sym->getChunk())
95     return false;
96
97   // Only allow the symbol kinds that make sense to export; in particular,
98   // disallow import symbols.
99   if (!isa<DefinedRegular>(Sym) && !isa<DefinedCommon>(Sym))
100     return false;
101   if (ExcludeSymbols.count(Sym->getName()))
102     return false;
103
104   // Don't export anything that looks like an import symbol (which also can be
105   // a manually defined data symbol with such a name).
106   if (Sym->getName().startswith("__imp_"))
107     return false;
108
109   // If a corresponding __imp_ symbol exists and is defined, don't export it.
110   if (Symtab->find(("__imp_" + Sym->getName()).str()))
111     return false;
112
113   // Check that file is non-null before dereferencing it, symbols not
114   // originating in regular object files probably shouldn't be exported.
115   if (!Sym->getFile())
116     return false;
117
118   StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
119
120   // Drop the file extension.
121   LibName = LibName.substr(0, LibName.rfind('.'));
122   if (!LibName.empty())
123     return !ExcludeLibs.count(LibName);
124
125   StringRef FileName = sys::path::filename(Sym->getFile()->getName());
126   return !ExcludeObjects.count(FileName);
127 }
128
129 void coff::writeDefFile(StringRef Name) {
130   std::error_code EC;
131   raw_fd_ostream OS(Name, EC, sys::fs::F_None);
132   if (EC)
133     fatal("cannot open " + Name + ": " + EC.message());
134
135   OS << "EXPORTS\n";
136   for (Export &E : Config->Exports) {
137     OS << "    " << E.ExportName << " "
138        << "@" << E.Ordinal;
139     if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) {
140       if (Def && Def->getChunk() &&
141           !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
142         OS << " DATA";
143     }
144     OS << "\n";
145   }
146 }