xref: /llvm-project-15.0.7/lld/COFF/MinGW.cpp (revision 7fe441b2)
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 "Error.h"
12 #include "llvm/Object/COFF.h"
13 #include "llvm/Support/Path.h"
14 #include "llvm/Support/raw_ostream.h"
15 
16 using namespace lld;
17 using namespace lld::coff;
18 using namespace llvm;
19 using namespace llvm::COFF;
20 
21 AutoExporter::AutoExporter() {
22   if (Config->Machine == I386)
23     ExcludeSymbols = {
24         "__NULL_IMPORT_DESCRIPTOR",
25         "__pei386_runtime_relocator",
26         "_do_pseudo_reloc",
27         "_impure_ptr",
28         "__impure_ptr",
29         "__fmode",
30         "_environ",
31         "___dso_handle",
32         // These are the MinGW names that differ from the standard
33         // ones (lacking an extra underscore).
34         "_DllMain@12",
35         "_DllEntryPoint@12",
36         "_DllMainCRTStartup@12",
37     };
38   else
39     ExcludeSymbols = {
40         "_NULL_IMPORT_DESCRIPTOR",
41         "_pei386_runtime_relocator",
42         "do_pseudo_reloc",
43         "impure_ptr",
44         "_impure_ptr",
45         "_fmode",
46         "environ",
47         "__dso_handle",
48         // These are the MinGW names that differ from the standard
49         // ones (lacking an extra underscore).
50         "DllMain",
51         "DllEntryPoint",
52         "DllMainCRTStartup",
53     };
54 
55   ExcludeLibs = {
56       "libgcc",
57       "libgcc_s",
58       "libstdc++",
59       "libmingw32",
60       "libmingwex",
61       "libg2c",
62       "libsupc++",
63       "libobjc",
64       "libgcj",
65       "libclang_rt.builtins-aarch64",
66       "libclang_rt.builtins-arm",
67       "libclang_rt.builtins-i386",
68       "libclang_rt.builtins-x86_64",
69       "libc++",
70       "libc++abi",
71       "libunwind",
72   };
73   ExcludeObjects = {
74       "crt0.o",
75       "crt1.o",
76       "crt1u.o",
77       "crt2.o",
78       "crt2u.o",
79       "dllcrt1.o",
80       "dllcrt2.o",
81       "gcrt0.o",
82       "gcrt1.o",
83       "gcrt2.o",
84       "crtbegin.o",
85       "crtend.o",
86   };
87 }
88 
89 bool AutoExporter::shouldExport(Defined *Sym) const {
90   if (!Sym || !Sym->isLive() || !Sym->getChunk())
91     return false;
92   if (ExcludeSymbols.count(Sym->getName()))
93     return false;
94   StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
95   // Drop the file extension.
96   LibName = LibName.substr(0, LibName.rfind('.'));
97   if (ExcludeLibs.count(LibName))
98     return false;
99   StringRef FileName = sys::path::filename(Sym->getFile()->getName());
100   if (LibName.empty() && ExcludeObjects.count(FileName))
101     return false;
102   return true;
103 }
104 
105 void coff::writeDefFile(StringRef Name) {
106   std::error_code EC;
107   raw_fd_ostream OS(Name, EC, sys::fs::F_None);
108   if (EC)
109     fatal("cannot open " + Name + ": " + EC.message());
110 
111   OS << "EXPORTS\n";
112   for (Export &E : Config->Exports) {
113     OS << "    " << E.ExportName << " "
114        << "@" << E.Ordinal;
115     if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) {
116       if (Def && Def->getChunk() &&
117           !(Def->getChunk()->getPermissions() & IMAGE_SCN_MEM_EXECUTE))
118         OS << " DATA";
119     }
120     OS << "\n";
121   }
122 }
123