|
|
@@ -10,11 +10,11 @@
|
|
|
#include <sstream>
|
|
|
#include <utility>
|
|
|
#include <vector>
|
|
|
+#include "table.cpp"
|
|
|
|
|
|
constexpr const char *TRACE_PIPE_PATH = "/sys/kernel/debug/tracing/trace_pipe";
|
|
|
|
|
|
// Php::out << "Value of fn: " << fnn << std::endl;
|
|
|
-//static std::string cb_fn;
|
|
|
|
|
|
const std::vector<std::string> syscall_prefixes = {
|
|
|
"sys_",
|
|
|
@@ -27,47 +27,12 @@ const std::vector<std::string> syscall_prefixes = {
|
|
|
"__riscv_sys_"
|
|
|
};
|
|
|
|
|
|
-
|
|
|
-class PerfEvent : public Php::Base {
|
|
|
-private:
|
|
|
- std::string cb;
|
|
|
-public:
|
|
|
- ebpf::BPF *bpf;
|
|
|
- std::string event_name;
|
|
|
-
|
|
|
- PerfEvent(ebpf::BPF *bpf_instance, const std::string &event_name)
|
|
|
- : bpf(bpf_instance), event_name(event_name) {}
|
|
|
-
|
|
|
- virtual ~PerfEvent() = default;
|
|
|
-
|
|
|
- static void callbackfn(void *cookie, void *data, int data_size) {
|
|
|
- auto *instance = static_cast<PerfEvent *>(cookie);
|
|
|
- if (!instance) return;
|
|
|
-
|
|
|
- Php::Value phpData((const char *) data, data_size);
|
|
|
- Php::call(instance->cb.c_str(), nullptr, phpData, data_size);
|
|
|
- }
|
|
|
-
|
|
|
- void php_open_perf_buffer(Php::Parameters ¶ms) {
|
|
|
- this->cb = params[0].stringValue();
|
|
|
- auto res = this->bpf->open_perf_buffer(this->event_name, callbackfn, nullptr, this);
|
|
|
- if (!res.ok()) {
|
|
|
- throw Php::Exception("open_perf_buffer error:" + res.msg());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- int perf_buffer_poll(int timeout_ms) {
|
|
|
- return bpf->poll_perf_buffer(this->event_name, timeout_ms); // perf_reader_event_read
|
|
|
- }
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
class EbpfExtension : public Php::Base {
|
|
|
private:
|
|
|
ebpf::BPF bpf;
|
|
|
+ void *mod;
|
|
|
Php::Object _perf_event;
|
|
|
- PerfEvent *_class_perf_event;
|
|
|
+ PerfEventArrayTable *_class_perf_event;
|
|
|
|
|
|
static std::string add_prefix(const std::string &prefix, const std::string &name) {
|
|
|
if (name.rfind(prefix, 0) != 0) {
|
|
|
@@ -121,15 +86,38 @@ public:
|
|
|
|
|
|
virtual ~EbpfExtension() = default;
|
|
|
|
|
|
-// Php::Value __get(const Php::Value &name)
|
|
|
-// {
|
|
|
+ Php::Value __get(const Php::Value &name) {
|
|
|
+ int from_attr = 1;
|
|
|
+ auto res = get_table_cls(name, from_attr); // 这里传递 std::vector<Php::Value>
|
|
|
+ if (!res.isObject()) {
|
|
|
+ return Php::Base::__get(name);
|
|
|
+ } else {
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+// printf("111111111\n");
|
|
|
// if (name == "events") return _perf_event;
|
|
|
//
|
|
|
-// auto a = new PerfEvent;
|
|
|
+// auto a = new PerfEventArrayTable;
|
|
|
// a->getMessage();
|
|
|
//
|
|
|
-// return Php::Base::__get(name);
|
|
|
-// }
|
|
|
+ }
|
|
|
+
|
|
|
+ void php_test(Php::Parameters ¶ms) {
|
|
|
+ int ty = bpf_table_type(this->mod, "counters");
|
|
|
+ Php::out << "counters type]" << ty << std::endl;
|
|
|
+ int ty2 = bpf_table_type(this->mod, "events");
|
|
|
+ Php::out << "events type]" << ty2 << std::endl;
|
|
|
+// bpf.get_map_in_map_table<int>("").get_fd();
|
|
|
+// auto aaa = bpf.table<>()("counters");
|
|
|
+// aaa.get_value(0, reinterpret_cast<std::string &>(val));
|
|
|
+//
|
|
|
+// auto control_table_hdl = bpf.get_array_table<uint64_t>("counters");
|
|
|
+// auto res1 = control_table_hdl.get_value(1, val);
|
|
|
+// Php::out<< "ok]" <<res1.ok() <<std::endl;
|
|
|
+// Php::out<< "msg]" << res1.msg() <<std::endl;
|
|
|
+// Php::out <<"val]" << val <<std::endl;
|
|
|
+ }
|
|
|
|
|
|
void __construct(Php::Parameters ¶ms) {
|
|
|
std::string bpf_code = params[0].stringValue();
|
|
|
@@ -137,6 +125,7 @@ public:
|
|
|
if (!init_res.ok()) {
|
|
|
throw Php::Exception("init error: " + init_res.msg());
|
|
|
}
|
|
|
+ this->mod = (void *) bpf.get_mod();
|
|
|
_trace_autoload();
|
|
|
}
|
|
|
|
|
|
@@ -329,8 +318,66 @@ public:
|
|
|
|
|
|
Php::Value php_perf_event(Php::Parameters ¶ms) {
|
|
|
std::string event_name = params[0].stringValue(); // Get event_name from the parameters
|
|
|
- this->_class_perf_event = new PerfEvent(&this->bpf, event_name);
|
|
|
- return Php::Object("PerfEvent", this->_class_perf_event);
|
|
|
+ this->_class_perf_event = new PerfEventArrayTable(&this->bpf, event_name);
|
|
|
+ return Php::Object("PerfEventArrayTable", this->_class_perf_event);
|
|
|
+ }
|
|
|
+
|
|
|
+ Php::Value get_table_cls(const char *table_name, int from_attr) {
|
|
|
+ int ttype = bpf_table_type(this->mod, table_name);
|
|
|
+ switch (ttype) {
|
|
|
+ case BPF_MAP_TYPE_HASH:
|
|
|
+ return Php::Object("HashTable", new HashTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_ARRAY:
|
|
|
+ return Php::Object("ArrayTable", new ArrayTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_PROG_ARRAY:
|
|
|
+ return Php::Object("ProgArrayTable", new ProgArrayTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
|
|
|
+ this->_class_perf_event = new PerfEventArrayTable(&this->bpf, table_name);
|
|
|
+ return Php::Object("PerfEventArrayTable", this->_class_perf_event);
|
|
|
+ case BPF_MAP_TYPE_PERCPU_HASH:
|
|
|
+ return Php::Object("PerCpuHashTable", new PerCpuHashTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_PERCPU_ARRAY:
|
|
|
+ return Php::Object("PerCpuArrayTable", new PerCpuArrayTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_LPM_TRIE:
|
|
|
+ return Php::Object("LpmTrieTable", new LpmTrieTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_STACK_TRACE:
|
|
|
+ return Php::Object("StackTraceTable", new StackTraceTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_LRU_HASH:
|
|
|
+ return Php::Object("LruHashTable", new LruHashTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_LRU_PERCPU_HASH:
|
|
|
+ return Php::Object("LruPerCpuHashTable", new LruPerCpuHashTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_CGROUP_ARRAY:
|
|
|
+ return Php::Object("CgroupArrayTable", new CgroupArrayTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_DEVMAP:
|
|
|
+ return Php::Object("DevMapTable", new DevMapTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_CPUMAP:
|
|
|
+ return Php::Object("CpuMapTable", new CpuMapTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_XSKMAP:
|
|
|
+ return Php::Object("XskMapTable", new XskMapTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_ARRAY_OF_MAPS:
|
|
|
+ return Php::Object("MapInMapArrayTable", new MapInMapArrayTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_HASH_OF_MAPS:
|
|
|
+ return Php::Object("MapInMapHashTable", new MapInMapHashTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_QUEUE:
|
|
|
+ case BPF_MAP_TYPE_STACK:
|
|
|
+ return Php::Object("QueueStackTable", new QueueStackTable(&this->bpf, table_name));
|
|
|
+ case BPF_MAP_TYPE_RINGBUF:
|
|
|
+ return Php::Object("RingBufTable", new RingBufTable(&this->bpf, table_name));
|
|
|
+ default:
|
|
|
+ if (from_attr) {
|
|
|
+ return ttype;
|
|
|
+ }
|
|
|
+ throw Php::Exception("Unknown table type " + std::to_string(ttype));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Php::Value php_table(Php::Parameters ¶ms) {
|
|
|
+ std::string table_name = params[0].stringValue(); // Get event_name from the parameters
|
|
|
+ int from_fn = 0;
|
|
|
+ return get_table_cls(table_name.c_str(), from_fn);
|
|
|
+
|
|
|
+// this->_class_perf_event = new PerfEventArrayTable(&this->bpf, table_name);
|
|
|
+// return Php::Object("PerfEventArrayTable", this->_class_perf_event);
|
|
|
}
|
|
|
|
|
|
void php_perf_buffer_poll(Php::Parameters ¶ms) {
|
|
|
@@ -381,123 +428,9 @@ std::string get_kprobe_event(const std::string &kernel_func,
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-void bpf_new2(Php::Parameters ¶ms) {
|
|
|
- std::string param = params[0].stringValue();
|
|
|
-
|
|
|
- ebpf::BPF bpf;
|
|
|
-// void *mod = bpf_module_create_c_from_string(param.c_str(), 4, NULL, 0, true, NULL);
|
|
|
- std::string kernel_func = bpf.get_syscall_fnname("clone");
|
|
|
-
|
|
|
- bpf.init(param);
|
|
|
- const char *prob_fn = "kprobe__sys_clone";
|
|
|
- auto attach_res = bpf.attach_kprobe(kernel_func, prob_fn);
|
|
|
- Php::out << "Value of fn:kernel_func]" << kernel_func.c_str() << std::endl;
|
|
|
- Php::out << "Value of fn:prob_fn]" << prob_fn << std::endl;
|
|
|
-
|
|
|
- std::ifstream pipe("/sys/kernel/debug/tracing/trace_pipe");
|
|
|
- std::string line;
|
|
|
- if (!attach_res.ok()) {
|
|
|
- std::cerr << attach_res.msg() << std::endl;
|
|
|
- } else {
|
|
|
- std::cout << "Press Ctrl+C to stop..." << std::endl;
|
|
|
- while (true) {
|
|
|
- if (std::getline(pipe, line)) {
|
|
|
- std::cout << line << std::endl;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void bpf_new(Php::Parameters ¶ms) {
|
|
|
- std::string param = params[0].stringValue();
|
|
|
- void *mod = bpf_module_create_c_from_string(param.c_str(), 4, NULL, 0, true, NULL);
|
|
|
-// void *mod = bpf_module_create_c_from_string("BPF_TABLE(\"array\", int, int, stats, 10);\n", 4, NULL, 0, true, NULL);
|
|
|
-// bpf_prog_get_fd_by_id() ;
|
|
|
- Php::out << "Value of mod: " << mod << std::endl;
|
|
|
-
|
|
|
-// size_t num = bpf_num_functions(mod);
|
|
|
-// for (size_t i = 0; i < num; ++i) {
|
|
|
-// const char *fnn = bpf_function_name(mod, i);
|
|
|
-// Php::out << "Value of fn: " << fnn << std::endl;
|
|
|
-// }
|
|
|
-
|
|
|
-// Php::out << "Value of bpf_num_functions: " << num << std::endl;
|
|
|
- ebpf::BPF bpf;
|
|
|
- std::string kernel_func = bpf.get_syscall_fnname("clone");
|
|
|
-
|
|
|
- const char *prob_fn = "hello";
|
|
|
- void *func_start = bpf_function_start(mod, prob_fn);
|
|
|
- if (!func_start) {
|
|
|
- Php::out << "can not find of func_start: " << func_start << std::endl;
|
|
|
- }
|
|
|
- int log_level = 1;
|
|
|
- std::cout << "func_load ]" << prob_fn << std::endl;
|
|
|
- std::cout << "func_load func_start]" << func_start << std::endl;
|
|
|
- std::cout << "func_load func_size]" << bpf_function_size(mod, prob_fn) << std::endl;
|
|
|
- std::cout << "func_load license]" << bpf_module_license(mod) << std::endl;
|
|
|
- std::cout << "func_load kern_version]" << bpf_module_kern_version(mod) << std::endl;
|
|
|
- int fn_fd = bcc_func_load(mod, BPF_PROG_TYPE_KPROBE, prob_fn,
|
|
|
- static_cast<const bpf_insn *>(func_start),
|
|
|
- static_cast<int>(bpf_function_size(mod, prob_fn)),
|
|
|
- bpf_module_license(mod),
|
|
|
- bpf_module_kern_version(mod),
|
|
|
- log_level, nullptr, 0, 0, -1);
|
|
|
- if (fn_fd < 0) {
|
|
|
- Php::out << "Failed to load BPF program " << fn_fd << std::endl;
|
|
|
- } else {
|
|
|
- Php::out << "BPF program fd ]" << fn_fd << std::endl;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- std::string probe_event = get_kprobe_event(kernel_func, BPF_PROBE_ENTRY);
|
|
|
-
|
|
|
- std::cout << "kernel_func]" << kernel_func.c_str() << "! probe_event]" << probe_event.c_str() << std::endl;
|
|
|
- int kernel_func_offset = 0;
|
|
|
-// bpf_attach_kprobe(fn_fd, BPF_PROBE_ENTRY, probe_event.c_str(), fn, fn_offset, 0);
|
|
|
- int attach_res2 = bpf_attach_kprobe(fn_fd, BPF_PROBE_ENTRY, probe_event.c_str(), kernel_func.c_str(),
|
|
|
- kernel_func_offset, 0);
|
|
|
-
|
|
|
- std::cout << "main.cpp attach_res2---------->]" << attach_res2 << std::endl;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-// Php::out << "Value of clone_fnname: " << kernel_func << std::endl;
|
|
|
- std::ifstream pipe("/sys/kernel/debug/tracing/trace_pipe");
|
|
|
- std::string line;
|
|
|
-//
|
|
|
-// bpf.init(param);
|
|
|
-
|
|
|
- auto attach_res = bpf.attach_kprobe(kernel_func, prob_fn);
|
|
|
- std::cout << "main.cpp attach_res2-------->]" << attach_res.ok() << std::endl;
|
|
|
-
|
|
|
- if (!attach_res.ok() && attach_res2 <= 0) {
|
|
|
- std::cerr << attach_res.msg() << std::endl;
|
|
|
- } else {
|
|
|
- std::cout << "Starting HelloWorld with BCC " << 111 << std::endl;
|
|
|
- while (true) {
|
|
|
- if (std::getline(pipe, line)) {
|
|
|
- std::cout << "aaa Waiting for a sys_clone event" << std::endl;
|
|
|
- std::cout << line << std::endl;
|
|
|
- // Detach the probe if we got at least one line.
|
|
|
- auto detach_res = bpf.detach_kprobe(kernel_func);
|
|
|
- if (!detach_res.ok()) {
|
|
|
- std::cerr << detach_res.msg() << std::endl;
|
|
|
- }
|
|
|
- break;
|
|
|
- } else {
|
|
|
- std::cout << "Waiting for a sys_clone event" << std::endl;
|
|
|
- sleep(1);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
extern "C" {
|
|
|
PHPCPP_EXPORT void *get_module() {
|
|
|
static Php::Extension extension("ebpf", "1.0.0");
|
|
|
- extension.add<bpf_new>("bpf_new", {Php::ByVal("a", Php::Type::String)});
|
|
|
- extension.add<bpf_new2>("bpf_new2", {Php::ByVal("a", Php::Type::String)});
|
|
|
Php::Class<EbpfExtension> ebpf_class("Ebpf");
|
|
|
ebpf_class.method<&EbpfExtension::php_trace_print>("trace_print");
|
|
|
ebpf_class.method<&EbpfExtension::php_trace_fields>("trace_fields");
|
|
|
@@ -537,6 +470,10 @@ PHPCPP_EXPORT void *get_module() {
|
|
|
Php::ByVal("ev_name", Php::Type::String),
|
|
|
});
|
|
|
|
|
|
+ ebpf_class.method<&EbpfExtension::php_table>("table", {
|
|
|
+ Php::ByVal("tb_name", Php::Type::String),
|
|
|
+ });
|
|
|
+
|
|
|
ebpf_class.method<&EbpfExtension::php_perf_buffer_poll>("perf_buffer_poll", {});
|
|
|
|
|
|
ebpf_class.method<&EbpfExtension::php_get_syscall_fnname>("get_syscall_fnname", {
|
|
|
@@ -552,16 +489,70 @@ PHPCPP_EXPORT void *get_module() {
|
|
|
Php::ByVal("symbol", Php::Type::String),
|
|
|
Php::ByVal("options", Php::Type::Array, false),
|
|
|
});
|
|
|
+ ebpf_class.method<&EbpfExtension::php_test>("test", {});
|
|
|
+ extension.add(std::move(ebpf_class));
|
|
|
|
|
|
-
|
|
|
- Php::Class<PerfEvent> ebpf_perf_event_class("PerfEvent");
|
|
|
- ebpf_perf_event_class.method<&PerfEvent::php_open_perf_buffer>("open_perf_buffer", {
|
|
|
+ /*HashTable*/
|
|
|
+ Php::Class<HashTable> ebpf_hashtable_cls("HashTable");
|
|
|
+ /*ArrayTable*/
|
|
|
+ Php::Class<ArrayTable> ebpf_array_table_cls("ArrayTable");
|
|
|
+ ebpf_array_table_cls.method<&ArrayTable::Value>("value", {
|
|
|
+ Php::ByVal("i", Php::Type::Numeric),
|
|
|
+ });
|
|
|
+ /*ProgArrayTable*/
|
|
|
+ Php::Class<ProgArrayTable> ebpf_prog_array_table_cls("ProgArrayTable");
|
|
|
+ /*PerfEventArrayTable*/
|
|
|
+ Php::Class<PerfEventArrayTable> ebpf_perf_event_class("PerfEventArrayTable");
|
|
|
+ ebpf_perf_event_class.method<&PerfEventArrayTable::php_open_perf_buffer>("open_perf_buffer", {
|
|
|
Php::ByVal("callback", Php::Type::Callable),
|
|
|
});
|
|
|
-
|
|
|
- extension.add(std::move(ebpf_class));
|
|
|
+ /*PerCpuHashTable*/
|
|
|
+ Php::Class<PerCpuHashTable> ebpf_percpuhash_table_cls("PerCpuHashTable");
|
|
|
+ /*PerCpuArrayTable*/
|
|
|
+ Php::Class<PerCpuArrayTable> ebpf_percpuarray_table_cls("PerCpuArrayTable");
|
|
|
+ /*LpmTrieTable*/
|
|
|
+ Php::Class<LpmTrieTable> ebpf_lpmtrie_table_cls("LpmTrieTable");
|
|
|
+ /*StackTraceTable*/
|
|
|
+ Php::Class<StackTraceTable> ebpf_stack_trace_table_cls("StackTraceTable");
|
|
|
+ /*LruHashTable*/
|
|
|
+ Php::Class<LruHashTable> ebpf_lruhash_table_cls("LruHashTable");
|
|
|
+ /*LruPerCpuHashTable*/
|
|
|
+ Php::Class<LruPerCpuHashTable> ebpf_lruper_cpuhash_table_cls("LruPerCpuHashTable");
|
|
|
+ /*CgroupArrayTable*/
|
|
|
+ Php::Class<CgroupArrayTable> ebpf_cgroup_array_table_cls("CgroupArrayTable");
|
|
|
+ /*DevMapTable*/
|
|
|
+ Php::Class<DevMapTable> ebpf_devmap_table_cls("DevMapTable");
|
|
|
+ /*CpuMapTable*/
|
|
|
+ Php::Class<CpuMapTable> ebpf_cpumap_table_cls("CpuMapTable");
|
|
|
+ /*XskMapTable*/
|
|
|
+ Php::Class<XskMapTable> ebpf_xskmap_table_cls("XskMapTable");
|
|
|
+ /*MapInMapArrayTable*/
|
|
|
+ Php::Class<MapInMapArrayTable> ebpf_map_in_map_array_table_cls("MapInMapArrayTable");
|
|
|
+ /*MapInMapHashTable*/
|
|
|
+ Php::Class<MapInMapHashTable> ebpf_map_in_maphash_table_cls("MapInMapHashTable");
|
|
|
+ /*QueueStackTable*/
|
|
|
+ Php::Class<QueueStackTable> ebpf_queue_stack_table_cls("QueueStackTable");
|
|
|
+ /*RingBufTable*/
|
|
|
+ Php::Class<RingBufTable> ebpf_ringbuf_table_cls("RingBufTable");
|
|
|
+
|
|
|
+ extension.add(std::move(ebpf_hashtable_cls));
|
|
|
+ extension.add(std::move(ebpf_array_table_cls));
|
|
|
+ extension.add(std::move(ebpf_prog_array_table_cls));
|
|
|
extension.add(std::move(ebpf_perf_event_class));
|
|
|
+ extension.add(std::move(ebpf_percpuhash_table_cls));
|
|
|
+ extension.add(std::move(ebpf_percpuarray_table_cls));
|
|
|
+ extension.add(std::move(ebpf_lpmtrie_table_cls));
|
|
|
+ extension.add(std::move(ebpf_stack_trace_table_cls));
|
|
|
+ extension.add(std::move(ebpf_lruhash_table_cls));
|
|
|
+ extension.add(std::move(ebpf_lruper_cpuhash_table_cls));
|
|
|
+ extension.add(std::move(ebpf_cgroup_array_table_cls));
|
|
|
+ extension.add(std::move(ebpf_devmap_table_cls));
|
|
|
+ extension.add(std::move(ebpf_cpumap_table_cls));
|
|
|
+ extension.add(std::move(ebpf_xskmap_table_cls));
|
|
|
+ extension.add(std::move(ebpf_map_in_map_array_table_cls));
|
|
|
+ extension.add(std::move(ebpf_map_in_maphash_table_cls));
|
|
|
+ extension.add(std::move(ebpf_queue_stack_table_cls));
|
|
|
+ extension.add(std::move(ebpf_ringbuf_table_cls));
|
|
|
return extension;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
+}
|