gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

load_store.go (4913B)


      1 package asm
      2 
      3 //go:generate stringer -output load_store_string.go -type=Mode,Size
      4 
      5 // Mode for load and store operations
      6 //
      7 //    msb      lsb
      8 //    +---+--+---+
      9 //    |MDE|sz|cls|
     10 //    +---+--+---+
     11 type Mode uint8
     12 
     13 const modeMask OpCode = 0xe0
     14 
     15 const (
     16 	// InvalidMode is returned by getters when invoked
     17 	// on non load / store OpCodes
     18 	InvalidMode Mode = 0xff
     19 	// ImmMode - immediate value
     20 	ImmMode Mode = 0x00
     21 	// AbsMode - immediate value + offset
     22 	AbsMode Mode = 0x20
     23 	// IndMode - indirect (imm+src)
     24 	IndMode Mode = 0x40
     25 	// MemMode - load from memory
     26 	MemMode Mode = 0x60
     27 	// XAddMode - add atomically across processors.
     28 	XAddMode Mode = 0xc0
     29 )
     30 
     31 // Size of load and store operations
     32 //
     33 //    msb      lsb
     34 //    +---+--+---+
     35 //    |mde|SZ|cls|
     36 //    +---+--+---+
     37 type Size uint8
     38 
     39 const sizeMask OpCode = 0x18
     40 
     41 const (
     42 	// InvalidSize is returned by getters when invoked
     43 	// on non load / store OpCodes
     44 	InvalidSize Size = 0xff
     45 	// DWord - double word; 64 bits
     46 	DWord Size = 0x18
     47 	// Word - word; 32 bits
     48 	Word Size = 0x00
     49 	// Half - half-word; 16 bits
     50 	Half Size = 0x08
     51 	// Byte - byte; 8 bits
     52 	Byte Size = 0x10
     53 )
     54 
     55 // Sizeof returns the size in bytes.
     56 func (s Size) Sizeof() int {
     57 	switch s {
     58 	case DWord:
     59 		return 8
     60 	case Word:
     61 		return 4
     62 	case Half:
     63 		return 2
     64 	case Byte:
     65 		return 1
     66 	default:
     67 		return -1
     68 	}
     69 }
     70 
     71 // LoadMemOp returns the OpCode to load a value of given size from memory.
     72 func LoadMemOp(size Size) OpCode {
     73 	return OpCode(LdXClass).SetMode(MemMode).SetSize(size)
     74 }
     75 
     76 // LoadMem emits `dst = *(size *)(src + offset)`.
     77 func LoadMem(dst, src Register, offset int16, size Size) Instruction {
     78 	return Instruction{
     79 		OpCode: LoadMemOp(size),
     80 		Dst:    dst,
     81 		Src:    src,
     82 		Offset: offset,
     83 	}
     84 }
     85 
     86 // LoadImmOp returns the OpCode to load an immediate of given size.
     87 //
     88 // As of kernel 4.20, only DWord size is accepted.
     89 func LoadImmOp(size Size) OpCode {
     90 	return OpCode(LdClass).SetMode(ImmMode).SetSize(size)
     91 }
     92 
     93 // LoadImm emits `dst = (size)value`.
     94 //
     95 // As of kernel 4.20, only DWord size is accepted.
     96 func LoadImm(dst Register, value int64, size Size) Instruction {
     97 	return Instruction{
     98 		OpCode:   LoadImmOp(size),
     99 		Dst:      dst,
    100 		Constant: value,
    101 	}
    102 }
    103 
    104 // LoadMapPtr stores a pointer to a map in dst.
    105 func LoadMapPtr(dst Register, fd int) Instruction {
    106 	if fd < 0 {
    107 		return Instruction{OpCode: InvalidOpCode}
    108 	}
    109 
    110 	return Instruction{
    111 		OpCode:   LoadImmOp(DWord),
    112 		Dst:      dst,
    113 		Src:      PseudoMapFD,
    114 		Constant: int64(uint32(fd)),
    115 	}
    116 }
    117 
    118 // LoadMapValue stores a pointer to the value at a certain offset of a map.
    119 func LoadMapValue(dst Register, fd int, offset uint32) Instruction {
    120 	if fd < 0 {
    121 		return Instruction{OpCode: InvalidOpCode}
    122 	}
    123 
    124 	fdAndOffset := (uint64(offset) << 32) | uint64(uint32(fd))
    125 	return Instruction{
    126 		OpCode:   LoadImmOp(DWord),
    127 		Dst:      dst,
    128 		Src:      PseudoMapValue,
    129 		Constant: int64(fdAndOffset),
    130 	}
    131 }
    132 
    133 // LoadIndOp returns the OpCode for loading a value of given size from an sk_buff.
    134 func LoadIndOp(size Size) OpCode {
    135 	return OpCode(LdClass).SetMode(IndMode).SetSize(size)
    136 }
    137 
    138 // LoadInd emits `dst = ntoh(*(size *)(((sk_buff *)R6)->data + src + offset))`.
    139 func LoadInd(dst, src Register, offset int32, size Size) Instruction {
    140 	return Instruction{
    141 		OpCode:   LoadIndOp(size),
    142 		Dst:      dst,
    143 		Src:      src,
    144 		Constant: int64(offset),
    145 	}
    146 }
    147 
    148 // LoadAbsOp returns the OpCode for loading a value of given size from an sk_buff.
    149 func LoadAbsOp(size Size) OpCode {
    150 	return OpCode(LdClass).SetMode(AbsMode).SetSize(size)
    151 }
    152 
    153 // LoadAbs emits `r0 = ntoh(*(size *)(((sk_buff *)R6)->data + offset))`.
    154 func LoadAbs(offset int32, size Size) Instruction {
    155 	return Instruction{
    156 		OpCode:   LoadAbsOp(size),
    157 		Dst:      R0,
    158 		Constant: int64(offset),
    159 	}
    160 }
    161 
    162 // StoreMemOp returns the OpCode for storing a register of given size in memory.
    163 func StoreMemOp(size Size) OpCode {
    164 	return OpCode(StXClass).SetMode(MemMode).SetSize(size)
    165 }
    166 
    167 // StoreMem emits `*(size *)(dst + offset) = src`
    168 func StoreMem(dst Register, offset int16, src Register, size Size) Instruction {
    169 	return Instruction{
    170 		OpCode: StoreMemOp(size),
    171 		Dst:    dst,
    172 		Src:    src,
    173 		Offset: offset,
    174 	}
    175 }
    176 
    177 // StoreImmOp returns the OpCode for storing an immediate of given size in memory.
    178 func StoreImmOp(size Size) OpCode {
    179 	return OpCode(StClass).SetMode(MemMode).SetSize(size)
    180 }
    181 
    182 // StoreImm emits `*(size *)(dst + offset) = value`.
    183 func StoreImm(dst Register, offset int16, value int64, size Size) Instruction {
    184 	return Instruction{
    185 		OpCode:   StoreImmOp(size),
    186 		Dst:      dst,
    187 		Offset:   offset,
    188 		Constant: value,
    189 	}
    190 }
    191 
    192 // StoreXAddOp returns the OpCode to atomically add a register to a value in memory.
    193 func StoreXAddOp(size Size) OpCode {
    194 	return OpCode(StXClass).SetMode(XAddMode).SetSize(size)
    195 }
    196 
    197 // StoreXAdd atomically adds src to *dst.
    198 func StoreXAdd(dst, src Register, size Size) Instruction {
    199 	return Instruction{
    200 		OpCode: StoreXAddOp(size),
    201 		Dst:    dst,
    202 		Src:    src,
    203 	}
    204 }