#!/bin/bash

# Copyright (c) 2018-2022 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 building an assembler source file without creating a gap in the notes.

TEST_NAME=assembler-gap
. $srcdir/common.sh

PLUGIN_OPTS="-fplugin-arg-annobin-no-attach"

start_test

# Assemble the file, and include debug information which will
# identify the producer as being AS.

$GAS --gdwarf-2 $srcdir/gap.S -o gap1.o

# Compile a C source file as well, so that we end up with a binary
# that was partially built by GCC, and partially not.  Note - we
# are not using all of the hardening options as we want to be sure
# that annocheck will notice.

pwd
echo $GCC -fplugin=$PLUGIN $PLUGIN_OPTS -c -O2 -fPIC $srcdir/hello.c 

$GCC -fplugin=$PLUGIN $PLUGIN_OPTS -c -O2 -fPIC $srcdir/hello.c 
$GCC -fplugin=$PLUGIN $PLUGIN_OPTS -c -O2 -fPIC $srcdir/hello2.c 
$GCC -fplugin=$PLUGIN $PLUGIN_OPTS -c -O2 -fPIC $srcdir/hello3.c 

# Put our assembled file between C files, so that the gap will be noticed.
$GCC -nostartfiles -e 0 hello.o hello2.o gap1.o hello3.o -o assembler-gap-test1.exe \
     -Wl,--defsym,extern_func3=0 \
     -Wl,-z,now -pie

$ANNOCHECK -v assembler-gap-test1.exe > assembler-gap-test1.out

# FAIL if a gap is NOT reported
# The "Not check for gaps" match is for the ARM where annobin notes are not expected.
grep --silent -e "gaps were detected" -e "because not all of the .text section is covered by notes" -e "Not checking for gaps" assembler-gap-test1.out
if [ $? != 0 ];
then
    echo "  $TEST_NAME: FAIL: GAP *not* found in notes:"
    cat assembler-gap-test1.out
    $ANNOCHECK --disable-hardened --enable-notes assembler-gap-test1.exe
    exit 1
fi

# Repeat the test, but this time, instead of generating debug information
# generate a note.

$GAS --generate-missing-build-notes=yes $srcdir/gap.S -o gap2.o
if [ $? != 0 ];
then
    echo "  $TEST_NAME: Assembler does not support generating build notes.  Skipping test."
    exit 0
fi

$GCC -nostartfiles -e 0 hello.o hello2.o gap2.o hello3.o -o assembler-gap-test2.exe \
     -Wl,--defsym,extern_func3=0 \
     -Wl,-z,now -pie -Wl,-Map,assembler-gap-test2.map

$ANNOCHECK -v assembler-gap-test2.exe --skip-all --test-notes --test-gaps > assembler-gap-test2.out

# FAIL if a gap is NOT reported
grep --silent -e "no gaps found" -e "Not checking for gaps" assembler-gap-test2.out
if [ $? != 0 ];
then
    echo "  $TEST_NAME: FAIL: GAP found in notes (with assembler auto-covered):"
    cat assembler-gap-test2.out
    $ANNOCHECK --disable-hardened --enable-notes assembler-gap-test2.exe
    objdump -d assembler-gap-test2.exe
    cat assembler-gap-test2.map
    exit 1
fi

end_test
