From c382ecf3f71399471770ca64d109237c7ce287ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Sun, 10 Mar 2019 00:00:00 +0000 Subject: [PATCH] gcc: neverbuild, Buildroot can rebuild it :-) --- README.adoc | 77 ++++++++++++++++++++++++++++ build | 3 +- buildroot_override | 4 +- userland/arch/x86_64/binutils_hack.c | 2 + userland/gcc_hack.c | 13 +++++ 5 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 userland/gcc_hack.c diff --git a/README.adoc b/README.adoc index bbfcc34..4be0468 100644 --- a/README.adoc +++ b/README.adoc @@ -434,6 +434,83 @@ and we se that `myinc` worked since the assert did not fail! Tested on b60784d59bee993bf0de5cde6c6380dd69420dda + 1. +===== Your first GCC hack + +OK, now time to hack GCC. + +For convenience, let's use the <>. + +If we run the program link:userland/gcc_hack.c[]: + +.... +./build-userland --static +./run --static --userland gcc_hack +.... + +it produces the normal boring output: + +.... +i = 2 +j = 0 +.... + +So how about we swap `++` and `--` to make things more fun? + +Open the file: + +.... +vim submodules/gcc/gcc/c/c-parser.c +.... + +and find the function `c_parser_postfix_expression_after_primary`. + +In that function, swap `case CPP_PLUS_PLUS` and `case CPP_MINUS_MINUS`: + +.... +diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c +index 101afb8e35f..89535d1759a 100644 +--- a/gcc/c/c-parser.c ++++ b/gcc/c/c-parser.c +@@ -8529,7 +8529,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, + expr.original_type = DECL_BIT_FIELD_TYPE (field); + } + break; +- case CPP_PLUS_PLUS: ++ case CPP_MINUS_MINUS: + /* Postincrement. */ + start = expr.get_start (); + finish = c_parser_peek_token (parser)->get_finish (); +@@ -8548,7 +8548,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, + expr.original_code = ERROR_MARK; + expr.original_type = NULL; + break; +- case CPP_MINUS_MINUS: ++ case CPP_PLUS_PLUS: + /* Postdecrement. */ + start = expr.get_start (); + finish = c_parser_peek_token (parser)->get_finish (); +.... + +Now rebuild GCC, the program and re-run it: + +.... +./build-buildroot -- host-gcc-final-rebuild +./build-userland --static +./run --static --userland gcc_hack +.... + +and the new ouptut is now: + +.... +j = 0 +i = 2 +.... + +We need to use the ugly `-final` thing because GCC has to packages in Buildroot, `-initial` and `-final`: https://stackoverflow.com/questions/54992977/how-to-select-an-override-srcdir-source-for-gcc-when-building-buildroot No one is able to example precisely with a minimal example why this is required: + +* https://stackoverflow.com/questions/39883865/why-multiple-passes-for-building-linux-from-scratch-lfs +* https://stackoverflow.com/questions/27457835/why-do-cross-compilers-have-a-two-stage-compilation + ==== About the QEMU Buildroot setup This is our reference setup, and the best supported one, use it unless you have good reason not to. diff --git a/build b/build index 18a9854..a4adfed 100755 --- a/build +++ b/build @@ -112,8 +112,7 @@ so looping over all of them would waste time. }, submodules_shallow = { 'binutils-gdb', - # https://stackoverflow.com/questions/54992977/how-to-select-an-override-srcdir-source-for-gcc-when-building-buildroot - # 'gcc', + 'gcc', 'glibc', }, # https://buildroot.org/downloads/manual/manual.html#requirement diff --git a/buildroot_override b/buildroot_override index 0afd5e7..af0fb6f 100644 --- a/buildroot_override +++ b/buildroot_override @@ -1,6 +1,6 @@ BINUTILS_OVERRIDE_SRCDIR = ../../submodules/binutils-gdb -# https://stackoverflow.com/questions/54992977/how-to-select-an-override-srcdir-source-for-gcc-when-building-buildroot -GCC_OVERRIDE_SRCDIR = ../../submodules/gcc +GCC_INITIAL_OVERRIDE_SRCDIR = ../../submodules/gcc +GCC_FINAL_OVERRIDE_SRCDIR = ../../submodules/gcc GDB_OVERRIDE_SRCDIR = ../../submodules/binutils-gdb GLIBC_OVERRIDE_SRCDIR = ../../submodules/glibc LINUX_OVERRIDE_SRCDIR = ../../submodules/linux diff --git a/userland/arch/x86_64/binutils_hack.c b/userland/arch/x86_64/binutils_hack.c index c957536..6871f68 100644 --- a/userland/arch/x86_64/binutils_hack.c +++ b/userland/arch/x86_64/binutils_hack.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#your-first-binutils-hack */ + #include #include diff --git a/userland/gcc_hack.c b/userland/gcc_hack.c new file mode 100644 index 0000000..c89e41e --- /dev/null +++ b/userland/gcc_hack.c @@ -0,0 +1,13 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#your-first-gcc-hack */ + +#include +#include + +int main(void) { + int i = 1; + int j = 1; + i++; + j--; + printf("i = %d\n", i); + printf("j = %d\n", j); +}