// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: BSD-3-Clause //go:build linux && amd64 package debug import ( "fmt" "strings" "golang.org/x/arch/x86/x86asm" ) // Disassemble decodes the instruction at the given address in the debuggee's // memory and returns its text representation and length in bytes. func (s *Session) Disassemble(addr uint64) (string, int, error) { // Read up to 15 bytes (max x86 instruction length). mem, err := s.ReadMemory(addr, 15) if err != nil { // Try a shorter read if we're near a page boundary. mem, err = s.ReadMemory(addr, 1) if err != nil { return "", 0, err } } inst, err := x86asm.Decode(mem, 64) if err != nil { return "???", 1, nil } text := x86asm.IntelSyntax(inst, addr, nil) return text, inst.Len, nil } // DisassembleN decodes up to n instructions starting at addr and returns // them as a formatted string with addresses and byte offsets. func (s *Session) DisassembleN(addr uint64, n int) string { var result strings.Builder pc := addr for range n { text, length, err := s.Disassemble(pc) if err != nil { result.WriteString(fmt.Sprintf(" %#08x: \n", pc, err)) break } result.WriteString(fmt.Sprintf(" %#08x: %s\n", pc, text)) if length == 0 { length = 1 } pc += uint64(length) } return result.String() }