[clang-tools-extra] [llvm] [lld] [lld/ELF] Hint if R_X86_64_PC32 overflows and references a SHF_X86_64_LARGE section (PR #73045)

Arthur Eubanks via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 17 15:30:17 PST 2024


https://github.com/aeubanks updated https://github.com/llvm/llvm-project/pull/73045

>From 0145020ef2a803ec797e42f95bacde05dc32eac1 Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Tue, 21 Nov 2023 14:01:04 -0800
Subject: [PATCH 1/3] [lld/ELF] Hint if R_X86_64_PC32 overflows and references
 a SHF_X86_64_LARGE section

Makes it clearer what the issue is when hand-written assembly doesn't follow medium code model assumptions in a medium code model build.

Alternative to #71248 by only hinting on an overflow.
---
 lld/ELF/Relocations.cpp                   |  6 ++++++
 lld/test/ELF/x86-64-pc32-overflow-large.s | 25 +++++++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 lld/test/ELF/x86-64-pc32-overflow-large.s

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index fe3d7f419e84aa6..37a2363094020d0 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -105,6 +105,12 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
       hint = "; references '" + lld::toString(*rel.sym) + '\'';
     else if (auto *d = dyn_cast<Defined>(rel.sym))
       hint = ("; references section '" + d->section->name + "'").str();
+
+    if (rel.type == R_X86_64_PC32 && rel.sym->getOutputSection() &&
+        (rel.sym->getOutputSection()->flags & SHF_X86_64_LARGE)) {
+      hint += "; a R_X86_64_PC32 relocation should not reference a section "
+              "marked SHF_X86_64_LARGE";
+    }
   }
   if (!errPlace.srcLoc.empty())
     hint += "\n>>> referenced by " + errPlace.srcLoc;
diff --git a/lld/test/ELF/x86-64-pc32-overflow-large.s b/lld/test/ELF/x86-64-pc32-overflow-large.s
new file mode 100644
index 000000000000000..54c20eddfd04c33
--- /dev/null
+++ b/lld/test/ELF/x86-64-pc32-overflow-large.s
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o
+# RUN: not ld.lld %t/a.o -T %t/lds -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK: error: {{.*}}a.o:(.text+{{.*}}): relocation R_X86_64_PC32 out of range: {{.*}}; a R_X86_64_PC32 relocation should not reference a section marked SHF_X86_64_LARGE
+
+#--- a.s
+.text
+.globl _start
+.type _start, @function
+_start:
+  movq hello(%rip), %rax
+
+.section ldata,"awl", at progbits
+.type   hello, @object
+.globl  hello
+hello:
+.long   1
+
+#--- lds
+SECTIONS {
+  .text 0x100000 : { *(.text) }
+  ldata 0x80200000 : { *(ldata) }
+}

>From a4432ade194df8dedb7b4990a29efaa4e822d486 Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Wed, 17 Jan 2024 19:20:39 +0000
Subject: [PATCH 2/3] check emachine

---
 lld/ELF/Relocations.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index e1e047c3d052427..10f62f21274239b 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -106,7 +106,8 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
     else if (auto *d = dyn_cast<Defined>(rel.sym))
       hint = ("; references section '" + d->section->name + "'").str();
 
-    if (rel.type == R_X86_64_PC32 && rel.sym->getOutputSection() &&
+    if (config->emachine == EM_X86_64 && rel.type == R_X86_64_PC32 &&
+        rel.sym->getOutputSection() &&
         (rel.sym->getOutputSection()->flags & SHF_X86_64_LARGE)) {
       hint += "; a R_X86_64_PC32 relocation should not reference a section "
               "marked SHF_X86_64_LARGE";

>From 4447d474587ebf06d8b778616ef8c96c7cbd3c46 Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Wed, 17 Jan 2024 23:29:55 +0000
Subject: [PATCH 3/3] update error message

---
 lld/ELF/Relocations.cpp                   | 4 ++--
 lld/test/ELF/x86-64-pc32-overflow-large.s | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 10f62f21274239b..59b022079587175 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -109,8 +109,8 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
     if (config->emachine == EM_X86_64 && rel.type == R_X86_64_PC32 &&
         rel.sym->getOutputSection() &&
         (rel.sym->getOutputSection()->flags & SHF_X86_64_LARGE)) {
-      hint += "; a R_X86_64_PC32 relocation should not reference a section "
-              "marked SHF_X86_64_LARGE";
+      hint += "; R_X86_64_PC32 should not reference a section marked "
+              "SHF_X86_64_LARGE";
     }
   }
   if (!errPlace.srcLoc.empty())
diff --git a/lld/test/ELF/x86-64-pc32-overflow-large.s b/lld/test/ELF/x86-64-pc32-overflow-large.s
index 54c20eddfd04c33..fb8f3e4480c40f5 100644
--- a/lld/test/ELF/x86-64-pc32-overflow-large.s
+++ b/lld/test/ELF/x86-64-pc32-overflow-large.s
@@ -3,7 +3,7 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o
 # RUN: not ld.lld %t/a.o -T %t/lds -o /dev/null 2>&1 | FileCheck %s
 
-# CHECK: error: {{.*}}a.o:(.text+{{.*}}): relocation R_X86_64_PC32 out of range: {{.*}}; a R_X86_64_PC32 relocation should not reference a section marked SHF_X86_64_LARGE
+# CHECK: error: {{.*}}a.o:(.text+{{.*}}): relocation R_X86_64_PC32 out of range: {{.*}}; R_X86_64_PC32 should not reference a section marked SHF_X86_64_LARGE
 
 #--- a.s
 .text



More information about the cfe-commits mailing list