forked from OSchip/llvm-project
[ELF] Fail the link early if the map file path is invalid
As with the changes made in r297645, we do not want a potentially long link to be run, if it will ultimately fail because the map file is not writable. This change reuses the same functionality as the output file path check. See https://reviews.llvm.org/D30449 for further justification and explanations. Reviewers: ruiu Differential Revision: https://reviews.llvm.org/D31603 llvm-svn: 299420
This commit is contained in:
parent
74f823a045
commit
b7a90ef48e
|
@ -860,10 +860,12 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
|||
if (Config->OutputFile.empty())
|
||||
Config->OutputFile = "a.out";
|
||||
|
||||
// Fail early if the output file is not writable. If a user has a long link,
|
||||
// e.g. due to a large LTO link, they do not wish to run it and find that it
|
||||
// failed because there was a mistake in their command-line.
|
||||
if (!isFileWritable(Config->OutputFile))
|
||||
// Fail early if the output file or map file is not writable. If a user has a
|
||||
// long link, e.g. due to a large LTO link, they do not wish to run it and
|
||||
// find that it failed because there was a mistake in their command-line.
|
||||
if (!isFileWritable(Config->OutputFile, "output file"))
|
||||
return;
|
||||
if (!isFileWritable(Config->MapFile, "map file"))
|
||||
return;
|
||||
|
||||
// Use default entry point name if no name was given via the command
|
||||
|
|
|
@ -70,9 +70,9 @@ 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.
|
||||
bool elf::isFileWritable(StringRef Path) {
|
||||
bool elf::isFileWritable(StringRef Path, StringRef Desc) {
|
||||
if (auto EC = FileOutputBuffer::create(Path, 1).getError()) {
|
||||
error("cannot open output file " + Path + ": " + EC.message());
|
||||
error("cannot open " + Desc + " " + Path + ": " + EC.message());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
namespace lld {
|
||||
namespace elf {
|
||||
void unlinkAsync(StringRef Path);
|
||||
bool isFileWritable(StringRef Path);
|
||||
bool isFileWritable(StringRef Path, StringRef FileDescription);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,25 +2,32 @@
|
|||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
|
||||
# RUN: not ld.lld %t.o -o does_not_exist/output 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefixes=NO-DIR,CHECK
|
||||
# RUN: FileCheck %s -check-prefixes=NO-DIR-OUTPUT,CHECK
|
||||
# RUN: not ld.lld %t.o -o %s/dir_is_a_file 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefixes=DIR-IS-FILE,CHECK
|
||||
# RUN: FileCheck %s -check-prefixes=DIR-IS-OUTPUT,CHECK
|
||||
|
||||
# RUN: echo "OUTPUT(\"does_not_exist/output\")" > %t.script
|
||||
# RUN: not ld.lld %t.o %t.script 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefixes=NO-DIR,CHECK
|
||||
# RUN: FileCheck %s -check-prefixes=NO-DIR-OUTPUT,CHECK
|
||||
# RUN: echo "OUTPUT(\"%s/dir_is_a_file\")" > %t.script
|
||||
# RUN: not ld.lld %t.o %t.script 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefixes=DIR-IS-FILE,CHECK
|
||||
# RUN: FileCheck %s -check-prefixes=DIR-IS-OUTPUT,CHECK
|
||||
|
||||
# NO-DIR: error: cannot open output file does_not_exist/output:
|
||||
# DIR-IS-FILE: error: cannot open output file {{.*}}/dir_is_a_file:
|
||||
# RUN: not ld.lld %t.o -o %t -Map=does_not_exist/output 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefixes=NO-DIR-MAP,CHECK
|
||||
# RUN: not ld.lld %t.o -o %t -Map=%s/dir_is_a_file 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefixes=DIR-IS-MAP,CHECK
|
||||
|
||||
# NO-DIR-OUTPUT: error: cannot open output file does_not_exist/output:
|
||||
# DIR-IS-OUTPUT: error: cannot open output file {{.*}}/dir_is_a_file:
|
||||
# NO-DIR-MAP: error: cannot open map file does_not_exist/output:
|
||||
# DIR-IS-MAP: error: cannot open map file {{.*}}/dir_is_a_file:
|
||||
|
||||
# We should exit before doing the actual link. If an undefined symbol error is
|
||||
# discovered we haven't bailed out early as expected.
|
||||
# CHECK-NOT: undefined_symbol
|
||||
|
||||
# RUN: not ld.lld %t.o -o / 2>&1 | FileCheck %s -check-prefixes=ROOT
|
||||
# RUN: not ld.lld %t.o -o / 2>&1 | FileCheck %s -check-prefixes=ROOT,CHECK
|
||||
# ROOT: error: cannot open output file /
|
||||
|
||||
.globl _start
|
||||
|
|
|
@ -59,4 +59,4 @@ local:
|
|||
|
||||
// RUN: not ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=/ 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=FAIL %s
|
||||
// FAIL: cannot open /
|
||||
// FAIL: cannot open map file /
|
||||
|
|
Loading…
Reference in New Issue