Ver código fonte

Initial commit (php8)

Carl 8 meses atrás
pai
commit
338d3c9976
4 arquivos alterados com 432 adições e 165 exclusões
  1. 5 6
      README.md
  2. 5 5
      config.m4
  3. 211 154
      ebpf.cpp
  4. 211 0
      wrapper.h

+ 5 - 6
README.md

@@ -1,5 +1,5 @@
 # eBPF Observability for PHP
-**phbpf** 是专为 PHP 打造的,用于在 Linux 系统中高效创建内核级跟踪与操作程序。以 eBPF 技术为核心,提供丰富的工具与示例,帮助 PHP 开发者无需离开熟悉的生态就能使用强大的内核观测与动态插桩能力。
+**phbpf** 是专为 PHP 打造的,用于在 Linux 系统中高效创建内核级跟踪与操作程序。以 eBPF 技术为核心,提供丰富的工具与示例,帮助 PHP 开发者在熟悉的生态下,使用强大的内核观测与动态插桩能力。
 
 ## ✨ 特性
 - 原生 PHP 脚本直接操作 BPF 程序,适合快速开发与调试eBPF功能
@@ -21,7 +21,7 @@
                                    |
                                    v
                           +------------------+
-                          |   eBPF Subsystem |
+                          |  eBPF Subsystem  |
                           +------------------+
 
 ```
@@ -48,11 +48,10 @@ Tracing... Hit Ctrl-C to end.
 ```
 
 ## 🔗 依赖
-
-- PHP 7+
+- PHP 7 / 8
 - 内核,开启 BPF 支持
 - [libbpf](https://github.com/libbpf/libbpf)
-- [BCC](https://github.com/iovisor/bcc)
+- [libbcc >= v0.29.0](https://github.com/iovisor/bcc)
 - Clang / LLVM
 
 ## 🚀 快速开始
@@ -62,7 +61,7 @@ Tracing... Hit Ctrl-C to end.
 ```bash
 # 安装llvm / bcc / clang 等
 例如在Ubuntu系统:
-sudo apt install bpfcc-tools libbpfcc libbpf-dev linux-headers-$(uname -r) clang llvm
+sudo apt install bpfcc-tools linux-headers-$(uname -r)
 
 更多系统参考:https://github.com/iovisor/bcc/blob/master/INSTALL.md
 ```

+ 5 - 5
config.m4

@@ -51,11 +51,11 @@ if test "$PHP_EBPF" != "no"; then
   )
   BCC_C_SOURCE="$LIB_BCC/src/cc"
   PHP_ADD_INCLUDE($BCC_C_SOURCE)
-  AC_ARG_WITH([ebpf],
-      [AS_HELP_STRING([--with-llvm=DIR], [Specify the path to llvm headers and libraries])],
-      [LIB_LLVM="$withval"],
-      [LIB_LLVM="/usr/lib/llvm-14"]
-  )
+  dnl AC_ARG_WITH([ebpf],
+  dnl [AS_HELP_STRING([--with-llvm=DIR], [Specify the path to llvm headers and libraries])],
+  dnl [LIB_LLVM="$withval"],
+  dnl [LIB_LLVM="/usr/lib/llvm-14"]
+  dnl )
   PHP_ADD_INCLUDE($LIB_LLVM/include)
 
   dnl AC_ARG_WITH([ebpf],

+ 211 - 154
ebpf.cpp

@@ -25,6 +25,7 @@
 
 extern "C" {
 #include "php.h"
+#include "wrapper.h"
 #include "php_ini.h"
 #include "ext/standard/info.h"
 }
@@ -170,7 +171,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, hash_table_ce);
-			zend_update_property_string(hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -182,7 +183,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, array_table_ce);
-			zend_update_property_string(array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -194,7 +195,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, prog_array_table_ce);
-			zend_update_property_string(prog_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(prog_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -210,7 +211,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, perf_event_array_table_ce);
-			zend_update_property_string(perf_event_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(perf_event_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -223,7 +224,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, per_cpu_hash_table_ce);
-			zend_update_property_string(per_cpu_hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(per_cpu_hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -235,7 +236,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, per_cpu_array_table_ce);
-			zend_update_property_string(per_cpu_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(per_cpu_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -247,7 +248,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, lpm_trie_table_ce);
-			zend_update_property_string(lpm_trie_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(lpm_trie_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -259,7 +260,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, stack_trace_table_ce);
-			zend_update_property_string(stack_trace_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(stack_trace_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -271,7 +272,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, lru_hash_table_ce);
-			zend_update_property_string(lru_hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(lru_hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -283,7 +284,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, lru_per_cpu_hash_table_ce);
-			zend_update_property_string(lru_per_cpu_hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(lru_per_cpu_hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -295,7 +296,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, cgroup_array_table_ce);
-			zend_update_property_string(cgroup_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(cgroup_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -307,7 +308,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, dev_map_table_ce);
-			zend_update_property_string(dev_map_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(dev_map_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -319,7 +320,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, cpu_map_table_ce);
-			zend_update_property_string(cpu_map_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(cpu_map_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -331,7 +332,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, xsk_map_table_ce);
-			zend_update_property_string(xsk_map_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(xsk_map_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -343,7 +344,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, map_in_map_array_table_ce);
-			zend_update_property_string(map_in_map_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(map_in_map_array_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -355,7 +356,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, map_in_map_hash_table_ce);
-			zend_update_property_string(map_in_map_hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(map_in_map_hash_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -368,7 +369,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, queue_stack_table_ce);
-			zend_update_property_string(queue_stack_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(queue_stack_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -381,7 +382,7 @@ zval EbpfExtension::get_table_cls(const char *table_name, int from_attr) {
 				return retval;
 			}
 			object_init_ex(&retval, ring_buf_table_ce);
-			zend_update_property_string(ring_buf_table_ce, &retval, "name", sizeof("name") - 1, table_name);
+			sc_zend_update_property_string(ring_buf_table_ce, &retval, "name", sizeof("name") - 1, table_name);
 			sub_object *table_obj = table_fetch_object(Z_OBJ(retval));
 			table_obj->bpf = &this->bpf;
 			Z_ADDREF(retval);
@@ -555,7 +556,7 @@ void bpf_free_object(zend_object *object) {
 	zend_object_std_dtor(&intern->std);
 }
 
-zend_object *table_create_object(zend_class_entry *ce TSRMLS_DC) {
+zend_object *table_create_object(zend_class_entry *ce) {
 	sub_object *intern = (sub_object *) ecalloc(1, sizeof(sub_object) + zend_object_properties_size(ce));
 	zend_object_std_init(&intern->std, ce);
 	object_properties_init(&intern->std, ce);
@@ -1074,14 +1075,10 @@ PHP_METHOD (Bpf, perf_buffer_poll) {
 		zend_throw_error(NULL, "Invalid object state");
 		RETURN_NULL();
 	}
-	zval name_rv;
-	zval *name_zv = zend_read_property(
-			perf_event_array_table_ce,
-			&obj->ebpf_cpp_cls->_class_perf_event_obj,
-			"name", strlen("name"),
-			1,
-			&name_rv
-	);
+
+	zval *name_zv = sc_zend_read_property(perf_event_array_table_ce, &obj->ebpf_cpp_cls->_class_perf_event_obj, "name",
+	                                      sizeof("name") - 1, 0);
+
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
 		RETURN_NULL();
@@ -1144,12 +1141,12 @@ PHP_METHOD (Bpf, load_func) {
 
 	zval name_zv;
 	ZVAL_STRINGL(&name_zv, fn, fn_len);
-	zend_update_property(bpf_prog_func_ce, return_value, "name", sizeof("name") - 1, &name_zv);
+	sc_zend_update_property(bpf_prog_func_ce, return_value, "name", sizeof("name") - 1, &name_zv);
 	zval_ptr_dtor(&name_zv);
 
 	zval fd_zv;
 	ZVAL_LONG(&fd_zv, probe_fd);
-	zend_update_property(bpf_prog_func_ce, return_value, "fd", sizeof("fd") - 1, &fd_zv);
+	sc_zend_update_property(bpf_prog_func_ce, return_value, "fd", sizeof("fd") - 1, &fd_zv);
 }
 
 PHP_METHOD (Bpf, attach_raw_socket) {
@@ -1172,8 +1169,8 @@ PHP_METHOD (Bpf, attach_raw_socket) {
 		RETURN_NULL();
 	}
 
-	zval rv;
-	zval *fd = zend_read_property(Z_OBJCE_P(prog_fn), prog_fn, "fd", strlen("fd"), 1, &rv);
+	zval *fd = sc_zend_read_property(Z_OBJCE_P(prog_fn), prog_fn, "fd", strlen("fd"), 0);
+
 	if (!fd || Z_TYPE_P(fd) != IS_LONG) {
 		zend_throw_error(NULL, "Invalid BPFProgFunction object: missing or invalid fd property");
 		RETURN_NULL();
@@ -1203,15 +1200,8 @@ PHP_METHOD (PerfEventArrayTable, open_perf_buffer) {
 		RETURN_NULL();
 	}
 
-	zval name_rv;
-	zval *name_zv = zend_read_property(
-			Z_OBJCE_P(getThis()),
-			getThis(),
-			"name",
-			sizeof("name") - 1,
-			1,
-			&name_rv
-	);
+	zval *name_zv = sc_zend_read_property(Z_OBJCE_P(getThis()), getThis(), "name",
+	                                      sizeof("name") - 1, 0);
 
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
@@ -1237,17 +1227,8 @@ PHP_METHOD (PerfEventArrayTable, open_perf_buffer) {
 }
 
 PHP_METHOD (HashTable, values) {
-	zval name_rv;
-	zval *name_zv;
-
-	name_zv = zend_read_property(
-			Z_OBJCE_P(getThis()),
-			getThis(),
-			"name",
-			sizeof("name") - 1,
-			1,
-			&name_rv
-	);
+	zval *name_zv = sc_zend_read_property(Z_OBJCE_P(getThis()), getThis(), "name",
+	                                      sizeof("name") - 1, 0);
 
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
@@ -1283,26 +1264,17 @@ PHP_METHOD (HashTable, values) {
 }
 
 PHP_METHOD (HashTable, clear) {
-	zval name_rv;
-	zval *name_zv;
-
-	name_zv = zend_read_property(
-			Z_OBJCE_P(getThis()),
-			getThis(),
-			"name",
-			sizeof("name") - 1,
-			1,
-			&name_rv
-	);
+	zval *name_zv = sc_zend_read_property(Z_OBJCE_P(getThis()), getThis(), "name",
+	                                      sizeof("name") - 1, 0);
 
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
-		RETURN_NULL()
+		RETURN_NULL();
 	}
 	sub_object *obj = table_fetch_object(Z_OBJ_P(getThis()));
 	if (!obj || !obj->bpf) {
 		zend_throw_error(NULL, "Invalid object state");
-		RETURN_NULL()
+		RETURN_NULL();
 	}
 
 	auto table = obj->bpf->get_table(Z_STRVAL_P(name_zv));
@@ -1310,7 +1282,7 @@ PHP_METHOD (HashTable, clear) {
 
 	if (res.code() != 0) {
 		zend_throw_error(NULL, "Failed to clear table: %s", res.msg().c_str());
-		RETURN_NULL()
+		RETURN_NULL();
 	}
 
 	RETURN_TRUE;
@@ -1318,21 +1290,14 @@ PHP_METHOD (HashTable, clear) {
 
 PHP_METHOD (ArrayTable, get_value) {
 	zend_long index;
-	zval name_rv;
-	zval *name_zv;
+//	zval name_rv;
+//	zval *name_zv;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
 		RETURN_NULL();
 	}
-
-	name_zv = zend_read_property(
-			Z_OBJCE_P(getThis()),
-			getThis(),
-			"name",
-			sizeof("name") - 1,
-			1,
-			&name_rv
-	);
+	zval *name_zv = sc_zend_read_property(Z_OBJCE_P(getThis()), getThis(), "name",
+	                                      sizeof("name") - 1, 0);
 
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
@@ -1363,21 +1328,13 @@ PHP_METHOD (ArrayTable, get_value) {
 PHP_METHOD (ArrayTable, print_log2_hist) {
 	char *header;
 	size_t header_len;
-	zval name_rv;
-	zval *name_zv;
-
 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &header, &header_len) == FAILURE) {
 		RETURN_NULL();
 	}
 
-	name_zv = zend_read_property(
-			Z_OBJCE_P(getThis()),
-			getThis(),
-			"name",
-			sizeof("name") - 1,
-			1,
-			&name_rv
-	);
+	zval *name_zv = sc_zend_read_property(Z_OBJCE_P(getThis()), getThis(), "name",
+	                                      sizeof("name") - 1, 0);
+
 
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
@@ -1425,7 +1382,7 @@ PHP_METHOD (ArrayTable, print_log2_hist) {
 
 	if (idx_max == -1) {
 		std::cout << "No data to display." << std::endl;
-		RETURN_FALSE
+		RETURN_FALSE;
 	}
 
 	int stars_max = 40;
@@ -1460,27 +1417,18 @@ PHP_METHOD (ArrayTable, print_log2_hist) {
 		}
 	}
 
-	RETURN_FALSE
+	RETURN_FALSE;
 }
 
 PHP_METHOD (ArrayTable, print_linear_hist) {
 	char *header;
 	size_t header_len;
-	zval name_rv;
-	zval *name_zv;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &header, &header_len) == FAILURE) {
 		RETURN_NULL();
 	}
-
-	name_zv = zend_read_property(
-			Z_OBJCE_P(getThis()),
-			getThis(),
-			"name",
-			sizeof("name") - 1,
-			1,
-			&name_rv
-	);
+	zval *name_zv = sc_zend_read_property(Z_OBJCE_P(getThis()), getThis(), "name",
+	                                      sizeof("name") - 1, 0);
 
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
@@ -1498,7 +1446,7 @@ PHP_METHOD (ArrayTable, print_linear_hist) {
 
 	if (res.empty()) {
 		std::cout << "empty histogram" << std::endl;
-		RETURN_FALSE
+		RETURN_FALSE;
 	}
 
 	uint64_t max_val = *std::max_element(res.begin(), res.end());
@@ -1526,21 +1474,13 @@ PHP_METHOD (ArrayTable, print_linear_hist) {
 
 PHP_METHOD (PerCpuArrayTable, sum_value) {
 	int64_t index;
-	zval name_rv;
-	zval *name_zv;
-
 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
 		RETURN_NULL();
 	}
 
-	name_zv = zend_read_property(
-			Z_OBJCE_P(getThis()),
-			getThis(),
-			"name",
-			sizeof("name") - 1,
-			1,
-			&name_rv
-	);
+	zval *name_zv = sc_zend_read_property(Z_OBJCE_P(getThis()), getThis(), "name",
+	                                      sizeof("name") - 1, 0);
+
 
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
@@ -1579,21 +1519,13 @@ PHP_METHOD (PerCpuArrayTable, sum_value) {
 PHP_METHOD (StackTraceTable, values) {
 	zend_long stack_id;
 	zend_long pid = -1;
-	zval name_rv;
-	zval *name_zv;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &stack_id, &pid) == FAILURE) {
 		RETURN_NULL();
 	}
 
-	name_zv = zend_read_property(
-			Z_OBJCE_P(getThis()),
-			getThis(),
-			"name",
-			sizeof("name") - 1,
-			1,
-			&name_rv
-	);
+	zval *name_zv = sc_zend_read_property(Z_OBJCE_P(getThis()), getThis(), "name",
+	                                      sizeof("name") - 1, 0);
 
 	if (!name_zv || Z_TYPE_P(name_zv) != IS_STRING) {
 		zend_throw_error(NULL, "Invalid or missing name property");
@@ -1637,61 +1569,186 @@ static void php_ebpf_init_globals(zend_ebpf_globals *ebpf_globals)
 /* }}} */
 
 /* {{{ bpf_class_methods */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_construct, 0, 0, 1)
+    ZEND_ARG_ARRAY_INFO(0, opts, 0)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_get, 0, 0, 1)
-				ZEND_ARG_INFO(0, name)
+    ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_get_kprobe_functions, 0, 0, 1)
+    ZEND_ARG_INFO(0, fn)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_attach_kprobe, 0, 0, 2)
+    ZEND_ARG_INFO(0, kernel_func)
+    ZEND_ARG_INFO(0, probe_func)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_attach_tracepoint, 0, 0, 2)
+    ZEND_ARG_INFO(0, tp_func)
+    ZEND_ARG_INFO(0, probe_func)
+ZEND_END_ARG_INFO()
+
+#define arginfo_bpf_attach_raw_tracepoint arginfo_bpf_attach_tracepoint
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_attach_kfunc, 0, 0, 1)
+    ZEND_ARG_INFO(0, kfunc)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_attach_lsm, 0, 0, 1)
+    ZEND_ARG_INFO(0, lsm)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_attach_uprobe, 0, 0, 3)
+    ZEND_ARG_INFO(0, binary_path)
+    ZEND_ARG_INFO(0, symbol)
+    ZEND_ARG_INFO(0, probe_func)
+    ZEND_ARG_ARRAY_INFO(1, options, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_detach_kprobe, 0, 0, 1)
+    ZEND_ARG_INFO(0, fn)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_detach_uprobe, 0, 0, 2)
+    ZEND_ARG_INFO(0, binary_path)
+    ZEND_ARG_INFO(0, symbol)
+    ZEND_ARG_ARRAY_INFO(1, options, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_trace_print, 0, 0, 0)
+    ZEND_ARG_INFO(0, fmt) // Optional
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_trace_fields, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_get_table, 0, 0, 1)
+    ZEND_ARG_INFO(0, table_name)
 ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_perf_buffer_poll, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_get_syscall_fnname, 0, 0, 1)
+    ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_load_func, 0, 0, 2)
+    ZEND_ARG_INFO(0, fn)
+    ZEND_ARG_INFO(0, prog_type)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bpf_attach_raw_socket, 0, 0, 2)
+    ZEND_ARG_OBJ_INFO(0, prog_fn, BPFProgFunction, 0)
+    ZEND_ARG_INFO(0, interface)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/* {{{ arginfo for PerfEventArrayTable class */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_perf_event_array_table_open_perf_buffer, 0, 0, 1)
+    ZEND_ARG_INFO(0, cb_fn_str)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/* {{{ arginfo for HashTable class */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_table_values, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_table_clear, 0, 0, 0)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/* {{{ arginfo for ArrayTable class */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_array_table_get_value, 0, 0, 1)
+    ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_array_table_print_log2_hist, 0, 0, 1)
+    ZEND_ARG_INFO(0, header)
+ZEND_END_ARG_INFO()
+
+#define arginfo_array_table_print_linear_hist arginfo_array_table_print_log2_hist
+/* }}} */
+
+/* {{{ arginfo for PerCpuArrayTable class */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_per_cpu_array_table_sum_value, 0, 0, 1)
+    ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/* {{{ arginfo for StackTraceTable class */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_stack_trace_table_values, 0, 0, 1)
+    ZEND_ARG_INFO(0, stack_id)
+    ZEND_ARG_INFO(0, pid) // Optional
+ZEND_END_ARG_INFO()
+/* }}} */
+
+
+/* {{{ PHP_INI
+ */
+/* Remove comments if you have entries in php.ini
+PHP_INI_BEGIN()
+    DISPLAY_INI_ENTRIES();
+PHP_INI_END()
+*/
+/* }}} */
+
+/* {{{ bpf_class_methods */
 static const zend_function_entry bpf_class_methods[] = {
-		PHP_ME(Bpf, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
+		PHP_ME(Bpf, __construct, arginfo_bpf_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
 		PHP_ME(Bpf, __get, arginfo_bpf_get, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, get_kprobe_functions, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, attach_kprobe, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, attach_tracepoint, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, attach_raw_tracepoint, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, attach_kfunc, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, attach_lsm, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, attach_uprobe, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, detach_kprobe, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, detach_uprobe, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, trace_print, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, trace_fields, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, get_table, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, perf_buffer_poll, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, get_syscall_fnname, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, load_func, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(Bpf, attach_raw_socket, NULL, ZEND_ACC_PUBLIC)
-		PHP_FE_END
+	PHP_ME(Bpf, get_kprobe_functions, arginfo_bpf_get_kprobe_functions, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, attach_kprobe, arginfo_bpf_attach_kprobe, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, attach_tracepoint, arginfo_bpf_attach_tracepoint, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, attach_raw_tracepoint, arginfo_bpf_attach_raw_tracepoint, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, attach_kfunc, arginfo_bpf_attach_kfunc, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, attach_lsm, arginfo_bpf_attach_lsm, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, attach_uprobe, arginfo_bpf_attach_uprobe, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, detach_kprobe, arginfo_bpf_detach_kprobe, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, detach_uprobe, arginfo_bpf_detach_uprobe, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, trace_print, arginfo_bpf_trace_print, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, trace_fields, arginfo_bpf_trace_fields, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, get_table, arginfo_bpf_get_table, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, perf_buffer_poll, arginfo_bpf_perf_buffer_poll, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, get_syscall_fnname, arginfo_bpf_get_syscall_fnname, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, load_func, arginfo_bpf_load_func, ZEND_ACC_PUBLIC)
+	PHP_ME(Bpf, attach_raw_socket, arginfo_bpf_attach_raw_socket, ZEND_ACC_PUBLIC)
+	PHP_FE_END
 };
 /* }}} */
 
 /* {{{ table methods */
 static const zend_function_entry perf_event_array_table_methods[] = {
-		PHP_ME(PerfEventArrayTable, open_perf_buffer, NULL, ZEND_ACC_PUBLIC)
-		PHP_FE_END
+	PHP_ME(PerfEventArrayTable, open_perf_buffer, arginfo_perf_event_array_table_open_perf_buffer, ZEND_ACC_PUBLIC)
+	PHP_FE_END
 };
 
 static const zend_function_entry hash_table_methods[] = {
-		PHP_ME(HashTable, values, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(HashTable, clear, NULL, ZEND_ACC_PUBLIC)
-		PHP_FE_END
+	PHP_ME(HashTable, values, arginfo_hash_table_values, ZEND_ACC_PUBLIC)
+	PHP_ME(HashTable, clear, arginfo_hash_table_clear, ZEND_ACC_PUBLIC)
+	PHP_FE_END
 };
 
 static const zend_function_entry array_table_methods[] = {
-		PHP_ME(ArrayTable, get_value, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(ArrayTable, print_log2_hist, NULL, ZEND_ACC_PUBLIC)
-		PHP_ME(ArrayTable, print_linear_hist, NULL, ZEND_ACC_PUBLIC)
-		PHP_FE_END
+	PHP_ME(ArrayTable, get_value, arginfo_array_table_get_value, ZEND_ACC_PUBLIC)
+	PHP_ME(ArrayTable, print_log2_hist, arginfo_array_table_print_log2_hist, ZEND_ACC_PUBLIC)
+	PHP_ME(ArrayTable, print_linear_hist, arginfo_array_table_print_linear_hist, ZEND_ACC_PUBLIC)
+	PHP_FE_END
 };
 
 static const zend_function_entry prog_array_table_methods[] = {
-		PHP_FE_END
+	PHP_FE_END
 };
 
 static const zend_function_entry per_cpu_hash_table_methods[] = {
-		PHP_FE_END
+	PHP_FE_END
 };
 
 static const zend_function_entry per_cpu_array_table_methods[] = {
-		PHP_ME(PerCpuArrayTable, sum_value, NULL, ZEND_ACC_PUBLIC)
+		PHP_ME(PerCpuArrayTable, sum_value, arginfo_per_cpu_array_table_sum_value, ZEND_ACC_PUBLIC)
 		PHP_FE_END
 };
 
@@ -1700,7 +1757,7 @@ static const zend_function_entry lpm_trie_table_methods[] = {
 };
 
 static const zend_function_entry stack_trace_table_methods[] = {
-		PHP_ME(StackTraceTable, values, NULL, ZEND_ACC_PUBLIC)
+		PHP_ME(StackTraceTable, values, arginfo_stack_trace_table_values, ZEND_ACC_PUBLIC)
 		PHP_FE_END
 };
 

+ 211 - 0
wrapper.h

@@ -0,0 +1,211 @@
+#ifndef EBP_C_WRAPPER_H
+#define EBP_C_WRAPPER_H
+
+
+// PHP7.4 +
+#if !defined(ZEND_ACC_IMPLICIT_PUBLIC)
+# define ZEND_ACC_IMPLICIT_PUBLIC ZEND_ACC_PUBLIC
+#endif
+
+
+// PHP8+
+#if !defined(ZEND_ACC_DTOR)
+#define ZEND_ACC_DTOR       0x4000
+#endif
+
+// PHP5+
+#if PHP_MAJOR_VERSION <7
+
+#if PHP_VERSION_ID < 50500
+#define sc_zend_throw_exception(a, b, c) zend_throw_exception(a, (char *)b, c)
+#else
+#define sc_zend_throw_exception zend_throw_exception
+#endif
+
+#define sc_zend_throw_exception_tsrmls_cc sc_zend_throw_exception
+#define IS_TRUE                               1
+#define SC_MAKE_STD_ZVAL(p)                   MAKE_STD_ZVAL(p)
+#define SC_RETURN_STRINGL(k, l) RETURN_STRINGL(k, l, 1)
+#define sc_zval_ptr_dtor                      zval_ptr_dtor
+#define sc_zval_add_ref(a)                       zval_add_ref(&a)
+static inline int sc_add_assoc_long_ex(zval *arg, const char *key, size_t key_len, long value)
+{
+	return add_assoc_long_ex(arg, key, key_len + 1, value);
+}
+
+static inline int sc_add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double value)
+{
+	return add_assoc_double_ex(arg, key, key_len + 1, value);
+}
+
+static inline int sc_add_assoc_zval_ex(zval *arg, const char *key, size_t key_len, zval* value)
+{
+	return add_assoc_zval_ex(arg, key, key_len + 1, value);
+}
+
+static inline int sc_add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, char *str, size_t length, int __duplicate)
+{
+	return add_assoc_stringl_ex(arg, key, key_len + 1, str, length, __duplicate);
+}
+
+static inline int sc_add_assoc_null_ex(zval *arg, const char *key, size_t key_len)
+{
+	return add_assoc_null_ex(arg, key, key_len + 1);
+}
+
+static inline zval *sc_zend_hash_find(HashTable *ht, char *k, int len)
+{
+	zval **tmp = NULL;
+	if (zend_hash_find(ht, k, len + 1, (void **) &tmp) == SUCCESS)
+	{
+		return *tmp;
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+static inline zval *sc_zend_hash_index_find(HashTable *ht, ulong h)
+{
+	zval **tmp = NULL;
+	if (zend_hash_index_find(ht, h, (void **) &tmp) == SUCCESS)
+	{
+		return *tmp;
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+#define sc_zend_update_property_string    zend_update_property_string
+
+#define sc_zend_read_property(a, b, c, d, e)  zend_read_property(a, b, c, d, e TSRMLS_CC)
+
+#define SC_HASHTABLE_FOREACH_START2(ht, k, klen, ktype, entry)\
+    zval **tmp = NULL; ulong_t idx;\
+    for (zend_hash_internal_pointer_reset(ht); \
+            (ktype = zend_hash_get_current_key_ex(ht, &k, &klen, &idx, 0, NULL)) != HASH_KEY_NON_EXISTANT; \
+            zend_hash_move_forward(ht)\
+        ) { \
+    if (zend_hash_get_current_data(ht, (void**)&tmp) == FAILURE) {\
+        continue;\
+    }\
+    entry = *tmp;\
+    klen --;
+
+#define SC_HASHTABLE_FOREACH_END() }
+
+#define sc_add_next_index_stringl             add_next_index_stringl
+#define sc_zend_hash_get_current_data         zend_hash_get_current_data
+#else
+// PHP7
+#define sc_zend_throw_exception zend_throw_exception
+#define sc_zend_hash_find   zend_hash_str_find
+#define sc_zend_hash_index_find   zend_hash_index_find
+#define SC_MAKE_STD_ZVAL(p)             zval _stack_zval_##p; p = &(_stack_zval_##p)
+#define SC_RETURN_STRINGL(k, l) RETURN_STRINGL(k, l)
+#define sc_zval_ptr_dtor(p)  zval_ptr_dtor(*p)
+#define sc_zval_add_ref(p)   Z_TRY_ADDREF_P(p)
+#define sc_add_assoc_long_ex                  add_assoc_long_ex
+#define sc_add_assoc_double_ex                add_assoc_double_ex
+#define sc_add_assoc_zval_ex                  add_assoc_zval_ex
+#define sc_add_assoc_stringl_ex(a, b, c, d, e, f)               add_assoc_stringl_ex(a, b, c, d, e)
+#define sc_add_assoc_null_ex(a, b, c)               add_assoc_null_ex(a, b, c)
+
+
+
+#if PHP_VERSION_ID < 80000
+#define sc_zend_throw_exception_tsrmls_cc(a, b, c) sc_zend_throw_exception(a, b, c TSRMLS_CC)
+#else
+#define sc_zend_throw_exception_tsrmls_cc(a, b, c) sc_zend_throw_exception(a, b, c)
+#endif
+
+
+static inline zval* sc_zend_read_property(zend_class_entry *class_ptr, zval *obj, const char *s, size_t len, int silent)
+{
+    zval rv;
+#if PHP_VERSION_ID < 80000
+     return zend_read_property(class_ptr, obj, s, len, silent, &rv);
+#else
+    zend_object *zendObject;
+    zendObject=Z_OBJ_P(obj);
+     return zend_read_property(class_ptr, zendObject, s, len, silent, &rv);
+#endif
+
+}
+
+
+static  inline void sc_zend_update_property_string( zend_class_entry *scope, zval *object, const char *name, size_t name_length, const char *value)
+{
+#if PHP_VERSION_ID < 80000
+     return zend_update_property_string(scope, object, name, name_length,  value TSRMLS_CC);
+#else
+    zend_object *zendObject;
+    zendObject=Z_OBJ_P(object);
+    return zend_update_property_string(scope, zendObject, name, name_length,  value);
+#endif
+}
+
+
+static  inline void sc_zend_update_property(zend_class_entry *scope, zval *return_value, const char *name, size_t name_length, zval *value)
+{
+#if PHP_VERSION_ID < 80000
+     return zend_update_property(scope, return_value, name, name_length,  value TSRMLS_CC);
+#else
+    zend_object *zendObject;
+    zendObject=Z_OBJ_P(return_value);
+    return zend_update_property(scope, zendObject, name, name_length,  value);
+#endif
+}
+
+static  inline void sc_zend_update_property_long(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value)
+{
+#if PHP_VERSION_ID < 80000
+     return zend_update_property_long(scope, object, name, name_length,  value TSRMLS_CC);
+#else
+    zend_object *zendObject;
+    zendObject=Z_OBJ_P(object);
+    return zend_update_property_long(scope, zendObject, name, name_length,  value);
+#endif
+}
+
+static  inline void sc_zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value) /* {{{ */
+{
+#if PHP_VERSION_ID < 80000
+     return zend_update_property_bool(scope, object, name, name_length,  value TSRMLS_CC);
+#else
+    zend_object *zendObject;
+    zendObject=Z_OBJ_P(object);
+    return zend_update_property_bool(scope, zendObject, name, name_length,  value);
+#endif
+}
+
+#define SC_HASHTABLE_FOREACH_START2(ht, k, klen, ktype, _val) zend_string *_foreach_key;\
+    ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _foreach_key, _val);\
+    if (!_foreach_key) {k = NULL; klen = 0; ktype = 0;}\
+    else {k = _foreach_key->val, klen=_foreach_key->len; ktype = 1;} {
+
+#define SC_HASHTABLE_FOREACH_END()                 } ZEND_HASH_FOREACH_END();
+
+#define sc_add_next_index_stringl(arr, str, len, dup)    add_next_index_stringl(arr, str, len)
+
+static inline int sc_zend_hash_get_current_data(HashTable *ht, void **v)
+{
+    zval *value = zend_hash_get_current_data(ht);
+    if (value == NULL)
+    {
+        return FAILURE;
+    }
+    else
+    {
+        *v = (void *) value;
+        return SUCCESS;
+    }
+}
+#endif
+
+#define php_array_get_value(ht, str, v) ((v = sc_zend_hash_find(ht, (char *)str, sizeof(str)-1)) && !ZVAL_IS_NULL(v))
+
+#endif //EBP_C_WRAPPER_H