summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2019-02-27 05:36:15 +0000
committerYonghong Song <yhs@fb.com>2019-02-27 05:36:15 +0000
commitcc290a9e912e68677b8c33a3c82740435a6c04d8 (patch)
tree929f2d64273820951088a3befd854e9708c09e21
parentc01643087e71fe996c1fb77d7cb9bea1c2b61d52 (diff)
downloadbcm5719-llvm-cc290a9e912e68677b8c33a3c82740435a6c04d8.tar.gz
bcm5719-llvm-cc290a9e912e68677b8c33a3c82740435a6c04d8.zip
[BPF] Don't fail for static variables
Currently, the LLVM will print an error like Unsupported relocation: try to compile with -O2 or above, or check your static variable usage if user defines more than one static variables in a single ELF section (e.g., .bss or .data). There is ongoing effort to support static and global variables in libbpf and kernel. This patch removed the assertion so user programs with static variables won't fail compilation. The static variable in-section offset is written to the "imm" field of the corresponding to-be-relocated bpf instruction. Below is an example to show how the application (e.g., libbpf) can relate variable to relocations. -bash-4.4$ cat g1.c static volatile long a = 2; static volatile int b = 3; int test() { return a + b; } -bash-4.4$ clang -target bpf -O2 -c g1.c -bash-4.4$ llvm-readelf -r g1.o Relocation section '.rel.text' at offset 0x158 contains 2 entries: Offset Info Type Symbol's Value Symbol's Name 0000000000000000 0000000400000001 R_BPF_64_64 0000000000000000 .data 0000000000000018 0000000400000001 R_BPF_64_64 0000000000000000 .data -bash-4.4$ llvm-readelf -s g1.o Symbol table '.symtab' contains 6 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS g1.c 2: 0000000000000000 8 OBJECT LOCAL DEFAULT 4 a 3: 0000000000000008 4 OBJECT LOCAL DEFAULT 4 b 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 5: 0000000000000000 64 FUNC GLOBAL DEFAULT 2 test -bash-4.4$ llvm-objdump -d g1.o g1.o: file format ELF64-BPF Disassembly of section .text: 0000000000000000 test: 0: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll 2: 79 11 00 00 00 00 00 00 r1 = *(u64 *)(r1 + 0) 3: 18 02 00 00 08 00 00 00 00 00 00 00 00 00 00 00 r2 = 8 ll 5: 61 20 00 00 00 00 00 00 r0 = *(u32 *)(r2 + 0) 6: 0f 10 00 00 00 00 00 00 r0 += r1 7: 95 00 00 00 00 00 00 00 exit -bash-4.4$ . from symbol table, static variable "a" is in section #4, offset 0. . from symbol table, static variable "b" is in section #4, offset 8. . the first relocation is against symbol #4: 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 and in-section offset 0 (see llvm-objdump result) . the second relocation is against symbol #4: 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 and in-section offset 8 (see llvm-objdump result) . therefore, the first relocation is for variable "a", and the second relocation is for variable "b". Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Yonghong Song <yhs@fb.com> llvm-svn: 354954
-rw-r--r--llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp12
-rw-r--r--llvm/test/CodeGen/BPF/objdump_static_var.ll38
2 files changed, 44 insertions, 6 deletions
diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
index 0884469a8b5..ba35a175b9a 100644
--- a/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
+++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
@@ -72,12 +72,12 @@ void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
bool IsResolved,
const MCSubtargetInfo *STI) const {
if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) {
- if (Value) {
- MCContext &Ctx = Asm.getContext();
- Ctx.reportError(Fixup.getLoc(),
- "Unsupported relocation: try to compile with -O2 or above, "
- "or check your static variable usage");
- }
+ // 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<uint32_t>(&Data[Fixup.getOffset() + 4],
+ static_cast<uint32_t>(Value),
+ Endian);
} else if (Fixup.getKind() == FK_Data_4) {
support::endian::write<uint32_t>(&Data[Fixup.getOffset()], Value, Endian);
} else if (Fixup.getKind() == FK_Data_8) {
diff --git a/llvm/test/CodeGen/BPF/objdump_static_var.ll b/llvm/test/CodeGen/BPF/objdump_static_var.ll
new file mode 100644
index 00000000000..da0ca797ebc
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/objdump_static_var.ll
@@ -0,0 +1,38 @@
+; RUN: llc -march=bpfel -filetype=obj -o - %s | llvm-objdump -d - | FileCheck --check-prefix=CHECK %s
+; RUN: llc -march=bpfeb -filetype=obj -o - %s | llvm-objdump -d - | FileCheck --check-prefix=CHECK %s
+
+; src:
+; static volatile long a = 2;
+; static volatile int b = 3;
+; int test() { return a + b; }
+@a = internal global i64 2, align 8
+@b = internal global i32 3, align 4
+
+; Function Attrs: norecurse nounwind
+define dso_local i32 @test() local_unnamed_addr #0 {
+ %1 = load volatile i64, i64* @a, align 8, !tbaa !2
+; CHECK: r1 = 0 ll
+; CHECK: r1 = *(u64 *)(r1 + 0)
+ %2 = load volatile i32, i32* @b, align 4, !tbaa !6
+; CHECK: r2 = 8 ll
+; CHECK: r0 = *(u32 *)(r2 + 0)
+ %3 = trunc i64 %1 to i32
+ %4 = add i32 %2, %3
+; CHECK: r0 += r1
+ ret i32 %4
+; CHECK: exit
+}
+
+attributes #0 = { norecurse nounwind }
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!"clang version 8.0.20181009 "}
+!2 = !{!3, !3, i64 0}
+!3 = !{!"long", !4, i64 0}
+!4 = !{!"omnipotent char", !5, i64 0}
+!5 = !{!"Simple C/C++ TBAA"}
+!6 = !{!7, !7, i64 0}
+!7 = !{!"int", !4, i64 0}
OpenPOWER on IntegriCloud