summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/bootstrapGcc/14_g++4.6.4.md185
1 files changed, 185 insertions, 0 deletions
diff --git a/content/bootstrapGcc/14_g++4.6.4.md b/content/bootstrapGcc/14_g++4.6.4.md
new file mode 100644
index 0000000..9df600f
--- /dev/null
+++ b/content/bootstrapGcc/14_g++4.6.4.md
@@ -0,0 +1,185 @@
+Title: Milestone – Bootstrapped GCC 4.6.4 for RISC-V
+Date: 2024-05-17
+Category:
+Tags: Bootstrapping GCC in RISC-V
+Slug: bootstrapGcc14
+Lang: en
+Summary: So yeah, we bootstrapped GCC 4.6.4 for RISC-V. We even have C++
+ support!
+
+In latest posts we talked about many things: problems, our changes to other
+projects and other things. Now it's time to actually talk about something we
+actually *did*.
+
+But first, we fixed more extra things... This is a never ending story.
+
+### The things we need to deal with
+
+We have been trying to build GCC 4.6.4 with the backported RISC-V support using
+TinyCC. We already did a GCC 4.6.4 that worked but we only tested it building
+with a modern GCC. Building with a TinyCC with an incomplete backend that we
+had to improve ourselves is not that obvious as it would be with the very well
+established architecture like i386.
+
+We could build a minimal GCC, from TinyCC and Musl, but it didn't work. Me and
+my colleague Andrius Štikonas detected and patched around a problem that we
+still don't know where it is coming from ([we reported upstream][upstream]).
+This is the only one we need to apply to GCC, as we fixed many things in
+TinyCC.
+
+[upstream]: https://lists.nongnu.org/archive/html/tinycc-devel/2024-04/msg00028.html
+
+This simple patch was enough to build the whole GCC. Can you spot the
+difference?
+
+We find this kind of problems making small reproducers that we tried to tweak,
+and happened to work if we split things.
+
+``` diff
+diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
+index d05f8149170..d4ef8de4813 100644
+--- a/gcc/tree-ssa-operands.c
++++ b/gcc/tree-ssa-operands.c
+@@ -300,6 +300,7 @@ static inline void *
+ ssa_operand_alloc (unsigned size)
+ {
+ char *ptr;
++ int x;
+
+ gcc_assert (size == sizeof (struct use_optype_d)
+ || size == sizeof (struct def_optype_d));
+@@ -334,8 +335,8 @@ ssa_operand_alloc (unsigned size)
+ gimple_ssa_operands (cfun)->operand_memory_index = 0;
+ }
+
+- ptr = &(gimple_ssa_operands (cfun)->operand_memory
+- ->mem[gimple_ssa_operands (cfun)->operand_memory_index]);
++ x = gimple_ssa_operands (cfun)->operand_memory_index;
++ ptr = &(gimple_ssa_operands (cfun)->operand_memory->mem[x]);
+ gimple_ssa_operands (cfun)->operand_memory_index += size;
+ return ptr;
+ }
+```
+
+### We need to rebuild with Musl
+
+Once that very first GCC compiles, it's necessary to rebuild Musl with that
+GCC, and use the new GCC+Musl combination to rebuild GCC, now adding the C++
+support we missed first time.
+
+This gives us several things: a more stable GCC and a better Musl, that is
+compatible with GCC.
+
+If we don't do that, and we don't rebuild Musl, we see errors when building the
+second GCC, the `genmddeps` program, which is created and run during build
+process of GCC just fails.
+
+Also, we have to `--disable-bootstrap`, so rebuilding it is like doing the
+GCC's bootstrap ourselves.
+
+### Backport Musl support to GCC 4.6.4
+
+Next thing, remember from previous posts why we had to use Musl for our
+process. First, because it's a fully-featured C standard library; second,
+because it's simple and easy to build and, lastly, because we can't use GlibC:
+the newest version we can build doesn't support RISC-V.
+
+The main problem we have with GCC 4.6.4 since we started with all this journey
+is that 4.6.4 was written before our architecture, RISC-V, was invented, and
+this also happened with Musl.
+
+Andrius detected some missing declarations during the compilation process of
+the `libstdc++`, which happened because GCC was trying to use some GlibC
+specific functions for the build we didn't have, as we were using Musl instead.
+
+Turns out GCC needs extra configuration for Musl, that was added after our
+version was released, so I backported all that (not much) to GCC 4.6.4. Maybe I
+missed something, but now we can build GCC 4.6.4 with C++ support, using Musl,
+for RISC-V!
+
+### But it doesn't work!
+
+Right after building it, we tried to use it on a simple program:
+
+``` clike
+#include<iostream>
+
+int main (int argc, char* argv[]){
+ std::cout << "Hello World" << std::endl;
+ return 10;
+}
+```
+
+But this returns a huge set of errors looking like:
+
+``` something
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L0 ':
+(.text._ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKPi+0x3a): undefined reference to `operator new[](unsigned long)'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L15':
+(.text._ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKPi+0x172): undefined reference to `operator delete[](void*)'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L11':
+(.text._ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKPi+0x190): undefined reference to `__cxa_call_unexpected'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L0 ':
+(.text._ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi+0x3a): undefined reference to `operator new[](unsigned long)'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(c++locale.o): In function `.L39':
+(.text._ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi+0x1b4): undefined reference to `__cxa_call_unexpected'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L23':
+(.text._ZNSi6ignoreEl+0x21c): undefined reference to `__cxa_end_catch'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L24':
+(.text._ZNSi6ignoreEl+0x22e): undefined reference to `__cxa_end_catch'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.LEHB2':
+(.text._ZNSi6ignoreEl+0x24c): undefined reference to `__cxa_begin_catch'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L31':
+(.text._ZNSi6ignoreEl+0x272): undefined reference to `__cxa_rethrow'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.LEHE2':
+(.text._ZNSi6ignoreEl+0x27c): undefined reference to `__cxa_begin_catch'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L30':
+(.text._ZNSi6ignoreEl+0x29c): undefined reference to `__cxa_end_catch'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L51':
+(.text._ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl+0x22c): undefined reference to `__cxa_end_catch'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L52':
+(.text._ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl+0x23e): undefined reference to `__cxa_end_catch'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.LEHB9':
+(.text._ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl+0x25c): undefined reference to `__cxa_begin_catch'
+/gnu/store/f3chm93gvrina083lqp36qpf2w4fc3f1-profile/lib/libstdc++.a(compatibility.o): In function `.L59':
+(.text._ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl+0x282): undefined reference to `__cxa_rethrow'
+collect2: ld returned 1 exit status
+```
+
+Again, Andrius detected there was a line in the huge logs we have that said we
+were missing the `find` command. So we added it, and worked[^until-it-broke].
+
+[^until-it-broke]: There's something weird in this case, if I do a change like
+ this one below it fails:
+ <!-- Using a markdown fenced code block here fails -->
+
+ <pre class="language-diff">
+ <code class="language-diff">
+ (native-inputs `(("gcc" ,gcc-muslboot0)
+ ("libc" ,musl-boot)
+ - ("find" ,findutils)
+ ,@(modify-inputs (package-native-inputs gcc-muslboot0)
+ + (append findutils)
+ (replace "make" gnu-make-muslboot)
+ (delete "libc")
+ (delete "tcc"))))
+ </code>
+ </pre>
+
+### The thing built, and worked!
+
+So we managed to make it build and run, improving TinyCC in the process. Now
+TinyCC can build Musl and GCC 4.6.4 (with a very small patch), and that GCC is
+able to build itself, adding C++ support. And of course, the thing works!
+
+You can try if this thing worked, and see how, in the
+[`commencement.scm`][commencement] project where I'm keeping track of all this.
+
+[commencement]: https://github.com/ekaitz-zarraga/commencement.scm/commit/9bbb1c61a87e206fb275c3040d0493beba6ae0fe
+
+### Next
+
+So yeah, success but this didn't end. Now we need to use that GCC to build GCC
+7.5, and compile the world with it.
+
+Cross fingers.