disassemblers.scm 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. ;;; Disarchive
  2. ;;; Copyright © 2020, 2023 Timothy Sample <samplet@ngyro.com>
  3. ;;;
  4. ;;; This file is part of Disarchive.
  5. ;;;
  6. ;;; Disarchive is free software: you can redistribute it and/or modify
  7. ;;; it under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation, either version 3 of the License, or
  9. ;;; (at your option) any later version.
  10. ;;;
  11. ;;; Disarchive is distributed in the hope that it will be useful,
  12. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with Disarchive. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (disarchive disassemblers)
  19. #:use-module (gcrypt hash)
  20. #:use-module (ice-9 match)
  21. #:use-module (srfi srfi-1)
  22. #:use-module (srfi srfi-9)
  23. #:use-module (srfi srfi-26)
  24. #:export (<disassembler>
  25. make-disassembler
  26. disassembler?
  27. disassembler-x-file?
  28. disassembler-disassemble-x
  29. disassemble))
  30. ;;; Commentary:
  31. ;;;
  32. ;;; This module provides a generalized interface for disassemblers. A
  33. ;;; disassembler is a procedure that takes a filename and disassembles
  34. ;;; that file into its metadata and a reference to its data.
  35. ;;;
  36. ;;; Code:
  37. (define-record-type <disassembler>
  38. (make-disassembler x-file? disassemble-x)
  39. disassembler?
  40. (x-file? disassembler-x-file?)
  41. (disassemble-x disassembler-disassemble-x))
  42. (define (name->disassembler name)
  43. (let ((module `(disarchive assemblers ,name)))
  44. (module-ref (resolve-interface module)
  45. (symbol-append name '-disassembler))))
  46. (define %disassemblers
  47. (delay (map name->disassembler
  48. '(gzip-member
  49. xz-file
  50. bzip2-stream
  51. tarball
  52. directory-ref))))
  53. (define (file-disassembler filename)
  54. "Get the disassembler for the file named FILENAME."
  55. (define st (stat filename))
  56. (or (find (lambda (dasm)
  57. ((disassembler-x-file? dasm) filename st))
  58. (force %disassemblers))
  59. (error "No disassembler for file")))
  60. (define* (disassemble filename #:optional
  61. (algorithm (hash-algorithm sha256))
  62. #:key name)
  63. (match-let ((($ <disassembler> _ disassemble-x)
  64. (file-disassembler filename)))
  65. (apply disassemble-x filename algorithm
  66. (if name `(#:name ,name) '()))))