btf_vmlinux.go 3.8 KB

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