-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[RISCV] Vendor Relocations for Xqci extension #135400
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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-mc Author: Sudharsan Veeravalli (svs-quic) ChangesThis patch adds support for vendor relocations on Qualcomm uC Xqci instructions. It adds a new fixupNeedsMarkerELFRelocation function that targets can override to add any marker relocations in the ELF object. The psabi doc describes the vendor relocations here https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#nonstandard-relocations-aka-vendor-specific-relocations > These vendor-specific relocations must be preceded by a R_RISCV_VENDOR relocation against a vendor identifier symbol. The preceding R_RISCV_VENDOR relocation is used by the linker to choose the correct implementation for the associated nonstandard relocation. Full diff: https://github.com/llvm/llvm-project/pull/135400.diff 7 Files Affected:
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 5953de30c2eb2..fcc67afdc6fc5 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -125,6 +125,18 @@ class MCAsmBackend {
return false;
}
+ /// Hook to add any marker relocations that the target may need in addition
+ /// to the normal relocations on instructions. Currently used only by RISCV
+ /// to add vendor relocations.
+ virtual bool fixupNeedsMarkerELFRelocation(MCAssembler &Asm,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ unsigned &PreRelocType,
+ MCSymbol *&PreRelocSymbol,
+ uint64_t &PreRelocAddend) const {
+ return false;
+ }
+
/// Apply the \p Value for given \p Fixup into the provided data fragment, at
/// the offset specified by the fixup and following the fixup kind as
/// appropriate. Errors (such as an out of range fixup value) should be
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 23d5517920e7b..426937ee415bd 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -1435,6 +1435,21 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
: C;
FixedValue = usesRela(TO, FixupSection) ? 0 : Addend;
+ // Some RISC-V relocations need a marker relocation that appears before the
+ // relocation in question.
+ unsigned PreRelocType;
+ MCSymbol *PreRelocSymbol;
+ uint64_t PreRelocAddend;
+ if (Backend.fixupNeedsMarkerELFRelocation(Asm, *Fragment, Fixup, PreRelocType,
+ PreRelocSymbol, PreRelocAddend)) {
+ auto *SymbolELF = cast<MCSymbolELF>(PreRelocSymbol);
+ if (SymbolELF)
+ SymbolELF->setUsedInReloc();
+ ELFRelocationEntry Rec(FixupOffset, SymbolELF, PreRelocType,
+ PreRelocAddend);
+ Relocations[&FixupSection].push_back(Rec);
+ }
+
if (!RelocateWithSymbol) {
const auto *SectionSymbol =
SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 49c8c6957aa34..bbcb84ea78566 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -702,6 +702,33 @@ bool RISCVAsmBackend::handleAddSubRelocations(const MCAssembler &Asm,
return true;
}
+bool RISCVAsmBackend::fixupNeedsMarkerELFRelocation(
+ MCAssembler &Asm, const MCFragment &F, const MCFixup &Fixup,
+ unsigned &PreRelocType, MCSymbol *&PreRelocSymbol,
+ uint64_t &PreRelocAddend) const {
+ switch (Fixup.getTargetKind()) {
+ default:
+ return false;
+ case RISCV::fixup_riscv_qc_e_branch:
+ case RISCV::fixup_riscv_qc_e_32:
+ case RISCV::fixup_riscv_qc_abs20_u:
+ case RISCV::fixup_riscv_qc_e_jump_plt: {
+ MCContext &Ctx = Asm.getContext();
+ MCSymbol *VendorSymbol = Ctx.getOrCreateSymbol("QUALCOMM");
+ MCFragment &DF = F.getParent()->getDummyFragment();
+ VendorSymbol->setFragment(&DF);
+ VendorSymbol->setOffset(0);
+
+ Asm.registerSymbol(*VendorSymbol);
+
+ PreRelocType = ELF::R_RISCV_VENDOR;
+ PreRelocSymbol = VendorSymbol;
+ PreRelocAddend = 0;
+ return true;
+ }
+ }
+}
+
void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index f5e8d340d9bce..9076074987a37 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -56,6 +56,12 @@ class RISCVAsmBackend : public MCAsmBackend {
const MCFixup &Fixup, const MCValue &Target,
uint64_t &FixedValue) const override;
+ bool fixupNeedsMarkerELFRelocation(MCAssembler &Asm, const MCFragment &F,
+ const MCFixup &Fixup,
+ unsigned &PreRelocType,
+ MCSymbol *&PreRelocSymbol,
+ uint64_t &PreRelocAddend) const override;
+
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
uint64_t Value, bool IsResolved,
diff --git a/llvm/test/MC/RISCV/xqcibi-relocations.s b/llvm/test/MC/RISCV/xqcibi-relocations.s
index 7028e8a737c86..a0ab7a450349d 100644
--- a/llvm/test/MC/RISCV/xqcibi-relocations.s
+++ b/llvm/test/MC/RISCV/xqcibi-relocations.s
@@ -2,11 +2,13 @@
# RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcibi %s -o %t.o
# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOC %s
+# RUN: llvm-readelf -s %t.o | FileCheck -check-prefix=VENDORSYM %s
# Check prefixes:
# RELOC - Check the relocation in the object.
# FIXUP - Check the fixup on the instruction.
# INSTR - Check the instruction is handled properly by the ASMPrinter.
+# VENDORSYM - Check the vendor symbol.
.text
@@ -22,6 +24,15 @@ qc.e.bgeui x8, 12, foo
# INSTR: qc.e.bgeui s0, 12, foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_branch
+# Check that we print the correct relocations in exact mode
+.option exact
+qc.e.bgeui x8, 12, foo
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
+# RELOC: R_RISCV_CUSTOM193 foo 0x0
+# INSTR: qc.e.bgeui s0, 12, foo
+# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_branch
+.option noexact
+
# Check that a label in a different section is handled similar to an undefined
# symbol and gets relaxed to (qc.e.bgeui + jal)
qc.e.bltui x4, 9, .bar
@@ -34,6 +45,9 @@ qc.e.beqi x7, 8, .L1
# INSTR: qc.e.beqi t2, 8, .L1
# FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_qc_e_branch
+# Check that there is only one vendor symbol created and that it is local and NOTYPE
+# VENDORSYM-COUNT-1: 00000000 0 NOTYPE LOCAL DEFAULT 2 QUALCOMM
+
.L1:
ret
diff --git a/llvm/test/MC/RISCV/xqcilb-relocations.s b/llvm/test/MC/RISCV/xqcilb-relocations.s
index a475cde3f6bfd..f9787df352f36 100644
--- a/llvm/test/MC/RISCV/xqcilb-relocations.s
+++ b/llvm/test/MC/RISCV/xqcilb-relocations.s
@@ -2,41 +2,49 @@
# RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilb %s -o %t.o
# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOC %s
+# RUN: llvm-readelf -s %t.o | FileCheck -check-prefix=VENDORSYM %s
# Check prefixes:
# RELOC - Check the relocation in the object.
# FIXUP - Check the fixup on the instruction.
# INSTR - Check the instruction is handled properly by the ASMPrinter.
+# VENDORSYM - Check the vendor symbol.
.text
qc.e.j foo
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM195 foo 0x0
# INSTR: qc.e.j foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_jump_plt
qc.e.j foo@plt
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM195 foo 0x0
# INSTR: qc.e.j foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_jump_plt
qc.e.jal foo@plt
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM195 foo 0x0
# INSTR: qc.e.jal foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_jump_plt
qc.e.jal foo
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM195 foo 0x0
# INSTR: qc.e.jal foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_jump_plt
# Check that a label in a different section is handled similar to an undefined symbol
qc.e.j .bar
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM195 .bar 0x0
# INSTR: qc.e.j .bar
# FIXUP: fixup A - offset: 0, value: .bar, kind: fixup_riscv_qc_e_jump_plt
qc.e.jal .bar
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM195 .bar 0x0
# INSTR: qc.e.jal .bar
# FIXUP: fixup A - offset: 0, value: .bar, kind: fixup_riscv_qc_e_jump_plt
@@ -50,6 +58,9 @@ qc.e.jal .L1
# INSTR:qc.e.jal .L1
# FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_qc_e_jump_plt
+# Check that there is only one vendor symbol created and that it is local and NOTYPE
+# VENDORSYM-COUNT-1: 00000000 0 NOTYPE LOCAL DEFAULT 2 QUALCOMM
+
.L1:
ret
diff --git a/llvm/test/MC/RISCV/xqcili-relocations.s b/llvm/test/MC/RISCV/xqcili-relocations.s
index b0a3f3bae11d5..b7ed8fedb35f8 100644
--- a/llvm/test/MC/RISCV/xqcili-relocations.s
+++ b/llvm/test/MC/RISCV/xqcili-relocations.s
@@ -2,31 +2,37 @@
# RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcili %s -o %t.o
# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOC %s
+# RUN: llvm-readelf -s %t.o | FileCheck -check-prefix=VENDORSYM %s
# Check prefixes:
# RELOC - Check the relocation in the object.
# FIXUP - Check the fixup on the instruction.
# INSTR - Check the instruction is handled properly by the ASMPrinter.
+# VENDORSYM - Check the vendor symbol.
.text
qc.li x4, %qc.abs20(foo)
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM192 foo 0x0
# INSTR: qc.li tp, %qc.abs20(foo)
# FIXUP: fixup A - offset: 0, value: %qc.abs20(foo), kind: fixup_riscv_qc_abs20_u
qc.e.li x5, foo
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM194 foo 0x0
# INSTR: qc.e.li t0, foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_32
# Check that a label in a different section is handled similar to an undefined symbol
qc.li x9, %qc.abs20(.bar)
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM192 .bar 0x0
# INSTR: qc.li s1, %qc.abs20(.bar)
# FIXUP: fixup A - offset: 0, value: %qc.abs20(.bar), kind: fixup_riscv_qc_abs20_u
qc.e.li x8, .bar
+# RELOC: R_RISCV_VENDOR QUALCOMM 0x0
# RELOC: R_RISCV_CUSTOM194 .bar 0x0
# INSTR: qc.e.li s0, .bar
# FIXUP: fixup A - offset: 0, value: .bar, kind: fixup_riscv_qc_e_32
@@ -40,6 +46,9 @@ qc.e.li x6, .L1
# INSTR: qc.e.li t1, .L1
# FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_qc_e_32
+# Check that there is only one vendor symbol created and that it is local and NOTYPE
+# VENDORSYM-COUNT-1: 00000000 0 NOTYPE LOCAL DEFAULT 2 QUALCOMM
+
.L1:
ret
|
@MaskRay I've tagged you in the review because this hits target-independent MC code. We weren't sure of a better way to accomplish what is needed for the RISC-V R_RISCV_VENDOR relocations. We didn't want a separate fixup (as for Relaxation) because we didn't want to emit the R_RISCV_VENDOR relocation if the fixup could be evaluated/applied by the compiler, and that kind of "evaluating one fixup deletes another fixup" seemed complex and error-prone. Hopefully you find our approach reasonable. There is linker support for these relocations, in https://github.com/qualcomm/eld - which requires the |
Tests for the eld implementation are here: qualcomm/eld#16 |
llvm/lib/MC/ELFObjectWriter.cpp
Outdated
unsigned PreRelocType; | ||
MCSymbol *PreRelocSymbol; | ||
uint64_t PreRelocAddend; | ||
if (Backend.fixupNeedsMarkerELFRelocation(Asm, *Fragment, Fixup, PreRelocType, |
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.
(MCAssembler.cpp and ELFObjectWriter.cpp have significant tech debt. I try to clean up them from time to time. Just noticed that my latest change 19730e3 might need you to rebase.)
I think we should refrain from adding new hooks. (I added Backend.handleAddSubRelocations
in the past, and on reflection we might need some cleanup so that it could be combined with getRelocType).
Can you add an extra fixup when fixup_riscv_qc_e_branch
is appended? Or the hook is here because in some scenarios the fixup can be resolved and you don't want to add a redundant marker?
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 we should refrain from adding new hooks.
I do too, but "refrain from" doesn't mean "never". We could not find another way to accomplish this.
Or the hook is here because in some scenarios the fixup can be resolved and you don't want to add a redundant marker?
This. For instance, branches can be evaluated when not relaxing.
From my comment, above:
We didn't want a separate fixup (as for Relaxation) because we didn't want to emit the R_RISCV_VENDOR relocation if the fixup could be evaluated/applied by the compiler, and that kind of "evaluating one fixup deletes another fixup" seemed complex and error-prone.
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.
You could customize evaluateTargetFixup
. If the fixup is not resolved, call recordRelocation
to append the marker relocation, and then rely on the default recordRelocation
in evaluateFixup
to append the actual relocation.
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 looked into this, and evaluateTargetFixup
doesn't get any info about the fixup being resolved (the info comes from this function when the IsTarget fixup flag is given) - to work this way we'd need to pass more information into this function (the RecordReloc
bool), and replicate lots of the logic in evaluateFixup
which is bypassed if you have the IsTarget
fixup flag.
With all this in mind, I continue to think that the new hook is the best way to achieve vendor relocations for RISC-V.
I realise you've been away recently (me too), I'm happy to discuss this further when you're back.
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.
@MaskRay Ping?
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.
fixupNeedsMarkerELFRelocation
adds unneeded overhead to almost all relocations for most targets.
I still believe evaluateTargetFixup
is the best way to add another relocation. Could you demonstrate the change you'd need if we don't use fixupNeedsMarkerELFRelocation
?
It's acceptable to pass more args (like RecordReloc
) to evaluateTargetFixup
, a slow path.
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 have made the change, and commented about the duplicated code, which I don't like having to copy-paste. There is also complex logic working out when IsResolved
might not be enough of a signal that a relocation is required, especially as RISC-V forces relocations during relaxation (which is also hard to test).
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.
Cc @jrtc27 who introduced evaluateTargetFixup
Currently, the MCFixupKindInfo::FKF_IsTarget code path in MCAssembler.cpp skips the common code paths (getAddSym/getSubSym), because PCREL_LO12[IS] don't need them.
Now evaluateTargetFixup is reused by QUIC relocations, leading to some duplication. I think we can make evaluateTargetFixup return more information so that QUIC relocations keep reusing the common code path.
// MCAssembler.cpp
if (FixupFlags & MCFixupKindInfo::FKF_IsTarget) {
IsResolved =
getBackend().evaluateTargetFixup(*this, Fixup, DF, Target, STI, Value);
} else {
// QUIC relocations should reuse this code path while PCREL_LO12[IS] skip it.
const MCSymbol *Add = Target.getAddSym(); 7 refs
const MCSymbol *Sub = Target.getSubSym();
The latter half of the duplication that adds a R_RISCV_VENDOR relocation can probably be refactored to reuse Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
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.
evaluteTargetFixup did exactly what was needed at the time and nothing more. If there are cases now where more of the surrounding code needs reusing then coming up with a way to communicate that seems perfectly reasonable to me.
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've refactored the relocation generation further. There is now an addReloc hook and #140494 demonstrates how to add two relocations from one fixup. For VENDOR, we just need to call .recordRelocation for a specific fixup kind.
@tclin914 I've tagged you because you'll likely want this functionality for the andes extension with relocations, and it would be good to avoid duplicating this work. |
# Check that we print the correct relocations in exact mode | ||
.option exact | ||
qc.e.bgeui x8, 12, foo | ||
# RELOC: R_RISCV_VENDOR QUALCOMM 0x0 |
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.
For relocation generation testing we should use llvm-objdump -dr to test r_offset and test that we don't incorrectly emit redundant relocations. See Sparc/Relocations/relocation-specifier.s for a modern example using llvm-objdump -dr
Looks like R_RISCV_VENDOR is only generated with exact
. We should test that without exact
there is no QUALCOMM
. This is unclear from the PR description.
FIXUP from -show-encoding output is not really useful for relocations. Just remove it.
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.
QUALCOMM should be emitted even without exact
, we have started to use exact to avoid instruction compression happening and make testing more specific.
I will move to objdump -dr
, I agree it's often clearer. I will revisit these tests.
Just wanted to note that we (CHERI, and specifically CHERIoT) are very interested in seeing |
@resistor I'm going to try to make some more progress on this today. |
This patch implements vendor relocation support for RISC-V, starting with the Xqci extensions. This is done by re-organising `RISCVAsmBackend::evaluateTargetFixup`, to also handle emitting the vendor relocation when the fixup is unresolved. An extra parameter `bool RecordReloc` is added to `evaluateTargetFixup`, so that the relocation is only emitted when it should be, as `evaluateTargetFixup` works the same way. This adds tests showing resolveable and unresolvable symbols for the xqci fixups (some of which are absolute and some of which are pc-relative), including tests when relaxation is enabled which forces relocations that might otherwise not be needed. Co-authored-by: Sudharsan Veeravalli <quic_svs@quicinc.com>
✅ With the latest revision this PR passed the C/C++ code formatter. |
|
||
.text | ||
## This test checks that we emit the right relocations for Xqcilb | ||
## relative jumps. These can be resolved within the same section |
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.
These can be resolved within the same section and the destination symbol is local?
Otherwise I think there will be a relocation as well. (We also emit a relocation when the destination is a gnu ifunc symbol, which is an edge case that we don't necessarily describe).
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.
Yeah, I think these always need a relocation. I forgot these are to the PLT, was just focussed on them being pc-relative.
I don't think I found the LLVM code to always emit the relocation (that I expect for call_plt), i will look over it all again.
cast<MCSymbolELF>(Ctx.createLocalSymbol(VendorIdentifier)); | ||
|
||
// Vendor Symbols are Absolute, Local, NOTYPE. | ||
VendorSymbol->setType(ELF::STT_NOTYPE); |
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.
The symbol is by default NOTYPE and LOCAL. In the rare scenario that the users changes the type/binding, we should respect that.
So setType/setBinding should be omitted.
This patch implements vendor relocation support for RISC-V, starting with the Xqci extensions.
This is done by re-organising
RISCVAsmBackend::evaluateTargetFixup
, to also handle emitting the vendor relocation when the fixup is unresolved.An extra parameter
bool RecordReloc
is added toevaluateTargetFixup
, so that the relocation is only emitted when it should be, asevaluateTargetFixup
works the same way.This adds tests showing resolveable and unresolvable symbols for the xqci fixups (some of which are absolute and some of which are pc-relative), including tests when relaxation is enabled which forces relocations that might otherwise not be needed.