#!/bin/bash

# Copyright (c) 2018-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 that a bad GNU Property note section/segment is detected.

# FIXME: Currently only property notes for AArch64 and x86_64 are
# used (for hardening purposes) so this test needs to be host
# architecture specific.

TEST_NAME=property-note
. $srcdir/common.sh

PLUGIN_OPTS="-fplugin-arg-annobin-no-attach"
OPTS="-c -O2 -D_FORTIFY_SOURCE=2 -fPIE -Wall -fstack-protector-strong -D_GLIBCXX_ASSERTIONS -fstack-clash-protection"
EXTRA_OPTS="-fcf-protection -mstackrealign"

start_test

uname -m > host
grep -q -e "x86_64" host
if [ $? != 0 ];
then
    echo "$TEST_NAME: SKIP: This test is currently only supported on the x86_64 architecture"
    end_test
    exit $EXIT_TEST_SKIPPED
fi


$GCC -fplugin=$PLUGIN $PLUGIN_OPTS -g $OPTS $EXTRA_OPTS  $srcdir/hello_hard.c 
if [ $? != 0 ];
then
    echo "Compiler might not support -fcf-protection, retrying without it"
    EXTRA_OPTS="-mstackrealign"
    $GCC -fplugin=$PLUGIN $PLUGIN_OPTS -g $OPTS  $EXTRA_OPTS $srcdir/hello_hard.c 
    if [ $? != 0 ];
    then
	echo "Compiler might not support -mstackrealign, retrying without it"
	EXTRA_OPTS="-fcf-protection"
	$GCC -fplugin=$PLUGIN $PLUGIN_OPTS -g $OPTS $EXTRA_OPTS $srcdir/hello_hard.c 
	if [ $? != 0 ];
	then
	    echo "Compiler might not support either -fcf-protection or -mstackrealign, retrying without both"
	    EXTRA_OPTS=""
	    $GCC -fplugin=$PLUGIN $PLUGIN_OPTS -g $OPTS $EXTRA_OPTS $srcdir/hello_hard.c 
	    if [ $? != 0 ];
	    then
		echo "$TEST_NAME: SKIP: Unable to compile test files"
		end_test
		exit $EXIT_TEST_SKIPPED
	    fi
	fi
    fi
fi

$GAS $srcdir/property-note.S -o property-note.o
$GCC -fplugin=$PLUGIN $PLUGIN_OPTS $OPTS $EXTRA_OPTS -c $srcdir/hello.c $srcdir/hello3.c
$GCC -pie hello.o property-note.o hello3.o -Wl,--defsym,big_stack=0 -Wl,-z,now -o $EXE > $G_OUT 2>&1
if [ $? != 0 ];
then
    echo " $TEST_NAME: SKIP: unable to compile & link test code"
    cat $G_OUT
    end_test
    exit $EXIT_TEST_SKIPPED
fi

SKIPS="--skip-cf-protection --skip-lto"

$ANNOCHECK $SKIPS $EXE --suppress-version-warnings > $A_OUT

grep -q -e "FAIL: property-note" $A_OUT
if [ $? != 0 ];
then
    echo " $TEST_NAME: FAIL: annocheck did not detect a bad property note"
    cat $A_OUT
    end_test
    exit $EXIT_TEST_FAILED
fi

echo " $TEST_NAME: PASS: annocheck detected a bad property note"

end_test
