[lld] [lld] check the format of libary and skip the wrong one (PR #78874)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 20 22:15:33 PST 2024
https://github.com/W-50243 updated https://github.com/llvm/llvm-project/pull/78874
>From 3f67e78f52433dbaeb8005815fc05314779601b4 Mon Sep 17 00:00:00 2001
From: W-50243 <wanghao636 at huawei.com>
Date: Sun, 21 Jan 2024 11:39:12 +0800
Subject: [PATCH 1/2] [lld] check the format of libary and skip the wrong one
---
lld/ELF/Config.h | 3 +-
lld/ELF/Driver.cpp | 80 +++++++++++++++++++++++++++++++++
lld/ELF/DriverUtils.cpp | 9 ++--
lld/ELF/Options.td | 4 ++
lld/test/ELF/aarch64-lld-path.s | 49 ++++++++++++++++++++
lld/test/ELF/x86-lld-path.s | 49 ++++++++++++++++++++
6 files changed, 190 insertions(+), 4 deletions(-)
create mode 100644 lld/test/ELF/aarch64-lld-path.s
create mode 100644 lld/test/ELF/x86-lld-path.s
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 56229334f9a44a..1bb12b955f0535 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -122,6 +122,7 @@ class LinkerDriver {
void linkerMain(ArrayRef<const char *> args);
void addFile(StringRef path, bool withLOption);
void addLibrary(StringRef name);
+ bool checkFile(StringRef name);
private:
void createFiles(llvm::opt::InputArgList &args);
@@ -424,11 +425,11 @@ struct Config {
// not supported on Android 11 & 12.
bool androidMemtagStack;
+ bool CheckFormat = true;
// When using a unified pre-link LTO pipeline, specify the backend LTO mode.
LtoKind ltoKind = LtoKind::Default;
unsigned threadCount;
-
// If an input file equals a key, remap it to the value.
llvm::DenseMap<llvm::StringRef, llvm::StringRef> remapInputs;
// If an input file matches a wildcard pattern, remap it to the value.
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 07f4263c90e62b..3f0502bf04df12 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -82,6 +82,7 @@ Ctx elf::ctx;
static void setConfigs(opt::InputArgList &args);
static void readConfigs(opt::InputArgList &args);
+static bool checkFileFormat(InputFile *file);
void elf::errorOrWarn(const Twine &msg) {
if (config->noinhibitExec)
@@ -1219,6 +1220,9 @@ static void readConfigs(opt::InputArgList &args) {
errorHandler().vsDiagnostics =
args.hasArg(OPT_visual_studio_diagnostics_format, false);
+ config->CheckFormat =
+ args.hasFlag(OPT_check_format, OPT_no_check_format, true);
+
config->allowMultipleDefinition =
args.hasFlag(OPT_allow_multiple_definition,
OPT_no_allow_multiple_definition, false) ||
@@ -3070,3 +3074,79 @@ void LinkerDriver::link(opt::InputArgList &args) {
// Write the result to the file.
invokeELFT(writeResult,);
}
+
+static bool checkFileFormat(InputFile *file) {
+ if (!file->isElf() && !isa<BitcodeFile>(file))
+ return true;
+
+ if (file->ekind == config->ekind && file->emachine == config->emachine) {
+ if (config->emachine != EM_MIPS)
+ return true;
+ if (isMipsN32Abi(file) == config->mipsN32Abi)
+ return true;
+ }
+
+ StringRef target =
+ !config->bfdname.empty() ? config->bfdname : config->emulation;
+ warn(toString(file) + " is incompatible with " + target);
+ return false;
+}
+
+bool LinkerDriver::checkFile(StringRef path) {
+ using namespace sys::fs;
+ if (config->ekind == ELFNoneKind || !config->CheckFormat)
+ return true;
+
+ Optional<MemoryBufferRef> buffer = readFile(path);
+ if(!buffer)
+ return false;
+
+ MemoryBufferRef mbref = *buffer;
+
+ switch(identify_magic(mbref.getBuffer())){
+ case file_magic::unknown:
+ return true;
+ case file_magic::archive: {
+ auto members = getArchiveMembers(mbref);
+ if(inWholeArchive){
+ for (const auto &p : members) {
+ bool SingleFile=isBitcode(p.first)?
+ checkFileFormat(make<BitcodeFile>(p.first, path, p.second, false)):
+ checkFileFormat(createObjFile(p.first, path));
+ return SingleFile;
+ }
+ }
+ for (const auto &p : members){
+ switch(identify_magic(p.first.getBuffer())){
+ case file_magic::elf_relocatable:
+ if(!checkFileFormat(createObjFile(p.first, path, true)))
+ return false;
+ break;
+ case file_magic::bitcode:
+ if(!checkFileFormat(make<BitcodeFile>(p.first, path, p.second, true)))
+ return false;
+ break;
+ default:{
+ warn(path + ": archive member '" + p.first.getBufferIdentifier() +
+ "' is neither ET_REL nor LLVM bitcode");
+ }
+ }
+ }
+ return true;
+ }
+ case file_magic::elf_shared_object:
+ if (config->isStatic || config->relocatable) {
+ warn("attempted static link of dynamic object " + path);
+ return false;
+ }
+ path = mbref.getBufferIdentifier();
+ return checkFileFormat(make<SharedFile>(mbref, path));
+ case file_magic::bitcode:
+ return checkFileFormat(make<BitcodeFile>(mbref, "", 0, inLib));
+ case file_magic::elf_relocatable:
+ return checkFileFormat(createObjFile(mbref, "", inLib));
+ default:
+ warn(path + ": unknown file type");
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index 0a27422e3b2df8..da6426549c5117 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -225,7 +225,8 @@ static std::optional<std::string> findFile(StringRef path1,
std::optional<std::string> elf::findFromSearchPaths(StringRef path) {
for (StringRef dir : config->searchPaths)
if (std::optional<std::string> s = findFile(dir, path))
- return s;
+ if (driver->checkFile(*s))
+ return s;
return std::nullopt;
}
@@ -235,9 +236,11 @@ std::optional<std::string> elf::searchLibraryBaseName(StringRef name) {
for (StringRef dir : config->searchPaths) {
if (!config->isStatic)
if (std::optional<std::string> s = findFile(dir, "lib" + name + ".so"))
- return s;
+ if (driver->checkFile(*s))
+ return s;
if (std::optional<std::string> s = findFile(dir, "lib" + name + ".a"))
- return s;
+ if (driver->checkFile(*s))
+ return s;
}
return std::nullopt;
}
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index c2c9cabc92a4da..141e6494600077 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -229,6 +229,10 @@ defm fatal_warnings: B<"fatal-warnings",
"Treat warnings as errors",
"Do not treat warnings as errors (default)">;
+defm check_format: B<"check-format",
+ "Please check the file format(default)",
+ "Please not check the file format">;
+
defm filter: Eq<"filter", "Set DT_FILTER field to the specified name">;
defm fini: Eq<"fini", "Specify a finalizer function">, MetaVarName<"<symbol>">;
diff --git a/lld/test/ELF/aarch64-lld-path.s b/lld/test/ELF/aarch64-lld-path.s
new file mode 100644
index 00000000000000..b17d7791fa040d
--- /dev/null
+++ b/lld/test/ELF/aarch64-lld-path.s
@@ -0,0 +1,49 @@
+# REQUIRES: aarch64
+
+# RUN: rm -rf %t && split-file %s %t && cd %t && mkdir be le
+# RUN: llvm-mc -filetype=obj -triple=aarch64 main.s -o main.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64 ref.s -o le/ref.o && ld.lld -shared le/ref.o -o le/libref.so
+# RUN: llvm-mc -filetype=obj -triple=aarch64_be ref.s -o be/ref.o && ld.lld -shared be/ref.o -o be/libref.so
+
+# One error formatted library
+# RUN: not ld.lld main.o -lref -Lbe -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -l:libref.so -Lbe -o /dev/null 2>&1 | FileCheck %s
+
+# Format not specified and the checkFile function is in default.
+# RUN: not ld.lld main.o -lref -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -l:libref.so -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s
+
+# Format not specified and the checkFile function is closed
+# RUN: not ld.lld main.o -no-check-format -lref -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -no-check-format -l:libref.so -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s
+
+# Specified format and the checkFile function is closed
+# RUN: not ld.lld -m aarch64linux -no-check-format main.o -lref -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR
+# RUN: not ld.lld -m aarch64linux -no-check-format main.o -l:libref.so -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR
+
+# Specified format and the checkFile function is in default with one error libary
+# RUN: not ld.lld -m aarch64linux main.o -lref -Lbe -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNTWO
+# RUN: not ld.lld -m aarch64linux main.o -l:libref.so -Lbe -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNONE
+
+# Specified format and the checkFile function is in default
+# RUN: ld.lld -m aarch64linux main.o -lref -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+# RUN: ld.lld -m aarch64linux main.o -l:libref.so -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+
+# CHECK-NOT: error:
+# CHECK: error: be/libref.so is incompatible with main.o
+
+# UNONE: warning: be/libref.so is incompatible with aarch64linux
+# UNONE: error: unable to find library -l:libref.so
+# UNTWO: warning: be/libref.so is incompatible with aarch64linux
+# UNTWO: error: unable to find library -lref
+# ERROR: error: be/libref.so is incompatible with aarch64linux
+# WARN: warning: be/libref.so is incompatible with aarch64linux
+
+#--- ref.s
+.globl fun
+fun:
+ nop
+#--- main.s
+.globl _start
+_start:
+ bl fun at PLT
\ No newline at end of file
diff --git a/lld/test/ELF/x86-lld-path.s b/lld/test/ELF/x86-lld-path.s
new file mode 100644
index 00000000000000..7b80b1328d3fbf
--- /dev/null
+++ b/lld/test/ELF/x86-lld-path.s
@@ -0,0 +1,49 @@
+# REQUIRES: x86
+
+# RUN: rm -rf %t && split-file %s %t && cd %t && mkdir 32bit 64bit
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu main.s -o main.o
+# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux-gnu ref.s -o 32bit/ref.o && ld.lld -shared 32bit/ref.o -o 32bit/libref.so
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu ref.s -o 64bit/ref.o && ld.lld -shared 64bit/ref.o -o 64bit/libref.so
+
+# One error formatted library
+# RUN: not ld.lld main.o -lref -L32bit -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -l:libref.so -L32bit -o /dev/null 2>&1 | FileCheck %s
+
+# Format not specified and the checkFile function is in default.
+# RUN: not ld.lld main.o -lref -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -l:libref.so -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s
+
+# Format not specified and the checkFile function is closed
+# RUN: not ld.lld main.o -no-check-format -lref -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -no-check-format -l:libref.so -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s
+
+# Specified format and the checkFile function is closed
+# RUN: not ld.lld -m elf_x86_64 -no-check-format main.o -lref -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR
+# RUN: not ld.lld -m elf_x86_64 -no-check-format main.o -l:libref.so -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR
+
+# Specified format and the checkFile function is in default with one error libary
+# RUN: not ld.lld -m elf_x86_64 main.o -lref -L32bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNTWO
+# RUN: not ld.lld -m elf_x86_64 main.o -l:libref.so -L32bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNONE
+
+# Specified format and the checkFile function is in default
+# RUN: ld.lld -m elf_x86_64 main.o -lref -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+# RUN: ld.lld -m elf_x86_64 main.o -l:libref.so -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+
+# CHECK-NOT: error:
+# CHECK: error: 32bit/libref.so is incompatible with main.o
+
+# UNONE: warning: 32bit/libref.so is incompatible with elf_x86_64
+# UNONE: error: unable to find library -l:libref.so
+# UNTWO: warning: 32bit/libref.so is incompatible with elf_x86_64
+# UNTWO: error: unable to find library -lref
+# ERROR: error: 32bit/libref.so is incompatible with elf_x86_64
+# WARN: warning: 32bit/libref.so is incompatible with elf_x86_64
+
+#--- ref.s
+.globl fun
+fun:
+ nop
+#--- main.s
+.global _start
+_start:
+ call fun
>From 692b2803516c0cb9e8017dffccd58276e2e8391f Mon Sep 17 00:00:00 2001
From: W-50243 <wanghao636 at huawei.com>
Date: Sun, 21 Jan 2024 11:39:12 +0800
Subject: [PATCH 2/2] [lld] check the format of libary and skip the wrong one
---
lld/ELF/Config.h | 3 +-
lld/ELF/Driver.cpp | 81 +++++++++++++++++++++++++++++++++
lld/ELF/DriverUtils.cpp | 9 ++--
lld/ELF/Options.td | 4 ++
lld/test/ELF/aarch64-lld-path.s | 49 ++++++++++++++++++++
lld/test/ELF/x86-lld-path.s | 49 ++++++++++++++++++++
6 files changed, 191 insertions(+), 4 deletions(-)
create mode 100644 lld/test/ELF/aarch64-lld-path.s
create mode 100644 lld/test/ELF/x86-lld-path.s
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 56229334f9a44a..1bb12b955f0535 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -122,6 +122,7 @@ class LinkerDriver {
void linkerMain(ArrayRef<const char *> args);
void addFile(StringRef path, bool withLOption);
void addLibrary(StringRef name);
+ bool checkFile(StringRef name);
private:
void createFiles(llvm::opt::InputArgList &args);
@@ -424,11 +425,11 @@ struct Config {
// not supported on Android 11 & 12.
bool androidMemtagStack;
+ bool CheckFormat = true;
// When using a unified pre-link LTO pipeline, specify the backend LTO mode.
LtoKind ltoKind = LtoKind::Default;
unsigned threadCount;
-
// If an input file equals a key, remap it to the value.
llvm::DenseMap<llvm::StringRef, llvm::StringRef> remapInputs;
// If an input file matches a wildcard pattern, remap it to the value.
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 07f4263c90e62b..28d74774331618 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -82,6 +82,7 @@ Ctx elf::ctx;
static void setConfigs(opt::InputArgList &args);
static void readConfigs(opt::InputArgList &args);
+static bool checkFileFormat(InputFile *file);
void elf::errorOrWarn(const Twine &msg) {
if (config->noinhibitExec)
@@ -1219,6 +1220,9 @@ static void readConfigs(opt::InputArgList &args) {
errorHandler().vsDiagnostics =
args.hasArg(OPT_visual_studio_diagnostics_format, false);
+ config->CheckFormat =
+ args.hasFlag(OPT_check_format, OPT_no_check_format, true);
+
config->allowMultipleDefinition =
args.hasFlag(OPT_allow_multiple_definition,
OPT_no_allow_multiple_definition, false) ||
@@ -3070,3 +3074,80 @@ void LinkerDriver::link(opt::InputArgList &args) {
// Write the result to the file.
invokeELFT(writeResult,);
}
+
+static bool checkFileFormat(InputFile *file) {
+ if (!file->isElf() && !isa<BitcodeFile>(file))
+ return true;
+
+ if (file->ekind == config->ekind && file->emachine == config->emachine) {
+ if (config->emachine != EM_MIPS)
+ return true;
+ if (isMipsN32Abi(file) == config->mipsN32Abi)
+ return true;
+ }
+
+ StringRef target =
+ !config->bfdname.empty() ? config->bfdname : config->emulation;
+ warn(toString(file) + " is incompatible with " + target);
+ return false;
+}
+
+bool LinkerDriver::checkFile(StringRef path) {
+ using namespace sys::fs;
+ if (config->ekind == ELFNoneKind || !config->CheckFormat)
+ return true;
+
+ Optional<MemoryBufferRef> buffer = readFile(path);
+ if (!buffer)
+ return false;
+
+ MemoryBufferRef mbref = *buffer;
+
+ switch(identify_magic(mbref.getBuffer())){
+ case file_magic::unknown:
+ return true;
+ case file_magic::archive: {
+ auto members = getArchiveMembers(mbref);
+ if (inWholeArchive) {
+ for (const auto &p : members) {
+ bool SingleFile = isBitcode(p.first)
+ ? checkFileFormat(make<BitcodeFile>(
+ p.first, path, p.second, false))
+ : checkFileFormat(createObjFile(p.first, path));
+ return SingleFile;
+ }
+ }
+ for (const auto &p : members) {
+ switch (identify_magic(p.first.getBuffer())) {
+ case file_magic::elf_relocatable:
+ if (!checkFileFormat(createObjFile(p.first, path, true)))
+ return false;
+ break;
+ case file_magic::bitcode:
+ if (!checkFileFormat(make<BitcodeFile>(p.first, path, p.second, true)))
+ return false;
+ break;
+ default: {
+ warn(path + ": archive member '" + p.first.getBufferIdentifier() +
+ "' is neither ET_REL nor LLVM bitcode");
+ }
+ }
+ }
+ return true;
+ }
+ case file_magic::elf_shared_object:
+ if (config->isStatic || config->relocatable) {
+ warn("attempted static link of dynamic object " + path);
+ return false;
+ }
+ path = mbref.getBufferIdentifier();
+ return checkFileFormat(make<SharedFile>(mbref, path));
+ case file_magic::bitcode:
+ return checkFileFormat(make<BitcodeFile>(mbref, "", 0, inLib));
+ case file_magic::elf_relocatable:
+ return checkFileFormat(createObjFile(mbref, "", inLib));
+ default:
+ warn(path + ": unknown file type");
+ return false;
+ }
+}
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index 0a27422e3b2df8..da6426549c5117 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -225,7 +225,8 @@ static std::optional<std::string> findFile(StringRef path1,
std::optional<std::string> elf::findFromSearchPaths(StringRef path) {
for (StringRef dir : config->searchPaths)
if (std::optional<std::string> s = findFile(dir, path))
- return s;
+ if (driver->checkFile(*s))
+ return s;
return std::nullopt;
}
@@ -235,9 +236,11 @@ std::optional<std::string> elf::searchLibraryBaseName(StringRef name) {
for (StringRef dir : config->searchPaths) {
if (!config->isStatic)
if (std::optional<std::string> s = findFile(dir, "lib" + name + ".so"))
- return s;
+ if (driver->checkFile(*s))
+ return s;
if (std::optional<std::string> s = findFile(dir, "lib" + name + ".a"))
- return s;
+ if (driver->checkFile(*s))
+ return s;
}
return std::nullopt;
}
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index c2c9cabc92a4da..141e6494600077 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -229,6 +229,10 @@ defm fatal_warnings: B<"fatal-warnings",
"Treat warnings as errors",
"Do not treat warnings as errors (default)">;
+defm check_format: B<"check-format",
+ "Please check the file format(default)",
+ "Please not check the file format">;
+
defm filter: Eq<"filter", "Set DT_FILTER field to the specified name">;
defm fini: Eq<"fini", "Specify a finalizer function">, MetaVarName<"<symbol>">;
diff --git a/lld/test/ELF/aarch64-lld-path.s b/lld/test/ELF/aarch64-lld-path.s
new file mode 100644
index 00000000000000..b17d7791fa040d
--- /dev/null
+++ b/lld/test/ELF/aarch64-lld-path.s
@@ -0,0 +1,49 @@
+# REQUIRES: aarch64
+
+# RUN: rm -rf %t && split-file %s %t && cd %t && mkdir be le
+# RUN: llvm-mc -filetype=obj -triple=aarch64 main.s -o main.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64 ref.s -o le/ref.o && ld.lld -shared le/ref.o -o le/libref.so
+# RUN: llvm-mc -filetype=obj -triple=aarch64_be ref.s -o be/ref.o && ld.lld -shared be/ref.o -o be/libref.so
+
+# One error formatted library
+# RUN: not ld.lld main.o -lref -Lbe -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -l:libref.so -Lbe -o /dev/null 2>&1 | FileCheck %s
+
+# Format not specified and the checkFile function is in default.
+# RUN: not ld.lld main.o -lref -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -l:libref.so -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s
+
+# Format not specified and the checkFile function is closed
+# RUN: not ld.lld main.o -no-check-format -lref -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -no-check-format -l:libref.so -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s
+
+# Specified format and the checkFile function is closed
+# RUN: not ld.lld -m aarch64linux -no-check-format main.o -lref -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR
+# RUN: not ld.lld -m aarch64linux -no-check-format main.o -l:libref.so -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR
+
+# Specified format and the checkFile function is in default with one error libary
+# RUN: not ld.lld -m aarch64linux main.o -lref -Lbe -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNTWO
+# RUN: not ld.lld -m aarch64linux main.o -l:libref.so -Lbe -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNONE
+
+# Specified format and the checkFile function is in default
+# RUN: ld.lld -m aarch64linux main.o -lref -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+# RUN: ld.lld -m aarch64linux main.o -l:libref.so -Lbe -Lle -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+
+# CHECK-NOT: error:
+# CHECK: error: be/libref.so is incompatible with main.o
+
+# UNONE: warning: be/libref.so is incompatible with aarch64linux
+# UNONE: error: unable to find library -l:libref.so
+# UNTWO: warning: be/libref.so is incompatible with aarch64linux
+# UNTWO: error: unable to find library -lref
+# ERROR: error: be/libref.so is incompatible with aarch64linux
+# WARN: warning: be/libref.so is incompatible with aarch64linux
+
+#--- ref.s
+.globl fun
+fun:
+ nop
+#--- main.s
+.globl _start
+_start:
+ bl fun at PLT
\ No newline at end of file
diff --git a/lld/test/ELF/x86-lld-path.s b/lld/test/ELF/x86-lld-path.s
new file mode 100644
index 00000000000000..7b80b1328d3fbf
--- /dev/null
+++ b/lld/test/ELF/x86-lld-path.s
@@ -0,0 +1,49 @@
+# REQUIRES: x86
+
+# RUN: rm -rf %t && split-file %s %t && cd %t && mkdir 32bit 64bit
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu main.s -o main.o
+# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux-gnu ref.s -o 32bit/ref.o && ld.lld -shared 32bit/ref.o -o 32bit/libref.so
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu ref.s -o 64bit/ref.o && ld.lld -shared 64bit/ref.o -o 64bit/libref.so
+
+# One error formatted library
+# RUN: not ld.lld main.o -lref -L32bit -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -l:libref.so -L32bit -o /dev/null 2>&1 | FileCheck %s
+
+# Format not specified and the checkFile function is in default.
+# RUN: not ld.lld main.o -lref -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -l:libref.so -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s
+
+# Format not specified and the checkFile function is closed
+# RUN: not ld.lld main.o -no-check-format -lref -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld main.o -no-check-format -l:libref.so -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s
+
+# Specified format and the checkFile function is closed
+# RUN: not ld.lld -m elf_x86_64 -no-check-format main.o -lref -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR
+# RUN: not ld.lld -m elf_x86_64 -no-check-format main.o -l:libref.so -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR
+
+# Specified format and the checkFile function is in default with one error libary
+# RUN: not ld.lld -m elf_x86_64 main.o -lref -L32bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNTWO
+# RUN: not ld.lld -m elf_x86_64 main.o -l:libref.so -L32bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNONE
+
+# Specified format and the checkFile function is in default
+# RUN: ld.lld -m elf_x86_64 main.o -lref -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+# RUN: ld.lld -m elf_x86_64 main.o -l:libref.so -L32bit -L64bit -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
+
+# CHECK-NOT: error:
+# CHECK: error: 32bit/libref.so is incompatible with main.o
+
+# UNONE: warning: 32bit/libref.so is incompatible with elf_x86_64
+# UNONE: error: unable to find library -l:libref.so
+# UNTWO: warning: 32bit/libref.so is incompatible with elf_x86_64
+# UNTWO: error: unable to find library -lref
+# ERROR: error: 32bit/libref.so is incompatible with elf_x86_64
+# WARN: warning: 32bit/libref.so is incompatible with elf_x86_64
+
+#--- ref.s
+.globl fun
+fun:
+ nop
+#--- main.s
+.global _start
+_start:
+ call fun
More information about the llvm-commits
mailing list