mirror of
https://github.com/varun-r-mallya/Python-BPF.git
synced 2025-12-31 21:06:25 +00:00
Compare commits
4 Commits
ringbuf-he
...
2ec67b6978
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ec67b6978 | |||
| a2274ef29d | |||
| eb73001063 | |||
| 26f8f769c5 |
46
demo/bcc.py
46
demo/bcc.py
@ -1,46 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
from bcc import BPF
|
|
||||||
from bcc.utils import printb
|
|
||||||
|
|
||||||
# load BPF program
|
|
||||||
b = BPF(text="""
|
|
||||||
#include <uapi/linux/ptrace.h>
|
|
||||||
|
|
||||||
BPF_HASH(last);
|
|
||||||
|
|
||||||
int do_trace(struct pt_regs *ctx) {
|
|
||||||
u64 ts, *tsp, delta, key = 0;
|
|
||||||
|
|
||||||
// attempt to read stored timestamp
|
|
||||||
tsp = last.lookup(&key);
|
|
||||||
if (tsp != NULL) {
|
|
||||||
delta = bpf_ktime_get_ns() - *tsp;
|
|
||||||
if (delta < 1000000000) {
|
|
||||||
// output if time is less than 1 second
|
|
||||||
bpf_trace_printk("%d\\n", delta / 1000000);
|
|
||||||
}
|
|
||||||
last.delete(&key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update stored timestamp
|
|
||||||
ts = bpf_ktime_get_ns();
|
|
||||||
last.update(&key, &ts);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
|
|
||||||
b.attach_kprobe(event=b.get_syscall_fnname("sync"), fn_name="do_trace")
|
|
||||||
print("Tracing for quick sync's... Ctrl-C to end")
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
# format output
|
|
||||||
start = 0
|
|
||||||
while 1:
|
|
||||||
try:
|
|
||||||
(task, pid, cpu, flags, ts, ms) = b.trace_fields()
|
|
||||||
if start == 0:
|
|
||||||
start = ts
|
|
||||||
ts = ts - start
|
|
||||||
printb(b"At time %.2f s: multiple syncs detected, last %s ms ago" % (ts, ms))
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
exit()
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,23 +0,0 @@
|
|||||||
from pythonbpf import bpf, section, bpfglobal, compile
|
|
||||||
|
|
||||||
from ctypes import c_void_p, c_int64
|
|
||||||
|
|
||||||
# Instructions to how to run this program
|
|
||||||
# 1. Install PythonBPF: pip install pythonbpf
|
|
||||||
# 2. Run the program: python demo/pybpf0.py
|
|
||||||
# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf0.o
|
|
||||||
# 4. Start up any program and watch the output
|
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
|
||||||
@section("tracepoint/syscalls/sys_enter_execve")
|
|
||||||
def hello_world(ctx: c_void_p) -> c_int64:
|
|
||||||
print("Hello, World!")
|
|
||||||
return c_int64(0)
|
|
||||||
|
|
||||||
@bpf
|
|
||||||
@bpfglobal
|
|
||||||
def LICENSE() -> str:
|
|
||||||
return "GPL"
|
|
||||||
|
|
||||||
compile()
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
from pythonbpf import bpf, map, section, bpfglobal, compile
|
|
||||||
from pythonbpf.helpers import ktime
|
|
||||||
from pythonbpf.maps import HashMap
|
|
||||||
|
|
||||||
from ctypes import c_void_p, c_int64, c_uint64
|
|
||||||
|
|
||||||
# Instructions to how to run this program
|
|
||||||
# 1. Install PythonBPF: pip install pythonbpf
|
|
||||||
# 2. Run the program: python demo/pybpf3.py
|
|
||||||
# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf3.o
|
|
||||||
# 4. Start up any program and watch the output
|
|
||||||
|
|
||||||
@bpf
|
|
||||||
@map
|
|
||||||
def last() -> HashMap:
|
|
||||||
return HashMap(key=c_uint64, value=c_uint64, max_entries=3)
|
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
|
||||||
@section("tracepoint/syscalls/sys_enter_execve")
|
|
||||||
def do_trace(ctx: c_void_p) -> c_int64:
|
|
||||||
key = 0
|
|
||||||
tsp = last().lookup(key)
|
|
||||||
if tsp:
|
|
||||||
kt = ktime()
|
|
||||||
delta = (kt - tsp)
|
|
||||||
if delta < 1000000000:
|
|
||||||
time_ms = (delta // 1000000)
|
|
||||||
print(f"Execve syscall entered within last second, last {time_ms} ms ago")
|
|
||||||
last().delete(key)
|
|
||||||
else:
|
|
||||||
kt = ktime()
|
|
||||||
last().update(key, kt)
|
|
||||||
return c_int64(0)
|
|
||||||
|
|
||||||
@bpf
|
|
||||||
@section("tracepoint/syscalls/sys_exit_execve")
|
|
||||||
def do_exit(ctx: c_void_p) -> c_int64:
|
|
||||||
va = 8
|
|
||||||
nm = 5 ^ va
|
|
||||||
al = 6 & 3
|
|
||||||
ru = (nm + al)
|
|
||||||
print(f"this is a variable {ru}")
|
|
||||||
return c_int64(0)
|
|
||||||
|
|
||||||
@bpf
|
|
||||||
@bpfglobal
|
|
||||||
def LICENSE() -> str:
|
|
||||||
return "GPL"
|
|
||||||
|
|
||||||
|
|
||||||
compile()
|
|
||||||
430
examples/IO-run.ipynb
Normal file
430
examples/IO-run.ipynb
Normal file
File diff suppressed because one or more lines are too long
@ -2,38 +2,39 @@
|
|||||||
#include <bpf/bpf_helpers.h>
|
#include <bpf/bpf_helpers.h>
|
||||||
|
|
||||||
#define u64 unsigned long long
|
#define u64 unsigned long long
|
||||||
|
#define u32 unsigned int
|
||||||
|
|
||||||
// Define the map
|
// Define the map
|
||||||
struct {
|
struct {
|
||||||
__uint(type, BPF_MAP_TYPE_HASH);
|
__uint(type, BPF_MAP_TYPE_HASH);
|
||||||
__type(key, u64);
|
__type(key, u64);
|
||||||
__type(value, u64);
|
__type(value, u32);
|
||||||
__uint(max_entries, 4);
|
__uint(max_entries, 4);
|
||||||
} last SEC(".maps");
|
} last SEC(".maps");
|
||||||
|
|
||||||
// Handler for syscall entry
|
// // Handler for syscall entry
|
||||||
SEC("tracepoint/syscalls/sys_enter_execve")
|
// SEC("tracepoint/syscalls/sys_enter_execve")
|
||||||
int hello(void *ctx) {
|
// int hello(void *ctx) {
|
||||||
bpf_printk("entered");
|
// bpf_printk("entered");
|
||||||
bpf_printk("multi constant support");
|
// bpf_printk("multi constant support");
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Handler for syscall exit
|
// // Handler for syscall exit
|
||||||
SEC("tracepoint/syscalls/sys_exit_execve")
|
// SEC("tracepoint/syscalls/sys_exit_execve")
|
||||||
long hello_again(void *ctx) {
|
// long hello_again(void *ctx) {
|
||||||
bpf_printk("exited");
|
// bpf_printk("exited");
|
||||||
|
|
||||||
// Create a key for map lookup
|
// // Create a key for map lookup
|
||||||
u64 key = 0;
|
// u64 key = 0;
|
||||||
|
|
||||||
// Simple lookup without conditionals
|
// // Simple lookup without conditionals
|
||||||
u64 *tsp = bpf_map_lookup_elem(&last, &key);
|
// u64 *tsp = bpf_map_lookup_elem(&last, &key);
|
||||||
|
|
||||||
// Get current timestamp
|
// // Get current timestamp
|
||||||
u64 ts = bpf_ktime_get_ns();
|
// u64 ts = bpf_ktime_get_ns();
|
||||||
|
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
char LICENSE[] SEC("license") = "GPL";
|
char LICENSE[] SEC("license") = "GPL";
|
||||||
|
|||||||
420
examples/clone-matplotlib.ipynb
Normal file
420
examples/clone-matplotlib.ipynb
Normal file
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
from pythonbpf.decorators import bpf, map, section, bpfglobal
|
from pythonbpf import bpf, map, section, bpfglobal, compile_to_ir
|
||||||
from ctypes import c_void_p, c_int64, c_int32, c_uint64
|
from ctypes import c_void_p, c_int64, c_int32, c_uint64
|
||||||
from pythonbpf.helpers import ktime
|
from pythonbpf.helpers import ktime
|
||||||
from pythonbpf.maps import HashMap
|
from pythonbpf.maps import HashMap
|
||||||
@ -10,26 +10,28 @@ def last() -> HashMap:
|
|||||||
return HashMap(key=c_uint64, value=c_uint64, max_entries=1)
|
return HashMap(key=c_uint64, value=c_uint64, max_entries=1)
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
# @bpf
|
||||||
@section("tracepoint/syscalls/sys_enter_execve")
|
# @section("tracepoint/syscalls/sys_enter_execve")
|
||||||
def hello(ctx: c_void_p) -> c_int32:
|
# def hello(ctx: c_void_p) -> c_int32:
|
||||||
print("entered")
|
# print("entered")
|
||||||
print("multi constant support")
|
# print("multi constant support")
|
||||||
return c_int32(0)
|
# return c_int32(0)
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
# @bpf
|
||||||
@section("tracepoint/syscalls/sys_exit_execve")
|
# @section("tracepoint/syscalls/sys_exit_execve")
|
||||||
def hello_again(ctx: c_void_p) -> c_int64:
|
# def hello_again(ctx: c_void_p) -> c_int64:
|
||||||
print("exited")
|
# print("exited")
|
||||||
key = 0
|
# key = 0
|
||||||
tsp = last().lookup(key)
|
# tsp = last().lookup(key)
|
||||||
print(tsp)
|
# print(tsp)
|
||||||
ts = ktime()
|
# ts = ktime()
|
||||||
return c_int64(0)
|
# return c_int64(0)
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
@bpfglobal
|
@bpfglobal
|
||||||
def LICENSE() -> str:
|
def LICENSE() -> str:
|
||||||
return "GPL"
|
return "GPL"
|
||||||
|
|
||||||
|
compile_to_ir("execve2.py", "execve2.ll")
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
# This is what it is going to look like
|
|
||||||
# pylint: disable-all# type: ignore
|
|
||||||
from pythonbpf.decorators import tracepoint, syscalls, bpfglobal, bpf
|
|
||||||
from ctypes import c_void_p, c_int32
|
|
||||||
|
|
||||||
@bpf
|
|
||||||
@tracepoint(syscalls.sys_clone)
|
|
||||||
def trace_clone(ctx: c_void_p) -> c_int32:
|
|
||||||
print("Hello, World!")
|
|
||||||
return c_int32(0)
|
|
||||||
|
|
||||||
@bpf
|
|
||||||
@bpfglobal
|
|
||||||
def LICENSE() -> str:
|
|
||||||
return "GPL"
|
|
||||||
35
examples/pybpf0.py
Normal file
35
examples/pybpf0.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from pythonbpf import bpf, section, bpfglobal, BPF
|
||||||
|
import sys
|
||||||
|
from ctypes import c_void_p, c_int64
|
||||||
|
|
||||||
|
# Instructions to how to run this program
|
||||||
|
# 1. Install PythonBPF: pip install pythonbpf
|
||||||
|
# 2. `sudo /path/to/venv/bin/python ./python-bpf/demo/pybpf0.py`
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@section("tracepoint/syscalls/sys_enter_execve")
|
||||||
|
def hello_world(ctx: c_void_p) -> c_int64:
|
||||||
|
print("Hello, World!")
|
||||||
|
return c_int64(0)
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@bpfglobal
|
||||||
|
def LICENSE() -> str:
|
||||||
|
return "GPL"
|
||||||
|
|
||||||
|
b = BPF()
|
||||||
|
b.load_and_attach()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
with open("/sys/kernel/debug/tracing/trace_pipe", "r") as f:
|
||||||
|
for line in f:
|
||||||
|
sys.stdout.write(line)
|
||||||
|
sys.stdout.flush()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
except PermissionError:
|
||||||
|
sys.stderr.write("Need root privileges to read trace_pipe\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
49
examples/pybpf3.py
Normal file
49
examples/pybpf3.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
from pythonbpf import *
|
||||||
|
from pylibbpf import *
|
||||||
|
import sys
|
||||||
|
from ctypes import c_void_p, c_int64, c_uint64
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@map
|
||||||
|
def last() -> HashMap:
|
||||||
|
return HashMap(key=c_uint64, value=c_uint64, max_entries=3)
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@section("tracepoint/syscalls/sys_enter_clone")
|
||||||
|
def do_trace(ctx: c_void_p) -> c_int64:
|
||||||
|
key = 0
|
||||||
|
tsp = last().lookup(key)
|
||||||
|
if tsp:
|
||||||
|
kt = ktime()
|
||||||
|
delta = (kt - tsp)
|
||||||
|
if delta < 1000000000:
|
||||||
|
time_ms = (delta // 1000000)
|
||||||
|
print(f"Clone syscall entered within last second, last {time_ms} ms ago")
|
||||||
|
last().delete(key)
|
||||||
|
else:
|
||||||
|
kt = ktime()
|
||||||
|
last().update(key, kt)
|
||||||
|
return c_int64(0)
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@bpfglobal
|
||||||
|
def LICENSE() -> str:
|
||||||
|
return "GPL"
|
||||||
|
|
||||||
|
b = BPF()
|
||||||
|
# autoattaches tracepoints
|
||||||
|
b.load_and_attach()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
with open("/sys/kernel/debug/tracing/trace_pipe", "r") as f:
|
||||||
|
for line in f:
|
||||||
|
sys.stdout.write(line)
|
||||||
|
sys.stdout.flush()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
except PermissionError:
|
||||||
|
sys.stderr.write("Need root privileges to read trace_pipe\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@ -3,7 +3,8 @@ import time
|
|||||||
from pythonbpf import bpf, map, section, bpfglobal, BPF
|
from pythonbpf import bpf, map, section, bpfglobal, BPF
|
||||||
from pythonbpf.helpers import pid
|
from pythonbpf.helpers import pid
|
||||||
from pythonbpf.maps import HashMap
|
from pythonbpf.maps import HashMap
|
||||||
from pylibbpf import *
|
from pylibbpf import BpfMap
|
||||||
|
|
||||||
from ctypes import c_void_p, c_int64, c_uint64, c_int32
|
from ctypes import c_void_p, c_int64, c_uint64, c_int32
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
@ -40,7 +41,6 @@ def hello(ctx: c_void_p) -> c_int64:
|
|||||||
def LICENSE() -> str:
|
def LICENSE() -> str:
|
||||||
return "GPL"
|
return "GPL"
|
||||||
|
|
||||||
|
|
||||||
b = BPF()
|
b = BPF()
|
||||||
b.load_and_attach()
|
b.load_and_attach()
|
||||||
hist = BpfMap(b, hist)
|
hist = BpfMap(b, hist)
|
||||||
@ -48,9 +48,15 @@ print("Recording")
|
|||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
|
|
||||||
counts = list(hist.values())
|
counts = list(hist.values())
|
||||||
|
x = 0
|
||||||
|
for key in hist.keys():
|
||||||
|
if hist[key] > 40:
|
||||||
|
x += 1
|
||||||
|
print(f"PID {key} called clone() >40 times")
|
||||||
|
|
||||||
|
print(f"Total PIDs with clone() >40 times: {x}")
|
||||||
plt.hist(counts, bins=20)
|
plt.hist(counts, bins=20)
|
||||||
plt.xlabel("Clone calls per PID")
|
plt.xlabel("Clone calls per PID")
|
||||||
plt.ylabel("Frequency")
|
plt.ylabel("Number of processes that called clone() x times in last 10 seconds")
|
||||||
plt.title("Syscall clone counts")
|
plt.title("x")
|
||||||
plt.show()
|
plt.show()
|
||||||
@ -1,2 +1,4 @@
|
|||||||
from .decorators import bpf, map, section, bpfglobal, struct
|
from .decorators import bpf, map, section, bpfglobal, struct
|
||||||
from .codegen import compile_to_ir, compile, BPF
|
from .codegen import compile_to_ir, compile, BPF
|
||||||
|
from .maps import HashMap, PerfEventArray
|
||||||
|
from .helpers import pid, XDP_DROP, XDP_PASS, ktime, deref
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import ast
|
import ast
|
||||||
from llvmlite import ir
|
from llvmlite import ir
|
||||||
|
|
||||||
|
from .debuginfo import DW_LANG_C11, DwarfBehaviorEnum
|
||||||
from .license_pass import license_processing
|
from .license_pass import license_processing
|
||||||
from .functions_pass import func_proc
|
from .functions_pass import func_proc
|
||||||
from .maps_pass import maps_proc
|
from .maps_pass import maps_proc
|
||||||
@ -12,6 +14,7 @@ from pathlib import Path
|
|||||||
from pylibbpf import BpfProgram
|
from pylibbpf import BpfProgram
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
version = "v0.1.3"
|
||||||
|
|
||||||
def find_bpf_chunks(tree):
|
def find_bpf_chunks(tree):
|
||||||
"""Find all functions decorated with @bpf in the AST."""
|
"""Find all functions decorated with @bpf in the AST."""
|
||||||
@ -50,16 +53,18 @@ def compile_to_ir(filename: str, output: str):
|
|||||||
module.triple = "bpf"
|
module.triple = "bpf"
|
||||||
|
|
||||||
if not hasattr(module, '_debug_compile_unit'):
|
if not hasattr(module, '_debug_compile_unit'):
|
||||||
module._file_metadata = module.add_debug_info("DIFile", { # type: ignore
|
module._file_metadata = module.add_debug_info("DIFile", { # type: ignore
|
||||||
"filename": filename,
|
"filename": filename,
|
||||||
"directory": os.path.dirname(filename)
|
"directory": os.path.dirname(filename)
|
||||||
})
|
})
|
||||||
|
|
||||||
module._debug_compile_unit = module.add_debug_info("DICompileUnit", { # type: ignore
|
module._debug_compile_unit = module.add_debug_info("DICompileUnit", { # type: ignore
|
||||||
"language": 29, # DW_LANG_C11
|
"language": DW_LANG_C11,
|
||||||
"file": module._file_metadata, # type: ignore
|
"file": module._file_metadata, # type: ignore
|
||||||
"producer": "PythonBPF DSL Compiler",
|
"producer": f"PythonBPF {version}",
|
||||||
"isOptimized": True,
|
"isOptimized": True, #TODO: This is probably not true
|
||||||
|
#TODO: add a global field here that keeps track of all the globals. Works without it, but I think it might
|
||||||
|
# be required for kprobes.
|
||||||
"runtimeVersion": 0,
|
"runtimeVersion": 0,
|
||||||
"emissionKind": 1,
|
"emissionKind": 1,
|
||||||
"splitDebugInlining": False,
|
"splitDebugInlining": False,
|
||||||
@ -67,32 +72,32 @@ def compile_to_ir(filename: str, output: str):
|
|||||||
}, is_distinct=True)
|
}, is_distinct=True)
|
||||||
|
|
||||||
module.add_named_metadata(
|
module.add_named_metadata(
|
||||||
"llvm.dbg.cu", module._debug_compile_unit) # type: ignore
|
"llvm.dbg.cu", module._debug_compile_unit) # type: ignore
|
||||||
|
|
||||||
processor(source, filename, module)
|
processor(source, filename, module)
|
||||||
|
|
||||||
wchar_size = module.add_metadata([ir.Constant(ir.IntType(32), 1),
|
wchar_size = module.add_metadata([DwarfBehaviorEnum.ERROR_IF_MISMATCH,
|
||||||
"wchar_size",
|
"wchar_size",
|
||||||
ir.Constant(ir.IntType(32), 4)])
|
ir.Constant(ir.IntType(32), 4)])
|
||||||
frame_pointer = module.add_metadata([ir.Constant(ir.IntType(32), 7),
|
frame_pointer = module.add_metadata([DwarfBehaviorEnum.OVERRIDE_USE_LARGEST,
|
||||||
"frame-pointer",
|
"frame-pointer",
|
||||||
ir.Constant(ir.IntType(32), 2)])
|
ir.Constant(ir.IntType(32), 2)])
|
||||||
# Add Debug Info Version (3 = DWARF v3, which LLVM expects)
|
# Add Debug Info Version 3
|
||||||
debug_info_version = module.add_metadata([ir.Constant(ir.IntType(32), 2),
|
debug_info_version = module.add_metadata([DwarfBehaviorEnum.WARNING_IF_MISMATCH,
|
||||||
"Debug Info Version",
|
"Debug Info Version",
|
||||||
ir.Constant(ir.IntType(32), 3)])
|
ir.Constant(ir.IntType(32), 3)])
|
||||||
|
|
||||||
# Add explicit DWARF version (4 is common, works with LLVM BPF backend)
|
# Add explicit DWARF version 5
|
||||||
dwarf_version = module.add_metadata([ir.Constant(ir.IntType(32), 2),
|
dwarf_version = module.add_metadata([DwarfBehaviorEnum.OVERRIDE_USE_LARGEST,
|
||||||
"Dwarf Version",
|
"Dwarf Version",
|
||||||
ir.Constant(ir.IntType(32), 4)])
|
ir.Constant(ir.IntType(32), 5)])
|
||||||
|
|
||||||
module.add_named_metadata("llvm.module.flags", wchar_size)
|
module.add_named_metadata("llvm.module.flags", wchar_size)
|
||||||
module.add_named_metadata("llvm.module.flags", frame_pointer)
|
module.add_named_metadata("llvm.module.flags", frame_pointer)
|
||||||
module.add_named_metadata("llvm.module.flags", debug_info_version)
|
module.add_named_metadata("llvm.module.flags", debug_info_version)
|
||||||
module.add_named_metadata("llvm.module.flags", dwarf_version)
|
module.add_named_metadata("llvm.module.flags", dwarf_version)
|
||||||
|
|
||||||
module.add_named_metadata("llvm.ident", ["llvmlite PythonBPF v0.0.1"])
|
module.add_named_metadata("llvm.ident", [f"PythonBPF {version}"])
|
||||||
|
|
||||||
print(f"IR written to {output}")
|
print(f"IR written to {output}")
|
||||||
with open(output, "w") as f:
|
with open(output, "w") as f:
|
||||||
@ -125,8 +130,8 @@ def BPF() -> BpfProgram:
|
|||||||
caller_frame = inspect.stack()[1]
|
caller_frame = inspect.stack()[1]
|
||||||
src = inspect.getsource(caller_frame.frame)
|
src = inspect.getsource(caller_frame.frame)
|
||||||
with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".py") as f, \
|
with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".py") as f, \
|
||||||
tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".ll") as inter, \
|
tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".ll") as inter, \
|
||||||
tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".o") as obj_file:
|
tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".o") as obj_file:
|
||||||
f.write(src)
|
f.write(src)
|
||||||
f.flush()
|
f.flush()
|
||||||
source = f.name
|
source = f.name
|
||||||
|
|||||||
2
pythonbpf/debuginfo/__init__.py
Normal file
2
pythonbpf/debuginfo/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .dwarf_constants import *
|
||||||
|
from .dtypes import *
|
||||||
6
pythonbpf/debuginfo/dtypes.py
Normal file
6
pythonbpf/debuginfo/dtypes.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import llvmlite.ir as ir
|
||||||
|
|
||||||
|
class DwarfBehaviorEnum:
|
||||||
|
ERROR_IF_MISMATCH = ir.Constant(ir.IntType(32), 1)
|
||||||
|
WARNING_IF_MISMATCH = ir.Constant(ir.IntType(32), 2)
|
||||||
|
OVERRIDE_USE_LARGEST = ir.Constant(ir.IntType(32), 7)
|
||||||
@ -1,7 +1,6 @@
|
|||||||
import ast
|
import ast
|
||||||
from llvmlite import ir
|
from llvmlite import ir
|
||||||
from .type_deducer import ctypes_to_ir
|
from .debuginfo import dwarf_constants as dc
|
||||||
from . import dwarf_constants as dc
|
|
||||||
|
|
||||||
map_sym_tab = {}
|
map_sym_tab = {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user