btf_vmlinux.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. fmt.Println(err)
  66. return ETR_UPDATE_MAP_FAILD
  67. }
  68. opts.MapReplacements[mapName] = newMap
  69. //opts.MapReplacements = map[string]*ebpf.Map{
  70. // mapName: newMap,
  71. //}
  72. } else {
  73. return ETR_UPDATE_MAP_FAILD
  74. }
  75. return ETR_OK
  76. }
  77. func bpf_table_set_value(collection *ebpf.Collection, mapName string, key uint32, data any) (int, error) {
  78. m, ok := collection.Maps[mapName]
  79. //for s, m2 := range collection.Maps {
  80. // fmt.Println(s, m2.String())
  81. //}
  82. //fmt.Println("bpf_table_set_value", m, mapName, data)
  83. if ok {
  84. k := make([]byte, 4) // Assuming int k size is 4 bytes
  85. binary.LittleEndian.PutUint32(k, key) // Assuming the key is an integer
  86. if err := m.Update(k, data, ebpf.UpdateAny); err != nil {
  87. return ETR_UPDATE_MAP_FAILD, err
  88. }
  89. } else {
  90. return ETR_UPDATE_MAP_FAILD, errors.New("cannot find map " + mapName)
  91. }
  92. return ETR_OK, nil
  93. }
  94. func test(collectionSpec *ebpf.CollectionSpec, opts *ebpf.CollectionOptions) {
  95. fmt.Println("collectionSpec.Maps start --")
  96. var newMap *ebpf.Map
  97. var err error
  98. m, ok := collectionSpec.Maps["test_heap"]
  99. if ok {
  100. newMap, err = ebpf.NewMap(&ebpf.MapSpec{
  101. Type: m.Type, // 设置 Map 的类型
  102. KeySize: m.KeySize, // 设置 Key 的大小
  103. ValueSize: m.ValueSize, // 设置 Value 的大小
  104. MaxEntries: m.MaxEntries, // 设置最大条目数
  105. })
  106. if err != nil {
  107. fmt.Println("Failed to create map:", err)
  108. }
  109. data := &testStruct{
  110. test_id: 123123123,
  111. }
  112. // Convert test_t to slice
  113. numCPU := runtime.NumCPU()
  114. value := make([]testStruct, numCPU)
  115. for i := range value {
  116. value[i] = *data
  117. }
  118. key := make([]byte, 4) // Assuming int key size is 4 bytes
  119. binary.LittleEndian.PutUint32(key, 0) // Assuming the key is an integer
  120. if err := newMap.Update(key, value, 0); err != nil {
  121. panic(err)
  122. }
  123. opts.MapReplacements["test_heap"] = newMap
  124. //opts.MapReplacements = map[string]*ebpf.Map{
  125. // "test_heap": newMap,
  126. //}
  127. }
  128. }