Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions armhelpers/arm_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func Xreg2num(arg interface{}) (int, bool) {
if !ok {
return 0, false
}
ndx = aa.Reg(n)
ndx = n
default:
return 0, false
}
Expand All @@ -46,7 +46,9 @@ func Xreg2num(arg interface{}) (int, bool) {

// DecodeRegister converts the result of calling Reg.String()
// into the initial register's value.
func DecodeRegister(reg string) (uint64, bool) {
func DecodeRegister(reg string) (aa.Reg, bool) {
const maxRegister = uint64(aa.V31)

// This function is essentially just the inverse
// of https://cs.opensource.google/go/x/arch/+/fc48f9fe:arm64/arm64asm/inst.go;l=335
length := len(reg)
Expand All @@ -65,7 +67,10 @@ func DecodeRegister(reg string) (uint64, bool) {
if err != nil {
return 0, false
}
return val, true
if val > maxRegister {
return 0, false
}
return aa.Reg(val), true
}

// Otherwise, we want to strip out the
Expand Down Expand Up @@ -98,16 +103,20 @@ func DecodeRegister(reg string) (uint64, bool) {
return 0, false
}

return val + regOffset, true
res := val + regOffset
if res > maxRegister {
return 0, false
}
return aa.Reg(res), true
}

// DecodeImmediate converts an arm64asm Arg of immediate type to it's value.
func DecodeImmediate(arg aa.Arg) (uint64, bool) {
func DecodeImmediate(arg aa.Arg) (int64, bool) {
switch val := arg.(type) {
case aa.Imm:
return uint64(val.Imm), true
return int64(val.Imm), true
case aa.PCRel:
return uint64(val), true
return int64(val), true
case aa.MemImmediate:
// The MemImmediate layout changes quite
// a bit depending on its mode.
Expand Down Expand Up @@ -139,13 +148,13 @@ func DecodeImmediate(arg aa.Arg) (uint64, bool) {
// Note that the second %s here is the print
// format from a register. Annoyingly this isn't a
// register type, so we have to unwind it manually
val, err := DecodeRegister(fields[1])
if !err {
reg, ok := DecodeRegister(fields[1])
if !ok {
return 0, false
}
// The Go disassembler always adds X0 here.
// See https://cs.opensource.google/go/x/arch/+/fc48f9fe:arm64/arm64asm/inst.go;l=526
return val - uint64(aa.X0), true
return int64(reg - aa.X0), true
}

// Otherwise all of the strings end with a ], so we just parse
Expand All @@ -156,12 +165,12 @@ func DecodeImmediate(arg aa.Arg) (uint64, bool) {
if err != nil {
return 0, false
}
return uint64(out), true
return out, true

case aa.ImmShift:
// Sadly, ImmShift{} does not have public fields.
// https://github.com/golang/go/issues/51517
var imm uint64
var imm int64
n, err := fmt.Sscanf(val.String(), "#%v", &imm)
if err != nil || n != 1 {
return 0, false
Expand Down
4 changes: 2 additions & 2 deletions interpreter/hotspot/stubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ Outer:
continue
}

spOffs += int64(imm)
spOffs += imm
}
case aa.SUB:
for _, arg := range insn.Args[:2] {
Expand All @@ -220,7 +220,7 @@ Outer:
continue
}

spOffs -= int64(imm)
spOffs -= imm
}
}

Expand Down
7 changes: 5 additions & 2 deletions interpreter/php/decode_aarch64.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ func retrieveZendVMKindARM(code []byte) (uint, error) {
if !ok {
break
}
if val > ZEND_VM_KIND_HYBRID {
return 0, fmt.Errorf("zend_vm_kind has an invalid value %d", val)
}
return uint(val), nil
}
}
Expand Down Expand Up @@ -117,7 +120,7 @@ func retrieveJITBufferPtrARM(code []byte, addrBase libpf.SymbolValue) (
//
// We also assume that the first BL we encounter is the one we care about.
// This is because the first call inside zend_jit_protect is a call to mprotect.
var regOffset [32]uint64
var regOffset [32]int64

bufRetVal := libpf.SymbolValueInvalid
sizeRetVal := libpf.SymbolValueInvalid
Expand Down Expand Up @@ -163,7 +166,7 @@ func retrieveJITBufferPtrARM(code []byte, addrBase libpf.SymbolValue) (

// The instruction specifies that this value needs to
// shifted about before being added to the PC.
pc := uint64(addrBase) + uint64(offs)
pc := int64(addrBase) + int64(offs)
regOffset[dest] = ((pc + a2) >> 12) << 12
case aa.LDR:
m, ok := inst.Args[1].(aa.MemImmediate)
Expand Down
4 changes: 2 additions & 2 deletions interpreter/python/arm64_decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func decodeStubArgumentARM64(code []byte,
// B .pthread_getspecific

// Storage for load offsets for each Xn register
var regOffset [32]uint64
var regOffset [32]int64
retValue := libpf.SymbolValueInvalid

for offs := 0; offs < len(code); offs += 4 {
Expand All @@ -65,7 +65,7 @@ func decodeStubArgumentARM64(code []byte,
continue
}

instOffset := uint64(0)
instOffset := int64(0)
instRetval := libpf.SymbolValueInvalid
switch inst.Op {
case aa.ADD:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import (

func arm64GetAnalyzers() []Analyzer {
return []Analyzer{
{"tls_set", AnalyzeTLSSetARM64},
{"tls_set", analyzeTLSSetARM},
}
}

// AnalyzeTLSSet looks at the assembly of the `tls_set` function in the
// analyzeTLSSetARM looks at the assembly of the `tls_set` function in the
// kernel in order to compute the offset of `tp_value` into `task_struct`.
func AnalyzeTLSSetARM64(code []byte) (uint32, error) {
func analyzeTLSSetARM(code []byte) (uint32, error) {
// This tries to extract offset of thread.uw.tp_value relative to
// struct task_struct. The code analyzed comes from:
// linux/arch/arm64/kernel/ptrace.c: tls_set(struct task_struct *target, ...) {
Expand Down
Loading