From 5e55cab89895c5a06a58b1dd17e7e3d126bad7ee Mon Sep 17 00:00:00 2001 From: Sam Elliott Date: Wed, 20 Nov 2024 08:01:51 -0800 Subject: [PATCH 1/2] [RISCV] Support Parsing Nonstandard Relocations 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` 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. --- llvm/include/llvm/BinaryFormat/ELF.h | 3 ++ .../ELFRelocs/RISCV_nonstandard.def | 30 +++++++++++++++++++ .../RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 5 +++- llvm/test/MC/RISCV/custom_reloc.s | 17 +++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 8abacf1b546a0..1bc69f791bd84 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -689,6 +689,9 @@ enum : unsigned { // ELF Relocation types for RISC-V enum { #include "ELFRelocs/RISCV.def" +#define ELF_RISCV_NONSTANDARD_RELOC(_vendor, name, value) name = value, +#include "ELFRelocs/RISCV_nonstandard.def" +#undef ELF_RISCV_NONSTANDARD_RELOC }; enum { 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 0000000000000..26631ddb6a52b --- /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_ABS20_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 eab4a5e77d96e..0cb1ef0a66b60 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -38,9 +38,12 @@ std::optional RISCVAsmBackend::getFixupKind(StringRef Name) const { if (STI.getTargetTriple().isOSBinFormatELF()) { unsigned Type; Type = llvm::StringSwitch(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 4bd470008ee52..740f36d6db5ca 100644 --- a/llvm/test/MC/RISCV/custom_reloc.s +++ b/llvm/test/MC/RISCV/custom_reloc.s @@ -34,3 +34,20 @@ nop # CHECK-ASM: nop # CHECK-OBJ: addi zero, zero, 0x0 + + .reloc ., R_RISCV_VENDOR, QUALCOMM + .reloc ., R_RISCV_QC_ABS20_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_ABS20_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 From c54aae4eba0501cc3e1ff08466309d3a9ab53662 Mon Sep 17 00:00:00 2001 From: Sam Elliott Date: Mon, 6 Jan 2025 02:21:20 -0800 Subject: [PATCH 2/2] fixup! [RISCV] Support Parsing Nonstandard Relocations --- .../ELFRelocs/RISCV_nonstandard.def | 24 +++++++++---------- llvm/test/MC/RISCV/custom_reloc.s | 8 +++---- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def index 26631ddb6a52b..7ae3d3f205772 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def @@ -10,20 +10,18 @@ #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. -*/ +// 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 */ +// Qualcomm Nonstandard Relocations ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_ABS20_U, 192) ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_BRANCH, 193) ELF_RISCV_NONSTANDARD_RELOC(QUALCOMM, R_RISCV_QC_E_32, 194) diff --git a/llvm/test/MC/RISCV/custom_reloc.s b/llvm/test/MC/RISCV/custom_reloc.s index 740f36d6db5ca..cdb819467875f 100644 --- a/llvm/test/MC/RISCV/custom_reloc.s +++ b/llvm/test/MC/RISCV/custom_reloc.s @@ -21,13 +21,13 @@ .reloc ., R_RISCV_VENDOR, VENDOR_NAME .reloc ., R_RISCV_CUSTOM192, my_foo + 1 addi a0, a0, 0 - # CHECK-ASM: [[L1:.L[^:]+]]: + # CHECK-ASM: [[L1:.L[^:]+]]: # CHECK-ASM-NEXT: .reloc [[L1]], R_RISCV_VENDOR, VENDOR_NAME # CHECK-ASM-NEXT: [[L2:.L[^:]+]]: # CHECK-ASM-NEXT: .reloc [[L2]], R_RISCV_CUSTOM192, my_foo+1 # CHECK-ASM-NEXT: mv a0, a0 - # CHECK-OBJ: addi a0, a0, 0 + # CHECK-OBJ: addi a0, a0, 0 # CHECK-OBJ-NEXT: R_RISCV_VENDOR VENDOR_NAME # CHECK-OBJ-NEXT: R_RISCV_CUSTOM192 my_foo+0x1 @@ -38,13 +38,13 @@ .reloc ., R_RISCV_VENDOR, QUALCOMM .reloc ., R_RISCV_QC_ABS20_U, my_bar + 2 addi a1, a1, 0 - # CHECK-ASM: [[L3:.L[^:]+]]: + # 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_ABS20_U, my_bar+2 # CHECK-ASM-NEXT: mv a1, a1 - # CHECK-OBJ: addi a1, a1, 0 + # CHECK-OBJ: addi a1, a1, 0 # CHECK-OBJ-NEXT: R_RISCV_VENDOR QUALCOMM # CHECK-OBJ-NEXT: R_RISCV_CUSTOM192 my_bar+0x2