-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathasm-x86.el
More file actions
136 lines (118 loc) · 5.05 KB
/
asm-x86.el
File metadata and controls
136 lines (118 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
;;; asm-x86.el --- X86 utilities -*- lexical-binding: t; -*-
;; Copyright (C) 2022-2025 Michał Krzywkowski
;; Author: Michał Krzywkowski <k.michal@zoho.com>
;; Keywords: languages, tools
;; Version: 0.1.0
;; Homepage: https://github.com/mkcms/emacs-binary-utils
;; Package-Requires: ((emacs "27"))
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; This package provides x86 handlers for the binfile package.
;;; Code:
(require 'cl-lib)
(require 'map)
(defun asm-x86--format-reloc-and-addend (reloc addend)
"Return a string for relocation RELOC with ADDEND.
This returns a string like \"reloc+0x1a\". ADDEND can be nil."
(format "%s%s"
reloc
(if (and addend (not (zerop addend)))
(if (cl-plusp addend)
(format "+0x%x" addend)
(format "-0x%x" (abs addend)))
"")))
(defun asm-x86--reloc-replace-0x0 (_type reloc _address addend _function-name)
"Simply replace the string \"0x0\" with the relocation name, RELOC+ADDEND."
(when (re-search-forward "\\b0x0\\b" nil t)
;; Check if we have another '0x0' and don't replace in that case.
(unless (save-match-data (re-search-forward "\\b0x0\\b" nil t))
(replace-match (asm-x86--format-reloc-and-addend reloc addend) nil t)
t)))
(defun asm-x86--reloc-replace-address-minus-addend
(_type reloc address addend _function-name)
"Subtract ADDEND from the ADDRESS and replace that with RELOC."
(setq address (- address (or addend 0)))
(save-excursion
(goto-char (point-max))
(when (re-search-backward (format "\\b%x\\b" address) nil t)
(goto-char (match-beginning 0))
(unless (save-match-data
(looking-back "^[[:space:]]+" (line-beginning-position)))
;; Handle the case when we matched address of the instruction itself -
;; we don't want that. We want to match an address _inside_ the
;; instruction.
(replace-match reloc nil t)
t))))
(defun asm-x86--reloc-replace-0x0-plus-addend-plus-4
(_type reloc _address addend _function-name)
"Replace the string \"0x0\" with the RELOC+ADDEND, plus 4."
(when (re-search-forward "\\b0x0\\b" nil t)
;; Only replace if we have exactly one '0x0'
(unless (save-match-data (re-search-forward "\\b0x0\\b" nil t))
(replace-match
(asm-x86--format-reloc-and-addend reloc (+ addend 4)) nil t)
t)))
(defun asm-x86--reloc-64
(reloc-type reloc reloc-address reloc-addend function-name)
"Handle x64 RELOC-TYPE RELOC at RELOC-ADDRESS RELOC-ADDEND in FUNCTION-NAME."
(pcase reloc-type
('"R_X86_64_PC32"
(or (asm-x86--reloc-replace-address-minus-addend
reloc-type reloc reloc-address reloc-addend function-name)
(asm-x86--reloc-replace-0x0-plus-addend-plus-4
reloc-type reloc reloc-address reloc-addend function-name)))
('"R_X86_64_GOTPCREL"
(asm-x86--reloc-replace-address-minus-addend
reloc-type reloc reloc-address reloc-addend function-name))
('"R_X86_64_REX_GOTPCRELX"
(asm-x86--reloc-replace-address-minus-addend
reloc-type reloc reloc-address reloc-addend function-name))
('"R_X86_64_PLT32"
(asm-x86--reloc-replace-address-minus-addend
reloc-type reloc reloc-address reloc-addend function-name))
('"R_X86_64_32"
(asm-x86--reloc-replace-0x0
reloc-type reloc reloc-address reloc-addend function-name))))
(defun asm-x86--postprocess (_beg _end _name)
"Do final cleanups on x86 binaries."
(save-excursion
;; Intel syntax
(while (re-search-forward
"\\(\\[rip\\+0x0]\\)\\([^\n]*\\)#\\s-*\\([^\n]*?\\)[[:space:]]*$"
nil t)
(replace-match "[rip+\\3]\\2")))
(save-excursion
;; AT&T syntax
(while (re-search-forward
(rx
(group word-boundary "0x0")
"(%rip)"
(group (one-or-more (not (in ?#))))
?#
(zero-or-more space)
(group (one-or-more (not space)))
(group (zero-or-more not-newline) eol))
nil t)
(let ((rest (match-string 4)))
(replace-match "\\3(%rip)\\2")
(unless (string-match-p "\\s-*" rest)
(insert rest))))))
(cl-eval-when (compile)
(require 'binfile))
(with-eval-after-load 'binfile
(setf (map-elt binfile-relocation-handler-alist "^R_X86_64_.*")
#'asm-x86--reloc-64)
(setf (map-elt binfile-region-postprocessing-functions-alist "elf64-x86-64")
#'asm-x86--postprocess))
(provide 'asm-x86)
;;; asm-x86.el ends here