forked from rosa/hakurei
cmd/irdump: improvements?
This commit is contained in:
@@ -6,9 +6,71 @@ import (
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unique"
|
||||
)
|
||||
|
||||
type asmOutLine struct {
|
||||
type AsmMessage struct {
|
||||
data AsmData
|
||||
sig AsmSig
|
||||
}
|
||||
type AsmGenerator struct {
|
||||
i uintptr
|
||||
as chan AsmMessage
|
||||
lbl []uintptr
|
||||
}
|
||||
type AsmSig int
|
||||
|
||||
const (
|
||||
AsmSigEnd AsmSig = iota
|
||||
AsmSigLbl
|
||||
AsmSigHead
|
||||
AsmSigVal
|
||||
)
|
||||
|
||||
// GenerateAll collects all asm sent to this generator and outputs formatted data to the given [io.Writer].
|
||||
func (g *AsmGenerator) GenerateAll(w io.Writer) error {
|
||||
for a := <-g.as; a.sig != AsmSigEnd; a = <-g.as {
|
||||
switch a.sig {
|
||||
case AsmSigLbl:
|
||||
|
||||
break
|
||||
case AsmSigHead:
|
||||
|
||||
break
|
||||
case AsmSigVal:
|
||||
_, err := w.Write([]byte(a.data.Line(g)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
default:
|
||||
panic("invalid asm signal")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AsmFormatter struct {
|
||||
// if false, generate labels. if true, bare idents will be shown.
|
||||
Real bool
|
||||
// if true, header data and the dependencies list will be shown.
|
||||
ShowHeader bool
|
||||
// if true, don't generate raw byte data (only generate raw assembly).
|
||||
Raw bool
|
||||
}
|
||||
type AsmData interface {
|
||||
Line(*AsmGenerator) string
|
||||
Offset(int)
|
||||
}
|
||||
|
||||
type AsmDataNone struct{}
|
||||
|
||||
func (a AsmDataNone) Line(*AsmGenerator) string {
|
||||
return ""
|
||||
}
|
||||
func (a AsmDataNone) Offset(int) {}
|
||||
|
||||
type AsmLine struct {
|
||||
pos int
|
||||
word int
|
||||
kindData int64
|
||||
@@ -18,7 +80,22 @@ type asmOutLine struct {
|
||||
value string
|
||||
}
|
||||
|
||||
var spacingLine = asmOutLine{
|
||||
func (l AsmLine) Line(gen *AsmGenerator) string {
|
||||
return ""
|
||||
}
|
||||
func (l AsmLine) Offset(offset int) {
|
||||
l.pos += offset
|
||||
}
|
||||
|
||||
type AsmHeaderLine struct {
|
||||
pos int
|
||||
kind string
|
||||
kindData int64
|
||||
label string
|
||||
id unique.Handle[ID]
|
||||
}
|
||||
|
||||
var spacingLine = AsmLine{
|
||||
pos: -1,
|
||||
kindData: -1,
|
||||
valueData: nil,
|
||||
@@ -28,7 +105,7 @@ var spacingLine = asmOutLine{
|
||||
}
|
||||
|
||||
func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool) (s string, err error) {
|
||||
var lines []asmOutLine
|
||||
var lines []AsmLine
|
||||
sb := new(strings.Builder)
|
||||
header := true
|
||||
pos := new(int)
|
||||
@@ -46,10 +123,10 @@ func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool)
|
||||
break
|
||||
}
|
||||
if showHeader {
|
||||
lines = append(lines, asmOutLine{p, 8, int64(kind), bsize, 0, "head " + intToKind(kind), ""})
|
||||
lines = append(lines, AsmLine{p, 8, int64(kind), bsize, 0, "head " + intToKind(kind), ""})
|
||||
}
|
||||
for i := 0; uint64(i) < size; i++ {
|
||||
var did Checksum
|
||||
var did ID
|
||||
var dkind uint64
|
||||
p := *pos
|
||||
if _, dkind, err = nextUint64(r, pos); err != nil {
|
||||
@@ -59,7 +136,7 @@ func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool)
|
||||
break
|
||||
}
|
||||
if showHeader {
|
||||
lines = append(lines, asmOutLine{p, 8, int64(dkind), nil, 1, intToKind(dkind), Encode(did)})
|
||||
lines = append(lines, AsmLine{p, 8, int64(dkind), nil, 1, intToKind(dkind), Encode(did)})
|
||||
}
|
||||
}
|
||||
header = false
|
||||
@@ -82,9 +159,9 @@ func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool)
|
||||
if _, sum, err = nextIdent(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), ba, 1, "end ", Encode(sum)})
|
||||
lines = append(lines, AsmLine{p, 4, int64(kind), ba, 1, "end ", Encode(sum)})
|
||||
} else {
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), []byte{0, 0, 0, 0}, 1, "end ", ""})
|
||||
lines = append(lines, AsmLine{p, 4, int64(kind), []byte{0, 0, 0, 0}, 1, "end ", ""})
|
||||
}
|
||||
lines = append(lines, spacingLine)
|
||||
header = true
|
||||
@@ -96,12 +173,12 @@ func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool)
|
||||
if a, _, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
var sum Checksum
|
||||
if _, sum, err = nextIdent(r, pos); err != nil {
|
||||
var id ID
|
||||
if _, id, err = nextIdent(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), a, 1, "id ", Encode(sum)})
|
||||
lines = append(lines, AsmLine{p, 4, int64(kind), a, 1, "id ", Encode(id)})
|
||||
continue
|
||||
case IRKindUint32:
|
||||
var i uint32
|
||||
@@ -109,7 +186,7 @@ func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool)
|
||||
if bi, i, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), bi, 1, "int ", strconv.FormatUint(uint64(i), 10)})
|
||||
lines = append(lines, AsmLine{p, 4, int64(kind), bi, 1, "int ", strconv.FormatUint(uint64(i), 10)})
|
||||
case IRKindString:
|
||||
var l uint32
|
||||
var bl []byte
|
||||
@@ -123,14 +200,14 @@ func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool)
|
||||
}
|
||||
*pos = *pos + n
|
||||
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), bl, 1, "str ", strconv.Quote(string(s[:l]))})
|
||||
lines = append(lines, AsmLine{p, 4, int64(kind), bl, 1, "str ", strconv.Quote(string(s[:l]))})
|
||||
continue
|
||||
default:
|
||||
var bi []byte
|
||||
if bi, _, err = nextUint32(r, pos); err != nil {
|
||||
break
|
||||
}
|
||||
lines = append(lines, asmOutLine{p, 4, int64(kind), bi, 1, "????", ""})
|
||||
lines = append(lines, AsmLine{p, 4, int64(kind), bi, 1, "????", ""})
|
||||
}
|
||||
}
|
||||
if err != io.EOF {
|
||||
@@ -182,14 +259,14 @@ func nextUint64(r io.Reader, pos *int) ([]byte, uint64, error) {
|
||||
*pos = p
|
||||
return i, binary.LittleEndian.Uint64(i), nil
|
||||
}
|
||||
func nextIdent(r io.Reader, pos *int) ([]byte, Checksum, error) {
|
||||
func nextIdent(r io.Reader, pos *int) ([]byte, ID, error) {
|
||||
i := make([]byte, 48)
|
||||
if _, err := r.Read(i); err != nil {
|
||||
return i, Checksum{}, err
|
||||
return i, ID{}, err
|
||||
}
|
||||
p := *pos + 48
|
||||
*pos = p
|
||||
return i, Checksum(i), nil
|
||||
return i, ID(i), nil
|
||||
}
|
||||
func intToKind(i uint64) string {
|
||||
switch Kind(i) {
|
||||
|
||||
Reference in New Issue
Block a user