Add architecture normalization
ober
056a56942f0932c331ed9f5c3e72fb3d193103cd
--- a/lib/jasm/disasm.ss +++ b/lib/jasm/disasm.ss @@ -3,6 +3,8 @@ (library (jasm disasm) (export supported-architectures + normalize-architecture + architecture-endianness hex-string->bytevector disassemble-bytevector disassemble->string @@ -16,7 +18,39 @@ (import (chezscheme)) - (define supported-architectures '(x86-64 aarch64)) + (define supported-architectures '(x86-64 aarch64 mips mipsel mips64 mips64el)) + + (define architecture-aliases + '((x86-64 . x86-64) + (x86_64 . x86-64) + (amd64 . x86-64) + (aarch64 . aarch64) + (arm64 . aarch64) + (mips . mips) + (mips32 . mips) + (mipseb . mips) + (mips32eb . mips) + (mipsel . mipsel) + (mips32el . mipsel) + (mips64 . mips64) + (mips64eb . mips64) + (mips64el . mips64el))) + + (define (normalize-architecture arch) + (let* ([sym (cond + [(symbol? arch) arch] + [(string? arch) (string->symbol arch)] + [else (error 'normalize-architecture "architecture must be a symbol or string" arch)])] + [cell (assq sym architecture-aliases)]) + (if cell + (cdr cell) + (error 'normalize-architecture "unsupported architecture" arch)))) + + (define (architecture-endianness arch) + (case (normalize-architecture arch) + [(mips mips64) 'big] + [(mipsel mips64el) 'little] + [else 'little])) (define (instruction? x) (and (pair? x) (eq? (car x) 'instruction))) @@ -337,13 +371,14 @@ [else (a64-unknown-word bv offset address remaining)]))))) (define (decode-instruction arch bv offset address options) - (cond - [(eq? arch 'x86-64) (decode-x86-64 bv offset address options)] - [(eq? arch 'aarch64) (decode-aarch64 bv offset address options)] - [else (error 'decode-instruction "unsupported architecture" arch)])) + (case (normalize-architecture arch) + [(x86-64) (decode-x86-64 bv offset address options)] + [(aarch64) (decode-aarch64 bv offset address options)] + [else (error 'decode-instruction "decoder not implemented for architecture" arch)])) (define (disassemble-bytevector arch bv . maybe-options) - (let* ([options (if (null? maybe-options) '() (car maybe-options))] + (let* ([arch (normalize-architecture arch)] + [options (if (null? maybe-options) '() (car maybe-options))] [base (option-ref options 'address 0)] [len (bytevector-length bv)]) (let loop ([offset 0] [address base] [out '()]) --- a/main.ss +++ b/main.ss @@ -4,18 +4,13 @@ (define (usage) (display "Usage:\n") - (display " jasm raw --arch <x86-64|aarch64> [--syntax att|intel] [--address n] --hex <bytes>\n") + (display " jasm raw --arch <x86-64|aarch64|mips|mipsel|mips64|mips64el> [--syntax att|intel] [--address n] --hex <bytes>\n") (display "\nExamples:\n") (display " jasm raw --arch x86-64 --syntax intel --hex '55 48 89 e5 c3'\n") (display " jasm raw --arch aarch64 --hex '20 00 80 d2 c0 03 5f d6'\n")) (define (string->arch s) - (cond - [(string=? s "x86-64") 'x86-64] - [(string=? s "x86_64") 'x86-64] - [(string=? s "aarch64") 'aarch64] - [(string=? s "arm64") 'aarch64] - [else (error 'jasm "unsupported architecture" s)])) + (normalize-architecture s)) (define (parse-number s) (let ([n (string->number s 0)]) --- a/tests/test-jasm.ss +++ b/tests/test-jasm.ss @@ -32,6 +32,19 @@ (bytevector->u8-list (hex-string->bytevector "0x55, 48:89_e5")) '(85 72 137 229)) +(test "normalize architecture x86_64" + (normalize-architecture "x86_64") + 'x86-64) + +(test "normalize architecture mips32el" + (normalize-architecture 'mips32el) + 'mipsel) + +(test "architecture endianness" + (list (architecture-endianness 'mips) + (architecture-endianness 'mips64el)) + '(big little)) + (test "x86 push att" (one-text 'x86-64 "55") "pushq\t%rbp")