diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/BPF.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/BPF.def --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/BPF.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/BPF.def @@ -5,4 +5,7 @@ // No relocation ELF_RELOC(R_BPF_NONE, 0) ELF_RELOC(R_BPF_64_64, 1) +ELF_RELOC(R_BPF_64_LD64_32, 2) +ELF_RELOC(R_BPF_64_PC32, 3) +ELF_RELOC(R_BPF_64_ALLOC32, 4) ELF_RELOC(R_BPF_64_32, 10) diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -951,6 +951,7 @@ report_fatal_error("Relocation type not implemented yet!"); break; case ELF::R_BPF_NONE: + case ELF::R_BPF_64_ALLOC32: break; case ELF::R_BPF_64_64: { write(isBE, Section.getAddressWithOffset(Offset), Value + Addend); diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp @@ -63,13 +63,11 @@ MutableArrayRef Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const { - if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) { + if (Fixup.getKind() == FK_SecRel_4) { // The Value is 0 for global variables, and the in-section offset // for static variables. Write to the immediate field of the inst. - assert(Value <= UINT32_MAX); support::endian::write(&Data[Fixup.getOffset() + 4], - static_cast(Value), - Endian); + Value, Endian); } else if (Fixup.getKind() == FK_Data_4) { support::endian::write(&Data[Fixup.getOffset()], Value, Endian); } else if (Fixup.getKind() == FK_Data_8) { diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp @@ -42,11 +42,12 @@ switch (Fixup.getKind()) { default: llvm_unreachable("invalid fixup kind!"); - case FK_SecRel_8: - return ELF::R_BPF_64_64; - case FK_PCRel_4: case FK_SecRel_4: - return ELF::R_BPF_64_32; + // LD_imm64 instruction. + return ELF::R_BPF_64_LD64_32; + case FK_PCRel_4: + // CALL instruction. + return ELF::R_BPF_64_PC32; case FK_Data_8: return ELF::R_BPF_64_64; case FK_Data_4: @@ -63,19 +64,17 @@ if (Sym.isTemporary()) { // .BTF.ext generates FK_Data_4 relocations for // insn offset by creating temporary labels. - // The insn offset is within the code section and - // already been fulfilled by applyFixup(). No - // further relocation is needed. // The reloc symbol should be in text section. + // Use a different relocation to instruct execution engine (JIT) + // not to write the resolved address to the symbol buffer. if ((Flags & ELF::SHF_ALLOC) && (Flags & ELF::SHF_EXECINSTR)) - return ELF::R_BPF_NONE; + return ELF::R_BPF_64_ALLOC32; } else { // .BTF generates FK_Data_4 relocations for variable - // offset in DataSec kind. Similar to the above .BTF.ext - // insn offset, no further relocation is needed. + // offset in DataSec kind. // The reloc symbol should be in data section. if ((Flags & ELF::SHF_ALLOC) && (Flags & ELF::SHF_WRITE)) - return ELF::R_BPF_NONE; + return ELF::R_BPF_64_ALLOC32; } } } diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp @@ -103,7 +103,7 @@ // func call name Fixups.push_back(MCFixup::create(0, Expr, FK_PCRel_4)); else if (MI.getOpcode() == BPF::LD_imm64) - Fixups.push_back(MCFixup::create(0, Expr, FK_SecRel_8)); + Fixups.push_back(MCFixup::create(0, Expr, FK_SecRel_4)); else // bb label Fixups.push_back(MCFixup::create(0, Expr, FK_PCRel_2)); diff --git a/llvm/test/CodeGen/BPF/reloc-2.ll b/llvm/test/CodeGen/BPF/reloc-2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/reloc-2.ll @@ -0,0 +1,60 @@ +; RUN: llc -march=bpfel -filetype=obj -o %t.el < %s +; RUN: llvm-objdump -r %t.el | FileCheck --check-prefix=RELOC %s +; RUN: llvm-objdump -d --no-show-raw-insn %t.el | FileCheck --check-prefix=DUMP %s +; RUN: llc -march=bpfeb -filetype=obj -o %t.eb < %s +; RUN: llvm-objdump -r %t.eb | FileCheck --check-prefix=RELOC %s +; RUN: llvm-objdump -d --no-show-raw-insn %t.eb | FileCheck --check-prefix=DUMP %s + +; source code: +; static __attribute__((noinline)) __attribute__((section("sec1"))) +; int add(int a, int b) { +; return a + b; +; } +; static __attribute__((noinline)) +; int sub(int a, int b) { +; return a - b; +; } +; int test(int a, int b) { +; return add(a, b) + sub(a, b); +; } +; compilation flag: +; clang -target bpf -O2 -emit-llvm -S test.c + +define dso_local i32 @test(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %call = tail call fastcc i32 @add(i32 %a, i32 %b) + %call1 = tail call fastcc i32 @sub(i32 %a, i32 %b) + %add = add nsw i32 %call1, %call + ret i32 %add +} + +define internal fastcc i32 @add(i32 %a, i32 %b) unnamed_addr #1 section "sec1" { +entry: + %add = add nsw i32 %b, %a + ret i32 %add +} + +; Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn mustprogress +define internal fastcc i32 @sub(i32 %a, i32 %b) unnamed_addr #1 { +entry: + %sub = sub nsw i32 %a, %b + ret i32 %sub +} + +; DUMP: .text: +; DUMP-EMPTY: +; DUMP-NEXT: +; DUMP-NEXT: r[[#]] = r[[#]] +; DUMP-NEXT: r[[#]] = r[[#]] +; DUMP-NEXT: call -1 + +; DUMP: sec1: +; DUMP-EMPTY: +; DUMP-NEXT: + +; RELOC: RELOCATION RECORDS FOR [.text]: +; RELOC: R_BPF_64_PC32 sec1 +; RELOC-NOT: R_BPF_64_PC32 + +attributes #0 = { nofree norecurse nosync nounwind readnone willreturn mustprogress "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { nofree noinline norecurse nosync nounwind readnone willreturn mustprogress "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } diff --git a/llvm/test/CodeGen/BPF/reloc-btf-2.ll b/llvm/test/CodeGen/BPF/reloc-btf-2.ll --- a/llvm/test/CodeGen/BPF/reloc-btf-2.ll +++ b/llvm/test/CodeGen/BPF/reloc-btf-2.ll @@ -22,9 +22,12 @@ } ; CHECK-RELOC: file format elf64-bpf +; CHECK-RELOC: RELOCATION RECORDS FOR [.text]: +; CHECK-RELOC: R_BPF_64_LD64_32 g +; CHECK-RELOC: R_BPF_64_LD64_32 .bss ; CHECK-RELOC: RELOCATION RECORDS FOR [.BTF]: -; CHECK-RELOC: R_BPF_NONE .bss -; CHECK-RELOC: R_BPF_NONE g +; CHECK-RELOC: R_BPF_64_ALLOC32 .bss +; CHECK-RELOC: R_BPF_64_ALLOC32 g ; CHECK-RELOC: RELOCATION RECORDS FOR [.BTF.ext]: attributes #0 = { norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/BPF/reloc-btf.ll b/llvm/test/CodeGen/BPF/reloc-btf.ll --- a/llvm/test/CodeGen/BPF/reloc-btf.ll +++ b/llvm/test/CodeGen/BPF/reloc-btf.ll @@ -11,7 +11,7 @@ ; CHECK-RELOC: R_BPF_64_32 .debug_abbrev ; CHECK-RELOC: R_BPF_64_64 .text ; CHECK-RELOC: RELOCATION RECORDS FOR [.BTF.ext]: -; CHECK-RELOC: R_BPF_NONE .text +; CHECK-RELOC: R_BPF_64_ALLOC32 .text attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/MC/BPF/insn-unit.s b/llvm/test/MC/BPF/insn-unit.s --- a/llvm/test/MC/BPF/insn-unit.s +++ b/llvm/test/MC/BPF/insn-unit.s @@ -27,7 +27,7 @@ // CHECK: 18 09 00 00 ff ff ff ff 00 00 00 00 01 00 00 00 r9 = 8589934591 ll // CHECK: 18 09 00 00 ff ff ff ff 00 00 00 00 01 00 00 00 r9 = 8589934591 ll // CHECK: 18 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r9 = 0 ll -// CHECK: 0000000000000060: R_BPF_64_64 dummy_map +// CHECK: 0000000000000060: R_BPF_64_LD64_32 dummy_map // ======== BPF_LDX Class ======== r5 = *(u8 *)(r0 + 0) // BPF_LDX | BPF_B