diff options
author | Nguyễn Gia Phong <mcsinyx@disroot.org> | 2024-08-07 13:18:46 +0900 |
---|---|---|
committer | Nguyễn Gia Phong <mcsinyx@disroot.org> | 2024-08-07 13:19:24 +0900 |
commit | 3ffe5c3ab044bafd0e64b3ba4a2947db9c8c7454 (patch) | |
tree | 7dd3671be7ede641e18e12661eebe6efb7e906c5 | |
parent | f117aa2ead7a31802363a84c26d3f6863bdd7414 (diff) | |
download | guix-3ffe5c3ab044bafd0e64b3ba4a2947db9c8c7454.tar.gz |
gnu: Add e9patch.
* gnu/packages/engineering.scm (e9patch): New variable. Change-Id: I8da4e76043bf6d577e8d14a89cc7bc35caa3933f
-rw-r--r-- | gnu/packages/engineering.scm | 42 | ||||
-rw-r--r-- | gnu/packages/patches/e9patch-check.patch | 199 | ||||
-rw-r--r-- | gnu/packages/patches/e9patch-devendor.patch | 61 |
3 files changed, 302 insertions, 0 deletions
diff --git a/gnu/packages/engineering.scm b/gnu/packages/engineering.scm index 92bd7a63ff..a78b1eb157 100644 --- a/gnu/packages/engineering.scm +++ b/gnu/packages/engineering.scm @@ -96,6 +96,7 @@ #:use-module (gnu packages digest) #:use-module (gnu packages docbook) #:use-module (gnu packages documentation) + #:use-module (gnu packages elf) #:use-module (gnu packages file) #:use-module (gnu packages flex) #:use-module (gnu packages fontutils) @@ -165,6 +166,7 @@ #:use-module (gnu packages tls) #:use-module (gnu packages tree-sitter) #:use-module (gnu packages version-control) + #:use-module (gnu packages vim) #:use-module (gnu packages web) #:use-module (gnu packages wxwidgets) #:use-module (gnu packages xdisorg) @@ -1981,6 +1983,46 @@ and a fallback for environments without libc for Zydis.") @end itemize") (license license:expat))) +(define-public e9patch + (let ((commit "5b17f53b4c76b91e2e13e5421012b2a75af59b90") + (revision "0")) + (package + (name "e9patch") + (version (git-version "1.0.0-dev" revision commit)) + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/GJDuck/e9patch") + (commit commit))) + (sha256 + (base32 + "0ydjpb5ij2jjwlaw1499xbi08rnadw39drazkc8jxin2z8dlb7b6")) + (file-name (git-file-name name version)) + (patches (search-patches "e9patch-devendor.patch" + "e9patch-check.patch")))) + (build-system gnu-build-system) + (arguments `(#:phases (modify-phases %standard-phases + (delete 'configure)))) + (native-inputs (list xxd)) + (inputs (list elfutils zycore zydis zlib)) + (home-page "https://github.com/GJDuck/e9patch") + (synopsis "Static binary rewriting tool") + (description + "E9Patch is a static binary rewriting tool for x86-64 ELF binaries. +E9Patch is: +@itemize +@item Scalable: E9Patch can reliably rewrite large/complex binaries + including web browsers (>100MB in size). +@item Compatible: The rewritten binary is a drop-in replacement of the original, + with no additional dependencies. +@item Fast: E9Patch can rewrite most binaries in a few seconds. +@item Low Overheads: Both performance and memory. +@item Programmable: E9Patch is designed so that it can be easily integrated + into other projects. +@end itemize") + (license (list license:expat ;src/e9patch/e9loader_*.cpp + license:gpl3+))))) ;rest + (define-public asco (package (name "asco") diff --git a/gnu/packages/patches/e9patch-check.patch b/gnu/packages/patches/e9patch-check.patch new file mode 100644 index 0000000000..38c924da2f --- /dev/null +++ b/gnu/packages/patches/e9patch-check.patch @@ -0,0 +1,199 @@ +diff --git a/Makefile b/Makefile +index a5ea0d7ab1ad..acaa7dc64fd0 100644 +--- a/Makefile ++++ b/Makefile +@@ -45,6 +45,8 @@ E9TOOL_LDFLAGS=\ + -Wl,--dynamic-list=src/e9tool/e9tool.syms \ + -lpthread -ldl -lz + ++all: release tool ++ + release: CXXFLAGS += -O2 -D NDEBUG + release: $(E9PATCH_OBJS) + $(CXX) $(CXXFLAGS) $(E9PATCH_OBJS) -o e9patch +@@ -103,3 +105,12 @@ clean: + rm -rf $(E9PATCH_OBJS) e9patch \ + src/e9patch/e9loader.c e9loader.out e9loader.o e9loader.bin + ++regtest: e9tool ++ $(MAKE) -C test/regtest ++ ++stresstest: e9tool ++ $(MAKE) -C test/stresstest ++ ++check: regtest # stresstest ++ ++.PHONY: regtest stresstest check +diff --git a/e9compile.sh b/e9compile.sh +index 0f2e3b31c7c2..c84c19161138 100755 +--- a/e9compile.sh ++++ b/e9compile.sh +@@ -15,6 +15,8 @@ + # You should have received a copy of the GNU General Public License + # along with this program. If not, see <http://www.gnu.org/licenses/>. + ++set -e ++ + if [ -t 1 ] + then + RED="\033[31m" +@@ -95,8 +97,7 @@ then + exit 1 + fi + +-RELOCS=`readelf -r "$BASENAME" | head -n 10 | grep 'R_X86_64_'` +-if [ ! -z "$RELOCS" ] ++if readelf -r "$BASENAME" | head -n 10 | grep -q 'R_X86_64_' + then + echo >&2 + echo "${RED}warning${OFF}: the generated file (${YELLOW}$BASENAME${OFF}) contains relocations" >&2 +diff --git a/test/regtest/Makefile b/test/regtest/Makefile +index 992b1bc40984..142d29e54276 100644 +--- a/test/regtest/Makefile ++++ b/test/regtest/Makefile +@@ -3,32 +3,63 @@ FCF_NONE := $(shell \ + then true; \ + else echo -fcf-protection=none; fi) + +-all: ++check: regtest test test.pie test.libc test_c test_c.debug bugs inst patch dl init fini example.so ++ ./$< ++ ++test: + gcc -x assembler-with-cpp -o test test.s -no-pie -nostdlib \ + -Wl,--section-start=.text=0xa000000 -Wl,--section-start=.bss=0xc000000 \ + -Wl,-z -Wl,max-page-size=4096 -DPIE=0 ++ ++test.pie: + gcc -x assembler-with-cpp -o test.pie test.s -pie -nostdlib \ + -Wl,--section-start=.text=0xa000000 -Wl,--section-start=.bss=0xc000000 \ + -Wl,-z -Wl,max-page-size=4096 -DPIE=1 \ + -Wl,--export-dynamic ++ ++bugs: + gcc -x assembler-with-cpp -o bugs bugs.s -no-pie -nostdlib \ + -Wl,--section-start=.text=0xa000000 -Wl,--section-start=.bss=0xc000000 \ + -Wl,-z -Wl,max-page-size=4096 -DPIE=0 ++ ++test.libc: + gcc -x assembler-with-cpp -o test.libc test_libc.s -pie -Wl,--export-dynamic ++ ++libtest.so: + gcc -x assembler-with-cpp -shared -o libtest.so libtest.s ++ ++test_c: + gcc -O2 -fPIC $(FCF_NONE) -pie -o test_c test_c.c \ + -Wl,--export-dynamic -U_FORTIFY_SOURCE + strip test_c ++ ++test_c.debug: + gcc -O0 -g -fPIC -pie -o test_c.debug test_c.c ++ ++inst: + ../../e9compile.sh inst.c -I ../../examples/ ++ ++patch: + ../../e9compile.sh patch.cpp -std=c++11 -I ../../examples/ ++ ++dl: + NO_SIMD_CHECK=1 ../../e9compile.sh dl.c -I ../../examples/ ++ ++init: + ../../e9compile.sh init.c -I ../../examples/ ++ ++fini: + ../../e9compile.sh fini.c -I ../../examples/ ++ ++example.so: + g++ -std=c++11 -fPIC -shared -o example.so -O2 \ + ../../examples/plugins/example.cpp -I ../../src/e9tool/ ++ ++regtest: + g++ -std=c++11 -pie -fPIC -o regtest regtest.cpp -O2 + + clean: + rm -f *.log *.out *.exe test test.pie test.libc libtest.so inst inst.o \ + patch patch.o init init.o regtest ++ ++.PHONY: check clean +diff --git a/test/regtest/regtest.cpp b/test/regtest/regtest.cpp +index e86e0af03228..9d78f9c6d670 100644 +--- a/test/regtest/regtest.cpp ++++ b/test/regtest/regtest.cpp +@@ -164,11 +164,11 @@ static bool runTest(const struct dirent *test, const std::string &options) + { + fclose(OUT); fclose(EXP); + command.clear(); +- command += "diff "; ++ command += "diff -u "; + command += out; + command += ' '; + command += exp; +- command += " >"; ++ command += " | tee "; + command += diff; + printf("\t%s\n", command.c_str()); + (void)system(command.c_str()); +diff --git a/test/stresstest/Makefile b/test/stresstest/Makefile +index 64bcb5432a0e..2c8b98e7577c 100644 +--- a/test/stresstest/Makefile ++++ b/test/stresstest/Makefile +@@ -1,2 +1,15 @@ ++ROOT_DIR = ../.. ++ ++check: stresstest.sh nop example.so ++ ./$< ++ ++nop: $(ROOT_DIR)/e9compile.sh $(ROOT_DIR)/examples/nop.c ++ $^ ++ ++example.so: $(ROOT_DIR)/examples/plugins/example.cpp ++ g++ -std=c++11 -fPIC -shared -I$(ROOT_DIR)/src/e9tool -o $@ -O2 $< ++ + clean: + rm -rf example.so nop nop.o tmp ++ ++.PHONY: check clean +diff --git a/test/stresstest/stresstest.sh b/test/stresstest/stresstest.sh +index 86ac9e0db1f4..be4048f52f27 100755 +--- a/test/stresstest/stresstest.sh ++++ b/test/stresstest/stresstest.sh +@@ -1,4 +1,5 @@ +-#!/bin/bash ++#!/bin/sh ++set -e + + if [ -t 1 ] + then +@@ -15,20 +16,14 @@ else + OFF= + fi + +-set -e +-mkdir -p tmp +-../../e9compile.sh ../../examples/nop.c >/dev/null 2>&1 +- +-# Setup the example.so plugin +-g++ -std=c++11 -fPIC -shared -o example.so -O2 \ +- ../../examples/plugins/example.cpp -I ../../src/e9tool/ +- + runtest() + { + MATCH=$1 + PATCH=$2 + EXTRA=$3 + ++ mkdir tmp ++ + # Step (1): duplicate the tools + if ! ../../e9tool ../../e9tool "--match=$MATCH" "--patch=$PATCH" $EXTRA \ + -o tmp/e9tool.patched -c 6 -s >/dev/null 2>&1 +@@ -72,6 +67,8 @@ runtest() + else + echo -e "${RED}FAILED${OFF}: e9patch ${YELLOW}-M $MATCH -P $PATCH${OFF}" + fi ++ ++ rm -r tmp + } + + runtest true empty diff --git a/gnu/packages/patches/e9patch-devendor.patch b/gnu/packages/patches/e9patch-devendor.patch new file mode 100644 index 0000000000..f486415b83 --- /dev/null +++ b/gnu/packages/patches/e9patch-devendor.patch @@ -0,0 +1,61 @@ +diff --git a/Makefile b/Makefile +index a5ea0d7ab1ad..cfab982a991d 100644 +--- a/Makefile ++++ b/Makefile +@@ -33,17 +33,11 @@ E9TOOL_OBJS=\ + src/e9tool/e9tool.o \ + src/e9tool/e9types.o \ + src/e9tool/e9x86_64.o +-E9TOOL_LIBS=\ +- contrib/zydis/libZydis.a \ +- contrib/libdw/libdw.a +-E9TOOL_CXXFLAGS=\ +- -I src/e9tool/ -Wno-unused-function \ +- -I contrib/libdw/ \ +- -I contrib/zydis/include/ \ +- -I contrib/zydis/dependencies/zycore/include/ ++E9TOOL_LIBS= ++E9TOOL_CXXFLAGS=-fPIE -I src/e9tool/ -Wno-unused-function + E9TOOL_LDFLAGS=\ + -Wl,--dynamic-list=src/e9tool/e9tool.syms \ +- -lpthread -ldl -lz ++ -lpthread -ldl -ldw -lz -lZydis + + release: CXXFLAGS += -O2 -D NDEBUG + release: $(E9PATCH_OBJS) +diff --git a/src/e9tool/e9dwarf.cpp b/src/e9tool/e9dwarf.cpp +index 03afee65a091..183684d2293d 100644 +--- a/src/e9tool/e9dwarf.cpp ++++ b/src/e9tool/e9dwarf.cpp +@@ -28,7 +28,7 @@ + #include "e9misc.h" + #include "e9tool.h" + +-#include "libdw.h" ++#include <elfutils/libdw.h> + + using namespace e9tool; + +diff --git a/src/e9tool/e9x86_64.cpp b/src/e9tool/e9x86_64.cpp +index 6a7f5cff3692..03eb3a41dd66 100644 +--- a/src/e9tool/e9x86_64.cpp ++++ b/src/e9tool/e9x86_64.cpp +@@ -152,8 +152,7 @@ void e9tool::getInstrInfo(const ELF *elf, const Instr *I, InstrInfo *info, + ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]; + + ZyanStatus result = ZydisDecoderDecodeFull(&decoder, +- elf->data + I->offset, I->size, D, operands, ZYDIS_MAX_OPERAND_COUNT, +- 0); ++ elf->data + I->offset, I->size, D, operands); + if (!ZYAN_SUCCESS(result) || I->size != D->length || + D->operand_count > sizeof(info->op) / sizeof(info->op[0])) + error("failed to decompress instruction at address 0x%lx; decode " +@@ -336,7 +335,7 @@ void e9tool::getInstrInfo(const ELF *elf, const Instr *I, InstrInfo *info, + info->string.section = elf->strs + shdr->sh_name; + result = ZydisFormatterFormatInstruction(&formatter, D, operands, + D->operand_count_visible, info->string.instr, +- sizeof(info->string.instr)-1, I->address); ++ sizeof(info->string.instr)-1, I->address, ZYAN_NULL); + if (!ZYAN_SUCCESS(result)) + error("failed to decompress instruction at address 0x%lx; " + "formatting failed", I->address); |