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, 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,7 +63,7 @@ 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_8) { // 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); 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 @@ -43,10 +43,9 @@ default: llvm_unreachable("invalid fixup kind!"); case FK_SecRel_8: - return ELF::R_BPF_64_64; + return ELF::R_BPF_64_LD64; case FK_PCRel_4: - case FK_SecRel_4: - return ELF::R_BPF_64_32; + return ELF::R_BPF_64_PC32; case FK_Data_8: return ELF::R_BPF_64_64; case FK_Data_4: @@ -63,19 +62,15 @@ 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. 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/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,45 @@ +; RUN: llc -march=bpfel -filetype=obj < %s | llvm-objdump -r - | FileCheck %s +; RUN: llc -march=bpfeb -filetype=obj < %s | llvm-objdump -r - | FileCheck %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 +} + +; CHECK: RELOCATION RECORDS FOR [.text]: +; CHECK: R_BPF_64_PC32 sec1 +; CHECK-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 g +; CHECK-RELOC: R_BPF_64_LD64 .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 dummy_map // ======== BPF_LDX Class ======== r5 = *(u8 *)(r0 + 0) // BPF_LDX | BPF_B