Skip to content

[RISCV] Support Parsing Nonstandard Relocations #119909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 7, 2025

Conversation

lenary
Copy link
Member

@lenary lenary commented Dec 13, 2024

This allows nonstandard relocation names to be used in .reloc assembly directives (giving the correct relocation number).

No translation is done by the assembler into R_RISCV_CUSTOM<n> names, and the assembler does not automatically add the relevant R_RISCV_VENDOR relocation with the vendor symbol. If we want, we can have a different directive that does this later.

The first batch of relocations to be added are from Qualcomm's RISC-V psABI extensions.

@llvmbot
Copy link
Member

llvmbot commented Dec 13, 2024

@llvm/pr-subscribers-mc
@llvm/pr-subscribers-backend-risc-v

@llvm/pr-subscribers-llvm-binary-utilities

Author: Sam Elliott (lenary)

Changes

This allows nonstandard relocation names to be used in .reloc assembly directives (giving the correct relocation number).

No translation is done by the assembler into R_RISCV_CUSTOM&lt;n&gt; names, and the assembler does not automatically add the relevant R_RISCV_VENDOR relocation with the vendor symbol. If we want, we can have a different directive that does this later.

The first batch of relocations to be added are from Qualcomm's RISC-V psABI extensions.


Full diff: https://github.com/llvm/llvm-project/pull/119909.diff

3 Files Affected:

  • (added) llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def (+30)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp (+4-1)
  • (modified) llvm/test/MC/RISCV/custom_reloc.s (+17)
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def
new file mode 100644
index 00000000000000..8a9f856f196b5f
--- /dev/null
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def
@@ -0,0 +1,30 @@
+//===--- RISC-V Nonstandard Relocation List ---------------------*- C++ -*-===//
+//
+// 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 ELF_RISCV_NONSTANDARD_RELOC
+#error "ELF_RISCV_NONSTANDARD_RELOC must be defined"
+#endif
+
+/*
+  ELF_RISCV_NONSTANDARD_RELOC(VENDOR, NAME, ID) defines information about
+  nonstandard relocation codes. This can be used when parsing relocations, or
+  when printing them, to provide better information.
+
+  VENDOR should be the symbol name expected in the associated `R_RISCV_VENDOR`
+  relocation. NAME and ID work like `ELF_RELOC` but the mapping is not expected
+  to be 1:1.
+
+  The mapping in RISCV.def is 1:1, and should be used when the only information
+  available is the relocation enum value.
+*/
+
+/* Qualcomm Nonstandard Relocations */
+ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_LO20_U,     192)
+ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_BRANCH,   193)
+ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_32,       194)
+ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_JUMP_PLT, 195)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index eab4a5e77d96e5..0cb1ef0a66b60b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -38,9 +38,12 @@ std::optional<MCFixupKind> RISCVAsmBackend::getFixupKind(StringRef Name) const {
   if (STI.getTargetTriple().isOSBinFormatELF()) {
     unsigned Type;
     Type = llvm::StringSwitch<unsigned>(Name)
-#define ELF_RELOC(X, Y) .Case(#X, Y)
+#define ELF_RELOC(NAME, ID) .Case(#NAME, ID)
 #include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
 #undef ELF_RELOC
+#define ELF_RISCV_NONSTANDARD_RELOC(_VENDOR, NAME, ID) .Case(#NAME, ID)
+#include "llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def"
+#undef ELF_RISCV_NONSTANDARD_RELOC
                .Case("BFD_RELOC_NONE", ELF::R_RISCV_NONE)
                .Case("BFD_RELOC_32", ELF::R_RISCV_32)
                .Case("BFD_RELOC_64", ELF::R_RISCV_64)
diff --git a/llvm/test/MC/RISCV/custom_reloc.s b/llvm/test/MC/RISCV/custom_reloc.s
index d6fea8fac36713..feb6bd371e65a8 100644
--- a/llvm/test/MC/RISCV/custom_reloc.s
+++ b/llvm/test/MC/RISCV/custom_reloc.s
@@ -33,3 +33,20 @@
   nop
   # CHECK-ASM: nop
   # CHECK-OBJ: addi zero, zero, 0x0
+
+  .reloc ., R_RISCV_VENDOR,    QUALCOMM
+  .reloc ., R_RISCV_QC_LO20_U, my_bar + 2
+  addi a1, a1, 0
+  # CHECK-ASM: [[L3:.L[^:]+]]:
+  # CHECK-ASM-NEXT: .reloc [[L3]], R_RISCV_VENDOR, QUALCOMM
+  # CHECK-ASM-NEXT: [[L4:.L[^:]+]]:
+  # CHECK-ASM-NEXT: .reloc [[L4]], R_RISCV_QC_LO20_U, my_bar+2
+  # CHECK-ASM-NEXT: mv a1, a1
+
+  # CHECK-OBJ: addi a1, a1, 0
+  # CHECK-OBJ-NEXT: R_RISCV_VENDOR    QUALCOMM
+  # CHECK-OBJ-NEXT: R_RISCV_CUSTOM192 my_bar+0x2
+
+  nop
+  # CHECK-ASM: nop
+  # CHECK-OBJ: addi zero, zero, 0x0

# CHECK-ASM: [[L3:.L[^:]+]]:
# CHECK-ASM-NEXT: .reloc [[L3]], R_RISCV_VENDOR, QUALCOMM
# CHECK-ASM-NEXT: [[L4:.L[^:]+]]:
# CHECK-ASM-NEXT: .reloc [[L4]], R_RISCV_QC_LO20_U, my_bar+2
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assembly streamer here just re-emits the string which it was passed from the directive parser in the call. I don't know if we want to do anything to normalise this into R_RISCV_CUSTOM<n> - it's a possibility.

This allows nonstandard relocation names to be used in `.reloc` assembly
directives (giving the correct relocation number).

No translation is done by the assembler into `R_RISCV_CUSTOM<n>` names,
and the assembler does not automatically add the relevant
`R_RISCV_VENDOR` relocation with the vendor symbol. If we want, we can
have a different directive that does this later.

The first batch of relocations to be added are from Qualcomm's RISC-V
psABI extensions.
@lenary lenary force-pushed the pr/riscv-vendor-relocs branch from c64a3ff to 5e55cab Compare January 2, 2025 16:35
@lenary
Copy link
Member Author

lenary commented Jan 2, 2025

Updated with the new relocation name from quic/riscv-elf-psabi-quic-extensions@50f54da and included these names in the RISC-V elf relocation code enum so future code can be a bit clearer.

Copy link
Contributor

@svs-quic svs-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but please wait for someone else to review before merging.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

#endif

/*
ELF_RISCV_NONSTANDARD_RELOC(VENDOR, NAME, ID) defines information about
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer //

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

available is the relocation enum value.
*/

/* Qualcomm Nonstandard Relocations */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

.reloc ., R_RISCV_VENDOR, QUALCOMM
.reloc ., R_RISCV_QC_ABS20_U, my_bar + 2
addi a1, a1, 0
# CHECK-ASM: [[L3:.L[^:]+]]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ASM: line, shorter than the next line by 5, should be indented to align with the following lines

ditto below

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@lenary lenary merged commit 525f526 into llvm:main Jan 7, 2025
8 checks passed
@lenary lenary deleted the pr/riscv-vendor-relocs branch January 7, 2025 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants