Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
5.2 KiB

  1. ;;; autodisass-java-bytecode.el --- Automatically disassemble Java bytecode
  2. ;; Copyright (C) 2014, George Balatsouras
  3. ;;
  4. ;; Author: George Balatsouras <gbalats(at)gmail(dot)com>
  5. ;; Maintainer: George Balatsouras <gbalats(at)gmail(dot)com>
  6. ;; Created: 22 Jun 2014
  7. ;; Version: 1.3
  8. ;; Keywords: convenience, data, files
  9. ;;
  10. ;; This file is NOT part of Emacs.
  11. ;;
  12. ;; This program is free software; you can redistribute it and/or
  13. ;; modify it under the terms of the GNU General Public License as
  14. ;; published by the Free Software Foundation; either version 3 of
  15. ;; the License, or (at your option) any later version.
  16. ;;
  17. ;; This program is distributed in the hope that it will be
  18. ;; useful, but WITHOUT ANY WARRANTY; without even the implied
  19. ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  20. ;; PURPOSE. See the GNU General Public License for more details.
  21. ;;
  22. ;; You should have received a copy of the GNU General Public License
  23. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. ;;
  25. ;; To use, save `autodisass-java-bytecode.el' to a directory in your
  26. ;; load-path and add the following to your `.emacs'.
  27. ;;
  28. ;; (require 'autodisass-java-bytecode)
  29. ;;; Commentary:
  30. ;; This package enables automatic disassembly of Java bytecode.
  31. ;;
  32. ;; It was inspired by a blog post of Christopher Wellons:
  33. ;; http://nullprogram.com/blog/2012/08/01/
  34. ;;
  35. ;; Disassembly can happen in two cases:
  36. ;; (a) when opening a Java .class file
  37. ;; (b) when disassembling a .class file inside a jar
  38. ;;
  39. ;; In any case, `javap' must be installed in the system for this
  40. ;; extension to have any effect, since that is the tool that actually
  41. ;; performs the disassembly.
  42. ;;; Code:
  43. (require 'ad-javap-mode)
  44. (defconst autodisass-java-bytecode-version "1.3")
  45. (defgroup autodisass-java-bytecode nil
  46. "Automatic disassembly of Java bytecode."
  47. :tag "Java Bytecode Disassembly"
  48. :prefix "ad-java-bytecode-"
  49. :group 'autodisass)
  50. (defconst ad-java-bytecode-regexp "\\.class$"
  51. "Regular expressions that matches Java bytecode files.")
  52. (defcustom ad-java-bytecode-disassembler "javap"
  53. "Return the name of the disassembler command.
  54. If the command is not on your path, you may specify a fully
  55. qualified path to it. The command should accept the input file
  56. name as its last argument and print the disassembled file on the
  57. output stream."
  58. :tag "Disassembler command"
  59. :group 'autodisass-java-bytecode
  60. :type 'string)
  61. (defcustom ad-java-bytecode-parameters
  62. '("-private" "-verbose")
  63. "Extra parameters for the disassembler process."
  64. :tag "Command line options"
  65. :group 'autodisass-java-bytecode
  66. :type '(repeat string))
  67. (defun ad-java-bytecode-disassemble-p (file)
  68. "Return t if automatic disassembly should be performed for FILE."
  69. (and (string-match ad-java-bytecode-regexp file)
  70. (executable-find ad-java-bytecode-disassembler)
  71. (y-or-n-p (format "Disassemble %s using %s? " file
  72. ad-java-bytecode-disassembler))))
  73. (defun ad-java-bytecode-class-name (class-file)
  74. "Return the corresponding CLASS-NAME of a CLASS-FILE."
  75. (replace-regexp-in-string
  76. "/" "." (file-name-sans-extension class-file)))
  77. (defun ad-java-bytecode-buffer (class-file &optional jar-file)
  78. "Disassembles a Java CLASS-FILE inside the current buffer, using `javap'.
  79. The JAR-FILE argument is non-nil if the disassembly is happening
  80. inside a jar archive, during auto-extraction."
  81. (let ((class-name (ad-java-bytecode-class-name class-file))
  82. (class-path (or jar-file (file-name-directory class-file)))
  83. (orig-buffer-name (buffer-name))
  84. (orig-buffer-file-name (buffer-file-name)))
  85. ;; kill previous buffer
  86. (kill-buffer orig-buffer-name)
  87. ;; create and select new buffer with disassembled contents
  88. (switch-to-buffer (generate-new-buffer orig-buffer-name))
  89. (message "Disassembling %s" class-file)
  90. ;; disassemble .class file
  91. (apply 'call-process ad-java-bytecode-disassembler nil t nil
  92. (append ad-java-bytecode-parameters
  93. (list "-classpath" class-path
  94. (if jar-file class-name class-file))))
  95. ;; set some properties
  96. (set-visited-file-name nil)
  97. (setq buffer-file-name orig-buffer-file-name)
  98. (setq buffer-read-only t) ; mark as modified
  99. (set-buffer-modified-p nil) ; mark as read-only
  100. (goto-char (point-min)) ; jump to top
  101. (ad-javap-mode)
  102. (message "Disassembled %s" class-file)
  103. (current-buffer)))
  104. ;; Add hook for automatically disassembling .class files
  105. (add-hook 'find-file-hook
  106. (lambda () (let ((class-file (buffer-file-name)))
  107. (when (ad-java-bytecode-disassemble-p class-file)
  108. (ad-java-bytecode-buffer class-file)))))
  109. ;; Add hook for automatically disassembling .class files inside jars
  110. (add-hook 'archive-extract-hooks
  111. (lambda ()
  112. (let* ((components (split-string (buffer-file-name) ":"))
  113. (jar-file (car components))
  114. (class-file (cadr components)))
  115. (when (ad-java-bytecode-disassemble-p class-file)
  116. (ad-java-bytecode-buffer class-file jar-file)))))
  117. (provide 'autodisass-java-bytecode)
  118. ;;; autodisass-java-bytecode.el ends here