diff options
| author | Nguyễn Gia Phong <cnx@loang.net> | 2026-03-03 13:52:51 +0900 |
|---|---|---|
| committer | Liliana Marie Prikler <liliana.prikler@gmail.com> | 2026-03-19 07:35:03 +0100 |
| commit | d78f9a3285ed1ab94e9d92f53ab7f6494aad7a44 (patch) | |
| tree | 3aba4740e707c6d23fe901e6de22200129eacdc9 | |
| parent | 80da50edf16e34303ec44972dff41d3d59a7193d (diff) | |
gnu: Add e9patch.
* gnu/packages/patchutils.scm (e9patch): New variable.
* gnu/packages/patches/e9patch-zydis-4.1-compat.patch: New file.
* gnu/local.mk (dist_patch_DATA): Register it.
Co-Authored-By: Liliana Marie Prikler <liliana.prikler@gmail.com>
Change-Id: Iad3da332c17e3236ed1fd635cffae006195a77a6
Signed-off-by: Liliana Marie Prikler <liliana.prikler@gmail.com>
| -rw-r--r-- | gnu/local.mk | 1 | ||||
| -rw-r--r-- | gnu/packages/patches/e9patch-zydis-4.1-compat.patch | 80 | ||||
| -rw-r--r-- | gnu/packages/patchutils.scm | 57 |
3 files changed, 138 insertions, 0 deletions
diff --git a/gnu/local.mk b/gnu/local.mk index c7db93ecd68..8b6ebc51f41 100644 --- a/gnu/local.mk +++ b/gnu/local.mk | |||
| @@ -1215,6 +1215,7 @@ dist_patch_DATA = \ | |||
| 1215 | %D%/packages/patches/dvdbackup-with-libdvdread-6.1.0+.patch \ | 1215 | %D%/packages/patches/dvdbackup-with-libdvdread-6.1.0+.patch \ |
| 1216 | %D%/packages/patches/dvd+rw-tools-add-include.patch \ | 1216 | %D%/packages/patches/dvd+rw-tools-add-include.patch \ |
| 1217 | %D%/packages/patches/dwarves-threading-reproducibility.patch \ | 1217 | %D%/packages/patches/dwarves-threading-reproducibility.patch \ |
| 1218 | %D%/packages/patches/e9patch-zydis-4.1-compat.patch \ | ||
| 1218 | %D%/packages/patches/efitools-riscv64-support.patch \ | 1219 | %D%/packages/patches/efitools-riscv64-support.patch \ |
| 1219 | %D%/packages/patches/efivar-fix-fprint-format.patch \ | 1220 | %D%/packages/patches/efivar-fix-fprint-format.patch \ |
| 1220 | %D%/packages/patches/elastix-1404.patch \ | 1221 | %D%/packages/patches/elastix-1404.patch \ |
diff --git a/gnu/packages/patches/e9patch-zydis-4.1-compat.patch b/gnu/packages/patches/e9patch-zydis-4.1-compat.patch new file mode 100644 index 00000000000..93621b687ea --- /dev/null +++ b/gnu/packages/patches/e9patch-zydis-4.1-compat.patch | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | commit c02dd23b12fd687a041ab3b872b3f989cd1342dc | ||
| 2 | Author: Nguyễn Gia Phong <cnx@loang.net> | ||
| 3 | Date: 2024-11-18 15:13:17 +0900 | ||
| 4 | |||
| 5 | Make compatible with Zydis 4.1 | ||
| 6 | |||
| 7 | This Zydis version is more explicit in formatting | ||
| 8 | lea instructions in Intel format. | ||
| 9 | |||
| 10 | The hunk adding sqrtss is due to a bug in Zydis: | ||
| 11 | https://github.com/zyantific/zydis/issues/542 | ||
| 12 | |||
| 13 | For this reason, E9Patch is not open to updating Zydis. | ||
| 14 | |||
| 15 | diff --git a/src/e9tool/e9x86_64.cpp b/src/e9tool/e9x86_64.cpp | ||
| 16 | index 6a7f5cff3692..03eb3a41dd66 100644 | ||
| 17 | --- a/src/e9tool/e9x86_64.cpp | ||
| 18 | +++ b/src/e9tool/e9x86_64.cpp | ||
| 19 | @@ -152,8 +152,7 @@ void e9tool::getInstrInfo(const ELF *elf, const Instr *I, InstrInfo *info, | ||
| 20 | ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]; | ||
| 21 | |||
| 22 | ZyanStatus result = ZydisDecoderDecodeFull(&decoder, | ||
| 23 | - elf->data + I->offset, I->size, D, operands, ZYDIS_MAX_OPERAND_COUNT, | ||
| 24 | - 0); | ||
| 25 | + elf->data + I->offset, I->size, D, operands); | ||
| 26 | if (!ZYAN_SUCCESS(result) || I->size != D->length || | ||
| 27 | D->operand_count > sizeof(info->op) / sizeof(info->op[0])) | ||
| 28 | error("failed to decompress instruction at address 0x%lx; decode " | ||
| 29 | @@ -336,7 +335,7 @@ void e9tool::getInstrInfo(const ELF *elf, const Instr *I, InstrInfo *info, | ||
| 30 | info->string.section = elf->strs + shdr->sh_name; | ||
| 31 | result = ZydisFormatterFormatInstruction(&formatter, D, operands, | ||
| 32 | D->operand_count_visible, info->string.instr, | ||
| 33 | - sizeof(info->string.instr)-1, I->address); | ||
| 34 | + sizeof(info->string.instr)-1, I->address, ZYAN_NULL); | ||
| 35 | if (!ZYAN_SUCCESS(result)) | ||
| 36 | error("failed to decompress instruction at address 0x%lx; " | ||
| 37 | "formatting failed", I->address); | ||
| 38 | diff --git a/test/regtest/print_intel.exp b/test/regtest/print_intel.exp | ||
| 39 | index ae91f44..9bdbe0f 100644 | ||
| 40 | --- a/test/regtest/print_intel.exp | ||
| 41 | +++ b/test/regtest/print_intel.exp | ||
| 42 | @@ -24,14 +24,14 @@ jmp 0xa000163 | ||
| 43 | call 0xa000168 | ||
| 44 | jmp 0xa00016d | ||
| 45 | jmp 0xa000177 | ||
| 46 | -lea r10, [rip+0x14] | ||
| 47 | +lea r10, qword ptr [rip+0x14] | ||
| 48 | push r10 | ||
| 49 | push r11 | ||
| 50 | mov rcx, 0xffffffffffff8889 | ||
| 51 | jmp qword ptr [rsp+rcx*1+0x777f] | ||
| 52 | call 0xa0001b5 | ||
| 53 | add rsp, 0x8 | ||
| 54 | -lea rdx, [rip+0x2] | ||
| 55 | +lea rdx, qword ptr [rip+0x2] | ||
| 56 | call rdx | ||
| 57 | pop r14 | ||
| 58 | add r9, 0x6 | ||
| 59 | @@ -85,7 +85,7 @@ xor eax, eax | ||
| 60 | inc eax | ||
| 61 | mov edi, eax | ||
| 62 | inc rdi | ||
| 63 | -lea rsi, [rip+0x54] | ||
| 64 | +lea rsi, qword ptr [rip+0x54] | ||
| 65 | mov rdx, 0x7 | ||
| 66 | syscall | ||
| 67 | PASSED | ||
| 68 | diff --git a/test/regtest/same_op_2.exp b/test/regtest/same_op_2.exp | ||
| 69 | index f99033a..45790b8 100644 | ||
| 70 | --- a/test/regtest/same_op_2.exp | ||
| 71 | +++ b/test/regtest/same_op_2.exp | ||
| 72 | @@ -12,6 +12,7 @@ shl $0x7, %rdi | ||
| 73 | sar $0x3, %rdi | ||
| 74 | pxor %xmm0, %xmm0 | ||
| 75 | cvtsi2ss %rax, %xmm0 | ||
| 76 | +sqrtss %xmm0, %xmm1 | ||
| 77 | xor %esi, %esi | ||
| 78 | xor %eax, %eax | ||
| 79 | PASSED | ||
| 80 | |||
diff --git a/gnu/packages/patchutils.scm b/gnu/packages/patchutils.scm index 52979779f95..b980359edc1 100644 --- a/gnu/packages/patchutils.scm +++ b/gnu/packages/patchutils.scm | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #:use-module (gnu packages compression) | 34 | #:use-module (gnu packages compression) |
| 35 | #:use-module (gnu packages databases) | 35 | #:use-module (gnu packages databases) |
| 36 | #:use-module (gnu packages django) | 36 | #:use-module (gnu packages django) |
| 37 | #:use-module (gnu packages elf) | ||
| 38 | #:use-module (gnu packages engineering) | ||
| 37 | #:use-module (gnu packages file) | 39 | #:use-module (gnu packages file) |
| 38 | #:use-module (gnu packages freedesktop) | 40 | #:use-module (gnu packages freedesktop) |
| 39 | #:use-module (gnu packages gawk) | 41 | #:use-module (gnu packages gawk) |
| @@ -44,6 +46,7 @@ | |||
| 44 | #:use-module (gnu packages gtk) | 46 | #:use-module (gnu packages gtk) |
| 45 | #:use-module (gnu packages less) | 47 | #:use-module (gnu packages less) |
| 46 | #:use-module (gnu packages mail) | 48 | #:use-module (gnu packages mail) |
| 49 | #:use-module (gnu packages markup) | ||
| 47 | #:use-module (gnu packages ncurses) | 50 | #:use-module (gnu packages ncurses) |
| 48 | #:use-module (gnu packages ocaml) | 51 | #:use-module (gnu packages ocaml) |
| 49 | #:use-module (gnu packages package-management) | 52 | #:use-module (gnu packages package-management) |
| @@ -56,6 +59,7 @@ | |||
| 56 | #:use-module (gnu packages text-editors) | 59 | #:use-module (gnu packages text-editors) |
| 57 | #:use-module (gnu packages time) | 60 | #:use-module (gnu packages time) |
| 58 | #:use-module (gnu packages version-control) | 61 | #:use-module (gnu packages version-control) |
| 62 | #:use-module (gnu packages vim) | ||
| 59 | #:use-module (gnu packages xml) | 63 | #:use-module (gnu packages xml) |
| 60 | #:use-module (gnu packages) | 64 | #:use-module (gnu packages) |
| 61 | #:use-module (guix build-system glib-or-gtk) | 65 | #:use-module (guix build-system glib-or-gtk) |
| @@ -121,6 +125,59 @@ using semantic patches in the @acronym{SmPL, Semantic Patch Language} for | |||
| 121 | specifying desired matches and transformations in the C code.") | 125 | specifying desired matches and transformations in the C code.") |
| 122 | (license license:gpl2)))) | 126 | (license license:gpl2)))) |
| 123 | 127 | ||
| 128 | (define-public e9patch | ||
| 129 | (package | ||
| 130 | (name "e9patch") | ||
| 131 | (version "1.0.0") | ||
| 132 | (source | ||
| 133 | (origin | ||
| 134 | (method git-fetch) | ||
| 135 | (uri (git-reference | ||
| 136 | (url "https://github.com/GJDuck/e9patch") | ||
| 137 | (commit (string-append "v" version)))) | ||
| 138 | (file-name (git-file-name name version)) | ||
| 139 | (sha256 | ||
| 140 | (base32 "1bgv05fnz0kfzpyikadp96zrr83214lk2nx82jpmlv9dq0lhxccq")) | ||
| 141 | ;; E9Patch is sensitive to Zydis version, including the latter's bugs: | ||
| 142 | ;; https://github.com/GJDuck/e9patch/pull/94#issuecomment-2525069952 | ||
| 143 | (patches (search-patches "e9patch-zydis-4.1-compat.patch")) | ||
| 144 | (modules '((guix build utils))) | ||
| 145 | ;; The following snippet is also for Zydis 4.1 compatibility. | ||
| 146 | ;; The patch replaces a single line in 43 files, producing a giant diff: | ||
| 147 | ;; https://github.com/GJDuck/e9patch/pull/93.patch | ||
| 148 | (snippet | ||
| 149 | #~(begin | ||
| 150 | (substitute* (find-files "test/regtest" "\\.exp$") | ||
| 151 | (("\\$0x8877665544332211") | ||
| 152 | "$-0x778899aabbccddef")) | ||
| 153 | ;; The regular expression to test is .*a.*, | ||
| 154 | ;; matching the number produced by the substitution above. | ||
| 155 | (substitute* "test/regtest/not_regex.exp" | ||
| 156 | ((".*\\$-0x778899aabbccddef.*") | ||
| 157 | "")))))) | ||
| 158 | (build-system gnu-build-system) | ||
| 159 | (arguments | ||
| 160 | (list | ||
| 161 | #:phases | ||
| 162 | #~(modify-phases %standard-phases | ||
| 163 | (delete 'configure)) | ||
| 164 | #:make-flags | ||
| 165 | #~(list (string-append "CC=" #$(cc-for-target)) | ||
| 166 | (string-append "PREFIX=" #$output)))) | ||
| 167 | (native-inputs (list markdown xxd)) | ||
| 168 | (inputs (list elfutils zycore zydis zlib)) | ||
| 169 | (home-page "https://github.com/GJDuck/e9patch") | ||
| 170 | (synopsis "Static binary rewriting tool") | ||
| 171 | (description | ||
| 172 | "E9Patch is a static binary rewriting tool for x86-64 ELF binaries, | ||
| 173 | both executables and shared objects. The patched binaries can be used | ||
| 174 | in place of the original, without requiring additional runtime dependencies. | ||
| 175 | Binary patches can be defined through a high-level interface, which focuses | ||
| 176 | on ease of use, or low-level interfaces, which provide additional flexibility | ||
| 177 | and allow optimizations for performance.") | ||
| 178 | (license (list license:expat ;src/e9patch/e9loader_*.cpp | ||
| 179 | license:gpl3+)))) ;rest | ||
| 180 | |||
| 124 | (define-public patchutils | 181 | (define-public patchutils |
| 125 | (package | 182 | (package |
| 126 | (name "patchutils") | 183 | (name "patchutils") |
