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 } 177