#!/bin/bash

# Copyright (c) 2017-2026 Red Hat.
#
# This is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 3, or (at your
# option) any later version.
#
# It is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

TEST_NAME=hardening
. $srcdir/common.sh

OPTS="-fplugin=$PLUGIN -fplugin-arg-annobin-no-attach"
OPTS+=" -g -O2 -D_FORTIFY_SOURCE=2 -fPIE -Wall -flto"
OPTS+=" -fstack-protector-strong -D_GLIBCXX_ASSERTIONS -fstack-clash-protection"

start_test

export COLLECT_GCC_OPTIONS=

# See which hardening options are available.

H_OPT="-fcf-protection=full"
$GCC -c $OPTS $H_OPT $srcdir/hello_hard.c > $G_OUT 2>&1
if [ $? == 0 ];
then
    OPTS+=" $H_OPT"
fi

H_OPT="-mstackrealign"
$GCC -c $OPTS $H_OPT $srcdir/hello_hard.c > $G_OUT 2>&1
if [ $? == 0 ];
then
    OPTS+=" $H_OPT"
fi

H_OPT="-mbranch-protection=standard"
$GCC -c $OPTS $H_OPT $srcdir/hello_hard.c > $G_OUT 2>&1
if [ $? == 0 ];
then
    OPTS+=" $H_OPT"
fi

H_OPT="-fhardened"
$GCC -c $OPTS $H_OPT $srcdir/hello_hard.c > $G_OUT 2>&1
if [ $? == 0 ];
then
    OPTS+=" $H_OPT"
fi

# Now build the binary.

$GCC -c $OPTS -O3 $srcdir/hello_hard.c
$GCC -c $OPTS -g3 $srcdir/hello2.c
$GCC -c $OPTS -fverbose-asm $srcdir/hello3.c
$GCC -c $OPTS -shared $srcdir/hello_lib.c -o libhello.so

COMMAND="$GCC $OPTS hello_hard.o hello2.o hello3.o -L. -lhello  -Wl,-z,now -o $EXE"
$COMMAND > $G_OUT 2>&1
if [ $? != 0 ];
then
    echo " $TEST_NAME: SKIP: unable to link test"
    echo " $TEST_NAME: command: $COMMAND"
    cat $G_OUT
    end_test
    exit $EXIT_TEST_SKIPPED
fi

# The s390 and PPC targets always create some gaps.  Have not found out why...
# The entry point test (on x86/x86_64) will fail with a MAYBE result because the entry point is 0...
SKIPS="--ignore-gaps --skip-entry --skip-lto --skip-pie"

$ANNOCHECK $SKIPS $EXE --enable-timing --suppress-version-warnings --enable-notes --verbose > $A_OUT
if [ $? != 0 ];
then
    echo " $TEST_NAME: FAIL: annocheck FAILed a good binary"
    echo " $TEST_NAME: compilation command: $COMMAND"
    echo " $TEST_NAME: annocheck output:"
    cat $A_OUT
    end_test
    exit $EXIT_TEST_FAILED
fi

end_test
