From 7fd99fc4754a9ccd24f0cc0fcd0ff4df8c19206a Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Mon, 11 Mar 2019 16:30:55 +0000 Subject: [PATCH] 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 --- lld/COFF/Driver.cpp | 7 +++++++ lld/Common/CMakeLists.txt | 1 + lld/{ELF => Common}/Filesystem.cpp | 9 +++------ lld/ELF/CMakeLists.txt | 1 - lld/ELF/Driver.cpp | 2 +- lld/ELF/Writer.cpp | 2 +- lld/{ELF => include/lld/Common}/Filesystem.h | 6 ++---- lld/test/COFF/driver.test | 4 ++++ 8 files changed, 19 insertions(+), 13 deletions(-) rename lld/{ELF => Common}/Filesystem.cpp (95%) rename lld/{ELF => include/lld/Common}/Filesystem.h (85%) diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 0d161ecc..50017c5 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -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 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()) { diff --git a/lld/Common/CMakeLists.txt b/lld/Common/CMakeLists.txt index 29f38d0..70849cc 100644 --- a/lld/Common/CMakeLists.txt +++ b/lld/Common/CMakeLists.txt @@ -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 diff --git a/lld/ELF/Filesystem.cpp b/lld/Common/Filesystem.cpp similarity index 95% rename from lld/ELF/Filesystem.cpp rename to lld/Common/Filesystem.cpp index 5c8475f..6484286 100644 --- a/lld/ELF/Filesystem.cpp +++ b/lld/Common/Filesystem.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 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 == "-") diff --git a/lld/ELF/CMakeLists.txt b/lld/ELF/CMakeLists.txt index a1c23b0..7057874 100644 --- a/lld/ELF/CMakeLists.txt +++ b/lld/ELF/CMakeLists.txt @@ -27,7 +27,6 @@ add_lld_library(lldELF Driver.cpp DriverUtils.cpp EhFrame.cpp - Filesystem.cpp ICF.cpp InputFiles.cpp InputSection.cpp diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 784efb3..5ef50c1 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.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" diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 705ce0f..c8e6a83 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -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" diff --git a/lld/ELF/Filesystem.h b/lld/include/lld/Common/Filesystem.h similarity index 85% rename from lld/ELF/Filesystem.h rename to lld/include/lld/Common/Filesystem.h index c92a5d2..4411870 100644 --- a/lld/ELF/Filesystem.h +++ b/lld/include/lld/Common/Filesystem.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 namespace lld { -namespace elf { void unlinkAsync(StringRef Path); std::error_code tryCreateFile(StringRef Path); -} // namespace elf } // namespace lld #endif diff --git a/lld/test/COFF/driver.test b/lld/test/COFF/driver.test index aef7046..50aa91b 100644 --- a/lld/test/COFF/driver.test +++ b/lld/test/COFF/driver.test @@ -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 -- 2.7.4