[lld] 6edfda1 - [NFC][ELF][AArch64][MTE] Don't duplicate addRelativeReloc call for MTE globals

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 24 03:00:40 PST 2025


Author: Jessica Clarke
Date: 2025-12-24T11:00:36Z
New Revision: 6edfda169302df704b541b4d5b5c9996cb4adacd

URL: https://github.com/llvm/llvm-project/commit/6edfda169302df704b541b4d5b5c9996cb4adacd
DIFF: https://github.com/llvm/llvm-project/commit/6edfda169302df704b541b4d5b5c9996cb4adacd.diff

LOG: [NFC][ELF][AArch64][MTE] Don't duplicate addRelativeReloc call for MTE globals

This call to addRelativeReloc is the same as the one at the end of the
function, so skip the relrDyn code for this case and add the special
out-of-bounds handling code to the end of the function. This makes it
obvious where MTE globals differ in behaviour rather than having to
compare the two different implementations.

This also adds a comment documenting why relrDyn isn't used, and in it
highlights that it's probably safe to use relrDyn so long as the offset
is within the symbol's bounds.

Reviewers: pcc, kovdan01, MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/171181

Added: 
    

Modified: 
    lld/ELF/Relocations.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 0a386b0b8addc..d60216da2b03f 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -705,35 +705,36 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec,
                              RelExpr expr, RelType type) {
   Partition &part = isec.getPartition(ctx);
 
-  if (sym.isTagged()) {
-    part.relaDyn->addRelativeReloc<shard>(ctx.target->relativeRel, isec,
-                                          offsetInSec, sym, addend, type, expr);
-    // With MTE globals, we always want to derive the address tag by `ldg`-ing
-    // the symbol. When we have a RELATIVE relocation though, we no longer have
-    // a reference to the symbol. Because of this, when we have an addend that
-    // puts the result of the RELATIVE relocation out-of-bounds of the symbol
-    // (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI
-    // says we should store the offset to the start of the symbol in the target
-    // field. This is described in further detail in:
-    // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative
-    if (addend < 0 || static_cast<uint64_t>(addend) >= sym.getSize())
-      isec.addReloc({R_ADDEND_NEG, type, offsetInSec, addend, &sym});
-    return;
-  }
-
   // Add a relative relocation. If relrDyn section is enabled, and the
   // relocation offset is guaranteed to be even, add the relocation to
   // the relrDyn section, otherwise add it to the relaDyn section.
   // relrDyn sections don't support odd offsets. Also, relrDyn sections
   // don't store the addend values, so we must write it to the relocated
   // address.
-  if (part.relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) {
-    part.relrDyn->addRelativeReloc<shard>(isec, offsetInSec, sym, addend, type,
-                                          expr);
+  //
+  // MTE globals may need to store the original addend as well so cannot use
+  // relrDyn. TODO: It should be unambiguous when not using R_ADDEND_NEG below?
+  RelrBaseSection *relrDyn = part.relrDyn.get();
+  if (sym.isTagged())
+    relrDyn = nullptr;
+  if (relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) {
+    relrDyn->addRelativeReloc<shard>(isec, offsetInSec, sym, addend, type,
+                                     expr);
     return;
   }
   part.relaDyn->addRelativeReloc<shard>(ctx.target->relativeRel, isec,
                                         offsetInSec, sym, addend, type, expr);
+  // With MTE globals, we always want to derive the address tag by `ldg`-ing
+  // the symbol. When we have a RELATIVE relocation though, we no longer have
+  // a reference to the symbol. Because of this, when we have an addend that
+  // puts the result of the RELATIVE relocation out-of-bounds of the symbol
+  // (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI
+  // says we should store the offset to the start of the symbol in the target
+  // field. This is described in further detail in:
+  // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative
+  if (sym.isTagged() &&
+      (addend < 0 || static_cast<uint64_t>(addend) >= sym.getSize()))
+    isec.addReloc({R_ADDEND_NEG, type, offsetInSec, addend, &sym});
 }
 
 template <class PltSection, class GotPltSection>


        


More information about the llvm-commits mailing list