Skip to content

Commit

Permalink
asm: use correct bitfield order on big-endian arches
Browse files Browse the repository at this point in the history
Strictly speaking, bitfield order is defined by a respective arch ABI,
however, in practice it always the same as byte order, and LLVM already
makes use of this correlation, therefore do the same in here.

Signed-off-by: Ilya Leoshkevich <[email protected]>
  • Loading branch information
iii-i committed May 4, 2020
1 parent 53d5228 commit 364d17d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
19 changes: 16 additions & 3 deletions asm/instruction.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package asm
import (
"encoding/binary"
"fmt"
"github.com/cilium/ebpf/internal"
"io"
"math"
"strings"
Expand Down Expand Up @@ -433,15 +434,27 @@ type bpfInstruction struct {
type bpfRegisters uint8

func newBPFRegisters(dst, src Register) bpfRegisters {
return bpfRegisters((src << 4) | (dst & 0xF))
if internal.NativeEndian == binary.LittleEndian {
return bpfRegisters((src << 4) | (dst & 0xF))
} else {
return bpfRegisters((dst << 4) | (src & 0xF))
}
}

func (r bpfRegisters) Dst() Register {
return Register(r & 0xF)
if internal.NativeEndian == binary.LittleEndian {
return Register(r & 0xF)
}else {
return Register(r >> 4)
}
}

func (r bpfRegisters) Src() Register {
return Register(r >> 4)
if internal.NativeEndian == binary.LittleEndian {
return Register(r >> 4)
} else {
return Register(r & 0xf)
}
}

type unreferencedSymbolError struct {
Expand Down
31 changes: 31 additions & 0 deletions asm/instruction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"io/ioutil"
"math"
"testing"

"github.com/cilium/ebpf/internal"
)

var test64bitImmProg = []byte{
Expand Down Expand Up @@ -179,3 +181,32 @@ func ExampleInstructions_Format() {
// 1: LdImmDW dst: r0 imm: 42
// 3: Exit
}

var testSrcDstProg = []byte{
// on little-endian: r0 = r1
// on big-endian: be: r1 = r0
0xbf, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}

func TestReadSrcDst(t *testing.T) {
var ins Instruction
n, err := ins.Unmarshal(bytes.NewReader(testSrcDstProg), binary.BigEndian)
if err != nil {
t.Fatal(err)
}
if want := uint64(InstructionSize); n != want {
t.Errorf("Expected %d bytes to be read, got %d", want, n)
}
var expDst, expSrc Register
if internal.NativeEndian == binary.LittleEndian {
expDst, expSrc = 0, 1
} else {
expDst, expSrc = 1, 0
}
if ins.Dst != expDst {
t.Errorf("Expected destination to be %v, got %v", expDst, ins.Dst)
}
if ins.Src != expSrc {
t.Errorf("Expected source to be %v, got %v", expSrc, ins.Src)
}
}

0 comments on commit 364d17d

Please sign in to comment.