Fail early if an output file is not writable

Fixes https://bugs.llvm.org/show_bug.cgi?id=36478

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

llvm-svn: 355834
This commit is contained in:
Rui Ueyama 2019-03-11 16:30:55 +00:00
parent 90ede5f4bf
commit 7fd99fc475
8 changed files with 19 additions and 13 deletions

View File

@ -18,6 +18,7 @@
#include "lld/Common/Args.h"
#include "lld/Common/Driver.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Filesystem.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Timer.h"
@ -1525,6 +1526,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue());
}
// Fail early if an output file is not writable.
if (auto E = tryCreateFile(Config->OutputFile)) {
error("cannot open output file " + Config->OutputFile + ": " + E.message());
return;
}
if (ShouldCreatePDB) {
// Put the PDB next to the image if no /pdb flag was passed.
if (Config->PDBPath.empty()) {

View File

@ -30,6 +30,7 @@ set_property(SOURCE Version.cpp APPEND PROPERTY
add_lld_library(lldCommon
Args.cpp
ErrorHandler.cpp
Filesystem.cpp
Memory.cpp
Reproduce.cpp
Strings.cpp

View File

@ -10,8 +10,7 @@
//
//===----------------------------------------------------------------------===//
#include "Filesystem.h"
#include "Config.h"
#include "lld/Common/Filesystem.h"
#include "lld/Common/Threads.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/FileOutputBuffer.h"
@ -22,9 +21,7 @@
#include <thread>
using namespace llvm;
using namespace lld;
using namespace lld::elf;
// Removes a given file asynchronously. This is a performance hack,
// so remove this when operating systems are improved.
@ -41,7 +38,7 @@ using namespace lld::elf;
//
// This function spawns a background thread to remove the file.
// The calling thread returns almost immediately.
void elf::unlinkAsync(StringRef Path) {
void lld::unlinkAsync(StringRef Path) {
// Removing a file is async on windows.
#if defined(_WIN32)
sys::fs::remove(Path);
@ -93,7 +90,7 @@ void elf::unlinkAsync(StringRef Path) {
// FileOutputBuffer doesn't touch a desitnation file until commit()
// is called. We use that class without calling commit() to predict
// if the given file is writable.
std::error_code elf::tryCreateFile(StringRef Path) {
std::error_code lld::tryCreateFile(StringRef Path) {
if (Path.empty())
return std::error_code();
if (Path == "-")

View File

@ -27,7 +27,6 @@ add_lld_library(lldELF
Driver.cpp
DriverUtils.cpp
EhFrame.cpp
Filesystem.cpp
ICF.cpp
InputFiles.cpp
InputSection.cpp

View File

@ -24,7 +24,6 @@
#include "Driver.h"
#include "Config.h"
#include "Filesystem.h"
#include "ICF.h"
#include "InputFiles.h"
#include "InputSection.h"
@ -40,6 +39,7 @@
#include "lld/Common/Args.h"
#include "lld/Common/Driver.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Filesystem.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "lld/Common/TargetOptionsCommandFlags.h"

View File

@ -10,7 +10,6 @@
#include "AArch64ErrataFix.h"
#include "CallGraphSort.h"
#include "Config.h"
#include "Filesystem.h"
#include "LinkerScript.h"
#include "MapFile.h"
#include "OutputSections.h"
@ -19,6 +18,7 @@
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/Filesystem.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "lld/Common/Threads.h"

View File

@ -6,17 +6,15 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLD_ELF_FILESYSTEM_H
#define LLD_ELF_FILESYSTEM_H
#ifndef LLD_FILESYSTEM_H
#define LLD_FILESYSTEM_H
#include "lld/Common/LLVM.h"
#include <system_error>
namespace lld {
namespace elf {
void unlinkAsync(StringRef Path);
std::error_code tryCreateFile(StringRef Path);
} // namespace elf
} // namespace lld
#endif

View File

@ -15,3 +15,7 @@ LIBHELP: OVERVIEW: LLVM Lib
# RUN: not lld-link /WX /lib 2>&1 | FileCheck -check-prefix=LIBBAD %s
LIBBAD: ignoring /lib since it's not the first argument
# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
# RUN: not lld-link /out:/ %t.obj 2>&1 | FileCheck -check-prefix=DIR %s
DIR: cannot open output file