Files
wehub-resource-sync c4536f7e05
CI / test (push) Failing after 1s
CI / macOS amd64 (push) Has been cancelled
CI / macOS arm64 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:31 +08:00

93 lines
2.4 KiB
Go

// Command asmcheck reads `go tool objdump` output on stdin, extracts every Go
// (Plan 9) instruction mnemonic, and reports which ones asmhelp fails to
// resolve to real reference data. Throwaway analysis tool.
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strings"
"loov.dev/lensm/internal/asmhelp"
)
func main() {
arch := "arm64"
if len(os.Args) > 1 {
arch = os.Args[1]
}
count := map[string]int{} // mnemonic -> occurrences
sample := map[string]string{} // mnemonic -> one full instruction line
sc := bufio.NewScanner(os.Stdin)
sc.Buffer(make([]byte, 1<<20), 1<<20)
for sc.Scan() {
line := sc.Text()
if strings.HasPrefix(strings.TrimSpace(line), "TEXT ") {
continue // function header pseudo-op, not an instruction
}
// objdump instruction lines are tab-separated (with empty padding
// fields): file:line, addr, hex, instr. The instruction is the last
// non-empty field.
var instr string
for _, f := range strings.Split(line, "\t") {
if f = strings.TrimSpace(f); f != "" {
instr = f
}
}
if !strings.HasPrefix(strings.TrimSpace(line), " ") && !strings.Contains(line, "0x") {
continue // function header line, not an instruction
}
toks := strings.Fields(instr)
if len(toks) == 0 {
continue
}
m := toks[0]
count[m]++
if sample[m] == "" {
sample[m] = instr
}
}
var unresolved, notPlausible []string
resolved := 0
for m := range count {
help, ok := asmhelp.ForInstruction(arch, "", sample[m])
switch {
case ok && help.Note == "":
resolved++
case ok && help.Note != "":
unresolved = append(unresolved, m)
default:
notPlausible = append(notPlausible, m)
}
}
byCountDesc := func(list []string) {
sort.Slice(list, func(i, j int) bool {
if count[list[i]] != count[list[j]] {
return count[list[i]] > count[list[j]]
}
return list[i] < list[j]
})
}
byCountDesc(unresolved)
byCountDesc(notPlausible)
fmt.Printf("unique mnemonics: %d resolved: %d unresolved: %d not-plausible: %d\n\n",
len(count), resolved, len(unresolved), len(notPlausible))
fmt.Println("UNRESOLVED (plausible mnemonics with no reference data), by frequency:")
for _, m := range unresolved {
fmt.Printf(" %6d %-12s %s\n", count[m], m, sample[m])
}
if len(notPlausible) > 0 {
fmt.Println("\nNOT-PLAUSIBLE (skipped: directives, undecodable, etc.):")
for _, m := range notPlausible {
fmt.Printf(" %6d %s\n", count[m], m)
}
}
}