From f654b112fa28670872a2040d9f062f31117bec71 Mon Sep 17 00:00:00 2001 From: Dylan Reimerink Date: Tue, 22 Feb 2022 18:20:08 +0100 Subject: [PATCH] asm: moved Instruction.Symbol and Instruction.Reference into metadata This commit adds per-instruction metadata, which is sparse in nature, meaning that most instructions don't have metadata but some do. Metadata is linked to an instruction via a pointer which is nil by default, thus if an instruction has no metadata, at most one pointer worth of space is unused which is desirable since we expect the size of the metadata struct to grow in future commits. The metadata struct is copy-on-write, so multiple instructions can share the same metadata object after being copied, but as soon as a modification on one of the instruction's metadata is performed, the metadata object is copied so writes to a copied instruction doesn't effect the original instruction. This commit also deprecates `Instruction.Sym` in favor of `Instruction.WithSymbol`. This follows the convention of prefixing func names with `With...` if they have value receivers to make it clear to callers that this doesn't modify the instruction it is being called on. --- asm/dsl_test.go | 18 ++--- asm/instruction.go | 127 +++++++++++++++++++++++------- asm/instruction_test.go | 5 +- asm/jump.go | 60 +++++++------- collection.go | 8 +- collection_test.go | 9 +-- elf_reader.go | 12 ++- elf_reader_test.go | 2 +- example_sock_extract_dist_test.go | 8 +- features/misc.go | 6 +- info.go | 2 +- linker.go | 2 +- linker_test.go | 6 +- prog.go | 4 +- prog_test.go | 4 +- ringbuf/reader_test.go | 2 +- 16 files changed, 166 insertions(+), 109 deletions(-) diff --git a/asm/dsl_test.go b/asm/dsl_test.go index ddbf8172a..9409fc287 100644 --- a/asm/dsl_test.go +++ b/asm/dsl_test.go @@ -25,21 +25,21 @@ func TestDSL(t *testing.T) { OpCode: 0x04, Dst: R1, Constant: 22, }}, {"JSGT.Imm", JSGT.Imm(R1, 4, "foo"), Instruction{ - OpCode: 0x65, Dst: R1, Constant: 4, Offset: -1, Reference: "foo", - }}, + OpCode: 0x65, Dst: R1, Constant: 4, Offset: -1, + }.WithReference("foo")}, {"JSGT.Imm32", JSGT.Imm32(R1, -2, "foo"), Instruction{ - OpCode: 0x66, Dst: R1, Constant: -2, Offset: -1, Reference: "foo", - }}, + OpCode: 0x66, Dst: R1, Constant: -2, Offset: -1, + }.WithReference("foo")}, {"JSLT.Reg", JSLT.Reg(R1, R2, "foo"), Instruction{ - OpCode: 0xcd, Dst: R1, Src: R2, Offset: -1, Reference: "foo", - }}, + OpCode: 0xcd, Dst: R1, Src: R2, Offset: -1, + }.WithReference("foo")}, {"JSLT.Reg32", JSLT.Reg32(R1, R3, "foo"), Instruction{ - OpCode: 0xce, Dst: R1, Src: R3, Offset: -1, Reference: "foo", - }}, + OpCode: 0xce, Dst: R1, Src: R3, Offset: -1, + }.WithReference("foo")}, } for _, tc := range testcases { - if tc.have != tc.want { + if !tc.have.equal(tc.want) { t.Errorf("%s: have %v, want %v", tc.name, tc.have, tc.want) } } diff --git a/asm/instruction.go b/asm/instruction.go index bc3b883f4..10174c44b 100644 --- a/asm/instruction.go +++ b/asm/instruction.go @@ -35,17 +35,39 @@ type Instruction struct { Offset int16 Constant int64 - // Reference denotes a reference (e.g. a jump) to another symbol. - Reference string + // Metadata contains optional metadata about this instruction + metadata *metadata +} + +// WithSymbol marks the Instruction as a Symbol, which other Instructions +// can point to using corresponding calls to WithReference. +func (ins Instruction) WithSymbol(name string) Instruction { + if (ins.metadata != nil && ins.metadata.symbol == name) || + (ins.metadata == nil && name == "") { + return ins + } - // Symbol denotes an instruction at the start of a function body. - Symbol string + ins.metadata = ins.metadata.copy() + ins.metadata.symbol = name + return ins } // Sym creates a symbol. +// +// Deprecated: use WithSymbol instead. func (ins Instruction) Sym(name string) Instruction { - ins.Symbol = name - return ins + return ins.WithSymbol(name) +} + +// Symbol returns the value ins has been marked with using WithSymbol, +// otherwise returns an empty string. A symbol is often an Instruction +// at the start of a function body. +func (ins Instruction) Symbol() string { + if ins.metadata == nil { + return "" + } + + return ins.metadata.symbol } // Unmarshal decodes a BPF instruction. @@ -299,16 +321,63 @@ func (ins Instruction) Format(f fmt.State, c rune) { } ref: - if ins.Reference != "" { - fmt.Fprintf(f, " <%s>", ins.Reference) + if ins.Reference() != "" { + fmt.Fprintf(f, " <%s>", ins.Reference()) } } +func (ins Instruction) equal(other Instruction) bool { + return ins.OpCode == other.OpCode && + ins.Dst == other.Dst && + ins.Src == other.Src && + ins.Offset == other.Offset && + ins.Constant == other.Constant +} + // Size returns the amount of bytes ins would occupy in binary form. func (ins Instruction) Size() uint64 { return uint64(InstructionSize * ins.OpCode.rawInstructions()) } +// WithReference makes ins reference another Symbol or map by name. +func (ins Instruction) WithReference(ref string) Instruction { + if (ins.metadata != nil && ins.metadata.reference == ref) || + (ins.metadata == nil && ref == "") { + return ins + } + + ins.metadata = ins.metadata.copy() + ins.metadata.reference = ref + return ins +} + +// Reference returns the Symbol or map name referenced by ins, if any. +func (ins Instruction) Reference() string { + if ins.metadata == nil { + return "" + } + + return ins.metadata.reference +} + +// metadata holds metadata about an Instruction. +type metadata struct { + // reference denotes a reference (e.g. a jump) to another symbol. + reference string + // symbol denotes an instruction at the start of a function body. + symbol string +} + +// copy returns a copy of metadata. +// Always returns a valid pointer, even when called on a nil metadata. +func (m *metadata) copy() *metadata { + var copy metadata + if m != nil { + copy = *m + } + return © +} + // Instructions is an eBPF program. type Instructions []Instruction @@ -342,7 +411,7 @@ func (insns Instructions) Name() string { if len(insns) == 0 { return "" } - return insns[0].Symbol + return insns[0].Symbol() } func (insns Instructions) String() string { @@ -369,7 +438,7 @@ func (insns Instructions) RewriteMapPtr(symbol string, fd int) error { found := false for i := range insns { ins := &insns[i] - if ins.Reference != symbol { + if ins.Reference() != symbol { continue } @@ -393,15 +462,15 @@ func (insns Instructions) SymbolOffsets() (map[string]int, error) { offsets := make(map[string]int) for i, ins := range insns { - if ins.Symbol == "" { + if ins.Symbol() == "" { continue } - if _, ok := offsets[ins.Symbol]; ok { - return nil, fmt.Errorf("duplicate symbol %s", ins.Symbol) + if _, ok := offsets[ins.Symbol()]; ok { + return nil, fmt.Errorf("duplicate symbol %s", ins.Symbol()) } - offsets[ins.Symbol] = i + offsets[ins.Symbol()] = i } return offsets, nil @@ -418,7 +487,7 @@ func (insns Instructions) FunctionReferences() map[string]bool { continue } - if ins.Reference == "" { + if ins.Reference() == "" { continue } @@ -426,7 +495,7 @@ func (insns Instructions) FunctionReferences() map[string]bool { continue } - calls[ins.Reference] = true + calls[ins.Reference()] = true } return calls @@ -438,11 +507,11 @@ func (insns Instructions) ReferenceOffsets() map[string][]int { offsets := make(map[string][]int) for i, ins := range insns { - if ins.Reference == "" { + if ins.Reference() == "" { continue } - offsets[ins.Reference] = append(offsets[ins.Reference], i) + offsets[ins.Reference()] = append(offsets[ins.Reference()], i) } return offsets @@ -493,8 +562,8 @@ func (insns Instructions) Format(f fmt.State, c rune) { iter := insns.Iterate() for iter.Next() { - if iter.Ins.Symbol != "" { - fmt.Fprintf(f, "%s%s:\n", symIndent, iter.Ins.Symbol) + if iter.Ins.Symbol() != "" { + fmt.Fprintf(f, "%s%s:\n", symIndent, iter.Ins.Symbol()) } fmt.Fprintf(f, "%s%*d: %v\n", indent, offsetWidth, iter.Offset, iter.Ins) } @@ -552,15 +621,15 @@ func (insns Instructions) resolveFunctionReferences() error { for iter.Next() { ins := iter.Ins - if ins.Symbol == "" { + if ins.Symbol() == "" { continue } - if _, ok := symbolOffsets[ins.Symbol]; ok { - return fmt.Errorf("duplicate symbol %s", ins.Symbol) + if _, ok := symbolOffsets[ins.Symbol()]; ok { + return fmt.Errorf("duplicate symbol %s", ins.Symbol()) } - symbolOffsets[ins.Symbol] = iter.Offset + symbolOffsets[ins.Symbol()] = iter.Offset } // Find all instructions tagged as references to other symbols. @@ -572,23 +641,23 @@ func (insns Instructions) resolveFunctionReferences() error { offset := iter.Offset ins := iter.Ins - if ins.Reference == "" { + if ins.Reference() == "" { continue } switch { case ins.IsFunctionReference() && ins.Constant == -1: - symOffset, ok := symbolOffsets[ins.Reference] + symOffset, ok := symbolOffsets[ins.Reference()] if !ok { - return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference, ErrUnsatisfiedProgramReference) + return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference(), ErrUnsatisfiedProgramReference) } ins.Constant = int64(symOffset - offset - 1) case ins.OpCode.Class().IsJump() && ins.Offset == -1: - symOffset, ok := symbolOffsets[ins.Reference] + symOffset, ok := symbolOffsets[ins.Reference()] if !ok { - return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference, ErrUnsatisfiedProgramReference) + return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference(), ErrUnsatisfiedProgramReference) } ins.Offset = int16(symOffset - offset - 1) diff --git a/asm/instruction_test.go b/asm/instruction_test.go index b18c0f3a0..8d2bc9606 100644 --- a/asm/instruction_test.go +++ b/asm/instruction_test.go @@ -151,10 +151,9 @@ func TestInstructionLoadMapValue(t *testing.T) { func TestInstructionsRewriteMapPtr(t *testing.T) { insns := Instructions{ - LoadMapPtr(R1, 0), + LoadMapPtr(R1, 0).WithReference("good"), Return(), } - insns[0].Reference = "good" if err := insns.RewriteMapPtr("good", 1); err != nil { t.Fatal(err) @@ -181,7 +180,7 @@ func TestInstructionsRewriteMapPtr(t *testing.T) { // program is stringified. func ExampleInstructions_Format() { insns := Instructions{ - FnMapLookupElem.Call().Sym("my_func"), + FnMapLookupElem.Call().WithSymbol("my_func"), LoadImm(R0, 42, DWord), Return(), } diff --git a/asm/jump.go b/asm/jump.go index 199c06940..e31e42cac 100644 --- a/asm/jump.go +++ b/asm/jump.go @@ -63,47 +63,43 @@ func (op JumpOp) Op(source Source) OpCode { // Imm compares 64 bit dst to 64 bit value (sign extended), and adjusts PC by offset if the condition is fulfilled. func (op JumpOp) Imm(dst Register, value int32, label string) Instruction { return Instruction{ - OpCode: op.opCode(JumpClass, ImmSource), - Dst: dst, - Offset: -1, - Constant: int64(value), - Reference: label, - } + OpCode: op.opCode(JumpClass, ImmSource), + Dst: dst, + Offset: -1, + Constant: int64(value), + }.WithReference(label) } // Imm32 compares 32 bit dst to 32 bit value, and adjusts PC by offset if the condition is fulfilled. // Requires kernel 5.1. func (op JumpOp) Imm32(dst Register, value int32, label string) Instruction { return Instruction{ - OpCode: op.opCode(Jump32Class, ImmSource), - Dst: dst, - Offset: -1, - Constant: int64(value), - Reference: label, - } + OpCode: op.opCode(Jump32Class, ImmSource), + Dst: dst, + Offset: -1, + Constant: int64(value), + }.WithReference(label) } // Reg compares 64 bit dst to 64 bit src, and adjusts PC by offset if the condition is fulfilled. func (op JumpOp) Reg(dst, src Register, label string) Instruction { return Instruction{ - OpCode: op.opCode(JumpClass, RegSource), - Dst: dst, - Src: src, - Offset: -1, - Reference: label, - } + OpCode: op.opCode(JumpClass, RegSource), + Dst: dst, + Src: src, + Offset: -1, + }.WithReference(label) } // Reg32 compares 32 bit dst to 32 bit src, and adjusts PC by offset if the condition is fulfilled. // Requires kernel 5.1. func (op JumpOp) Reg32(dst, src Register, label string) Instruction { return Instruction{ - OpCode: op.opCode(Jump32Class, RegSource), - Dst: dst, - Src: src, - Offset: -1, - Reference: label, - } + OpCode: op.opCode(Jump32Class, RegSource), + Dst: dst, + Src: src, + Offset: -1, + }.WithReference(label) } func (op JumpOp) opCode(class Class, source Source) OpCode { @@ -118,16 +114,14 @@ func (op JumpOp) opCode(class Class, source Source) OpCode { func (op JumpOp) Label(label string) Instruction { if op == Call { return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(Call), - Src: PseudoCall, - Constant: -1, - Reference: label, - } + OpCode: OpCode(JumpClass).SetJumpOp(Call), + Src: PseudoCall, + Constant: -1, + }.WithReference(label) } return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(op), - Offset: -1, - Reference: label, - } + OpCode: OpCode(JumpClass).SetJumpOp(op), + Offset: -1, + }.WithReference(label) } diff --git a/collection.go b/collection.go index 8d27828c9..9a44818c1 100644 --- a/collection.go +++ b/collection.go @@ -465,7 +465,7 @@ func (cl *collectionLoader) loadProgram(progName string) (*Program, error) { for i := range progSpec.Instructions { ins := &progSpec.Instructions[i] - if !ins.IsLoadFromMap() || ins.Reference == "" { + if !ins.IsLoadFromMap() || ins.Reference() == "" { continue } @@ -475,17 +475,17 @@ func (cl *collectionLoader) loadProgram(progName string) (*Program, error) { continue } - m, err := cl.loadMap(ins.Reference) + m, err := cl.loadMap(ins.Reference()) if err != nil { return nil, fmt.Errorf("program %s: %w", progName, err) } fd := m.FD() if fd < 0 { - return nil, fmt.Errorf("map %s: %w", ins.Reference, sys.ErrClosedFd) + return nil, fmt.Errorf("map %s: %w", ins.Reference(), sys.ErrClosedFd) } if err := ins.RewriteMapPtr(m.FD()); err != nil { - return nil, fmt.Errorf("program %s: map %s: %w", progName, ins.Reference, err) + return nil, fmt.Errorf("program %s: map %s: %w", progName, ins.Reference(), err) } } diff --git a/collection_test.go b/collection_test.go index e40a749da..00f3a9103 100644 --- a/collection_test.go +++ b/collection_test.go @@ -25,7 +25,7 @@ func TestCollectionSpecNotModified(t *testing.T) { "test": { Type: SocketFilter, Instructions: asm.Instructions{ - asm.LoadImm(asm.R1, 0, asm.DWord), + asm.LoadImm(asm.R1, 0, asm.DWord).WithReference("my-map"), asm.LoadImm(asm.R0, 0, asm.DWord), asm.Return(), }, @@ -34,8 +34,6 @@ func TestCollectionSpecNotModified(t *testing.T) { }, } - cs.Programs["test"].Instructions[0].Reference = "my-map" - coll, err := NewCollection(&cs) if err != nil { t.Fatal(err) @@ -116,7 +114,7 @@ func TestCollectionSpecLoadCopy(t *testing.T) { func TestCollectionSpecRewriteMaps(t *testing.T) { insns := asm.Instructions{ // R1 map - asm.LoadMapPtr(asm.R1, 0), + asm.LoadMapPtr(asm.R1, 0).WithReference("test-map"), // R2 key asm.Mov.Reg(asm.R2, asm.R10), asm.Add.Imm(asm.R2, -4), @@ -125,9 +123,8 @@ func TestCollectionSpecRewriteMaps(t *testing.T) { asm.FnMapLookupElem.Call(), asm.JEq.Imm(asm.R0, 0, "ret"), asm.LoadMem(asm.R0, asm.R0, 0, asm.Word), - asm.Return().Sym("ret"), + asm.Return().WithSymbol("ret"), } - insns[0].Reference = "test-map" cs := &CollectionSpec{ Maps: map[string]*MapSpec{ diff --git a/elf_reader.go b/elf_reader.go index 774956c90..38cf176cb 100644 --- a/elf_reader.go +++ b/elf_reader.go @@ -349,10 +349,8 @@ func (ec *elfCode) loadFunctions(section *elfSection) (map[string]asm.Instructio insns asm.Instructions ) for { - ins := asm.Instruction{ - // Symbols denote the first instruction of a function body. - Symbol: section.symbols[offset].Name, - } + // Symbols denote the first instruction of a function body. + ins := asm.Instruction{}.WithSymbol(section.symbols[offset].Name) // Pull one instruction from the instruction stream. n, err := ins.Unmarshal(r, ec.ByteOrder) @@ -374,7 +372,7 @@ func (ec *elfCode) loadFunctions(section *elfSection) (map[string]asm.Instructio // Decoded the first instruction of a function body but insns already // holds a valid instruction stream. Store the result and flush insns. - if ins.Symbol != "" && insns.Name() != "" { + if ins.Symbol() != "" && insns.Name() != "" { funcs[insns.Name()] = insns insns = nil } @@ -399,7 +397,7 @@ func (ec *elfCode) loadFunctions(section *elfSection) (map[string]asm.Instructio return nil, fmt.Errorf("offset %d: no jump target found at offset %d", offset, tgt) } - ins.Reference = sym + ins = ins.WithReference(sym) ins.Constant = -1 } } @@ -579,7 +577,7 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err return fmt.Errorf("relocation to %q: %w", target.Name, ErrNotSupported) } - ins.Reference = name + *ins = ins.WithReference(name) return nil } diff --git a/elf_reader_test.go b/elf_reader_test.go index aea7e58b9..3ec5faa49 100644 --- a/elf_reader_test.go +++ b/elf_reader_test.go @@ -260,7 +260,7 @@ func TestInlineASMConstant(t *testing.T) { } spec := coll.Programs["asm_relocation"] - if spec.Instructions[0].Reference != "MY_CONST" { + if spec.Instructions[0].Reference() != "MY_CONST" { t.Fatal("First instruction is not a reference to MY_CONST") } diff --git a/example_sock_extract_dist_test.go b/example_sock_extract_dist_test.go index 25dccf65c..cbd1254fd 100644 --- a/example_sock_extract_dist_test.go +++ b/example_sock_extract_dist_test.go @@ -107,11 +107,11 @@ func newDistanceFilter() (*ebpf.Program, *ebpf.Map, error) { // 7th byte in IPv6 is Hop count // LDABS requires ctx in R6 - asm.Mov.Reg(asm.R6, asm.R1).Sym("ipv6"), + asm.Mov.Reg(asm.R6, asm.R1).WithSymbol("ipv6"), asm.LoadAbs(-0x100000+7, asm.Byte), // stash the load result into FP[-4] - asm.StoreMem(asm.RFP, -4, asm.R0, asm.Word).Sym("store-ttl"), + asm.StoreMem(asm.RFP, -4, asm.R0, asm.Word).WithSymbol("store-ttl"), // stash the &FP[-4] into r2 asm.Mov.Reg(asm.R2, asm.RFP), asm.Add.Imm(asm.R2, -4), @@ -128,7 +128,7 @@ func newDistanceFilter() (*ebpf.Program, *ebpf.Map, error) { // MapUpdate // r1 has map ptr - asm.LoadMapPtr(asm.R1, ttls.FD()).Sym("update-map"), + asm.LoadMapPtr(asm.R1, ttls.FD()).WithSymbol("update-map"), // r2 has key -> &FP[-4] asm.Mov.Reg(asm.R2, asm.RFP), asm.Add.Imm(asm.R2, -4), @@ -141,7 +141,7 @@ func newDistanceFilter() (*ebpf.Program, *ebpf.Map, error) { asm.FnMapUpdateElem.Call(), // set exit code to -1, don't trunc packet - asm.Mov.Imm(asm.R0, -1).Sym("exit"), + asm.Mov.Imm(asm.R0, -1).WithSymbol("exit"), asm.Return(), } diff --git a/features/misc.go b/features/misc.go index 1c2802dd9..8a81f001a 100644 --- a/features/misc.go +++ b/features/misc.go @@ -129,7 +129,7 @@ func createMiscProbeAttr(mt miscType) (*sys.ProgLoadAttr, error) { case boundedLoops: insns = asm.Instructions{ asm.Mov.Imm(asm.R0, 10), - asm.Sub.Imm(asm.R0, 1).Sym("loop"), + asm.Sub.Imm(asm.R0, 1).WithSymbol("loop"), asm.JNE.Imm(asm.R0, 0, "loop"), asm.Return(), } @@ -138,14 +138,14 @@ func createMiscProbeAttr(mt miscType) (*sys.ProgLoadAttr, error) { asm.Mov.Imm(asm.R0, 0), asm.JLT.Imm(asm.R0, 0, "exit"), asm.Mov.Imm(asm.R0, 1), - asm.Return().Sym("exit"), + asm.Return().WithSymbol("exit"), } case v3ISA: insns = asm.Instructions{ asm.Mov.Imm(asm.R0, 0), asm.JLT.Imm32(asm.R0, 0, "exit"), asm.Mov.Imm(asm.R0, 1), - asm.Return().Sym("exit"), + asm.Return().WithSymbol("exit"), } default: return nil, fmt.Errorf("misc probe %d not implemented", mt) diff --git a/info.go b/info.go index cf692c762..c1ad3fa5a 100644 --- a/info.go +++ b/info.go @@ -233,7 +233,7 @@ func (pi *ProgramInfo) Instructions() (asm.Instructions, error) { } // Tag the first instruction with the name of the program, if available. - insns[0] = insns[0].Sym(pi.Name) + insns[0] = insns[0].WithSymbol(pi.Name) return insns, nil } diff --git a/linker.go b/linker.go index 6f2357d97..d45c00148 100644 --- a/linker.go +++ b/linker.go @@ -121,7 +121,7 @@ func fixupAndValidate(insns asm.Instructions) error { ins := iter.Ins if ins.IsLoadFromMap() && ins.MapPtr() == -1 { - return fmt.Errorf("instruction %d: map %s: %w", iter.Index, ins.Reference, asm.ErrUnsatisfiedMapReference) + return fmt.Errorf("instruction %d: map %s: %w", iter.Index, ins.Reference(), asm.ErrUnsatisfiedMapReference) } fixupProbeReadKernel(ins) diff --git a/linker_test.go b/linker_test.go index 34e028de9..38327aa11 100644 --- a/linker_test.go +++ b/linker_test.go @@ -24,13 +24,13 @@ func TestFindReferences(t *testing.T) { }, "my_other_func": { Instructions: asm.Instructions{ - asm.LoadImm(asm.R0, 1337, asm.DWord).Sym("my_other_func"), + asm.LoadImm(asm.R0, 1337, asm.DWord).WithSymbol("my_other_func"), asm.Return(), }, }, "my_func": { Instructions: asm.Instructions{ - asm.Call.Label("my_other_func").Sym("my_func"), + asm.Call.Label("my_other_func").WithSymbol("my_func"), asm.Return(), }, }, @@ -80,7 +80,7 @@ func TestForwardFunctionDeclaration(t *testing.T) { // Append the implementation of fwd(). spec.Instructions = append(spec.Instructions, - asm.Mov.Imm32(asm.R0, 23).Sym("fwd"), + asm.Mov.Imm32(asm.R0, 23).WithSymbol("fwd"), asm.Return(), ) diff --git a/prog.go b/prog.go index ccac3f28e..61714d405 100644 --- a/prog.go +++ b/prog.go @@ -180,7 +180,7 @@ func (spec *ProgramSpec) layout() ([]reference, error) { // Skip non-symbols and symbols that describe the ProgramSpec itself, // which is usually the first instruction in Instructions. // ProgramSpec itself is already included and not present in references. - if ins.Symbol == "" || ins.Symbol == name { + if ins.Symbol() == "" || ins.Symbol() == name { continue } @@ -188,7 +188,7 @@ func (spec *ProgramSpec) layout() ([]reference, error) { // with valid progs that contain multiple symbols and don't have references // populated. Assume ProgramSpec is used similarly in the wild, so don't // alter this behaviour. - ref := spec.references[ins.Symbol] + ref := spec.references[ins.Symbol()] if ref != nil { out = append(out, reference{iter.Offset.Bytes(), ref}) } diff --git a/prog_test.go b/prog_test.go index f48b3b4cf..78f1e9adf 100644 --- a/prog_test.go +++ b/prog_test.go @@ -49,7 +49,7 @@ func TestProgramRun(t *testing.T) { } ins = append(ins, // return 42 - asm.LoadImm(asm.R0, 42, asm.DWord).Sym("out"), + asm.LoadImm(asm.R0, 42, asm.DWord).WithSymbol("out"), asm.Return(), ) @@ -695,7 +695,7 @@ func TestProgramInstructions(t *testing.T) { Type: SocketFilter, Name: name, Instructions: asm.Instructions{ - asm.LoadImm(asm.R0, -1, asm.DWord).Sym(name), + asm.LoadImm(asm.R0, -1, asm.DWord).WithSymbol(name), asm.LoadMapPtr(asm.R1, arr.FD()), asm.Mov.Imm32(asm.R0, 0), asm.Return(), diff --git a/ringbuf/reader_test.go b/ringbuf/reader_test.go index 9da5622c3..71278fbb6 100644 --- a/ringbuf/reader_test.go +++ b/ringbuf/reader_test.go @@ -134,7 +134,7 @@ func outputSamplesProg(flags int32, sampleSizes ...int) (*ebpf.Program, *ebpf.Ma } insns = append(insns, - asm.Mov.Imm(asm.R0, int32(0)).Sym("exit"), + asm.Mov.Imm(asm.R0, int32(0)).WithSymbol("exit"), asm.Return(), )