2.2.2.4. Your first Binutils hack
Have you ever felt that a single inc
instruction was not enough? Really? Me too!
So let’s hack the GNU GAS assembler, which is part of GNU Binutils, to add a new shiny version of inc
called… myinc
!
GCC uses GNU GAS as its backend, so we will test out new mnemonic with an GCC inline assembly test program: userland/arch/x86_64/binutils_hack.c, which is just a copy of userland/arch/x86_64/binutils_nohack.c but with myinc
instead of inc
.
The inline assembly is disabled with an #ifdef
, so first modify the source to enable that.
Then, try to build userland:
./build-userland
and watch it fail with:
binutils_hack.c:8: Error: no such instruction: `myinc %rax'
Now, edit the file
vim submodules/binutils-gdb/opcodes/i386-tbl.h
and add a copy of the "inc"
instruction just next to it, but with the new name "myinc"
:
diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h index af583ce578..3cc341f303 100644 --- a/opcodes/i386-tbl.h +++ b/opcodes/i386-tbl.h @@ -1502,6 +1502,19 @@ const insn_template i386_optab[] = { { { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } } } }, + { "myinc", 1, 0xfe, 0x0, 1, + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + { { { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } } } }, { "sub", 2, 0x28, None, 1, { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Finally, rebuild Binutils, userland and test our program with User mode simulation:
./build-buildroot -- host-binutils-rebuild ./build-userland --static ./run --static --userland userland/arch/x86_64/binutils_hack.c
and we se that myinc
worked since the assert did not fail!
Tested on b60784d59bee993bf0de5cde6c6380dd69420dda + 1.