[lld] [wip][LLD] Support RISCV vendor-specific relocations. (PR #168497)
Sam Elliott via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 18 00:56:41 PST 2025
================
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_ELF_ARCH_RISCVINTERNALRELOCATIONS_H
+#define LLD_ELF_ARCH_RISCVINTERNALRELOCATIONS_H
+
+#include "Relocations.h"
+#include "Symbols.h"
+
+namespace lld::elf {
+
+// Bit 8 of RelType is used to indicate linker-internal relocations that are
+// not vendor-specific.
+// These are internal relocation numbers for GP/X0 relaxation. They aren't part
+// of the psABI spec.
+constexpr uint32_t INTERNAL_R_RISCV_GPREL_I = 256;
+constexpr uint32_t INTERNAL_R_RISCV_GPREL_S = 257;
+constexpr uint32_t INTERNAL_R_RISCV_X0REL_I = 258;
+constexpr uint32_t INTERNAL_R_RISCV_X0REL_S = 259;
+
+// Bits 9 -> 31 of RelType are used to indicate vendor-specific relocations.
+constexpr uint32_t INTERNAL_RISCV_VENDOR_MASK = 0xFFFFFFFF << 9;
+constexpr uint32_t INTERNAL_RISCV_VENDOR_QUALCOMM = 1 << 9;
+constexpr uint32_t INTERNAL_RISCV_VENDOR_ANDES = 1 << 10;
----------------
lenary wrote:
Why does this need to be a mask? No relocation should have both bits set, right?
Surely we can effectively do this by viewing the 32-bit field as a 8 bit field (at the lsbs) and a 24-bit field (the msbs), where the 24-bit field is 0 for standard relocations, 1 for internal relocations, and 2+ for vendor relocations. I don't think we'll need to be more efficient than that, even though each vendor can only have 64 relocations, not 256.
I tried something more complex in ELD, which in retrospect was too clever.
```suggestion
constexpr uint32_t INTERNAL_RISCV_MASK = 0xFFFFFF << 8;
constexpr uint32_t INTERNAL_RISCV_INTERNAL = 1 << 8;
constexpr uint32_t INTERNAL_RISCV_VENDOR_QUALCOMM = 2 << 8;
constexpr uint32_t INTERNAL_RISCV_VENDOR_ANDES = 3 << 8;
constexpr uint32_t INTERNAL_R_RISCV_GPREL_I = INTERNAL_RISCV_INTERNAL | 0;
constexpr uint32_t INTERNAL_R_RISCV_GPREL_S = INTERNAL_RISCV_INTERNAL | 1;
constexpr uint32_t INTERNAL_R_RISCV_X0REL_I = INTERNAL_RISCV_INTERNAL | 2;
constexpr uint32_t INTERNAL_R_RISCV_X0REL_S = INTERNAL_RISCV_INTERNAL | 3;
```
https://github.com/llvm/llvm-project/pull/168497
More information about the llvm-commits
mailing list