Skip to content

Commit 7fd99fc

Browse files
committed
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
1 parent 90ede5f commit 7fd99fc

File tree

8 files changed

+19
-13
lines changed

8 files changed

+19
-13
lines changed

lld/COFF/Driver.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "lld/Common/Args.h"
1919
#include "lld/Common/Driver.h"
2020
#include "lld/Common/ErrorHandler.h"
21+
#include "lld/Common/Filesystem.h"
2122
#include "lld/Common/Memory.h"
2223
#include "lld/Common/Threads.h"
2324
#include "lld/Common/Timer.h"
@@ -1525,6 +1526,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
15251526
getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue());
15261527
}
15271528

1529+
// Fail early if an output file is not writable.
1530+
if (auto E = tryCreateFile(Config->OutputFile)) {
1531+
error("cannot open output file " + Config->OutputFile + ": " + E.message());
1532+
return;
1533+
}
1534+
15281535
if (ShouldCreatePDB) {
15291536
// Put the PDB next to the image if no /pdb flag was passed.
15301537
if (Config->PDBPath.empty()) {

lld/Common/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ set_property(SOURCE Version.cpp APPEND PROPERTY
3030
add_lld_library(lldCommon
3131
Args.cpp
3232
ErrorHandler.cpp
33+
Filesystem.cpp
3334
Memory.cpp
3435
Reproduce.cpp
3536
Strings.cpp

lld/ELF/Filesystem.cpp lld/Common/Filesystem.cpp

+3-6
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "Filesystem.h"
14-
#include "Config.h"
13+
#include "lld/Common/Filesystem.h"
1514
#include "lld/Common/Threads.h"
1615
#include "llvm/Config/llvm-config.h"
1716
#include "llvm/Support/FileOutputBuffer.h"
@@ -22,9 +21,7 @@
2221
#include <thread>
2322

2423
using namespace llvm;
25-
2624
using namespace lld;
27-
using namespace lld::elf;
2825

2926
// Removes a given file asynchronously. This is a performance hack,
3027
// so remove this when operating systems are improved.
@@ -41,7 +38,7 @@ using namespace lld::elf;
4138
//
4239
// This function spawns a background thread to remove the file.
4340
// The calling thread returns almost immediately.
44-
void elf::unlinkAsync(StringRef Path) {
41+
void lld::unlinkAsync(StringRef Path) {
4542
// Removing a file is async on windows.
4643
#if defined(_WIN32)
4744
sys::fs::remove(Path);
@@ -93,7 +90,7 @@ void elf::unlinkAsync(StringRef Path) {
9390
// FileOutputBuffer doesn't touch a desitnation file until commit()
9491
// is called. We use that class without calling commit() to predict
9592
// if the given file is writable.
96-
std::error_code elf::tryCreateFile(StringRef Path) {
93+
std::error_code lld::tryCreateFile(StringRef Path) {
9794
if (Path.empty())
9895
return std::error_code();
9996
if (Path == "-")

lld/ELF/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ add_lld_library(lldELF
2727
Driver.cpp
2828
DriverUtils.cpp
2929
EhFrame.cpp
30-
Filesystem.cpp
3130
ICF.cpp
3231
InputFiles.cpp
3332
InputSection.cpp

lld/ELF/Driver.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
#include "Driver.h"
2626
#include "Config.h"
27-
#include "Filesystem.h"
2827
#include "ICF.h"
2928
#include "InputFiles.h"
3029
#include "InputSection.h"
@@ -40,6 +39,7 @@
4039
#include "lld/Common/Args.h"
4140
#include "lld/Common/Driver.h"
4241
#include "lld/Common/ErrorHandler.h"
42+
#include "lld/Common/Filesystem.h"
4343
#include "lld/Common/Memory.h"
4444
#include "lld/Common/Strings.h"
4545
#include "lld/Common/TargetOptionsCommandFlags.h"

lld/ELF/Writer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "AArch64ErrataFix.h"
1111
#include "CallGraphSort.h"
1212
#include "Config.h"
13-
#include "Filesystem.h"
1413
#include "LinkerScript.h"
1514
#include "MapFile.h"
1615
#include "OutputSections.h"
@@ -19,6 +18,7 @@
1918
#include "Symbols.h"
2019
#include "SyntheticSections.h"
2120
#include "Target.h"
21+
#include "lld/Common/Filesystem.h"
2222
#include "lld/Common/Memory.h"
2323
#include "lld/Common/Strings.h"
2424
#include "lld/Common/Threads.h"

lld/ELF/Filesystem.h lld/include/lld/Common/Filesystem.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,15 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#ifndef LLD_ELF_FILESYSTEM_H
10-
#define LLD_ELF_FILESYSTEM_H
9+
#ifndef LLD_FILESYSTEM_H
10+
#define LLD_FILESYSTEM_H
1111

1212
#include "lld/Common/LLVM.h"
1313
#include <system_error>
1414

1515
namespace lld {
16-
namespace elf {
1716
void unlinkAsync(StringRef Path);
1817
std::error_code tryCreateFile(StringRef Path);
19-
} // namespace elf
2018
} // namespace lld
2119

2220
#endif

lld/test/COFF/driver.test

+4
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ LIBHELP: OVERVIEW: LLVM Lib
1515

1616
# RUN: not lld-link /WX /lib 2>&1 | FileCheck -check-prefix=LIBBAD %s
1717
LIBBAD: ignoring /lib since it's not the first argument
18+
19+
# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
20+
# RUN: not lld-link /out:/ %t.obj 2>&1 | FileCheck -check-prefix=DIR %s
21+
DIR: cannot open output file

0 commit comments

Comments
 (0)