mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
binutils: describe gas hello world hack
This commit is contained in:
69
README.adoc
69
README.adoc
@@ -365,6 +365,75 @@ Note that for arch agnostic features that don't rely on bleeding kernel changes
|
|||||||
|
|
||||||
Tested on a30ed0f047523ff2368d421ee2cce0800682c44e + 1.
|
Tested on a30ed0f047523ff2368d421ee2cce0800682c44e + 1.
|
||||||
|
|
||||||
|
===== Your first Binutils hack
|
||||||
|
|
||||||
|
Have you ever felt that a single `inc` instruction was not enough? Really? Me too!
|
||||||
|
|
||||||
|
So let's hack the link:https://en.wikipedia.org/wiki/GNU_Assembler[GNU GAS assembler], which is part of link:https://en.wikipedia.org/wiki/GNU_Binutils[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 inline assembly test program: link:userland/arch/x86_64/binutils_hack.c[], which is just a copy of link:userland/arch/x86_64/asm_hello.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-setup>>:
|
||||||
|
|
||||||
|
....
|
||||||
|
./build-buildroot -- host-binutils-rebuild
|
||||||
|
./build-userland --static
|
||||||
|
./run --static --userland arch/x86_64/binutils_hack
|
||||||
|
....
|
||||||
|
|
||||||
|
and we se that `myinc` worked since the assert did not fail!
|
||||||
|
|
||||||
|
Tested on b60784d59bee993bf0de5cde6c6380dd69420dda + 1.
|
||||||
|
|
||||||
==== About the QEMU Buildroot setup
|
==== About the QEMU Buildroot setup
|
||||||
|
|
||||||
This is our reference setup, and the best supported one, use it unless you have good reason not to.
|
This is our reference setup, and the best supported one, use it unless you have good reason not to.
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
uint32_t in = 1;
|
uint64_t in = 0xFFFFFFFF;
|
||||||
uint32_t out = 0;
|
uint64_t out = 0;
|
||||||
__asm__ (
|
__asm__ (
|
||||||
"mov %[in], %%eax;"
|
"mov %[in], %%rax;"
|
||||||
"inc %%eax;"
|
"inc %%rax;"
|
||||||
"mov %%eax, %[out]"
|
"movq %%rax, %[out]"
|
||||||
: [out] "=g" (out)
|
: [out] "=g" (out)
|
||||||
: [in] "g" (in)
|
: [in] "g" (in)
|
||||||
: "%eax"
|
: "rax"
|
||||||
);
|
);
|
||||||
assert(out == in + 1);
|
assert(out == in + 1);
|
||||||
}
|
}
|
||||||
|
|||||||
18
userland/arch/x86_64/binutils_hack.c
Normal file
18
userland/arch/x86_64/binutils_hack.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
#if 0
|
||||||
|
uint64_t in = 0xFFFFFFFF;
|
||||||
|
uint64_t out = 0;
|
||||||
|
__asm__ (
|
||||||
|
"mov %[in], %%rax;"
|
||||||
|
"myinc %%rax;"
|
||||||
|
"movq %%rax, %[out]"
|
||||||
|
: [out] "=g" (out)
|
||||||
|
: [in] "g" (in)
|
||||||
|
: "rax"
|
||||||
|
);
|
||||||
|
assert(out == in + 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user