|
| 1 | +package gomonkey |
| 2 | + |
| 3 | +import "unsafe" |
| 4 | + |
| 5 | +const ( |
| 6 | + REG_R0 uint32 = 0 |
| 7 | + REG_R29 = 29 |
| 8 | + REG_R30 = 30 |
| 9 | +) |
| 10 | + |
| 11 | +const ( |
| 12 | + OP_ORI uint32 = 0x00E << 22 |
| 13 | + OP_LU12IW = 0x00A << 25 |
| 14 | + OP_LU32ID = 0x00B << 25 |
| 15 | + OP_LU52ID = 0x00C << 22 |
| 16 | + OP_LDD = 0x0A3 << 22 |
| 17 | + OP_JIRL = 0x013 << 26 |
| 18 | +) |
| 19 | + |
| 20 | +func buildJmpDirective(double uintptr) []byte { |
| 21 | + res := make([]byte, 0, 24) |
| 22 | + |
| 23 | + bit11_0 := (double >> 0) & 0xFFF |
| 24 | + bit31_12 := (double >> 12) & 0xFFFFF |
| 25 | + bit51_32 := (double >> 32) & 0xFFFFF |
| 26 | + bit63_52 := (double >> 52) & 0xFFF |
| 27 | + |
| 28 | + // lu12i.w r29, bit31_12 |
| 29 | + // ori r29, r29, bit11_0 |
| 30 | + // lu32i.d r29, bit51_32 |
| 31 | + // lu52i.d r29, bit63_52 |
| 32 | + // ld.d, r30, r29, 0 |
| 33 | + // jirl r0, r30, 0 |
| 34 | + res = append(res, wireup_opc(OP_LU12IW, REG_R29, 0, bit31_12)...) |
| 35 | + res = append(res, wireup_opc(OP_ORI, REG_R29, REG_R29, bit11_0)...) |
| 36 | + res = append(res, wireup_opc(OP_LU32ID, REG_R29, 0, bit51_32)...) |
| 37 | + res = append(res, wireup_opc(OP_LU52ID, REG_R29, REG_R29, bit63_52)...) |
| 38 | + res = append(res, wireup_opc(OP_LDD, REG_R30, REG_R29, 0)...) |
| 39 | + res = append(res, wireup_opc(OP_JIRL, REG_R0, REG_R30, 0)...) |
| 40 | + |
| 41 | + return res |
| 42 | +} |
| 43 | + |
| 44 | +func wireup_opc(opc uint32, rd, rj uint32, val uintptr) []byte { |
| 45 | + var m uint32 = 0 |
| 46 | + |
| 47 | + switch opc { |
| 48 | + case OP_ORI, OP_LU52ID, OP_LDD: |
| 49 | + m |= opc |
| 50 | + m |= (rd & 0x1F) << 0 // rd |
| 51 | + m |= (rj & 0x1F) << 5 // rj |
| 52 | + m |= (uint32(val) & 0xFFF) << 10 // si12 |
| 53 | + |
| 54 | + case OP_LU12IW, OP_LU32ID: |
| 55 | + m |= opc |
| 56 | + m |= (rd & 0x1F) << 0 // rd |
| 57 | + m |= (uint32(val) & 0xFFFFF) << 5 // si20 |
| 58 | + |
| 59 | + case OP_JIRL: |
| 60 | + m |= opc |
| 61 | + m |= (rd & 0x1F) << 0 // rd |
| 62 | + m |= (rj & 0x1F) << 5 // rj |
| 63 | + m |= (uint32(val) & 0xFFFF) << 10 // si16 |
| 64 | + } |
| 65 | + |
| 66 | + res := make([]byte, 4) |
| 67 | + *(*uint32)(unsafe.Pointer(&res[0])) = m |
| 68 | + |
| 69 | + return res |
| 70 | +} |
0 commit comments