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:
parent
90ede5f4bf
commit
7fd99fc475
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 == "-")
|
|
@ -27,7 +27,6 @@ add_lld_library(lldELF
|
|||
Driver.cpp
|
||||
DriverUtils.cpp
|
||||
EhFrame.cpp
|
||||
Filesystem.cpp
|
||||
ICF.cpp
|
||||
InputFiles.cpp
|
||||
InputSection.cpp
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue