Skip to content

Commit 997b9ef

Browse files
alessandrodLucasSte
authored andcommitted
[SOL] fix 64 bit data relocations
Relocate FK_Data_8 fixups as R_BPF_64_ABS64. R_BPF_64_64 is used for ldimm64 which only makes sense in .text. Currently 64 bit values in non-text sections get chopped to 32 bits and shifted 32 bits to the left (that is, the first 8 bytes of a ldimm64 relocation). This commit fixes it so that 64 bit values get written fully at the intended offset. For backwards compatibility, the new behaviour is used only if the reloc-abs64 feature is on (required by -mcpu=sbfv2), since rbpf before solana-labs/rbpf#301 assumes the legacy buggy layout.
1 parent 9f6a8df commit 997b9ef

File tree

7 files changed

+56
-15
lines changed

7 files changed

+56
-15
lines changed

lld/ELF/Arch/BPF.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,18 @@ RelExpr BPF::getRelExpr(RelType type, const Symbol &s,
5858
}
5959

6060
RelType BPF::getDynRel(RelType type) const {
61-
return type;
61+
switch (type) {
62+
case R_BPF_64_ABS64:
63+
// R_BPF_64_ABS64 is symbolic like R_BPF_64_64, which is set as our
64+
// symbolicRel in the constructor. Return R_BPF_64_64 here so that if
65+
// the symbol isn't preemptible, we emit a _RELATIVE relocation instead
66+
// and skip emitting the symbol.
67+
//
68+
// See https://github.com/solana-labs/llvm-project/blob/6b6aef5dbacef31a3c7b3a54f7f1ba54cafc7077/lld/ELF/Relocations.cpp#L1179
69+
return R_BPF_64_64;
70+
default:
71+
return type;
72+
}
6273
}
6374

6475
int64_t BPF::getImplicitAddend(const uint8_t *buf, RelType type) const {

llvm/lib/Target/BPF/BPF.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ def FeatureDynamicFrames : SubtargetFeature<"dynamic-frames", "HasDynamicFrames"
3232
def FeatureSdiv : SubtargetFeature<"sdiv", "HasSdiv", "true",
3333
"Enable native BPF_SDIV support">;
3434

35+
def FeatureRelocAbs64 : SubtargetFeature<"reloc-abs64", "UseRelocAbs64", "true",
36+
"Fix 64bit data relocations">;
37+
3538
class Proc<string Name, list<SubtargetFeature> Features>
3639
: Processor<Name, NoItineraries, Features>;
3740

@@ -40,7 +43,7 @@ def : Proc<"v1", []>;
4043
def : Proc<"v2", []>;
4144
def : Proc<"v3", []>;
4245
def : Proc<"probe", []>;
43-
def : Proc<"sbfv2", [FeatureSolana, FeatureDynamicFrames, FeatureSdiv]>;
46+
def : Proc<"sbfv2", [FeatureSolana, FeatureDynamicFrames, FeatureSdiv, FeatureRelocAbs64]>;
4447

4548
def BPFInstPrinter : AsmWriter {
4649
string AsmWriterClassName = "InstPrinter";

llvm/lib/Target/BPF/BPFSubtarget.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class BPFSubtarget : public BPFGenSubtargetInfo {
5959
// whether we should use fixed or dynamic frames
6060
bool HasDynamicFrames;
6161

62+
// Fixme
63+
bool UseRelocAbs64;
64+
6265
// whether the cpu supports native BPF_SDIV
6366
bool HasSdiv;
6467

llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ namespace {
2424
class BPFAsmBackend : public MCAsmBackend {
2525
public:
2626
BPFAsmBackend(support::endianness Endian, const MCSubtargetInfo &STI)
27-
: MCAsmBackend(Endian),
28-
isSolana(STI.hasFeature(BPF::FeatureSolana) ||
29-
STI.getTargetTriple().getArch() == Triple::sbf) {}
27+
: MCAsmBackend(Endian),
28+
isSolana(STI.hasFeature(BPF::FeatureSolana) ||
29+
STI.getTargetTriple().getArch() == Triple::sbf),
30+
relocAbs64(STI.hasFeature(BPF::FeatureRelocAbs64)) {}
3031
~BPFAsmBackend() override = default;
3132

3233
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
@@ -50,6 +51,7 @@ class BPFAsmBackend : public MCAsmBackend {
5051
const MCSubtargetInfo *STI) const override;
5152
private:
5253
bool isSolana;
54+
bool relocAbs64;
5355
};
5456

5557
} // end anonymous namespace
@@ -105,7 +107,7 @@ void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
105107

106108
std::unique_ptr<MCObjectTargetWriter>
107109
BPFAsmBackend::createObjectTargetWriter() const {
108-
return createBPFELFObjectWriter(0, isSolana);
110+
return createBPFELFObjectWriter(0, isSolana, relocAbs64);
109111
}
110112

111113
MCAsmBackend *llvm::createBPFAsmBackend(const Target &T,

llvm/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace {
2121

2222
class BPFELFObjectWriter : public MCELFObjectTargetWriter {
2323
public:
24-
BPFELFObjectWriter(uint8_t OSABI, bool isSolana);
24+
BPFELFObjectWriter(uint8_t OSABI, bool isSolana, bool relocAbs64);
2525
~BPFELFObjectWriter() override = default;
2626

2727
protected:
@@ -32,6 +32,7 @@ class BPFELFObjectWriter : public MCELFObjectTargetWriter {
3232
unsigned Type) const override;
3333
private:
3434
bool isSolana;
35+
bool relocAbs64;
3536
};
3637

3738
} // end anonymous namespace
@@ -45,10 +46,11 @@ bool BPFELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
4546
return isSolana;
4647
}
4748

48-
BPFELFObjectWriter::BPFELFObjectWriter(uint8_t OSABI, bool isSolana)
49+
BPFELFObjectWriter::BPFELFObjectWriter(uint8_t OSABI, bool isSolana,
50+
bool relocAbs64)
4951
: MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_BPF,
5052
/*HasRelocationAddend*/ false),
51-
isSolana(isSolana) {}
53+
isSolana(isSolana), relocAbs64(relocAbs64) {}
5254

5355
unsigned BPFELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
5456
const MCFixup &Fixup,
@@ -64,7 +66,7 @@ unsigned BPFELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
6466
// CALL instruction.
6567
return ELF::R_BPF_64_32;
6668
case FK_Data_8:
67-
return isSolana ? ELF::R_BPF_64_64 : ELF::R_BPF_64_ABS64;
69+
return (isSolana && !relocAbs64) ? ELF::R_BPF_64_64 : ELF::R_BPF_64_ABS64;
6870
case FK_Data_4:
6971
if (const MCSymbolRefExpr *A = Target.getSymA()) {
7072
const MCSymbol &Sym = A->getSymbol();
@@ -102,6 +104,6 @@ unsigned BPFELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
102104
}
103105

104106
std::unique_ptr<MCObjectTargetWriter>
105-
llvm::createBPFELFObjectWriter(uint8_t OSABI, bool isSolana) {
106-
return std::make_unique<BPFELFObjectWriter>(OSABI, isSolana);
107+
llvm::createBPFELFObjectWriter(uint8_t OSABI, bool isSolana, bool useRelocAbs64) {
108+
return std::make_unique<BPFELFObjectWriter>(OSABI, isSolana, useRelocAbs64);
107109
}

llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ MCAsmBackend *createBPFbeAsmBackend(const Target &T, const MCSubtargetInfo &STI,
4242
const MCRegisterInfo &MRI,
4343
const MCTargetOptions &Options);
4444

45-
std::unique_ptr<MCObjectTargetWriter> createBPFELFObjectWriter(uint8_t OSABI,
46-
bool isSolana);
47-
}
45+
std::unique_ptr<MCObjectTargetWriter>
46+
createBPFELFObjectWriter(uint8_t OSABI, bool isSolana, bool useRelocAbs64);
47+
} // namespace llvm
4848

4949
// Defines symbolic names for BPF registers. This defines a mapping from
5050
// register name to register number.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llc -march=sbf -filetype=obj < %s | llvm-objdump -r - | tee -i /tmp/foo | FileCheck --check-prefix=CHECK-RELOC-SBF %s
2+
; RUN: llc -march=sbf -mcpu=sbfv2 -filetype=obj < %s | llvm-objdump -r - | tee -i /tmp/foo | FileCheck --check-prefix=CHECK-RELOC-SBFv2 %s
3+
4+
@.str = private unnamed_addr constant [25 x i8] c"reloc_64_relative_data.c\00", align 1
5+
@FILE = dso_local constant i64 ptrtoint ([25 x i8]* @.str to i64), align 8
6+
7+
; Function Attrs: noinline nounwind optnone
8+
define dso_local i64 @entrypoint(i8* %input) #0 {
9+
entry:
10+
%input.addr = alloca i8*, align 8
11+
store i8* %input, i8** %input.addr, align 8
12+
%0 = load volatile i64, i64* @FILE, align 8
13+
ret i64 %0
14+
}
15+
16+
; CHECK-RELOC-SBF: RELOCATION RECORDS FOR [.data.rel.ro]:
17+
; CHECK-RELOC-SBF: 0000000000000000 R_BPF_64_64 .L.str
18+
19+
; CHECK-RELOC-SBFv2: RELOCATION RECORDS FOR [.data.rel.ro]:
20+
; CHECK-RELOC-SBFv2: 0000000000000000 R_BPF_64_ABS64 .L.str

0 commit comments

Comments
 (0)