Commit ae05321a authored by Lucas Bremgartner's avatar Lucas Bremgartner Committed by Mikio Hara

bpf: disasm load extension to type LoadExtension

Load extension in BPF is an overload of the load absolute
instruction with a 'negative offset'. Disassemble load
absolute instructions to load extension, if the offset
is 'negative', respectively > (0xFFFFFFFF - 0x1000).

Fixes golang/go#18469

Change-Id: I13af8f5af89ce26b13a35d2b06879dd6e1c7434e
Reviewed-on: https://go-review.googlesource.com/34771
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarMikio Hara <mikioh.mikioh@gmail.com>
parent 279e8088
...@@ -70,6 +70,9 @@ type Extension int ...@@ -70,6 +70,9 @@ type Extension int
// Extension functions available in the Linux kernel. // Extension functions available in the Linux kernel.
const ( const (
// extOffset is the negative maximum number of instructions used
// to load instructions by overloading the K argument.
extOffset = -0x1000
// ExtLen returns the length of the packet. // ExtLen returns the length of the packet.
ExtLen Extension = 1 ExtLen Extension = 1
// ExtProto returns the packet's L3 protocol type. // ExtProto returns the packet's L3 protocol type.
......
...@@ -57,6 +57,9 @@ func (ri RawInstruction) Disassemble() Instruction { ...@@ -57,6 +57,9 @@ func (ri RawInstruction) Disassemble() Instruction {
} }
return LoadScratch{Dst: reg, N: int(ri.K)} return LoadScratch{Dst: reg, N: int(ri.K)}
case opAddrModeAbsolute: case opAddrModeAbsolute:
if ri.K > extOffset+0xffffffff {
return LoadExtension{Num: Extension(-extOffset + ri.K)}
}
return LoadAbsolute{Size: sz, Off: ri.K} return LoadAbsolute{Size: sz, Off: ri.K}
case opAddrModeIndirect: case opAddrModeIndirect:
return LoadIndirect{Size: sz, Off: ri.K} return LoadIndirect{Size: sz, Off: ri.K}
...@@ -259,7 +262,7 @@ func (a LoadExtension) Assemble() (RawInstruction, error) { ...@@ -259,7 +262,7 @@ func (a LoadExtension) Assemble() (RawInstruction, error) {
if a.Num == ExtLen { if a.Num == ExtLen {
return assembleLoad(RegA, 4, opAddrModePacketLen, 0) return assembleLoad(RegA, 4, opAddrModePacketLen, 0)
} }
return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(-0x1000+a.Num)) return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num))
} }
// StoreScratch stores register Src into scratch[N]. // StoreScratch stores register Src into scratch[N].
......
...@@ -197,3 +197,18 @@ func TestDisasmJumpIf(t *testing.T) { ...@@ -197,3 +197,18 @@ func TestDisasmJumpIf(t *testing.T) {
} }
} }
} }
func TestDisasmExtensions(t *testing.T) {
for _, instr := range allInstructions {
if extInstr, ok := instr.(LoadExtension); ok {
gotAsm, err := extInstr.Assemble()
if err != nil {
t.Fatalf("assembly of '%#v' failed: %s", extInstr, err)
}
got := gotAsm.Disassemble()
if !reflect.DeepEqual(extInstr, got) {
t.Errorf("program mutated by disassembly, expected: %#v, got: %#v", extInstr, got)
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment