Download raw body.
ld.so/sparc64: fix UA64 relocation mask selection and byte order
ld.so/sparc64: fix UA64 relocation mask selection and byte order
ld.so/sparc64: fix UA64 relocation mask selection and byte order
On Thu, 09 Jul 2026 14:55:45 +0200,
Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>
> I think we do. These "unaligned" relocations might not work in a
> multi-threaded context as threads may observed a partially updated
> state.
Make sense. This, actually, not that hard to change.
Something like that should do it.
I will include it into my large llvm-toolchain diff and into PR for llvm-upstream.
diff --git gnu/llvm/lld/ELF/SyntheticSections.cpp gnu/llvm/lld/ELF/SyntheticSections.cpp
index 57fcfc4cf3a..14ef5ed3c5b 100644
--- gnu/llvm/lld/ELF/SyntheticSections.cpp
+++ gnu/llvm/lld/ELF/SyntheticSections.cpp
@@ -1734,18 +1734,22 @@ void RelocationBaseSection::finalizeContents() {
void DynamicReloc::finalize(Ctx &ctx, SymbolTableBaseSection *symt) {
r_offset = getOffset();
- if (ctx.arg.emachine == EM_SPARCV9 && type == R_SPARC_UA64 &&
- needsDynSymIndex() && !sym->isPreemptible) {
- if (r_offset % 8 != 0) {
+ bool wasSparcUA64 = ctx.arg.emachine == EM_SPARCV9 && type == R_SPARC_UA64;
+ if (wasSparcUA64) {
+ if (r_offset % 8 == 0) {
+ type = R_SPARC_64;
+ } else if (needsDynSymIndex() && !sym->isPreemptible) {
Err(ctx) << "R_SPARC_UA64 relocation at offset " << r_offset
<< " against non-preemptible symbol " << sym
<< " is not 8-byte aligned";
- } else {
- type = ctx.target->relativeRel;
- isAgainstSymbol = false;
- expr = R_ABS;
}
}
+ if (wasSparcUA64 && type == R_SPARC_64 && needsDynSymIndex() &&
+ !sym->isPreemptible) {
+ type = ctx.target->relativeRel;
+ isAgainstSymbol = false;
+ expr = R_ABS;
+ }
r_sym = getSymIndex(symt);
addend = computeAddend(ctx);
isFinal = true; // Catch errors
--
wbr, Kirill
ld.so/sparc64: fix UA64 relocation mask selection and byte order
ld.so/sparc64: fix UA64 relocation mask selection and byte order
ld.so/sparc64: fix UA64 relocation mask selection and byte order