[lld] [lld] Fix ILP32 ABI checks for bitcode files. (PR #116537)

Alex Rønne Petersen via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 27 11:51:37 PST 2024


https://github.com/alexrp updated https://github.com/llvm/llvm-project/pull/116537

>From 59c50cf652e15112ed688fbe52f4d2080c65c867 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= <alex at alexrp.com>
Date: Sun, 17 Nov 2024 08:54:47 +0100
Subject: [PATCH] [lld] Fix ILP32 ABI checks for bitcode files.

Previously, using LTO with the MIPS N32 ABI and (e.g.) -m elf32btsmipn32 would
fail because isN32Abi() made no effort to check whether a bitcode file is using
the N32 ABI. Additionally, getBitcodeELFKind() would incorrectly pick 64-bit ELF
for all ILP32 ABIs (not just N32).
---
 lld/ELF/Arch/MipsArchTree.cpp |  2 ++
 lld/ELF/InputFiles.cpp        | 16 +++++++++-------
 lld/ELF/InputFiles.h          |  3 +++
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/lld/ELF/Arch/MipsArchTree.cpp b/lld/ELF/Arch/MipsArchTree.cpp
index 197cb30cdb8a56..e3cb26d7d8c8d3 100644
--- a/lld/ELF/Arch/MipsArchTree.cpp
+++ b/lld/ELF/Arch/MipsArchTree.cpp
@@ -363,6 +363,8 @@ uint8_t elf::getMipsFpAbiFlag(Ctx &ctx, InputFile *file, uint8_t oldFlag,
 template <class ELFT> static bool isN32Abi(const InputFile &f) {
   if (auto *ef = dyn_cast<ELFFileBase>(&f))
     return ef->template getObj<ELFT>().getHeader().e_flags & EF_MIPS_ABI2;
+  if (auto *bc = dyn_cast<BitcodeFile>(&f))
+    return bc->triple.isABIN32();
   return false;
 }
 
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 83a25e1b66cff0..b27de2e31b24ca 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1637,9 +1637,10 @@ template <class ELFT> void SharedFile::parse() {
 }
 
 static ELFKind getBitcodeELFKind(const Triple &t) {
-  if (t.isLittleEndian())
-    return t.isArch64Bit() ? ELF64LEKind : ELF32LEKind;
-  return t.isArch64Bit() ? ELF64BEKind : ELF32BEKind;
+  if (t.isArch64Bit() && !t.isABIN32() && !t.isX32() &&
+      t.getEnvironment() != Triple::GNUILP32)
+    return t.isLittleEndian() ? ELF64LEKind : ELF64BEKind;
+  return t.isLittleEndian() ? ELF32LEKind : ELF32BEKind;
 }
 
 static uint16_t getBitcodeMachineKind(Ctx &ctx, StringRef path,
@@ -1733,10 +1734,11 @@ BitcodeFile::BitcodeFile(Ctx &ctx, MemoryBufferRef mb, StringRef archiveName,
 
   obj = CHECK2(lto::InputFile::create(mbref), this);
 
-  Triple t(obj->getTargetTriple());
-  ekind = getBitcodeELFKind(t);
-  emachine = getBitcodeMachineKind(ctx, mb.getBufferIdentifier(), t);
-  osabi = getOsAbi(t);
+  this->triple = Triple(obj->getTargetTriple());
+
+  ekind = getBitcodeELFKind(this->triple);
+  emachine = getBitcodeMachineKind(ctx, mb.getBufferIdentifier(), this->triple);
+  osabi = getOsAbi(this->triple);
 }
 
 static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 9161fa13ad983c..f63500308616a8 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -19,6 +19,7 @@
 #include "llvm/Object/ELF.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/Threading.h"
+#include "llvm/TargetParser/Triple.h"
 
 namespace llvm {
 struct DILineInfo;
@@ -337,6 +338,8 @@ class BitcodeFile : public InputFile {
   void postParse();
   std::unique_ptr<llvm::lto::InputFile> obj;
   std::vector<bool> keptComdats;
+
+  llvm::Triple triple;
 };
 
 // .so file.



More information about the llvm-commits mailing list