Просмотр исходного кода

Toolchain: Enable -fexceptions and build a separate libstdc++ for the kernel

This enables building usermode programs with exception handling. It also
builds a libstdc++ without exception support for the kernel.

This is necessary because the libstdc++ that gets built is different
when exceptions are enabled. Using the same library binary would
require extensive stubs for exception-related functionality in the
kernel.
Gunnar Beutner 4 лет назад
Родитель
Сommit
d7978a3317
4 измененных файлов с 121 добавлено и 55 удалено
  1. 4 2
      Kernel/CMakeLists.txt
  2. 80 47
      Toolchain/BuildIt.sh
  3. 0 2
      Toolchain/CMake/CMakeToolchain.txt
  4. 37 4
      Toolchain/Patches/gcc.patch

+ 4 - 2
Kernel/CMakeLists.txt

@@ -352,8 +352,10 @@ file(GENERATE OUTPUT linker.ld INPUT linker.ld)
 if (${CMAKE_HOST_SYSTEM_NAME} MATCHES SerenityOS)
     include_directories(/usr/local/include/c++/10.2.0/)
 else()
-    include_directories(../Toolchain/Local/${SERENITY_ARCH}/${SERENITY_ARCH}-pc-serenity/include/c++/10.3.0/)
-    include_directories(../Toolchain/Local/${SERENITY_ARCH}/${SERENITY_ARCH}-pc-serenity/include/c++/10.3.0/${SERENITY_ARCH}-pc-serenity/)
+    include_directories(../Toolchain/Local/${SERENITY_ARCH}/Kernel/${SERENITY_ARCH}-pc-serenity/include/c++/10.3.0/)
+    include_directories(../Toolchain/Local/${SERENITY_ARCH}/Kernel/${SERENITY_ARCH}-pc-serenity/include/c++/10.3.0/${SERENITY_ARCH}-pc-serenity/)
+    link_directories(../Toolchain/Local/${SERENITY_ARCH}/Kernel/${SERENITY_ARCH}-pc-serenity/lib)
+    link_directories(../Toolchain/Local/${SERENITY_ARCH}/Kernel/lib/gcc/${SERENITY_ARCH}-pc-serenity/10.3.0/)
 endif()
 
 add_executable(Kernel ${SOURCES})

+ 80 - 47
Toolchain/BuildIt.sh

@@ -75,7 +75,6 @@ GCC_NAME="gcc-$GCC_VERSION"
 GCC_PKG="${GCC_NAME}.tar.gz"
 GCC_BASE_URL="http://ftp.gnu.org/gnu/gcc"
 
-
 # === CHECK CACHE AND REUSE ===
 
 pushd "$DIR"
@@ -189,17 +188,21 @@ popd
 
 # === COMPILE AND INSTALL ===
 
+rm -rf "$PREFIX"
 mkdir -p "$PREFIX"
-mkdir -p "$DIR/Build/$ARCH/binutils"
-mkdir -p "$DIR/Build/$ARCH/gcc"
 
 if [ -z "$MAKEJOBS" ]; then
     MAKEJOBS=$($NPROC)
 fi
 
+mkdir -p "$DIR/Build/$ARCH"
+
 pushd "$DIR/Build/$ARCH"
     unset PKG_CONFIG_LIBDIR # Just in case
 
+    rm -rf binutils
+    mkdir -p binutils
+
     pushd binutils
         echo "XXX configure binutils"
         "$DIR"/Tarballs/$BINUTILS_NAME/configure --prefix="$PREFIX" \
@@ -222,55 +225,85 @@ pushd "$DIR/Build/$ARCH"
         "$MAKE" install || exit 1
     popd
 
-    pushd gcc
-        if [ "$(uname -s)" = "OpenBSD" ]; then
-            perl -pi -e 's/-no-pie/-nopie/g' "$DIR/Tarballs/gcc-$GCC_VERSION/gcc/configure"
-        fi
+    echo "XXX serenity libc and libm headers"
+    mkdir -p "$BUILD"
+    pushd "$BUILD"
+        mkdir -p Root/usr/include/
+        SRC_ROOT=$($REALPATH "$DIR"/..)
+        FILES=$(find "$SRC_ROOT"/Userland/Libraries/LibC "$SRC_ROOT"/Userland/Libraries/LibM -name '*.h' -print)
+        for header in $FILES; do
+            target=$(echo "$header" | sed -e "s@$SRC_ROOT/Userland/Libraries/LibC@@" -e "s@$SRC_ROOT/Userland/Libraries/LibM@@")
+            $INSTALL -D "$header" "Root/usr/include/$target"
+        done
+        unset SRC_ROOT
+    popd
 
-        echo "XXX configure gcc and libgcc"
-        "$DIR/Tarballs/gcc-$GCC_VERSION/configure" --prefix="$PREFIX" \
-                                            --target="$TARGET" \
-                                            --with-sysroot="$SYSROOT" \
-                                            --disable-nls \
-                                            --with-newlib \
-                                            --enable-shared \
-                                            --enable-languages=c,c++ \
-                                            --enable-default-pie \
-                                            --enable-lto \
-                                            ${TRY_USE_LOCAL_TOOLCHAIN:+"--quiet"} || exit 1
-
-        echo "XXX serenity libc and libm headers"
-        mkdir -p "$BUILD"
-        pushd "$BUILD"
-            mkdir -p Root/usr/include/
-            SRC_ROOT=$($REALPATH "$DIR"/..)
-            FILES=$(find "$SRC_ROOT"/Userland/Libraries/LibC "$SRC_ROOT"/Userland/Libraries/LibM -name '*.h' -print)
-            for header in $FILES; do
-                target=$(echo "$header" | sed -e "s@$SRC_ROOT/Userland/Libraries/LibC@@" -e "s@$SRC_ROOT/Userland/Libraries/LibM@@")
-                $INSTALL -D "$header" "Root/usr/include/$target"
-            done
-            unset SRC_ROOT
-        popd
+    if [ "$(uname -s)" = "OpenBSD" ]; then
+        perl -pi -e 's/-no-pie/-nopie/g' "$DIR/Tarballs/gcc-$GCC_VERSION/gcc/configure"
+    fi
 
-        echo "XXX build gcc and libgcc"
-        "$MAKE" -j "$MAKEJOBS" all-gcc || exit 1
-        if [ "$(uname -s)" = "OpenBSD" ]; then
-            ln -sf liblto_plugin.so.0.0 gcc/liblto_plugin.so
-        fi
-        "$MAKE" -j "$MAKEJOBS" all-target-libgcc || exit 1
-        echo "XXX install gcc and libgcc"
-        "$MAKE" install-gcc install-target-libgcc || exit 1
+    if [ ! -f $DIR/Tarballs/gcc-$GCC_VERSION/gcc/config/serenity-userland.h ]; then
+        cp $DIR/Tarballs/gcc-$GCC_VERSION/gcc/config/serenity.h $DIR/Tarballs/gcc-$GCC_VERSION/gcc/config/serenity-kernel.h
+    fi
 
-        echo "XXX build libstdc++"
-        "$MAKE" -j "$MAKEJOBS" all-target-libstdc++-v3 || exit 1
-        echo "XXX install libstdc++"
-        "$MAKE" install-target-libstdc++-v3 || exit 1
+    for STAGE in Userland Kernel; do
+        rm -rf gcc
+        mkdir -p gcc
 
-        if [ "$(uname -s)" = "OpenBSD" ]; then
-            cd "$DIR/Local/${ARCH}/libexec/gcc/$TARGET/$GCC_VERSION" && ln -sf liblto_plugin.so.0.0 liblto_plugin.so
-        fi
+        pushd gcc
+            TEMPTARGET="$BUILD/Temp"
+            rm -rf "$TEMPTARGET"
 
-    popd
+            echo "XXX configure gcc and libgcc"
+            if [ "$STAGE" = "Userland" ]; then
+                REALTARGET="$PREFIX"
+            else
+                REALTARGET="$PREFIX/Kernel"
+            fi
+
+            cp $DIR/Tarballs/gcc-$GCC_VERSION/gcc/config/serenity-kernel.h $DIR/Tarballs/gcc-$GCC_VERSION/gcc/config/serenity.h
+            if [ "$STAGE" = "Userland" ]; then
+                sed -i 's@-fno-exceptions @@' $DIR/Tarballs/gcc-$GCC_VERSION/gcc/config/serenity.h
+            fi
+
+            "$DIR/Tarballs/gcc-$GCC_VERSION/configure" --prefix="$PREFIX" \
+                                                --target="$TARGET" \
+                                                --with-sysroot="$SYSROOT" \
+                                                --disable-nls \
+                                                --with-newlib \
+                                                --enable-shared \
+                                                --enable-languages=c,c++ \
+                                                --enable-default-pie \
+                                                --enable-lto \
+                                                ${TRY_USE_LOCAL_TOOLCHAIN:+"--quiet"} || exit 1
+
+            if [ "$STAGE" = "Userland" ]; then
+                echo "XXX build gcc and libgcc"
+                "$MAKE" -j "$MAKEJOBS" all-gcc || exit 1
+                if [ "$(uname -s)" = "OpenBSD" ]; then
+                    ln -sf liblto_plugin.so.0.0 gcc/liblto_plugin.so
+                fi
+                "$MAKE" -j "$MAKEJOBS" all-target-libgcc || exit 1
+                echo "XXX install gcc and libgcc"
+                "$MAKE" DESTDIR=$TEMPTARGET install-gcc install-target-libgcc || exit 1
+            fi
+
+            echo "XXX build libstdc++"
+            "$MAKE" -j "$MAKEJOBS" all-target-libstdc++-v3 || exit 1
+            echo "XXX install libstdc++"
+            "$MAKE" DESTDIR=$TEMPTARGET install-target-libstdc++-v3 || exit 1
+
+            mkdir -p "$REALTARGET"
+            cp -a $TEMPTARGET/$PREFIX/* "$REALTARGET/"
+            rm -rf "$TEMPTARGET"
+        popd
+
+        if [ "$STAGE" = "Userland" ]; then
+            if [ "$(uname -s)" = "OpenBSD" ]; then
+                cd "$DIR/Local/${ARCH}/libexec/gcc/$TARGET/$GCC_VERSION" && ln -sf liblto_plugin.so.0.0 liblto_plugin.so
+            fi
+        fi
+    done
 popd
 
 

+ 0 - 2
Toolchain/CMake/CMakeToolchain.txt

@@ -12,8 +12,6 @@ set(SERENITYOS 1)
 
 set(CMAKE_SYSTEM_PROCESSOR "$ENV{SERENITY_ARCH}")
 
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
-
 set(SERENITY_BUILD_DIR $ENV{SERENITY_ROOT}/Build/$ENV{SERENITY_ARCH})
 
 # where to read from/write to

+ 37 - 4
Toolchain/Patches/gcc.patch

@@ -102,11 +102,15 @@ diff -ruN a/gcc/config/arm/serenity-elf.h b/gcc/config/arm/serenity-elf.h
 diff -ruN a/gcc/config/serenity.h b/gcc/config/serenity.h
 --- a/gcc/config/serenity.h	1970-01-01 02:00:00.000000000 +0200
 +++ b/gcc/config/serenity.h	2020-12-12 10:43:35.280270540 +0200
-@@ -0,0 +1,37 @@
+@@ -0,0 +1,41 @@
 +/* Useful if you wish to make target-specific GCC changes. */
 +#undef TARGET_SERENITY
 +#define TARGET_SERENITY 1
 +
++#if defined(HAVE_LD_EH_FRAME_HDR)
++#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} "
++#endif
++
 +/* Default arguments you want when running your
 +   i686-serenity-gcc/x86_64-serenity-gcc toolchain */
 +#undef LIB_SPEC
@@ -200,16 +204,16 @@ diff -ruN a/libgcc/config.host b/libgcc/config.host
  	;;
 +i[34567]86-*-serenity*)
 +	extra_parts="$extra_parts crti.o crtbegin.o crtbeginS.o crtend.o crtendS.o crtn.o"
-+	tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic t-slibgcc"
++	tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic t-slibgcc t-eh-dw2-dip"
 +	;;
 +x86_64-*-serenity*)
 +	extra_parts="$extra_parts crti.o crtbegin.o crtbeginS.o crtend.o crtendS.o crtn.o"
-+	tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic t-slibgcc"
++	tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic t-slibgcc t-eh-dw2-dip"
 +	;;
 +arm-*-serenity*)
 +	tmake_file="${tmake_file} t-fixedpoint-gnu-prefix t-crtfm"
 +	tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
-+	tmake_file="${tmake_file} arm/t-bpabi"
++	tmake_file="${tmake_file} arm/t-bpabi t-eh-dw2-dip"
 +	tm_file="$tm_file arm/bpabi-lib.h"
 +	unwind_header=config/arm/unwind-arm.h
 +	extra_parts="$extra_parts crti.o crtn.o"
@@ -6224,3 +6228,32 @@ diff -ruN a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4
    arm*-*-symbianelf*)
      # This is a freestanding configuration; there is nothing to do here.
      ;;
+diff -Naur gcc-10.3.0/libgcc/unwind-dw2-fde-dip.c gcc-10.3.0.serenity/libgcc/unwind-dw2-fde-dip.c
+--- gcc-10.3.0/libgcc/unwind-dw2-fde-dip.c	2021-04-16 22:25:49.268958198 +0200
++++ gcc-10.3.0.serenity/libgcc/unwind-dw2-fde-dip.c	2021-04-16 22:26:09.732716890 +0200
+@@ -59,6 +59,12 @@
+ 
+ #if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
+     && defined(TARGET_DL_ITERATE_PHDR) \
++    && defined(__serenity__)
++# define USE_PT_GNU_EH_FRAME
++#endif
++
++#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
++    && defined(TARGET_DL_ITERATE_PHDR) \
+     && defined(__linux__)
+ # define USE_PT_GNU_EH_FRAME
+ #endif
+diff -Naur gcc-10.3.0/gcc/configure gcc-10.3.0.serenity/gcc/configure
+--- gcc-10.3.0/gcc/configure	2021-04-08 13:57:03.698170877 +0200
++++ gcc-10.3.0.serenity/gcc/configure	2021-04-16 22:40:03.969286691 +0200
+@@ -29982,6 +29982,9 @@
+   *-linux-musl*)
+     gcc_cv_target_dl_iterate_phdr=yes
+     ;;
++  *-serenity*)
++    gcc_cv_target_dl_iterate_phdr=yes
++    ;;
+ esac
+ 
+ if test x$gcc_cv_target_dl_iterate_phdr = xyes; then