Last active
January 27, 2018 15:55
-
-
Save Geal/bb3c10076c31277f7e1668549a3371ca to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
cargo rustc --release -- --emit=llvm-ir | |
cp target/release/deps/hello-*.ll hello.ll | |
cargo rustc --release -- --emit=llvm-bc | |
cp target/release/deps/hello-*.bc hello.bc | |
llc-4.0 hello.bc -march=bpf -filetype=obj -o hello.o |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ readelf -a hello.o | |
ELF Header: | |
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | |
Class: ELF64 | |
Data: 2's complement, little endian | |
Version: 1 (current) | |
OS/ABI: UNIX - System V | |
ABI Version: 0 | |
Type: REL (Relocatable file) | |
Machine: Linux BPF | |
Version: 0x1 | |
Entry point address: 0x0 | |
Start of program headers: 0 (bytes into file) | |
Start of section headers: 536 (bytes into file) | |
Flags: 0x0 | |
Size of this header: 64 (bytes) | |
Size of program headers: 0 (bytes) | |
Number of program headers: 0 | |
Size of section headers: 64 (bytes) | |
Number of section headers: 12 | |
Section header string table index: 1 | |
Section Headers: | |
[Nr] Name Type Address Offset | |
Size EntSize Flags Link Info Align | |
[ 0] NULL 0000000000000000 00000000 | |
0000000000000000 0000000000000000 0 0 0 | |
[ 1] .strtab STRTAB 0000000000000000 00000188 | |
000000000000008f 0000000000000000 0 0 1 | |
[ 2] .text PROGBITS 0000000000000000 00000040 | |
0000000000000000 0000000000000000 AX 0 0 4 | |
[ 3] kprobe/SyS_clone PROGBITS 0000000000000000 00000040 | |
0000000000000030 0000000000000000 AX 0 0 8 | |
[ 4] .relkprobe/SyS_cl REL 0000000000000000 00000158 | |
0000000000000010 0000000000000010 11 3 8 | |
[ 5] license PROGBITS 0000000000000000 00000070 | |
0000000000000008 0000000000000000 WA 0 0 8 | |
[ 6] .rellicense REL 0000000000000000 00000168 | |
0000000000000010 0000000000000010 11 5 8 | |
[ 7] version PROGBITS 0000000000000000 00000078 | |
0000000000000004 0000000000000000 A 0 0 4 | |
[ 8] .rodata.str1.1 PROGBITS 0000000000000000 0000007c | |
0000000000000008 0000000000000001 AMS 0 0 1 | |
[ 9] .eh_frame PROGBITS 0000000000000000 00000088 | |
0000000000000028 0000000000000000 A 0 0 8 | |
[10] .rel.eh_frame REL 0000000000000000 00000178 | |
0000000000000010 0000000000000010 11 9 8 | |
[11] .symtab SYMTAB 0000000000000000 000000b0 | |
00000000000000a8 0000000000000018 1 4 8 | |
Key to Flags: | |
W (write), A (alloc), X (execute), M (merge), S (strings), I (info), | |
L (link order), O (extra OS processing required), G (group), T (TLS), | |
C (compressed), x (unknown), o (OS specific), E (exclude), | |
p (processor specific) | |
There are no section groups in this file. | |
There are no program headers in this file. | |
There is no dynamic section in this file. | |
Relocation section '.relkprobe/SyS_clone' at offset 0x158 contains 1 entries: | |
Offset Info Type Sym. Value Sym. Name | |
000000000000 000200000001 unrecognized: 1 0000000000000004 byte_str.1 | |
Relocation section '.rellicense' at offset 0x168 contains 1 entries: | |
Offset Info Type Sym. Value Sym. Name | |
000000000000 000100000001 unrecognized: 1 0000000000000000 byte_str.0 | |
Relocation section '.rel.eh_frame' at offset 0x178 contains 1 entries: | |
Offset Info Type Sym. Value Sym. Name | |
00000000001c 00030000000a unrecognized: a 0000000000000000 kprobe/SyS_clone | |
The decoding of unwind sections for machine type Linux BPF is not currently supported. | |
Symbol table '.symtab' contains 7 entries: | |
Num: Value Size Type Bind Vis Ndx Name | |
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND | |
1: 0000000000000000 0 NOTYPE LOCAL DEFAULT 8 byte_str.0 | |
2: 0000000000000004 0 NOTYPE LOCAL DEFAULT 8 byte_str.1 | |
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3 | |
4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 5 _license | |
5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 7 _version | |
6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 3 kprobe__sys_clone | |
No version information found in this file. | |
$ readelf -x .rodata.str1.1 hello.o | |
Hex dump of section '.rodata.str1.1': | |
0x00000000 47504c00 41424300 GPL.ABC. | |
$ readelf -x license hello.o | |
Hex dump of section 'license': | |
NOTE: This section has relocations against it, but these have NOT been applied to this dump. | |
0x00000000 00000000 00000000 ........ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ readelf -a program.o | |
ELF Header: | |
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | |
Class: ELF64 | |
Data: 2's complement, little endian | |
Version: 1 (current) | |
OS/ABI: UNIX - System V | |
ABI Version: 0 | |
Type: REL (Relocatable file) | |
Machine: Linux BPF | |
Version: 0x1 | |
Entry point address: 0x0 | |
Start of program headers: 0 (bytes into file) | |
Start of section headers: 464 (bytes into file) | |
Flags: 0x0 | |
Size of this header: 64 (bytes) | |
Size of program headers: 0 (bytes) | |
Number of program headers: 0 | |
Size of section headers: 64 (bytes) | |
Number of section headers: 10 | |
Section header string table index: 1 | |
Section Headers: | |
[Nr] Name Type Address Offset | |
Size EntSize Flags Link Info Align | |
[ 0] NULL 0000000000000000 00000000 | |
0000000000000000 0000000000000000 0 0 0 | |
[ 1] .strtab STRTAB 0000000000000000 00000160 | |
0000000000000069 0000000000000000 0 0 1 | |
[ 2] .text PROGBITS 0000000000000000 00000040 | |
0000000000000000 0000000000000000 AX 0 0 4 | |
[ 3] kprobe/SyS_clone PROGBITS 0000000000000000 00000040 | |
0000000000000060 0000000000000000 AX 0 0 8 | |
[ 4] .rodata.str1.1 PROGBITS 0000000000000000 000000a0 | |
0000000000000007 0000000000000001 AMS 0 0 1 | |
[ 5] license PROGBITS 0000000000000000 000000a7 | |
0000000000000004 0000000000000000 WA 0 0 1 | |
[ 6] version PROGBITS 0000000000000000 000000ac | |
0000000000000004 0000000000000000 WA 0 0 4 | |
[ 7] .eh_frame PROGBITS 0000000000000000 000000b0 | |
0000000000000028 0000000000000000 A 0 0 8 | |
[ 8] .rel.eh_frame REL 0000000000000000 00000150 | |
0000000000000010 0000000000000010 9 7 8 | |
[ 9] .symtab SYMTAB 0000000000000000 000000d8 | |
0000000000000078 0000000000000018 1 2 8 | |
Key to Flags: | |
W (write), A (alloc), X (execute), M (merge), S (strings), I (info), | |
L (link order), O (extra OS processing required), G (group), T (TLS), | |
C (compressed), x (unknown), o (OS specific), E (exclude), | |
p (processor specific) | |
There are no section groups in this file. | |
There are no program headers in this file. | |
There is no dynamic section in this file. | |
Relocation section '.rel.eh_frame' at offset 0x150 contains 1 entries: | |
Offset Info Type Sym. Value Sym. Name | |
00000000001c 00010000000a unrecognized: a 0000000000000000 kprobe/SyS_clone | |
The decoding of unwind sections for machine type Linux BPF is not currently supported. | |
Symbol table '.symtab' contains 5 entries: | |
Num: Value Size Type Bind Vis Ndx Name | |
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND | |
1: 0000000000000000 0 SECTION LOCAL DEFAULT 3 | |
2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 5 _license | |
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 6 _version | |
4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 3 kprobe__sys_clone | |
No version information found in this file. | |
$ readelf -x .rodata.str1.1 program.o | |
Hex dump of section '.rodata.str1.1': | |
0x00000000 68656c6c 6f0a00 hello.. | |
$ readelf -x license program.o | |
Hex dump of section 'license': | |
0x00000000 47504c00 GPL. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'hello0-b4990b5a434d0f01306c6e79c17f427.rs' | |
source_filename = "hello0-b4990b5a434d0f01306c6e79c17f427.rs" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
@_license = local_unnamed_addr constant [4 x i8]* @byte_str.0, section "license", align 8 | |
@_version = local_unnamed_addr constant i32 -2, section "version", align 4 | |
@byte_str.0 = internal unnamed_addr constant [4 x i8] c"GPL\00", align 1 | |
@byte_str.1 = internal unnamed_addr constant [4 x i8] c"ABC\00", align 1 | |
; Function Attrs: nounwind uwtable | |
define i32 @kprobe__sys_clone(i8* nocapture readnone %ctx) unnamed_addr #0 section "kprobe/SyS_clone" { | |
start: | |
%0 = tail call i32 (i8*, i64, ...) inttoptr (i64 6 to i32 (i8*, i64, ...)*)(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @byte_str.1, i64 0, i64 0), i64 4) #1 | |
ret i32 0 | |
} | |
attributes #0 = { nounwind uwtable "probe-stack"="__rust_probestack" } | |
attributes #1 = { nounwind } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::mem::transmute; | |
#[no_mangle] | |
#[link_section = "license"] | |
pub static _license: &'static [u8; 4] = b"GPL\0"; | |
#[no_mangle] | |
#[link_section = "version"] | |
pub static _version: u32 = 0xFFFFFFFE; | |
#[no_mangle] | |
#[link_section = "kprobe/SyS_clone"] | |
pub extern "C" fn kprobe__sys_clone(ctx: *mut u8) -> i32 { | |
let BPF_FUNC_trace_printk = unsafe { | |
transmute::<usize, extern "C" fn(*const u8, usize, ...) -> i32>(6) | |
}; | |
let s = b"ABC\0"; | |
BPF_FUNC_trace_printk((&s).as_ptr(), 4); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this is the working eBPF program I try to reproduce. It will print | |
#include <linux/kconfig.h> | |
#include <linux/bpf.h> | |
#include <uapi/linux/ptrace.h> | |
// definitions of bpf helper functions we need, as found in | |
// http://elixir.free-electrons.com/linux/latest/source/samples/bpf/bpf_helpers.h | |
#define SEC(NAME) __attribute__((section(NAME), used)) | |
// BPF_FUNC_trace_printk is a member of an enum, its value is 6 | |
static int (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = | |
(void *) BPF_FUNC_trace_printk; | |
#define printt(fmt, ...) \ | |
({ \ | |
char ____fmt[] = fmt; \ | |
bpf_trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \ | |
}) | |
// the kprobe | |
SEC("kprobe/SyS_clone") | |
int kprobe__sys_clone(struct pt_regs *ctx) | |
{ | |
printt("hello\n"); | |
return 0; | |
} | |
char _license[] SEC("license") = "GPL"; | |
// this number will be interpreted by the elf loader | |
// to set the current running kernel version | |
__u32 _version SEC("version") = 0xFFFFFFFE; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'program.c' | |
source_filename = "program.c" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-pc-linux-gnu" | |
%struct.pt_regs = type { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } | |
@kprobe__sys_clone.____fmt = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 | |
@_license = global [4 x i8] c"GPL\00", section "license", align 1 | |
@_version = global i32 -2, section "version", align 4 | |
@llvm.used = appending global [3 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_license, i32 0, i32 0), i8* bitcast (i32* @_version to i8*), i8* bitcast (i32 (%struct.pt_regs*)* @kprobe__sys_clone to i8*)], section "llvm.metadata" | |
; Function Attrs: nounwind uwtable | |
define i32 @kprobe__sys_clone(%struct.pt_regs* nocapture readnone) #0 section "kprobe/SyS_clone" { | |
%2 = alloca [7 x i8], align 1 | |
%3 = getelementptr inbounds [7 x i8], [7 x i8]* %2, i64 0, i64 0 | |
call void @llvm.lifetime.start(i64 7, i8* nonnull %3) #2 | |
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %3, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @kprobe__sys_clone.____fmt, i64 0, i64 0), i64 7, i32 1, i1 false) | |
%4 = call i32 (i8*, i32, ...) inttoptr (i64 6 to i32 (i8*, i32, ...)*)(i8* nonnull %3, i32 7) #2 | |
call void @llvm.lifetime.end(i64 7, i8* nonnull %3) #2 | |
ret i32 0 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.start(i64, i8* nocapture) #1 | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #1 | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.end(i64, i8* nocapture) #1 | |
attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { argmemonly nounwind } | |
attributes #2 = { nounwind } | |
!llvm.ident = !{!0} | |
!0 = !{!"clang version 4.0.1-6 (tags/RELEASE_401/final)"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment