binutils: describe gas hello world hack

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-03-05 00:00:02 +00:00
parent b60784d59b
commit 23f80c2310
3 changed files with 93 additions and 6 deletions

View File

@@ -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.

View File

@@ -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);
} }

View 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
}