LLD/AMDGPU: Preserve ABI version during linking ELF for AMDGPU
authorKonstantin Zhuravlyov <kzhuravl_dev@outlook.com>
Thu, 14 Feb 2019 23:59:44 +0000 (23:59 +0000)
committerKonstantin Zhuravlyov <kzhuravl_dev@outlook.com>
Thu, 14 Feb 2019 23:59:44 +0000 (23:59 +0000)
Differential Revision: https://reviews.llvm.org/D58026

llvm-svn: 354086

lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/ELF/Writer.cpp
lld/test/ELF/amdgpu-abi-version-err.s [new file with mode: 0644]
lld/test/ELF/amdgpu-abi-version.s [new file with mode: 0644]

index c3e5b2f..2f0b5df 100644 (file)
@@ -239,6 +239,7 @@ ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
 
   EMachine = getObj().getHeader()->e_machine;
   OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
+  ABIVersion = getObj().getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
 }
 
 template <class ELFT>
index 105e5ec..b786042 100644 (file)
@@ -103,6 +103,7 @@ public:
   ELFKind EKind = ELFNoneKind;
   uint16_t EMachine = llvm::ELF::EM_NONE;
   uint8_t OSABI = 0;
+  uint8_t ABIVersion = 0;
 
   // Cache for toString(). Only toString() should use this member.
   mutable std::string ToStringCache;
index 42c1c0b..c48c4bf 100644 (file)
@@ -2384,9 +2384,21 @@ static uint16_t getELFType() {
 
 static uint8_t getAbiVersion() {
   // MIPS non-PIC executable gets ABI version 1.
-  if (Config->EMachine == EM_MIPS && getELFType() == ET_EXEC &&
-      (Config->EFlags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
-    return 1;
+  if (Config->EMachine == EM_MIPS) {
+    if (getELFType() == ET_EXEC &&
+        (Config->EFlags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
+      return 1;
+    return 0;
+  }
+
+  if (Config->EMachine == EM_AMDGPU) {
+    uint8_t Ver = ObjectFiles[0]->ABIVersion;
+    for (InputFile *File : makeArrayRef(ObjectFiles).slice(1))
+      if (File->ABIVersion != Ver)
+        error("incompatible ABI version: " + toString(File));
+    return Ver;
+  }
+
   return 0;
 }
 
diff --git a/lld/test/ELF/amdgpu-abi-version-err.s b/lld/test/ELF/amdgpu-abi-version-err.s
new file mode 100644 (file)
index 0000000..a670ec7
--- /dev/null
@@ -0,0 +1,10 @@
+# REQUIRES: amdgpu
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx900 -filetype=obj %s -o %t-0.o
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx900 -mattr=-code-object-v3 -filetype=obj %s -o %t-1.o
+# RUN: not ld.lld -shared %t-0.o %t-1.o -o %t.so 2>&1 | FileCheck %s
+
+# CHECK: ld.lld: error: incompatible ABI version: {{.*}}-1.o
+
+.text
+  s_nop 0x0
+  s_endpgm
diff --git a/lld/test/ELF/amdgpu-abi-version.s b/lld/test/ELF/amdgpu-abi-version.s
new file mode 100644 (file)
index 0000000..4a6bf2d
--- /dev/null
@@ -0,0 +1,11 @@
+# REQUIRES: amdgpu
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx900 -filetype=obj %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t.so
+# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
+
+# CHECK: OS/ABI: AMDGPU_HSA (0x40)
+# CHECK: ABIVersion: 1
+
+.text
+  s_nop 0x0
+  s_endpgm