[lld] [RISCV] Disable gp relaxation if part of object unreachable (PR #72655)

Nemanja Ivanovic via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 18 02:32:19 PST 2023


================
@@ -651,12 +651,38 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
   if (!isInt<12>(r.sym->getVA(r.addend) - gp->getVA()))
     return;
 
+  // The symbol may be accessed in multiple pieces with different addends.
+  // If we are relaxing the HI20 relocation, we need to ensure that we only
+  // relax (and delete the instruction) if all possible LO12 relocations
+  // that depend on it will be relaxable. The compiler will only access multiple
+  // pieces of an object with low relocations on the memory op if the alignment
+  // allows it. Therefore it should suffice to check that the smaller of the
+  // alignment and size can be reached from GP.
+  uint32_t alignAdjust =
+      r.sym->getOutputSection() ? r.sym->getOutputSection()->addralign : 0;
+  alignAdjust = std::min<uint32_t>(alignAdjust, r.sym->getSize());
+  if (alignAdjust)
+    alignAdjust--;
+
   switch (r.type) {
-  case R_RISCV_HI20:
+  case R_RISCV_HI20: {
+    uint64_t hiAddr = r.sym->getVA(r.addend);
+    // If the addend is zero, the LO12 relocations can only be accessing the
+    // range [base, base+alignAdjust] (where base == r.sym->getVA()).
+    if (r.addend == 0 && !isInt<12>(hiAddr + alignAdjust - gp->getVA()))
+      return;
+
+    // However, if the addend is non-zero, the LO12 relocations may be accessing
+    // the range [HI-alignAdjust-1, HI+alignAdjust].
+    if (r.addend != 0 && (!isInt<12>(hiAddr - alignAdjust - 1 - gp->getVA()) ||
----------------
nemanjai wrote:

I suppose we could check the negative range even in the `addend==0` case with the assumption that the compiler won't allow for out-of-bounds access as you describe here. This is just another one of those assumptions that the linker makes about what the compiler will or will not do.
There are of course other ways we can accomplish this:
- Disable relaxation if we see a negative addend on a `LO12` relaxation
- Keep track of symbols that are accessed with such negative addends and disable relaxation for relocations referencing those symbols
- Emit a fatal error if such a negative addend is used

https://github.com/llvm/llvm-project/pull/72655


More information about the llvm-commits mailing list