// TODO: disassembler support should be compiled in unconditionally, // instead of being decided by the build-target architecture, and be // part of the Arch object instead. package proc import ( "golang.org/x/arch/x86/x86asm" ) // AsmDecode decodes the assembly instruction starting at mem[0:] into asmInst. // It assumes that the Loc and AtPC fields of asmInst have already been filled. func (a *AMD64) AsmDecode(asmInst *AsmInstruction, mem []byte, regs Registers, memrw MemoryReadWriter, bi *BinaryInfo) error { return x86AsmDecode(asmInst, mem, regs, memrw, bi, 64) } func (a *AMD64) Prologues() []opcodeSeq { return prologuesAMD64 } // Possible stacksplit prologues are inserted by stacksplit in // $GOROOT/src/cmd/internal/obj/x86/obj6.go. // The stacksplit prologue will always begin with loading curg in CX, this // instruction is added by load_g_cx in the same file and is either 1 or 2 // MOVs. var prologuesAMD64 []opcodeSeq func init() { var tinyStacksplit = opcodeSeq{uint64(x86asm.CMP), uint64(x86asm.JBE)} var smallStacksplit = opcodeSeq{uint64(x86asm.LEA), uint64(x86asm.CMP), uint64(x86asm.JBE)} var bigStacksplit = opcodeSeq{uint64(x86asm.MOV), uint64(x86asm.CMP), uint64(x86asm.JE), uint64(x86asm.LEA), uint64(x86asm.SUB), uint64(x86asm.CMP), uint64(x86asm.JBE)} var unixGetG = opcodeSeq{uint64(x86asm.MOV)} var windowsGetG = opcodeSeq{uint64(x86asm.MOV), uint64(x86asm.MOV)} prologuesAMD64 = make([]opcodeSeq, 0, 2*3) for _, getG := range []opcodeSeq{unixGetG, windowsGetG} { for _, stacksplit := range []opcodeSeq{tinyStacksplit, smallStacksplit, bigStacksplit} { prologue := make(opcodeSeq, 0, len(getG)+len(stacksplit)) prologue = append(prologue, getG...) prologue = append(prologue, stacksplit...) prologuesAMD64 = append(prologuesAMD64, prologue) } } }