1717#include <stdio.h>
1818#include <stdlib.h>
1919#include <string.h>
20+ #include <inttypes.h>
2021#include <bpf/libbpf.h>
2122#include <bpf/btf.h>
2223#include <caml/mlvalues.h>
@@ -149,6 +150,7 @@ value btf_type_by_id_stub(value btf_handle, value type_id) {
149150 case BTF_KIND_STRUCT :
150151 case BTF_KIND_UNION :
151152 case BTF_KIND_ENUM :
153+ case BTF_KIND_ENUM64 :
152154 size = t -> size ;
153155 break ;
154156 case BTF_KIND_PTR :
@@ -206,8 +208,8 @@ value btf_type_get_members_stub(value btf_handle, value type_id) {
206208 }
207209
208210 int kind = btf_kind (t );
209- if (kind != BTF_KIND_STRUCT && kind != BTF_KIND_UNION && kind != BTF_KIND_ENUM ) {
210- /* Return empty array for non-struct/union/enum types */
211+ if (kind != BTF_KIND_STRUCT && kind != BTF_KIND_UNION && kind != BTF_KIND_ENUM && kind != BTF_KIND_ENUM64 ) {
212+ /* Return empty array for non-struct/union/enum/enum64 types */
211213 CAMLreturn (caml_alloc_tuple (0 ));
212214 }
213215
@@ -227,8 +229,30 @@ value btf_type_get_members_stub(value btf_handle, value type_id) {
227229
228230 member_tuple = caml_alloc_tuple (2 );
229231 Store_field (member_tuple , 0 , caml_copy_string (enum_name ));
230- /* For enums, store the value instead of type_id */
231- Store_field (member_tuple , 1 , Val_int (enums [i ].val ));
232+ /* For enums, convert value to string for consistency with enum64 */
233+ char value_str [16 ];
234+ snprintf (value_str , sizeof (value_str ), "%d" , enums [i ].val );
235+ Store_field (member_tuple , 1 , caml_copy_string (value_str ));
236+
237+ Store_field (result , i , member_tuple );
238+ }
239+ } else if (kind == BTF_KIND_ENUM64 ) {
240+ /* Handle enum64 types - extract enum values */
241+ const struct btf_enum64 * enums = btf_enum64 (t );
242+ for (int i = 0 ; i < vlen ; i ++ ) {
243+ const char * enum_name = btf__name_by_offset (btf , enums [i ].name_off );
244+ if (!enum_name ) enum_name = "" ;
245+
246+ member_tuple = caml_alloc_tuple (2 );
247+ Store_field (member_tuple , 0 , caml_copy_string (enum_name ));
248+
249+ /* For enum64, combine hi32 and lo32 to get the full 64-bit value */
250+ uint64_t full_value = ((uint64_t )enums [i ].val_hi32 << 32 ) | enums [i ].val_lo32 ;
251+
252+ /* Convert to string to preserve full precision */
253+ char value_str [32 ];
254+ snprintf (value_str , sizeof (value_str ), "%" PRIu64 , full_value );
255+ Store_field (member_tuple , 1 , caml_copy_string (value_str ));
232256
233257 Store_field (result , i , member_tuple );
234258 }
@@ -241,7 +265,10 @@ value btf_type_get_members_stub(value btf_handle, value type_id) {
241265
242266 member_tuple = caml_alloc_tuple (2 );
243267 Store_field (member_tuple , 0 , caml_copy_string (member_name ));
244- Store_field (member_tuple , 1 , Val_int (members [i ].type ));
268+ /* For struct/union, convert type_id to string for consistency */
269+ char type_id_str [16 ];
270+ snprintf (type_id_str , sizeof (type_id_str ), "%u" , members [i ].type );
271+ Store_field (member_tuple , 1 , caml_copy_string (type_id_str ));
245272
246273 Store_field (result , i , member_tuple );
247274 }
@@ -305,13 +332,15 @@ static char* resolve_type_to_string(struct btf *btf, int type_id) {
305332 }
306333 case BTF_KIND_STRUCT :
307334 case BTF_KIND_UNION :
308- case BTF_KIND_ENUM : {
335+ case BTF_KIND_ENUM :
336+ case BTF_KIND_ENUM64 : {
309337 const char * name = btf__name_by_offset (btf , t -> name_off );
310338 if (name && strlen (name ) > 0 ) {
311339 return strdup (name );
312340 }
313341 return strdup (kind == BTF_KIND_STRUCT ? "struct" :
314- kind == BTF_KIND_UNION ? "union" : "enum" );
342+ kind == BTF_KIND_UNION ? "union" :
343+ kind == BTF_KIND_ENUM ? "enum" : "enum64" );
315344 }
316345 default :
317346 return strdup ("unknown" );
@@ -477,22 +506,18 @@ value btf_resolve_type_stub(value btf_handle, value type_id) {
477506 }
478507 case BTF_KIND_STRUCT :
479508 case BTF_KIND_UNION :
480- case BTF_KIND_ENUM : {
481- const char * name = btf__name_by_offset (btf , t -> name_off );
482- if (name && strlen (name ) > 0 ) {
483- CAMLreturn (caml_copy_string (name ));
484- }
485- /* For anonymous structs/unions */
486- CAMLreturn (caml_copy_string (kind == BTF_KIND_STRUCT ? "struct" :
487- kind == BTF_KIND_UNION ? "union" : "enum" ));
488- }
509+ case BTF_KIND_ENUM :
489510 case BTF_KIND_ENUM64 : {
490511 const char * name = btf__name_by_offset (btf , t -> name_off );
491512 if (name && strlen (name ) > 0 ) {
492513 CAMLreturn (caml_copy_string (name ));
493514 }
494- CAMLreturn (caml_copy_string ("enum64" ));
515+ /* For anonymous structs/unions/enums */
516+ CAMLreturn (caml_copy_string (kind == BTF_KIND_STRUCT ? "struct" :
517+ kind == BTF_KIND_UNION ? "union" :
518+ kind == BTF_KIND_ENUM ? "enum" : "enum64" ));
495519 }
520+
496521 case BTF_KIND_FWD : {
497522 const char * name = btf__name_by_offset (btf , t -> name_off );
498523 if (name && strlen (name ) > 0 ) {
0 commit comments