]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/disasm: correct instruction length handling for riscv64
authorJoel Sing <joel@sing.id.au>
Fri, 3 Jan 2025 16:44:40 +0000 (03:44 +1100)
committerJoel Sing <joel@sing.id.au>
Tue, 7 Jan 2025 07:43:06 +0000 (23:43 -0800)
disasm_riscv64 currently always returns an instruction length of four,
which is not correct if compressed instructions are in use. Return the
length of the decoded instruction, defaulting to two bytes if the
instruction is unknown.

With this change it is possible to correctly objdump a binary that is
written in C and includes compressed instructions:

$ go tool objdump ./hello
TEXT _start(SB)
  :0                    0x5b0                   ef002002                CALL 8(PC)
  :0                    0x5b4                   aa87                    ADD X10, X0, X15
  :0                    0x5b6                   17250000                AUIPC $2, X10
  :0                    0x5ba                   033525a3                MOV -1486(X10), X10
  :0                    0x5be                   8265                    MOV (X2), X11
  :0                    0x5c0                   3000                    ADDI $8, X2, X12
  ...

Fixes #71102

Change-Id: Ia99eb114a98c6d535de872ce8a526cd5e6203fff
Reviewed-on: https://go-review.googlesource.com/c/go/+/639995
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Jorropo <jorropo.pgm@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/cmd/internal/disasm/disasm.go

index c317effa900f60d3080b387a13463152b379e121..3ae8989b38d08039bb9d7c79a94115b40e2b0437 100644 (file)
@@ -410,14 +410,16 @@ func disasm_ppc64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.By
 func disasm_riscv64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.ByteOrder, gnuAsm bool) (string, int) {
        inst, err := riscv64asm.Decode(code)
        var text string
+       size := inst.Len
        if err != nil || inst.Op == 0 {
+               size = 2
                text = "?"
        } else if gnuAsm {
                text = fmt.Sprintf("%-36s // %s", riscv64asm.GoSyntax(inst, pc, lookup, textReader{code, pc}), riscv64asm.GNUSyntax(inst))
        } else {
                text = riscv64asm.GoSyntax(inst, pc, lookup, textReader{code, pc})
        }
-       return text, 4
+       return text, size
 }
 
 func disasm_s390x(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder, gnuAsm bool) (string, int) {