zig/deps/lld/COFF/MinGW.cpp

167 lines
4.6 KiB
C++
Raw Normal View History

2018-01-18 06:29:21 +08:00
//===- MinGW.cpp ----------------------------------------------------------===//
//
2019-08-04 00:43:55 +08:00
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2018-01-18 06:29:21 +08:00
//
//===----------------------------------------------------------------------===//
#include "MinGW.h"
#include "SymbolTable.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
using namespace lld;
using namespace lld::coff;
using namespace llvm;
using namespace llvm::COFF;
2019-08-04 00:43:55 +08:00
AutoExporter::AutoExporter() {
excludeLibs = {
"libgcc",
"libgcc_s",
"libstdc++",
"libmingw32",
"libmingwex",
"libg2c",
"libsupc++",
"libobjc",
"libgcj",
"libclang_rt.builtins",
"libclang_rt.builtins-aarch64",
"libclang_rt.builtins-arm",
"libclang_rt.builtins-i386",
"libclang_rt.builtins-x86_64",
"libc++",
"libc++abi",
"libunwind",
"libmsvcrt",
"libucrtbase",
};
excludeObjects = {
"crt0.o", "crt1.o", "crt1u.o", "crt2.o", "crt2u.o", "dllcrt1.o",
"dllcrt2.o", "gcrt0.o", "gcrt1.o", "gcrt2.o", "crtbegin.o", "crtend.o",
};
excludeSymbolPrefixes = {
2019-02-08 06:07:18 +08:00
// Import symbols
"__imp_",
"__IMPORT_DESCRIPTOR_",
// Extra import symbols from GNU import libraries
"__nm_",
// C++ symbols
"__rtti_",
"__builtin_",
// Artifical symbols such as .refptr
".",
};
2019-08-04 00:43:55 +08:00
excludeSymbolSuffixes = {
2019-02-08 06:07:18 +08:00
"_iname",
"_NULL_THUNK_DATA",
};
2019-08-04 00:43:55 +08:00
if (config->machine == I386) {
excludeSymbols = {
2018-01-18 06:29:21 +08:00
"__NULL_IMPORT_DESCRIPTOR",
"__pei386_runtime_relocator",
"_do_pseudo_reloc",
"_impure_ptr",
"__impure_ptr",
"__fmode",
"_environ",
"___dso_handle",
// These are the MinGW names that differ from the standard
// ones (lacking an extra underscore).
"_DllMain@12",
"_DllEntryPoint@12",
"_DllMainCRTStartup@12",
};
2019-08-04 00:43:55 +08:00
excludeSymbolPrefixes.insert("__head_");
2018-01-18 06:29:21 +08:00
} else {
2019-08-04 00:43:55 +08:00
excludeSymbols = {
2019-02-08 06:07:18 +08:00
"__NULL_IMPORT_DESCRIPTOR",
2018-01-18 06:29:21 +08:00
"_pei386_runtime_relocator",
"do_pseudo_reloc",
"impure_ptr",
"_impure_ptr",
"_fmode",
"environ",
"__dso_handle",
// These are the MinGW names that differ from the standard
// ones (lacking an extra underscore).
"DllMain",
"DllEntryPoint",
"DllMainCRTStartup",
};
2019-08-04 00:43:55 +08:00
excludeSymbolPrefixes.insert("_head_");
2018-01-18 06:29:21 +08:00
}
2019-02-08 06:07:18 +08:00
}
2018-01-18 06:29:21 +08:00
2019-08-04 00:43:55 +08:00
void AutoExporter::addWholeArchive(StringRef path) {
StringRef libName = sys::path::filename(path);
2019-02-08 06:07:18 +08:00
// Drop the file extension, to match the processing below.
2019-08-04 00:43:55 +08:00
libName = libName.substr(0, libName.rfind('.'));
excludeLibs.erase(libName);
2019-02-08 06:07:18 +08:00
}
2019-08-04 00:43:55 +08:00
bool AutoExporter::shouldExport(Defined *sym) const {
if (!sym || !sym->isLive() || !sym->getChunk())
2018-01-18 06:29:21 +08:00
return false;
// Only allow the symbol kinds that make sense to export; in particular,
// disallow import symbols.
2019-08-04 00:43:55 +08:00
if (!isa<DefinedRegular>(sym) && !isa<DefinedCommon>(sym))
2018-01-18 06:29:21 +08:00
return false;
2019-08-04 00:43:55 +08:00
if (excludeSymbols.count(sym->getName()))
2018-01-18 06:29:21 +08:00
return false;
2019-08-04 00:43:55 +08:00
for (StringRef prefix : excludeSymbolPrefixes.keys())
if (sym->getName().startswith(prefix))
2019-02-08 06:07:18 +08:00
return false;
2019-08-04 00:43:55 +08:00
for (StringRef suffix : excludeSymbolSuffixes.keys())
if (sym->getName().endswith(suffix))
2019-02-08 06:07:18 +08:00
return false;
2018-01-18 06:29:21 +08:00
// If a corresponding __imp_ symbol exists and is defined, don't export it.
2019-08-04 00:43:55 +08:00
if (symtab->find(("__imp_" + sym->getName()).str()))
2018-01-18 06:29:21 +08:00
return false;
// Check that file is non-null before dereferencing it, symbols not
// originating in regular object files probably shouldn't be exported.
2019-08-04 00:43:55 +08:00
if (!sym->getFile())
2018-01-18 06:29:21 +08:00
return false;
2019-08-04 00:43:55 +08:00
StringRef libName = sys::path::filename(sym->getFile()->parentName);
2018-01-18 06:29:21 +08:00
// Drop the file extension.
2019-08-04 00:43:55 +08:00
libName = libName.substr(0, libName.rfind('.'));
if (!libName.empty())
return !excludeLibs.count(libName);
2018-01-18 06:29:21 +08:00
2019-08-04 00:43:55 +08:00
StringRef fileName = sys::path::filename(sym->getFile()->getName());
return !excludeObjects.count(fileName);
2018-01-18 06:29:21 +08:00
}
2019-08-04 00:43:55 +08:00
void coff::writeDefFile(StringRef name) {
std::error_code ec;
raw_fd_ostream os(name, ec, sys::fs::F_None);
if (ec)
fatal("cannot open " + name + ": " + ec.message());
os << "EXPORTS\n";
for (Export &e : config->exports) {
os << " " << e.exportName << " "
<< "@" << e.ordinal;
if (auto *def = dyn_cast_or_null<Defined>(e.sym)) {
if (def && def->getChunk() &&
!(def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
os << " DATA";
2018-01-18 06:29:21 +08:00
}
2019-08-04 00:43:55 +08:00
os << "\n";
2018-01-18 06:29:21 +08:00
}
}