[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