123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- package asm
- //go:generate stringer -output load_store_string.go -type=Mode,Size
- // Mode for load and store operations
- //
- // msb lsb
- // +---+--+---+
- // |MDE|sz|cls|
- // +---+--+---+
- type Mode uint8
- const modeMask OpCode = 0xe0
- const (
- // InvalidMode is returned by getters when invoked
- // on non load / store OpCodes
- InvalidMode Mode = 0xff
- // ImmMode - immediate value
- ImmMode Mode = 0x00
- // AbsMode - immediate value + offset
- AbsMode Mode = 0x20
- // IndMode - indirect (imm+src)
- IndMode Mode = 0x40
- // MemMode - load from memory
- MemMode Mode = 0x60
- // XAddMode - add atomically across processors.
- XAddMode Mode = 0xc0
- )
- // Size of load and store operations
- //
- // msb lsb
- // +---+--+---+
- // |mde|SZ|cls|
- // +---+--+---+
- type Size uint8
- const sizeMask OpCode = 0x18
- const (
- // InvalidSize is returned by getters when invoked
- // on non load / store OpCodes
- InvalidSize Size = 0xff
- // DWord - double word; 64 bits
- DWord Size = 0x18
- // Word - word; 32 bits
- Word Size = 0x00
- // Half - half-word; 16 bits
- Half Size = 0x08
- // Byte - byte; 8 bits
- Byte Size = 0x10
- )
- // Sizeof returns the size in bytes.
- func (s Size) Sizeof() int {
- switch s {
- case DWord:
- return 8
- case Word:
- return 4
- case Half:
- return 2
- case Byte:
- return 1
- default:
- return -1
- }
- }
- // LoadMemOp returns the OpCode to load a value of given size from memory.
- func LoadMemOp(size Size) OpCode {
- return OpCode(LdXClass).SetMode(MemMode).SetSize(size)
- }
- // LoadMem emits `dst = *(size *)(src + offset)`.
- func LoadMem(dst, src Register, offset int16, size Size) Instruction {
- return Instruction{
- OpCode: LoadMemOp(size),
- Dst: dst,
- Src: src,
- Offset: offset,
- }
- }
- // LoadImmOp returns the OpCode to load an immediate of given size.
- //
- // As of kernel 4.20, only DWord size is accepted.
- func LoadImmOp(size Size) OpCode {
- return OpCode(LdClass).SetMode(ImmMode).SetSize(size)
- }
- // LoadImm emits `dst = (size)value`.
- //
- // As of kernel 4.20, only DWord size is accepted.
- func LoadImm(dst Register, value int64, size Size) Instruction {
- return Instruction{
- OpCode: LoadImmOp(size),
- Dst: dst,
- Constant: value,
- }
- }
- // LoadMapPtr stores a pointer to a map in dst.
- func LoadMapPtr(dst Register, fd int) Instruction {
- if fd < 0 {
- return Instruction{OpCode: InvalidOpCode}
- }
- return Instruction{
- OpCode: LoadImmOp(DWord),
- Dst: dst,
- Src: PseudoMapFD,
- Constant: int64(uint32(fd)),
- }
- }
- // LoadMapValue stores a pointer to the value at a certain offset of a map.
- func LoadMapValue(dst Register, fd int, offset uint32) Instruction {
- if fd < 0 {
- return Instruction{OpCode: InvalidOpCode}
- }
- fdAndOffset := (uint64(offset) << 32) | uint64(uint32(fd))
- return Instruction{
- OpCode: LoadImmOp(DWord),
- Dst: dst,
- Src: PseudoMapValue,
- Constant: int64(fdAndOffset),
- }
- }
- // LoadIndOp returns the OpCode for loading a value of given size from an sk_buff.
- func LoadIndOp(size Size) OpCode {
- return OpCode(LdClass).SetMode(IndMode).SetSize(size)
- }
- // LoadInd emits `dst = ntoh(*(size *)(((sk_buff *)R6)->data + src + offset))`.
- func LoadInd(dst, src Register, offset int32, size Size) Instruction {
- return Instruction{
- OpCode: LoadIndOp(size),
- Dst: dst,
- Src: src,
- Constant: int64(offset),
- }
- }
- // LoadAbsOp returns the OpCode for loading a value of given size from an sk_buff.
- func LoadAbsOp(size Size) OpCode {
- return OpCode(LdClass).SetMode(AbsMode).SetSize(size)
- }
- // LoadAbs emits `r0 = ntoh(*(size *)(((sk_buff *)R6)->data + offset))`.
- func LoadAbs(offset int32, size Size) Instruction {
- return Instruction{
- OpCode: LoadAbsOp(size),
- Dst: R0,
- Constant: int64(offset),
- }
- }
- // StoreMemOp returns the OpCode for storing a register of given size in memory.
- func StoreMemOp(size Size) OpCode {
- return OpCode(StXClass).SetMode(MemMode).SetSize(size)
- }
- // StoreMem emits `*(size *)(dst + offset) = src`
- func StoreMem(dst Register, offset int16, src Register, size Size) Instruction {
- return Instruction{
- OpCode: StoreMemOp(size),
- Dst: dst,
- Src: src,
- Offset: offset,
- }
- }
- // StoreImmOp returns the OpCode for storing an immediate of given size in memory.
- func StoreImmOp(size Size) OpCode {
- return OpCode(StClass).SetMode(MemMode).SetSize(size)
- }
- // StoreImm emits `*(size *)(dst + offset) = value`.
- func StoreImm(dst Register, offset int16, value int64, size Size) Instruction {
- return Instruction{
- OpCode: StoreImmOp(size),
- Dst: dst,
- Offset: offset,
- Constant: value,
- }
- }
- // StoreXAddOp returns the OpCode to atomically add a register to a value in memory.
- func StoreXAddOp(size Size) OpCode {
- return OpCode(StXClass).SetMode(XAddMode).SetSize(size)
- }
- // StoreXAdd atomically adds src to *dst.
- func StoreXAdd(dst, src Register, size Size) Instruction {
- return Instruction{
- OpCode: StoreXAddOp(size),
- Dst: dst,
- Src: src,
- }
- }
|