github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/btf/core_reloc_test.go (about) 1 package btf_test 2 3 import ( 4 "bytes" 5 "io" 6 "os" 7 "slices" 8 "strings" 9 "testing" 10 11 "github.com/cilium/ebpf" 12 "github.com/cilium/ebpf/btf" 13 "github.com/cilium/ebpf/internal" 14 "github.com/cilium/ebpf/internal/testutils" 15 16 "github.com/go-quicktest/qt" 17 ) 18 19 func TestCORERelocationLoad(t *testing.T) { 20 file := testutils.NativeFile(t, "testdata/relocs-%s.elf") 21 fh, err := os.Open(file) 22 if err != nil { 23 t.Fatal(err) 24 } 25 defer fh.Close() 26 27 spec, err := ebpf.LoadCollectionSpecFromReader(fh) 28 if err != nil { 29 t.Fatal(err) 30 } 31 32 for _, progSpec := range spec.Programs { 33 t.Run(progSpec.Name, func(t *testing.T) { 34 if _, err := fh.Seek(0, io.SeekStart); err != nil { 35 t.Fatal(err) 36 } 37 38 prog, err := ebpf.NewProgramWithOptions(progSpec, ebpf.ProgramOptions{ 39 KernelTypes: spec.Types, 40 }) 41 testutils.SkipIfNotSupported(t, err) 42 43 if strings.HasPrefix(progSpec.Name, "err_") { 44 if err == nil { 45 prog.Close() 46 t.Fatal("Expected an error") 47 } 48 t.Log("Got expected error:", err) 49 return 50 } 51 52 if err != nil { 53 t.Fatal("Load program:", err) 54 } 55 defer prog.Close() 56 57 ret, _, err := prog.Test(internal.EmptyBPFContext) 58 testutils.SkipIfNotSupported(t, err) 59 if err != nil { 60 t.Fatal("Error when running:", err) 61 } 62 63 if ret != 0 { 64 t.Error("Assertion failed on line", ret) 65 } 66 }) 67 } 68 } 69 70 func TestCORERelocationRead(t *testing.T) { 71 file := testutils.NativeFile(t, "testdata/relocs_read-%s.elf") 72 spec, err := ebpf.LoadCollectionSpec(file) 73 if err != nil { 74 t.Fatal(err) 75 } 76 77 targetFile := testutils.NativeFile(t, "testdata/relocs_read_tgt-%s.elf") 78 targetSpec, err := btf.LoadSpec(targetFile) 79 if err != nil { 80 t.Fatal(err) 81 } 82 83 for _, progSpec := range spec.Programs { 84 t.Run(progSpec.Name, func(t *testing.T) { 85 prog, err := ebpf.NewProgramWithOptions(progSpec, ebpf.ProgramOptions{ 86 KernelTypes: targetSpec, 87 }) 88 testutils.SkipIfNotSupported(t, err) 89 if err != nil { 90 t.Fatal("Load program:", err) 91 } 92 defer prog.Close() 93 94 ret, _, err := prog.Test(internal.EmptyBPFContext) 95 testutils.SkipIfNotSupported(t, err) 96 if err != nil { 97 t.Fatal("Error when running:", err) 98 } 99 100 if ret != 0 { 101 t.Error("Assertion failed on line", ret) 102 } 103 }) 104 } 105 } 106 107 func TestLD64IMMReloc(t *testing.T) { 108 testutils.SkipOnOldKernel(t, "5.4", "vmlinux BTF in sysfs") 109 110 file := testutils.NativeFile(t, "testdata/relocs_enum-%s.elf") 111 fh, err := os.Open(file) 112 if err != nil { 113 t.Fatal(err) 114 } 115 defer fh.Close() 116 117 spec, err := ebpf.LoadCollectionSpecFromReader(fh) 118 if err != nil { 119 t.Fatal(err) 120 } 121 122 coll, err := ebpf.NewCollection(spec) 123 if err != nil { 124 t.Fatal(err) 125 } 126 defer coll.Close() 127 } 128 129 func TestCOREPoisonLineInfo(t *testing.T) { 130 testutils.SkipOnOldKernel(t, "5.0", "program ext_infos") 131 132 spec, err := ebpf.LoadCollectionSpec(testutils.NativeFile(t, "../testdata/errors-%s.elf")) 133 qt.Assert(t, qt.IsNil(err)) 134 135 var b btf.Builder 136 raw, err := b.Marshal(nil, nil) 137 qt.Assert(t, qt.IsNil(err)) 138 empty, err := btf.LoadSpecFromReader(bytes.NewReader(raw)) 139 qt.Assert(t, qt.IsNil(err)) 140 141 for _, test := range []struct { 142 name string 143 }{ 144 {"poisoned_single"}, 145 {"poisoned_double"}, 146 } { 147 progSpec := spec.Programs[test.name] 148 qt.Assert(t, qt.IsNotNil(progSpec)) 149 150 t.Run(test.name, func(t *testing.T) { 151 t.Log(progSpec.Instructions) 152 _, err := ebpf.NewProgramWithOptions(progSpec, ebpf.ProgramOptions{ 153 KernelTypes: empty, 154 }) 155 testutils.SkipIfNotSupported(t, err) 156 157 var ve *ebpf.VerifierError 158 qt.Assert(t, qt.ErrorAs(err, &ve)) 159 found := slices.ContainsFunc(ve.Log, func(line string) bool { 160 return strings.HasPrefix(line, "; instruction poisoned by CO-RE") 161 }) 162 qt.Assert(t, qt.IsTrue(found)) 163 t.Logf("%-5v", ve) 164 }) 165 } 166 }