Skip to content

Commit

Permalink
lld::COFF: better behavior when using as a library
Browse files Browse the repository at this point in the history
Previously, the COFF driver would call exit(0) when called
as a library.  Now it takes `ExitEarly` option, and if it
is false, it doesn't exit.  So it is now more library-friendly.

Furthermore, link() calls freeArena() before returning, to
clean up resources.

Based on an Andrew Kelley's patch.

Differential Revision: https://reviews.llvm.org/D39202

llvm-svn: 316370
  • Loading branch information
rui314 committed Oct 23, 2017
1 parent 9ed81c6 commit 6f4e255
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 14 deletions.
1 change: 1 addition & 0 deletions lld/COFF/Config.h
Expand Up @@ -166,6 +166,7 @@ struct Configuration {
uint32_t MinorImageVersion = 0;
uint32_t MajorOSVersion = 6;
uint32_t MinorOSVersion = 0;
bool CanExitEarly = false;
bool DynamicBase = true;
bool AllowBind = true;
bool NxCompat = true;
Expand Down
19 changes: 10 additions & 9 deletions lld/COFF/Driver.cpp
Expand Up @@ -54,18 +54,25 @@ BumpPtrAllocator BAlloc;
StringSaver Saver{BAlloc};
std::vector<SpecificAllocBase *> SpecificAllocBase::Instances;

bool link(ArrayRef<const char *> Args, raw_ostream &Diag) {
bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {
ErrorCount = 0;
ErrorOS = &Diag;

Config = make<Configuration>();
Config->Argv = {Args.begin(), Args.end()};
Config->ColorDiagnostics = ErrorOS->has_colors();
Config->CanExitEarly = CanExitEarly;

Symtab = make<SymbolTable>();

Driver = make<LinkerDriver>();
Driver->link(Args);

// Call exit() if we can to avoid calling destructors.
if (CanExitEarly)
exitLld(ErrorCount ? 1 : 0);

freeArena();
return !ErrorCount;
}

Expand Down Expand Up @@ -1087,7 +1094,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
if (!Args.hasArg(OPT_INPUT)) {
fixupExports();
createImportLibrary(/*AsLib=*/true);
exit(0);
return;
}

// Handle /delayload
Expand Down Expand Up @@ -1179,7 +1186,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// This is useful because MSVC link.exe can generate complete PDBs.
if (Args.hasArg(OPT_msvclto)) {
invokeMSVC(Args);
exit(0);
return;
}

// Do LTO by compiling bitcode input files to a set of native COFF files then
Expand Down Expand Up @@ -1273,12 +1280,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {

// Write the result.
writeResult();

if (ErrorCount)
return;

// Call exit to avoid calling destructors.
exit(0);
}

} // namespace coff
Expand Down
5 changes: 3 additions & 2 deletions lld/COFF/Error.cpp
Expand Up @@ -32,7 +32,7 @@ namespace coff {
uint64_t ErrorCount;
raw_ostream *ErrorOS;

static LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) {
LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) {
// Dealloc/destroy ManagedStatic variables before calling
// _exit(). In a non-LTO build, this is a nop. In an LTO
// build allows us to get the output of -time-passes.
Expand Down Expand Up @@ -78,7 +78,8 @@ void error(const Twine &Msg) {
print("error: ", raw_ostream::RED);
*ErrorOS << "too many errors emitted, stopping now"
<< " (use /ERRORLIMIT:0 to see all errors)\n";
exitLld(1);
if (Config->CanExitEarly)
exitLld(1);
}

++ErrorCount;
Expand Down
2 changes: 2 additions & 0 deletions lld/COFF/Error.h
Expand Up @@ -27,6 +27,8 @@ LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error &Err, const Twine &Prefix);

LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);

template <class T> T check(ErrorOr<T> V, const Twine &Prefix) {
if (auto EC = V.getError())
fatal(EC, Prefix);
Expand Down
2 changes: 1 addition & 1 deletion lld/MinGW/Driver.cpp
Expand Up @@ -217,5 +217,5 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) {
std::vector<const char *> Vec;
for (const std::string &S : LinkArgs)
Vec.push_back(S.c_str());
return coff::link(Vec);
return coff::link(Vec, true);
}
2 changes: 1 addition & 1 deletion lld/include/lld/Common/Driver.h
Expand Up @@ -15,7 +15,7 @@

namespace lld {
namespace coff {
bool link(llvm::ArrayRef<const char *> Args,
bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
llvm::raw_ostream &Diag = llvm::errs());
}

Expand Down
2 changes: 1 addition & 1 deletion lld/tools/lld/lld.cpp
Expand Up @@ -115,7 +115,7 @@ int main(int Argc, const char **Argv) {
return !mingw::link(Args);
return !elf::link(Args, true);
case WinLink:
return !coff::link(Args);
return !coff::link(Args, true);
case Darwin:
return !mach_o::link(Args);
default:
Expand Down

0 comments on commit 6f4e255

Please sign in to comment.