[PATCH] D106378: RISCV: relax the ABI mismatch checking

Saleem Abdulrasool via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 20 09:42:19 PDT 2021


compnerd created this revision.
compnerd added a reviewer: MaskRay.
Herald added subscribers: vkmr, frasercrmck, evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, arichardson, emaste.
compnerd requested review of this revision.
Herald added a project: LLVM.

The linker validates that the inputs that it is merging follow the same
ABI restrictions (i.e. floating point ABI and RVE).  However, the check
is not required or applicable when the input does not have code content
such as a data file.  This relaxes the check to only perform the checks
when the input is non-empty and has loaded code sections.  This matches
the behaviour of the BFD linker and enables adding data files which may
have mismatched ABI tags.

This also changes the behaviour of the RVC tagging to match BFD: the RVC
flag is only preserved if the input contributes code to the final
binary.

Rewrite the flag checking to use XOR which feels easier to read than the
equality check.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106378

Files:
  lld/ELF/Arch/RISCV.cpp
  lld/test/ELF/riscv-abi-mismatch.test


Index: lld/test/ELF/riscv-abi-mismatch.test
===================================================================
--- /dev/null
+++ lld/test/ELF/riscv-abi-mismatch.test
@@ -0,0 +1,51 @@
+// RUN: split-file %s %t
+
+// RUN: llvm-mc -triple riscv64 -filetype obj -o %t/function.o %t/function.s
+
+// RUN: yaml2obj %t/empty-lp64d.yml -o %t/empty-lp64d.o
+// RUN: ld.lld -shared %t/function.o %t/empty-lp64d.o -o %t/libfloatabi.so
+// RUN: not ld.lld -shared %t/empty-lp64d.o %t/function.o -o %t/libfloatabi.so 2>&1 | FileCheck %t/function.s -check-prefix CHECK-FLOAT-MISMATCH
+
+// RUN: yaml2obj %t/empty-rvc.yml -o %t/empty-rvc.o
+// RUN: ld.lld -shared %t/function.o %t/empty-rvc.o -o %t/librvc.so
+// RUN: llvm-readobj -h %t/librvc.so | FileCheck %t/function.s -check-prefix CHECK-NORVC-FLAGS
+
+// RUN: yaml2obj %t/empty-rvc.yml -o %t/empty-rvc.o
+// RUN: ld.lld -shared %t/empty-rvc.o %t/function.o -o %t/librvc.so
+// RUN: llvm-readobj -h %t/librvc.so | FileCheck %t/function.s -check-prefix CHECK-RVC-FLAGS
+
+// REQUIRES: riscv
+
+//--- empty-lp64d.yml
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data: ELFDATA2LSB
+  Type: ET_REL
+  Machine: EM_RISCV
+  Flags: [ EF_RISCV_FLOAT_ABI_DOUBLE ]
+
+//--- empty-rvc.yml
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data: ELFDATA2LSB
+  Type: ET_REL
+  Machine: EM_RISCV
+  Flags: [ EF_RISCV_RVC ]
+
+//--- function.s
+	.text
+	.global function
+	.type function, at function
+function:
+    ret
+
+// CHECK-FLOAT-MISMATCH: function.o: cannot link object files with different floating-point ABI
+
+// CHECK-NORVC-FLAGS:       Flags [ (0x0)
+// CHECK-NORVC-FLAGS-NEXT:  ]
+
+// CHECK-RVC-FLAGS:       Flags [ (0x1)
+// CHECK-RVC-FLAGS-NEXT:    EF_RISCV_RVC (0x1)
+// CHECK-RVC-FLAGS-NEXT:  ]
Index: lld/ELF/Arch/RISCV.cpp
===================================================================
--- lld/ELF/Arch/RISCV.cpp
+++ lld/ELF/Arch/RISCV.cpp
@@ -120,16 +120,24 @@
 
   for (InputFile *f : objectFiles) {
     uint32_t eflags = getEFlags(f);
-    if (eflags & EF_RISCV_RVC)
-      target |= EF_RISCV_RVC;
-
-    if ((eflags & EF_RISCV_FLOAT_ABI) != (target & EF_RISCV_FLOAT_ABI))
-      error(toString(f) +
-            ": cannot link object files with different floating-point ABI");
-
-    if ((eflags & EF_RISCV_RVE) != (target & EF_RISCV_RVE))
-      error(toString(f) +
-            ": cannot link object files with different EF_RISCV_RVE");
+    auto sections = f->getSections();
+
+    // Only validate for non-empty inputs which contain code sections which are
+    // loaded.
+    if (sections.size() && llvm::any_of(sections, [](const auto *section) {
+          return (section && (section->flags & (SHF_ALLOC | SHF_EXECINSTR)));
+        })) {
+      if ((eflags ^ target) & EF_RISCV_FLOAT_ABI)
+        error(toString(f) +
+              ": cannot link object files with different floating-point ABI");
+
+      if ((eflags ^ target) & EF_RISCV_RVE)
+        error(toString(f) +
+              ": cannot link object files with different EF_RISCV_RVE");
+
+      if (eflags & EF_RISCV_RVC)
+        target |= EF_RISCV_RVC;
+    }
   }
 
   return target;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D106378.360177.patch
Type: text/x-patch
Size: 3115 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210720/95100b89/attachment.bin>


More information about the llvm-commits mailing list