-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[LLD] Add support for statically resolved vendor-specific RISCV relocations. #169273
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
Conversation
…ations. This is achieved by using some of the bits of RelType to tag vendor namespaces. This change also adds a relocation iterator for RISCV that folds vendor namespaces into the RelType of the following relocation. This patch is extracted from the implementation of RISCV vendor-specific relocations in the CHERIoT LLVM downstream: CHERIoT-Platform/llvm-project@3d6d6f7
|
@llvm/pr-subscribers-lld @llvm/pr-subscribers-backend-risc-v Author: Owen Anderson (resistor) ChangesThis is achieved by using some of the bits of RelType to tag vendor namespaces. This patch is extracted from the implementation of RISCV vendor-specific relocations Full diff: https://github.com/llvm/llvm-project/pull/169273.diff 4 Files Affected:
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 5ed89e47c672e..b3a0f7e804020 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -8,6 +8,7 @@
#include "InputFiles.h"
#include "OutputSections.h"
+#include "RISCVInternalRelocations.h"
#include "RelocScan.h"
#include "Symbols.h"
#include "SyntheticSections.h"
@@ -345,8 +346,15 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
case R_RISCV_SUB_ULEB128:
return RE_RISCV_LEB128;
default:
- Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v
- << ") against symbol " << &s;
+ if (type.v & INTERNAL_RISCV_VENDOR_MASK) {
+ Err(ctx) << getErrorLoc(ctx, loc)
+ << "unsupported vendor-specific relocation " << type
+ << " against symbol " << &s;
+ return R_NONE;
+ }
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation ("
+ << (type.v & ~INTERNAL_RISCV_VENDOR_MASK) << ") against symbol "
+ << &s;
return R_NONE;
}
}
@@ -859,7 +867,7 @@ static bool relax(Ctx &ctx, int pass, InputSection &sec) {
std::fill_n(aux.relocTypes.get(), relocs.size(), R_RISCV_NONE);
aux.writes.clear();
- for (auto [i, r] : llvm::enumerate(relocs)) {
+ for (auto [i, r] : llvm::enumerate(riscv_vendor_relocs(relocs))) {
const uint64_t loc = secAddr + r.offset - delta;
uint32_t &cur = aux.relocDeltas[i], remove = 0;
switch (r.type) {
@@ -1503,12 +1511,18 @@ void RISCV::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
rvVendor = sym.getName();
continue;
} else if (!rvVendor.empty()) {
- Err(ctx) << getErrorLoc(ctx, loc)
- << "unknown vendor-specific relocation (" << type.v
- << ") in namespace '" << rvVendor << "' against symbol '" << &sym
- << "'";
+ uint32_t VendorFlag = getRISCVVendorRelMarker(rvVendor);
+ if (!VendorFlag) {
+ Err(ctx) << getErrorLoc(ctx, loc)
+ << "unknown vendor-specific relocation (" << type.v
+ << ") in namespace '" << rvVendor << "' against symbol '"
+ << &sym << "'";
+ rvVendor = "";
+ continue;
+ }
+
rvVendor = "";
- continue;
+ type.v |= VendorFlag;
}
rs.scan<ELFT, RelTy>(it, type, rs.getAddend<ELFT>(*it, type));
@@ -1533,3 +1547,21 @@ template <class ELFT> void RISCV::scanSection1(InputSectionBase &sec) {
void RISCV::scanSection(InputSectionBase &sec) {
invokeELFT(scanSection1, sec);
}
+
+namespace lld::elf {
+uint32_t getRISCVVendorRelMarker(StringRef rvVendor) {
+ return StringSwitch<uint32_t>(rvVendor)
+ .Case("QUALCOMM", INTERNAL_RISCV_VENDOR_QUALCOMM)
+ .Case("ANDES", INTERNAL_RISCV_VENDOR_ANDES)
+ .Default(0);
+}
+
+std::optional<StringRef> getRISCVVendorString(RelType ty) {
+ if ((ty.v & INTERNAL_RISCV_VENDOR_MASK) == INTERNAL_RISCV_VENDOR_QUALCOMM)
+ return "QUALCOMM";
+ if ((ty.v & INTERNAL_RISCV_VENDOR_MASK) == INTERNAL_RISCV_VENDOR_ANDES)
+ return "ANDES";
+ return std::nullopt;
+}
+
+} // namespace lld::elf
\ No newline at end of file
diff --git a/lld/ELF/Arch/RISCVInternalRelocations.h b/lld/ELF/Arch/RISCVInternalRelocations.h
new file mode 100644
index 0000000000000..3153dd0a3f9e7
--- /dev/null
+++ b/lld/ELF/Arch/RISCVInternalRelocations.h
@@ -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 = 2 << 9;
+
+constexpr uint32_t INTERNAL_RISCV_QC_ABS20_U =
+ INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_ABS20_U;
+constexpr uint32_t INTERNAL_RISCV_QC_E_BRANCH =
+ INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_BRANCH;
+constexpr uint32_t INTERNAL_RISCV_QC_E_32 =
+ INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_32;
+constexpr uint32_t INTERNAL_RISCV_QC_E_CALL_PLT =
+ INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_CALL_PLT;
+
+constexpr uint32_t INTERNAL_RISCV_NDS_BRANCH_10 =
+ INTERNAL_RISCV_VENDOR_ANDES | llvm::ELF::R_RISCV_NDS_BRANCH_10;
+
+uint32_t getRISCVVendorRelMarker(llvm::StringRef rvVendor);
+std::optional<llvm::StringRef> getRISCVVendorString(RelType ty);
+
+class vendor_reloc_iterator {
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = Relocation;
+ using difference_type = std::ptrdiff_t;
+ using pointer = Relocation *;
+ using reference = Relocation; // returned by value
+
+ vendor_reloc_iterator(MutableArrayRef<Relocation>::iterator i,
+ MutableArrayRef<Relocation>::iterator e)
+ : it(i), end(e) {}
+
+ // Dereference
+ Relocation operator*() const {
+ Relocation r = *it;
+ r.type.v |= rvVendorFlag;
+ return r;
+ }
+
+ struct vendor_reloc_proxy {
+ Relocation r;
+ const Relocation *operator->() const { return &r; }
+ };
+
+ vendor_reloc_proxy operator->() const {
+ return vendor_reloc_proxy{this->operator*()};
+ }
+
+ vendor_reloc_iterator &operator++() {
+ ++it;
+ if (it != end && it->type == llvm::ELF::R_RISCV_VENDOR) {
+ rvVendorFlag = getRISCVVendorRelMarker(it->sym->getName());
+ ++it;
+ } else {
+ rvVendorFlag = 0;
+ }
+ return *this;
+ }
+
+ vendor_reloc_iterator operator++(int) {
+ vendor_reloc_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ bool operator==(const vendor_reloc_iterator &other) const {
+ return it == other.it;
+ }
+ bool operator!=(const vendor_reloc_iterator &other) const {
+ return it != other.it;
+ }
+
+ Relocation *getUnderlyingRelocation() const { return &*it; }
+
+private:
+ MutableArrayRef<Relocation>::iterator it;
+ MutableArrayRef<Relocation>::iterator end;
+ uint32_t rvVendorFlag = 0;
+};
+
+inline auto riscv_vendor_relocs(MutableArrayRef<Relocation> arr) {
+ return llvm::make_range(vendor_reloc_iterator(arr.begin(), arr.end()),
+ vendor_reloc_iterator(arr.end(), arr.end()));
+}
+
+} // namespace lld::elf
+
+#endif
\ No newline at end of file
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 89e4dbeed3109..3fc3e3f16e9e0 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -24,6 +24,7 @@
//===----------------------------------------------------------------------===//
#include "Target.h"
+#include "Arch/RISCVInternalRelocations.h"
#include "InputFiles.h"
#include "OutputSections.h"
#include "RelocScan.h"
@@ -40,6 +41,14 @@ using namespace lld::elf;
std::string elf::toStr(Ctx &ctx, RelType type) {
StringRef s = getELFRelocationTypeName(ctx.arg.emachine, type);
+ if (ctx.arg.emachine == EM_RISCV && s == "Unknown") {
+ auto VendorString = getRISCVVendorString(type);
+ if (VendorString)
+ s = getRISCVVendorRelocationTypeName(type & ~INTERNAL_RISCV_VENDOR_MASK,
+ *VendorString);
+ if (s == "Unknown")
+ return ("Unknown vendor-specific (" + Twine(type) + ")").str();
+ }
if (s == "Unknown")
return ("Unknown (" + Twine(type) + ")").str();
return std::string(s);
diff --git a/lld/test/ELF/riscv-vendor-relocations.s b/lld/test/ELF/riscv-vendor-relocations.s
index b0f3c4a30d060..f121adec95cd0 100644
--- a/lld/test/ELF/riscv-vendor-relocations.s
+++ b/lld/test/ELF/riscv-vendor-relocations.s
@@ -8,12 +8,19 @@
TARGET:
nop
-.global INVALID_VENDOR
+.local INVALID_VENDOR
+.local QUALCOMM
+.local ANDES
.reloc 1f, R_RISCV_VENDOR, INVALID_VENDOR+0
.reloc 1f, R_RISCV_VENDOR, INVALID_VENDOR+0
.reloc 1f, R_RISCV_CUSTOM255, TARGET
-1:
- nop
-
# CHECK: error: {{.*}}:(.text+0x4): malformed consecutive R_RISCV_VENDOR relocations
# CHECK: error: {{.*}}:(.text+0x4): unknown vendor-specific relocation (255) in namespace 'INVALID_VENDOR' against symbol 'TARGET'
+.reloc 1f, R_RISCV_VENDOR, QUALCOMM+0
+.reloc 1f, R_RISCV_CUSTOM192, TARGET
+# CHECK: error: {{.*}}:(.text+0x4): unsupported vendor-specific relocation R_RISCV_QC_ABS20_U against symbol TARGET
+.reloc 1f, R_RISCV_VENDOR, ANDES+0
+.reloc 1f, R_RISCV_CUSTOM241, TARGET
+# CHECK: error: {{.*}}:(.text+0x4): unsupported vendor-specific relocation R_RISCV_NDS_BRANCH_10 against symbol TARGET
+1:
+ nop
|
|
@llvm/pr-subscribers-lld-elf Author: Owen Anderson (resistor) ChangesThis is achieved by using some of the bits of RelType to tag vendor namespaces. This patch is extracted from the implementation of RISCV vendor-specific relocations Full diff: https://github.com/llvm/llvm-project/pull/169273.diff 4 Files Affected:
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 5ed89e47c672e..b3a0f7e804020 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -8,6 +8,7 @@
#include "InputFiles.h"
#include "OutputSections.h"
+#include "RISCVInternalRelocations.h"
#include "RelocScan.h"
#include "Symbols.h"
#include "SyntheticSections.h"
@@ -345,8 +346,15 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
case R_RISCV_SUB_ULEB128:
return RE_RISCV_LEB128;
default:
- Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v
- << ") against symbol " << &s;
+ if (type.v & INTERNAL_RISCV_VENDOR_MASK) {
+ Err(ctx) << getErrorLoc(ctx, loc)
+ << "unsupported vendor-specific relocation " << type
+ << " against symbol " << &s;
+ return R_NONE;
+ }
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation ("
+ << (type.v & ~INTERNAL_RISCV_VENDOR_MASK) << ") against symbol "
+ << &s;
return R_NONE;
}
}
@@ -859,7 +867,7 @@ static bool relax(Ctx &ctx, int pass, InputSection &sec) {
std::fill_n(aux.relocTypes.get(), relocs.size(), R_RISCV_NONE);
aux.writes.clear();
- for (auto [i, r] : llvm::enumerate(relocs)) {
+ for (auto [i, r] : llvm::enumerate(riscv_vendor_relocs(relocs))) {
const uint64_t loc = secAddr + r.offset - delta;
uint32_t &cur = aux.relocDeltas[i], remove = 0;
switch (r.type) {
@@ -1503,12 +1511,18 @@ void RISCV::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
rvVendor = sym.getName();
continue;
} else if (!rvVendor.empty()) {
- Err(ctx) << getErrorLoc(ctx, loc)
- << "unknown vendor-specific relocation (" << type.v
- << ") in namespace '" << rvVendor << "' against symbol '" << &sym
- << "'";
+ uint32_t VendorFlag = getRISCVVendorRelMarker(rvVendor);
+ if (!VendorFlag) {
+ Err(ctx) << getErrorLoc(ctx, loc)
+ << "unknown vendor-specific relocation (" << type.v
+ << ") in namespace '" << rvVendor << "' against symbol '"
+ << &sym << "'";
+ rvVendor = "";
+ continue;
+ }
+
rvVendor = "";
- continue;
+ type.v |= VendorFlag;
}
rs.scan<ELFT, RelTy>(it, type, rs.getAddend<ELFT>(*it, type));
@@ -1533,3 +1547,21 @@ template <class ELFT> void RISCV::scanSection1(InputSectionBase &sec) {
void RISCV::scanSection(InputSectionBase &sec) {
invokeELFT(scanSection1, sec);
}
+
+namespace lld::elf {
+uint32_t getRISCVVendorRelMarker(StringRef rvVendor) {
+ return StringSwitch<uint32_t>(rvVendor)
+ .Case("QUALCOMM", INTERNAL_RISCV_VENDOR_QUALCOMM)
+ .Case("ANDES", INTERNAL_RISCV_VENDOR_ANDES)
+ .Default(0);
+}
+
+std::optional<StringRef> getRISCVVendorString(RelType ty) {
+ if ((ty.v & INTERNAL_RISCV_VENDOR_MASK) == INTERNAL_RISCV_VENDOR_QUALCOMM)
+ return "QUALCOMM";
+ if ((ty.v & INTERNAL_RISCV_VENDOR_MASK) == INTERNAL_RISCV_VENDOR_ANDES)
+ return "ANDES";
+ return std::nullopt;
+}
+
+} // namespace lld::elf
\ No newline at end of file
diff --git a/lld/ELF/Arch/RISCVInternalRelocations.h b/lld/ELF/Arch/RISCVInternalRelocations.h
new file mode 100644
index 0000000000000..3153dd0a3f9e7
--- /dev/null
+++ b/lld/ELF/Arch/RISCVInternalRelocations.h
@@ -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 = 2 << 9;
+
+constexpr uint32_t INTERNAL_RISCV_QC_ABS20_U =
+ INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_ABS20_U;
+constexpr uint32_t INTERNAL_RISCV_QC_E_BRANCH =
+ INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_BRANCH;
+constexpr uint32_t INTERNAL_RISCV_QC_E_32 =
+ INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_32;
+constexpr uint32_t INTERNAL_RISCV_QC_E_CALL_PLT =
+ INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_CALL_PLT;
+
+constexpr uint32_t INTERNAL_RISCV_NDS_BRANCH_10 =
+ INTERNAL_RISCV_VENDOR_ANDES | llvm::ELF::R_RISCV_NDS_BRANCH_10;
+
+uint32_t getRISCVVendorRelMarker(llvm::StringRef rvVendor);
+std::optional<llvm::StringRef> getRISCVVendorString(RelType ty);
+
+class vendor_reloc_iterator {
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = Relocation;
+ using difference_type = std::ptrdiff_t;
+ using pointer = Relocation *;
+ using reference = Relocation; // returned by value
+
+ vendor_reloc_iterator(MutableArrayRef<Relocation>::iterator i,
+ MutableArrayRef<Relocation>::iterator e)
+ : it(i), end(e) {}
+
+ // Dereference
+ Relocation operator*() const {
+ Relocation r = *it;
+ r.type.v |= rvVendorFlag;
+ return r;
+ }
+
+ struct vendor_reloc_proxy {
+ Relocation r;
+ const Relocation *operator->() const { return &r; }
+ };
+
+ vendor_reloc_proxy operator->() const {
+ return vendor_reloc_proxy{this->operator*()};
+ }
+
+ vendor_reloc_iterator &operator++() {
+ ++it;
+ if (it != end && it->type == llvm::ELF::R_RISCV_VENDOR) {
+ rvVendorFlag = getRISCVVendorRelMarker(it->sym->getName());
+ ++it;
+ } else {
+ rvVendorFlag = 0;
+ }
+ return *this;
+ }
+
+ vendor_reloc_iterator operator++(int) {
+ vendor_reloc_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ bool operator==(const vendor_reloc_iterator &other) const {
+ return it == other.it;
+ }
+ bool operator!=(const vendor_reloc_iterator &other) const {
+ return it != other.it;
+ }
+
+ Relocation *getUnderlyingRelocation() const { return &*it; }
+
+private:
+ MutableArrayRef<Relocation>::iterator it;
+ MutableArrayRef<Relocation>::iterator end;
+ uint32_t rvVendorFlag = 0;
+};
+
+inline auto riscv_vendor_relocs(MutableArrayRef<Relocation> arr) {
+ return llvm::make_range(vendor_reloc_iterator(arr.begin(), arr.end()),
+ vendor_reloc_iterator(arr.end(), arr.end()));
+}
+
+} // namespace lld::elf
+
+#endif
\ No newline at end of file
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 89e4dbeed3109..3fc3e3f16e9e0 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -24,6 +24,7 @@
//===----------------------------------------------------------------------===//
#include "Target.h"
+#include "Arch/RISCVInternalRelocations.h"
#include "InputFiles.h"
#include "OutputSections.h"
#include "RelocScan.h"
@@ -40,6 +41,14 @@ using namespace lld::elf;
std::string elf::toStr(Ctx &ctx, RelType type) {
StringRef s = getELFRelocationTypeName(ctx.arg.emachine, type);
+ if (ctx.arg.emachine == EM_RISCV && s == "Unknown") {
+ auto VendorString = getRISCVVendorString(type);
+ if (VendorString)
+ s = getRISCVVendorRelocationTypeName(type & ~INTERNAL_RISCV_VENDOR_MASK,
+ *VendorString);
+ if (s == "Unknown")
+ return ("Unknown vendor-specific (" + Twine(type) + ")").str();
+ }
if (s == "Unknown")
return ("Unknown (" + Twine(type) + ")").str();
return std::string(s);
diff --git a/lld/test/ELF/riscv-vendor-relocations.s b/lld/test/ELF/riscv-vendor-relocations.s
index b0f3c4a30d060..f121adec95cd0 100644
--- a/lld/test/ELF/riscv-vendor-relocations.s
+++ b/lld/test/ELF/riscv-vendor-relocations.s
@@ -8,12 +8,19 @@
TARGET:
nop
-.global INVALID_VENDOR
+.local INVALID_VENDOR
+.local QUALCOMM
+.local ANDES
.reloc 1f, R_RISCV_VENDOR, INVALID_VENDOR+0
.reloc 1f, R_RISCV_VENDOR, INVALID_VENDOR+0
.reloc 1f, R_RISCV_CUSTOM255, TARGET
-1:
- nop
-
# CHECK: error: {{.*}}:(.text+0x4): malformed consecutive R_RISCV_VENDOR relocations
# CHECK: error: {{.*}}:(.text+0x4): unknown vendor-specific relocation (255) in namespace 'INVALID_VENDOR' against symbol 'TARGET'
+.reloc 1f, R_RISCV_VENDOR, QUALCOMM+0
+.reloc 1f, R_RISCV_CUSTOM192, TARGET
+# CHECK: error: {{.*}}:(.text+0x4): unsupported vendor-specific relocation R_RISCV_QC_ABS20_U against symbol TARGET
+.reloc 1f, R_RISCV_VENDOR, ANDES+0
+.reloc 1f, R_RISCV_CUSTOM241, TARGET
+# CHECK: error: {{.*}}:(.text+0x4): unsupported vendor-specific relocation R_RISCV_NDS_BRANCH_10 against symbol TARGET
+1:
+ nop
|
lenary
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good, low-impact approach, and beyond the minor comments below, I am happy with how this works.
| constexpr uint32_t INTERNAL_RISCV_QC_ABS20_U = | ||
| INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_ABS20_U; | ||
| constexpr uint32_t INTERNAL_RISCV_QC_E_BRANCH = | ||
| INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_BRANCH; | ||
| constexpr uint32_t INTERNAL_RISCV_QC_E_32 = | ||
| INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_32; | ||
| constexpr uint32_t INTERNAL_RISCV_QC_E_CALL_PLT = | ||
| INTERNAL_RISCV_VENDOR_QUALCOMM | llvm::ELF::R_RISCV_QC_E_CALL_PLT; | ||
|
|
||
| constexpr uint32_t INTERNAL_RISCV_NDS_BRANCH_10 = | ||
| INTERNAL_RISCV_VENDOR_ANDES | llvm::ELF::R_RISCV_NDS_BRANCH_10; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can reuse RISCV_nonstandard.def for defining these, but that's a nit we can revisit in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect it's possible somehow, but it seems like it might require some metaprogramming heavy-lifting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be simplest to end up with identifiers such as INTERNAL_R_RISCV_QC_* etc, which would be doable with just token pasting, I think. Anyway, a reasonable follow-up if we want.
lenary
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…ations. (llvm#169273) This is achieved by using some of the bits of RelType to tag vendor namespaces. This change also adds a relocation iterator for RISCV that folds vendor namespaces into the RelType of the following relocation. This patch is extracted from the implementation of RISCV vendor-specific relocations in the CHERIoT LLVM downstream: CHERIoT-Platform/llvm-project@3d6d6f7
…ations. (llvm#169273) This is achieved by using some of the bits of RelType to tag vendor namespaces. This change also adds a relocation iterator for RISCV that folds vendor namespaces into the RelType of the following relocation. This patch is extracted from the implementation of RISCV vendor-specific relocations in the CHERIoT LLVM downstream: CHERIoT-Platform/llvm-project@3d6d6f7
This is achieved by using some of the bits of RelType to tag vendor namespaces.
This change also adds a relocation iterator for RISCV that folds vendor namespaces
into the RelType of the following relocation.
This patch is extracted from the implementation of RISCV vendor-specific relocations
in the CHERIoT LLVM downstream: CHERIoT-Platform/llvm-project@3d6d6f7