btf_vmlinux.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package tracer
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "github.com/cilium/ebpf"
  6. "github.com/cilium/ebpf/btf"
  7. "runtime"
  8. )
  9. func kernel_struct_field_offset(btfSpec *btf.Spec, member string, field string) int32 {
  10. typ, err := btfSpec.AnyTypeByName(member)
  11. if err != nil {
  12. return ETR_NOTSUPP
  13. }
  14. return kernel_struct_field_offset_helper(btfSpec, typ, field)
  15. }
  16. func kernel_struct_field_offset_helper(btfSpec *btf.Spec, typ btf.Type, field string) int32 {
  17. //var offset btf.Bits
  18. switch typ.(type) {
  19. case *btf.Struct, *btf.Union:
  20. var membersT []btf.Member
  21. switch t := typ.(type) {
  22. case *btf.Struct:
  23. membersT = t.Members
  24. case *btf.Union:
  25. membersT = t.Members
  26. }
  27. for _, member := range membersT {
  28. if member.Name == field {
  29. //fmt.Printf("Struct:%s,0x%x\n", member.Name, member.Offset.Bytes())
  30. return int32(member.Offset.Bytes())
  31. }
  32. if member.Name == "" {
  33. //fmt.Printf("下钻:%s,0x%x\n", member.Type, member.Offset/8)
  34. retval := kernel_struct_field_offset_helper(btfSpec, member.Type, field)
  35. if retval >= 0 {
  36. return int32(member.Offset.Bytes()) + retval
  37. }
  38. }
  39. }
  40. }
  41. return ETR_NOTEXIST
  42. }
  43. func bpf_table_pre_set_value(collectionSpec *ebpf.CollectionSpec, opts *ebpf.CollectionOptions, mapName string, data any) int {
  44. m, ok := collectionSpec.Maps[mapName]
  45. if ok {
  46. newMap, err := ebpf.NewMap(&ebpf.MapSpec{
  47. Type: m.Type,
  48. KeySize: m.KeySize,
  49. ValueSize: m.ValueSize,
  50. MaxEntries: m.MaxEntries,
  51. })
  52. if err != nil {
  53. return ETR_UPDATE_MAP_FAILD
  54. }
  55. //// Convert test_t to slice
  56. //numCPU := runtime.NumCPU()
  57. //off := make([]interface{}, numCPU)
  58. //for i := range off {
  59. // off[i] = data
  60. //}
  61. key := make([]byte, 4) // Assuming int key size is 4 bytes
  62. binary.LittleEndian.PutUint32(key, 0) // Assuming the key is an integer
  63. if err = newMap.Update(key, data, ebpf.UpdateAny); err != nil {
  64. return ETR_UPDATE_MAP_FAILD
  65. }
  66. opts.MapReplacements[mapName] = newMap
  67. //opts.MapReplacements = map[string]*ebpf.Map{
  68. // mapName: newMap,
  69. //}
  70. } else {
  71. return ETR_UPDATE_MAP_FAILD
  72. }
  73. return ETR_OK
  74. }
  75. func bpf_table_set_value(collection *ebpf.Collection, mapName string, key uint32, data any) int {
  76. m, ok := collection.Maps[mapName]
  77. //for s, m2 := range collection.Maps {
  78. // fmt.Println(s, m2.String())
  79. //}
  80. //fmt.Println("bpf_table_set_value", m, mapName, data)
  81. if ok {
  82. k := make([]byte, 4) // Assuming int k size is 4 bytes
  83. binary.LittleEndian.PutUint32(k, key) // Assuming the key is an integer
  84. if err := m.Update(k, data, ebpf.UpdateAny); err != nil {
  85. return ETR_UPDATE_MAP_FAILD
  86. }
  87. } else {
  88. return ETR_UPDATE_MAP_FAILD
  89. }
  90. return ETR_OK
  91. }
  92. func test(collectionSpec *ebpf.CollectionSpec, opts *ebpf.CollectionOptions) {
  93. fmt.Println("collectionSpec.Maps start --")
  94. var newMap *ebpf.Map
  95. var err error
  96. m, ok := collectionSpec.Maps["test_heap"]
  97. if ok {
  98. newMap, err = ebpf.NewMap(&ebpf.MapSpec{
  99. Type: m.Type, // 设置 Map 的类型
  100. KeySize: m.KeySize, // 设置 Key 的大小
  101. ValueSize: m.ValueSize, // 设置 Value 的大小
  102. MaxEntries: m.MaxEntries, // 设置最大条目数
  103. })
  104. if err != nil {
  105. fmt.Println("Failed to create map:", err)
  106. }
  107. data := &testStruct{
  108. test_id: 123123123,
  109. }
  110. // Convert test_t to slice
  111. numCPU := runtime.NumCPU()
  112. value := make([]testStruct, numCPU)
  113. for i := range value {
  114. value[i] = *data
  115. }
  116. key := make([]byte, 4) // Assuming int key size is 4 bytes
  117. binary.LittleEndian.PutUint32(key, 0) // Assuming the key is an integer
  118. if err := newMap.Update(key, value, 0); err != nil {
  119. panic(err)
  120. }
  121. opts.MapReplacements["test_heap"] = newMap
  122. //opts.MapReplacements = map[string]*ebpf.Map{
  123. // "test_heap": newMap,
  124. //}
  125. }
  126. }