2017-10-20 03:49:38 +08:00
|
|
|
//===- MinGW.cpp ----------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "MinGW.h"
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
#include "lld/Common/ErrorHandler.h"
|
2017-10-20 03:49:38 +08:00
|
|
|
#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;
|
|
|
|
|
|
|
|
AutoExporter::AutoExporter() {
|
2017-11-22 17:06:27 +08:00
|
|
|
if (Config->Machine == I386) {
|
2017-10-20 03:49:38 +08:00
|
|
|
ExcludeSymbols = {
|
|
|
|
"__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",
|
|
|
|
};
|
2017-11-22 17:06:27 +08:00
|
|
|
} else {
|
2017-10-20 03:49:38 +08:00
|
|
|
ExcludeSymbols = {
|
|
|
|
"_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",
|
|
|
|
"DllEntryPoint",
|
|
|
|
"DllMainCRTStartup",
|
|
|
|
};
|
2017-11-22 17:06:27 +08:00
|
|
|
}
|
2017-10-20 03:49:38 +08:00
|
|
|
|
|
|
|
ExcludeLibs = {
|
|
|
|
"libgcc",
|
|
|
|
"libgcc_s",
|
|
|
|
"libstdc++",
|
|
|
|
"libmingw32",
|
|
|
|
"libmingwex",
|
|
|
|
"libg2c",
|
|
|
|
"libsupc++",
|
|
|
|
"libobjc",
|
|
|
|
"libgcj",
|
|
|
|
"libclang_rt.builtins-aarch64",
|
|
|
|
"libclang_rt.builtins-arm",
|
|
|
|
"libclang_rt.builtins-i386",
|
|
|
|
"libclang_rt.builtins-x86_64",
|
2017-10-23 17:08:28 +08:00
|
|
|
"libc++",
|
|
|
|
"libc++abi",
|
|
|
|
"libunwind",
|
2017-11-07 04:33:13 +08:00
|
|
|
"libmsvcrt",
|
|
|
|
"libucrtbase",
|
2017-10-20 03:49:38 +08:00
|
|
|
};
|
|
|
|
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",
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AutoExporter::shouldExport(Defined *Sym) const {
|
|
|
|
if (!Sym || !Sym->isLive() || !Sym->getChunk())
|
|
|
|
return false;
|
2017-11-22 17:06:27 +08:00
|
|
|
|
2017-11-16 15:22:44 +08:00
|
|
|
// Only allow the symbol kinds that make sense to export; in particular,
|
|
|
|
// disallow import symbols.
|
|
|
|
if (!isa<DefinedRegular>(Sym) && !isa<DefinedCommon>(Sym))
|
|
|
|
return false;
|
2017-10-20 03:49:38 +08:00
|
|
|
if (ExcludeSymbols.count(Sym->getName()))
|
|
|
|
return false;
|
2017-11-22 17:06:27 +08:00
|
|
|
|
2017-11-16 15:22:44 +08:00
|
|
|
// Check that file is non-null before dereferencing it, symbols not
|
|
|
|
// originating in regular object files probably shouldn't be exported.
|
|
|
|
if (!Sym->getFile())
|
|
|
|
return false;
|
2017-11-22 17:06:27 +08:00
|
|
|
|
2017-10-20 03:49:38 +08:00
|
|
|
StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
|
2017-11-22 17:06:27 +08:00
|
|
|
|
2017-10-20 03:49:38 +08:00
|
|
|
// Drop the file extension.
|
|
|
|
LibName = LibName.substr(0, LibName.rfind('.'));
|
2017-11-22 17:06:42 +08:00
|
|
|
if (!LibName.empty())
|
|
|
|
return !ExcludeLibs.count(LibName);
|
2017-11-22 17:06:27 +08:00
|
|
|
|
2017-10-20 03:49:38 +08:00
|
|
|
StringRef FileName = sys::path::filename(Sym->getFile()->getName());
|
2017-11-22 17:06:42 +08:00
|
|
|
return !ExcludeObjects.count(FileName);
|
2017-10-20 03:49:38 +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()->getPermissions() & IMAGE_SCN_MEM_EXECUTE))
|
|
|
|
OS << " DATA";
|
|
|
|
}
|
|
|
|
OS << "\n";
|
|
|
|
}
|
|
|
|
}
|