diff --git a/.github/workflows/linux-gcc.yml b/.github/workflows/linux-gcc.yml index e6b5403..bf87710 100644 --- a/.github/workflows/linux-gcc.yml +++ b/.github/workflows/linux-gcc.yml @@ -11,24 +11,31 @@ jobs: arch: [ia32, x64, aa64, arm, riscv64, mips64] include: - arch: ia32 + dir: ia32 gcc: multilib cross_compile: - arch: x64 + dir: x86_64 gcc: multilib cross_compile: - arch: aa64 + dir: aarch64 gcc: aarch64-linux-gnu cross_compile: aarch64-linux-gnu- - arch: arm + dir: arm gcc: arm-linux-gnueabihf cross_compile: arm-linux-gnueabihf- - arch: riscv64 + dir: riscv64 gcc: riscv64-linux-gnu cross_compile: riscv64-linux-gnu- - arch: mips64 + dir: mips64el gcc: mips64el-linux-gnuabi64 cross_compile: mips64el-linux-gnuabi64- # - arch: loongarch64 +# dir: loongarch64 # gcc: loongarch64-linux-gnu # cross_compile: loongarch64-linux-gnu- @@ -42,7 +49,80 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - submodules: recursive - name: Build run: make ARCH=${{ matrix.arch }} CROSS_COMPILE=${{ matrix.cross_compile }} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.arch }} + path: ./${{ matrix.dir }}/apps/*.efi + + tests: + runs-on: ubuntu-latest + needs: build + + strategy: + matrix: + arch: [x64, ia32, aa64, arm] + include: + - arch: x64 + pkg: qemu-system-x86 + qemu_arch: x86_64 + qemu_opts: -M q35 + fw_base: OVMF + - arch: ia32 + pkg: qemu-system-x86 + qemu_arch: i386 + qemu_opts: -M pc + fw_base: OVMF + - arch: aa64 + pkg: qemu-system-arm + qemu_arch: aarch64 + qemu_opts: -M virt -cpu cortex-a57 + fw_base: AAVMF + - arch: arm + pkg: qemu-system-arm + qemu_arch: arm + qemu_opts: -M virt -cpu cortex-a15 + fw_base: AAVMF + + steps: + - name: Set up Linux environment + run: | + sudo apt-get update + sudo apt-get -y --no-install-recommends install ${{ matrix.pkg }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.arch }} + + - name: Download UEFI firmware + run: | + fw_arch=$(echo ${{ matrix.arch }} | tr a-z A-Z) + fw_zip=${{ matrix.fw_base }}-${fw_arch}.zip + curl -O https://efi.akeo.ie/${{ matrix.fw_base }}/${fw_zip} + 7z x ${fw_zip} + rm ${fw_zip} + + - name: Download UEFI Shell + run: | + curl -L -O https://github.com/pbatard/UEFI-Shell/releases/download/23H2/UEFI-Shell-2.2-23H2-RELEASE.iso + mkdir ./image + 7z x -o./image *.iso + rm *.iso + + - name: Run tests + run: | + export UEFI_ARCH=${{ matrix.arch }} + export UEFI_DIR=./image + export QEMU_CMD="qemu-system-${{ matrix.qemu_arch }} ${{ matrix.qemu_opts }} -L . -drive if=pflash,format=raw,unit=0,file=${{ matrix.fw_base }}.fd,readonly=on -drive format=raw,file=fat:rw:image -nodefaults -nographic -serial stdio -net none" + ./tests/gen_tests.sh ./tests/test_list.txt + ./tests/run_tests.sh diff --git a/.github/workflows/linux-mingw.yml b/.github/workflows/linux-mingw.yml index cc5059b..4dc1971 100644 --- a/.github/workflows/linux-mingw.yml +++ b/.github/workflows/linux-mingw.yml @@ -3,7 +3,7 @@ name: Linux, MinGW on: [push, pull_request] jobs: - MinGW-Build: + build: runs-on: ubuntu-latest strategy: @@ -11,9 +11,11 @@ jobs: arch: [x64, ia32] include: - arch: x64 + dir: x86_64 pkg: gcc-mingw-w64-x86-64 tuple: x86_64-w64-mingw32- - arch: ia32 + dir: ia32 pkg: gcc-mingw-w64-i686 tuple: i686-w64-mingw32- @@ -22,10 +24,73 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - submodules: recursive - name: Install gcc toolchain run: sudo apt install ${{ matrix.pkg }} - name: Build run: make ARCH=${{ matrix.arch }} CROSS_COMPILE=${{ matrix.tuple }} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.arch }} + path: ./${{ matrix.dir }}/apps/*.efi + + tests: + runs-on: ubuntu-latest + needs: build + + strategy: + matrix: + arch: [x64, ia32] + include: + - arch: x64 + pkg: qemu-system-x86 + qemu_arch: x86_64 + qemu_opts: -M q35 + fw_base: OVMF + - arch: ia32 + pkg: qemu-system-x86 + qemu_arch: i386 + qemu_opts: -M pc + fw_base: OVMF + + steps: + - name: Set up Linux environment + run: | + sudo apt-get update + sudo apt-get -y --no-install-recommends install ${{ matrix.pkg }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.arch }} + + - name: Download UEFI firmware + run: | + fw_arch=$(echo ${{ matrix.arch }} | tr a-z A-Z) + fw_zip=${{ matrix.fw_base }}-${fw_arch}.zip + curl -O https://efi.akeo.ie/${{ matrix.fw_base }}/${fw_zip} + 7z x ${fw_zip} + rm ${fw_zip} + + - name: Download UEFI Shell + run: | + curl -L -O https://github.com/pbatard/UEFI-Shell/releases/download/23H2/UEFI-Shell-2.2-23H2-RELEASE.iso + mkdir ./image + 7z x -o./image *.iso + rm *.iso + + - name: Run tests + run: | + export UEFI_ARCH=${{ matrix.arch }} + export UEFI_DIR=./image + export QEMU_CMD="qemu-system-${{ matrix.qemu_arch }} ${{ matrix.qemu_opts }} -L . -drive if=pflash,format=raw,unit=0,file=${{ matrix.fw_base }}.fd,readonly=on -drive format=raw,file=fat:rw:image -nodefaults -nographic -serial stdio -net none" + ./tests/gen_tests.sh ./tests/test_list.txt + ./tests/run_tests.sh diff --git a/.github/workflows/windows-mingw.yml b/.github/workflows/windows-mingw.yml index a45ecf7..2cf3b04 100644 --- a/.github/workflows/windows-mingw.yml +++ b/.github/workflows/windows-mingw.yml @@ -3,7 +3,7 @@ name: Windows, MinGW on: [push, pull_request] jobs: - MinGW-Build: + build: runs-on: windows-latest strategy: @@ -11,9 +11,11 @@ jobs: arch: [x64, ia32] include: - arch: x64 + dir: x86_64 sys: mingw64 env: x86_64 - arch: ia32 + dir: ia32 sys: mingw32 env: i686 @@ -36,7 +38,70 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - submodules: recursive - name: Build run: make + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.arch }} + path: ./${{ matrix.dir }}/apps/*.efi + + tests: + runs-on: ubuntu-latest + needs: build + + strategy: + matrix: + arch: [x64, ia32] + include: + - arch: x64 + pkg: qemu-system-x86 + qemu_arch: x86_64 + qemu_opts: -M q35 + fw_base: OVMF + - arch: ia32 + pkg: qemu-system-x86 + qemu_arch: i386 + qemu_opts: -M pc + fw_base: OVMF + + steps: + - name: Set up Linux environment + run: | + sudo apt-get update + sudo apt-get -y --no-install-recommends install ${{ matrix.pkg }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.arch }} + + - name: Download UEFI firmware + run: | + fw_arch=$(echo ${{ matrix.arch }} | tr a-z A-Z) + fw_zip=${{ matrix.fw_base }}-${fw_arch}.zip + curl -O https://efi.akeo.ie/${{ matrix.fw_base }}/${fw_zip} + 7z x ${fw_zip} + rm ${fw_zip} + + - name: Download UEFI Shell + run: | + curl -L -O https://github.com/pbatard/UEFI-Shell/releases/download/23H2/UEFI-Shell-2.2-23H2-RELEASE.iso + mkdir ./image + 7z x -o./image *.iso + rm *.iso + + - name: Run tests + run: | + export UEFI_ARCH=${{ matrix.arch }} + export UEFI_DIR=./image + export QEMU_CMD="qemu-system-${{ matrix.qemu_arch }} ${{ matrix.qemu_opts }} -L . -drive if=pflash,format=raw,unit=0,file=${{ matrix.fw_base }}.fd,readonly=on -drive format=raw,file=fat:rw:image -nodefaults -nographic -serial stdio -net none" + ./tests/gen_tests.sh ./tests/test_list.txt + ./tests/run_tests.sh diff --git a/.github/workflows/windows-vs2022.yml b/.github/workflows/windows-vs2022.yml index f860203..2ef4bf5 100644 --- a/.github/workflows/windows-vs2022.yml +++ b/.github/workflows/windows-vs2022.yml @@ -2,24 +2,20 @@ name: Windows, VS2022 on: [push, pull_request] -env: - SOLUTION_FILE_PATH: ./gnu-efi.sln - jobs: - VS2022-Build: + build: runs-on: windows-latest strategy: matrix: - TARGET_PLATFORM: [x64, ia32, aa64, arm] - CONFIGURATION: [Debug, Release] + arch: [x64, ia32, aa64, arm] + conf: [Debug, Release] steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - submodules: recursive - name: Add MSBuild to PATH uses: microsoft/setup-msbuild@v2 @@ -28,4 +24,79 @@ jobs: - name: Build shell: cmd - run: msbuild ${{ env.SOLUTION_FILE_PATH }} /m /p:Configuration=${{ matrix.CONFIGURATION }},Platform=${{ matrix.TARGET_PLATFORM }} + run: msbuild ./gnu-efi.sln /m /p:Configuration=${{ matrix.conf }},Platform=${{ matrix.arch }} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + if: ${{ matrix.conf == 'Release' }} + with: + name: ${{ matrix.arch }} + path: ./${{ matrix.arch }}/${{ matrix.conf }}/*.efi + + tests: + runs-on: ubuntu-latest + needs: build + + strategy: + matrix: + arch: [x64, ia32, aa64, arm] + include: + - arch: x64 + pkg: qemu-system-x86 + qemu_arch: x86_64 + qemu_opts: -M q35 + fw_base: OVMF + - arch: ia32 + pkg: qemu-system-x86 + qemu_arch: i386 + qemu_opts: -M pc + fw_base: OVMF + - arch: aa64 + pkg: qemu-system-arm + qemu_arch: aarch64 + qemu_opts: -M virt -cpu cortex-a57 + fw_base: AAVMF + - arch: arm + pkg: qemu-system-arm + qemu_arch: arm + qemu_opts: -M virt -cpu cortex-a15 + fw_base: AAVMF + + steps: + - name: Set up Linux environment + run: | + sudo apt-get update + sudo apt-get -y --no-install-recommends install ${{ matrix.pkg }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.arch }} + + - name: Download UEFI firmware + run: | + fw_arch=$(echo ${{ matrix.arch }} | tr a-z A-Z) + fw_zip=${{ matrix.fw_base }}-${fw_arch}.zip + curl -O https://efi.akeo.ie/${{ matrix.fw_base }}/${fw_zip} + 7z x ${fw_zip} + rm ${fw_zip} + + - name: Download UEFI Shell + run: | + curl -L -O https://github.com/pbatard/UEFI-Shell/releases/download/23H2/UEFI-Shell-2.2-23H2-RELEASE.iso + mkdir ./image + 7z x -o./image *.iso + rm *.iso + + - name: Run tests + run: | + export UEFI_ARCH=${{ matrix.arch }} + export UEFI_DIR=./image + export QEMU_CMD="qemu-system-${{ matrix.qemu_arch }} ${{ matrix.qemu_opts }} -L . -drive if=pflash,format=raw,unit=0,file=${{ matrix.fw_base }}.fd,readonly=on -drive format=raw,file=fat:rw:image -nodefaults -nographic -serial stdio -net none" + ./tests/gen_tests.sh ./tests/test_list.txt + ./tests/run_tests.sh diff --git a/Make.defaults b/Make.defaults index 278c80c..e33316b 100755 --- a/Make.defaults +++ b/Make.defaults @@ -192,8 +192,6 @@ GCCMACHINE := $(shell $(CC) -dumpmachine) IS_MINGW32 := $(findstring mingw32, $(GCCMACHINE)) ifeq ($(IS_MINGW32),) CFLAGS += -fPIE -else - CFLAGS += -DGNU_EFI_USE_MS_ABI endif ifeq (FreeBSD, $(findstring FreeBSD, $(OS))) @@ -203,16 +201,19 @@ CFLAGS += $(ARCH3264) -g -O2 -Wall -Wextra -Werror \ else CFLAGS += $(ARCH3264) -g -O2 -Wall -Wextra -Wno-pointer-sign -Werror \ -funsigned-char -fshort-wchar -fno-strict-aliasing \ - -ffreestanding -fno-stack-protector -fno-stack-check \ + -ffreestanding -fno-stack-protector -fno-stack-check \ $(if $(findstring gcc,$(CC)),-fno-merge-all-constants,) endif ARFLAGS := rDv ASFLAGS += $(ARCH3264) -LDFLAGS += -nostdlib --warn-common --no-undefined --fatal-warnings \ - --build-id=sha1 +LDFLAGS += -nostdlib ifeq ($(IS_MINGW32),) - LDFLAGS += -z nocombreloc -z norelro + LDFLAGS += --warn-common --no-undefined --fatal-warnings \ + --build-id=sha1 -z nocombreloc -z norelro +else + LDFLAGS += -Wl,--warn-common -Wl,--no-undefined -Wl,--fatal-warnings \ + -Wl,--build-id=sha1 endif ifneq ($(ARCH),arm) diff --git a/Make.rules b/Make.rules index cdb7aab..9982403 100644 --- a/Make.rules +++ b/Make.rules @@ -36,6 +36,7 @@ .SECONDARY: +ifeq ($(IS_MINGW32),) %.efi: %.so $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .rodata -j .rel \ -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \ @@ -49,6 +50,10 @@ %.so: %.o $(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBES) +else +%.efi: %.o + $(CC) $(LDFLAGS) $< -o $@ $(LOADLIBES) +endif %.o: %.c $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ diff --git a/apps/Makefile b/apps/Makefile index f582236..a43548b 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -68,26 +68,35 @@ LOADLIBES += $(LIBGCC) TARGET_APPS = t.efi t2.efi t3.efi t4.efi t5.efi t6.efi t7.efi t8.efi \ tcc.efi printenv.efi modelist.efi route80h.efi route80h.efi \ drv0_use.efi AllocPages.efi exit.efi FreePages.efi bltgrid.efi \ - lfbgrid.efi setdbg.efi unsetdbg.efi ctors_test.efi \ - ctors_dtors_priority_test.efi old_ABI.efi + lfbgrid.efi setdbg.efi unsetdbg.efi old_ABI.efi ifeq ($(IS_MINGW32),) -TARGET_APPS += setjmp.efi debughook.efi debughook.efi.debug +TARGET_APPS += setjmp.efi debughook.efi debughook.efi.debug \ + ctors_test.efi ctors_dtors_priority_test.efi endif TARGET_BSDRIVERS = drv0.efi TARGET_RTDRIVERS = +SUBSYSTEM := 0xa +$(TARGET_BSDRIVERS): SUBSYSTEM = 0xb +$(TARGET_RTDRIVERS): SUBSYSTEM = 0xc + ifneq ($(HAVE_EFI_OBJCOPY),) FORMAT := --target efi-app-$(ARCH) $(TARGET_BSDRIVERS): FORMAT=--target efi-bsdrv-$(ARCH) $(TARGET_RTDRIVERS): FORMAT=--target efi-rtdrv-$(ARCH) +ifneq ($(IS_MINGW32),) +LDFLAGS += -s -Wl,-dll -Wl,--subsystem,$(SUBSYSTEM) +ifeq ($(ARCH),ia32) +LDFLAGS += -e _efi_main else +LDFLAGS += -e efi_main +endif +endif -SUBSYSTEM := 0xa -$(TARGET_BSDRIVERS): SUBSYSTEM = 0xb -$(TARGET_RTDRIVERS): SUBSYSTEM = 0xc +else FORMAT := -O binary LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM) diff --git a/apps/t.c b/apps/t.c index c7e3d57..34c7f41 100644 --- a/apps/t.c +++ b/apps/t.c @@ -20,8 +20,8 @@ efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab) InitializeLib(image_handle, systab); conout = systab->ConOut; - uefi_call_wrapper(conout->OutputString, 2, conout, (CHAR16 *)L"Hello World!\n\r"); - uefi_call_wrapper(conout->OutputString, 2, conout, a2u("Hello World!\n\r")); + uefi_call_wrapper(conout->OutputString, 2, conout, (CHAR16 *)L"Hello World!\r\n"); + uefi_call_wrapper(conout->OutputString, 2, conout, a2u("Hello World!\r\n")); return EFI_SUCCESS; } diff --git a/apps/t2.c b/apps/t2.c index 6a09c42..19ff3ef 100644 --- a/apps/t2.c +++ b/apps/t2.c @@ -8,7 +8,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) InitializeLib(image, systab); conout = systab->ConOut; - uefi_call_wrapper(conout->OutputString, 2, conout, L"Hello World!\n\r"); + uefi_call_wrapper(conout->OutputString, 2, conout, L"Hello World!\r\n"); return EFI_SUCCESS; } diff --git a/apps/tcc.c b/apps/tcc.c index 09ad98b..1e5b326 100644 --- a/apps/tcc.c +++ b/apps/tcc.c @@ -328,12 +328,12 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) __asm__ volatile("out %0,%1" : : "a" ((uint8_t)0x14), "dN" (0x80)); #endif - Print(L"Hello\r\n"); + Print(L"Hello\n"); rc = test_failure(); if (EFI_ERROR(rc)) { Print(L"Returning Failure works\n"); } else { - Print(L"Returning failure doesn't work.\r\n"); + Print(L"Returning failure doesn't work.\n"); Print(L"%%rax was 0x%016x, should have been 0x%016x\n", rc, EFI_UNSUPPORTED); return EFI_INVALID_PARAMETER; @@ -341,7 +341,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call0(); if (!EFI_ERROR(rc)) { - Print(L"0 args works just fine here.\r\n"); + Print(L"0 args works just fine here.\n"); } else { Print(L"0 args failed: 0x%016x\n", rc); return rc; @@ -349,7 +349,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call1(); if (!EFI_ERROR(rc)) { - Print(L"1 arg works just fine here.\r\n"); + Print(L"1 arg works just fine here.\n"); } else { Print(L"1 arg failed: 0x%016x\n", rc); return rc; @@ -357,7 +357,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call2(); if (!EFI_ERROR(rc)) { - Print(L"2 args works just fine here.\r\n"); + Print(L"2 args works just fine here.\n"); } else { Print(L"2 args failed: 0x%016x\n", rc); return rc; @@ -365,7 +365,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call3(); if (!EFI_ERROR(rc)) { - Print(L"3 args works just fine here.\r\n"); + Print(L"3 args works just fine here.\n"); } else { Print(L"3 args failed: 0x%016x\n", rc); return rc; @@ -373,7 +373,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call4(); if (!EFI_ERROR(rc)) { - Print(L"4 args works just fine here.\r\n"); + Print(L"4 args works just fine here.\n"); } else { Print(L"4 args failed: 0x%016x\n", rc); return rc; @@ -381,7 +381,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call5(); if (!EFI_ERROR(rc)) { - Print(L"5 args works just fine here.\r\n"); + Print(L"5 args works just fine here.\n"); } else { Print(L"5 args failed: 0x%016x\n", rc); return rc; @@ -389,7 +389,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call6(); if (!EFI_ERROR(rc)) { - Print(L"6 args works just fine here.\r\n"); + Print(L"6 args works just fine here.\n"); } else { Print(L"6 args failed: 0x%016x\n", rc); return rc; @@ -397,7 +397,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call7(); if (!EFI_ERROR(rc)) { - Print(L"7 args works just fine here.\r\n"); + Print(L"7 args works just fine here.\n"); } else { Print(L"7 args failed: 0x%016x\n", rc); return rc; @@ -405,7 +405,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call8(); if (!EFI_ERROR(rc)) { - Print(L"8 args works just fine here.\r\n"); + Print(L"8 args works just fine here.\n"); } else { Print(L"8 args failed: 0x%016x\n", rc); return rc; @@ -413,7 +413,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call9(); if (!EFI_ERROR(rc)) { - Print(L"9 args works just fine here.\r\n"); + Print(L"9 args works just fine here.\n"); } else { Print(L"9 args failed: 0x%016x\n", rc); return rc; @@ -421,7 +421,7 @@ efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) rc = test_call10(); if (!EFI_ERROR(rc)) { - Print(L"10 args works just fine here.\r\n"); + Print(L"10 args works just fine here.\n"); } else { Print(L"10 args failed: 0x%016x\n", rc); return rc; diff --git a/tests/gen_tests.sh b/tests/gen_tests.sh new file mode 100755 index 0000000..28efc3e --- /dev/null +++ b/tests/gen_tests.sh @@ -0,0 +1,40 @@ +#!/bin/env bash + +## @file +# Test generation script for gnu-efi. +# +# Copyright (c) 2023-2024, Pete Batard +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +## + +TEST_DIR=./run + +rm -rf $TEST_DIR +mkdir $TEST_DIR + +test_number=0 + +while IFS=$'\r\n' read -r line; do + if [[ ${line:0:1} == "#" ]]; then + test_number=$((test_number + 1)) + data_file=$(printf "%s/%03d %s.dat" $TEST_DIR $test_number "${line:2}") + setup_file=$(printf "%s/%03d setup.sh" $TEST_DIR $test_number) + teardown_file=$(printf "%s/%03d teardown.sh" $TEST_DIR $test_number) + elif [[ ${line:0:1} == ">" ]]; then + if [[ ! -f "$setup_file" ]]; then + echo "#!/bin/env bash" > "$setup_file" + chmod 755 "$setup_file" + fi + echo "${line:2}" >> "$setup_file" + elif [[ ${line:0:1} == "<" ]]; then + if [[ ! -f "$teardown_file" ]]; then + echo "#!/bin/env bash" > "$teardown_file" + chmod 755 "$teardown_file" + fi + echo "${line:2}" >> "$teardown_file" + elif [[ ! -z "$line" ]]; then + echo "${line}" >> "$data_file" + fi +done < $1 diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 0000000..7cd420e --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,102 @@ +#!/bin/env bash + +## @file +# Test script for gnu-efi. +# +# Copyright (c) 2023-2024, Pete Batard +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +## + +TEST_DIR=./run +LINE_LEN=64 +TIMEOUT=2m +MIN_TEST="${1:-001}" +MAX_TEST="${2:-999}" +NUM_PASS=0 +NUM_FAIL=0 +NUM_ERROR=0 + +if [[ -z "$QEMU_CMD" ]]; then + echo '$QEMU_CMD is not set' + exit 1 +fi + +for t in $TEST_DIR/*.dat; do + + base=$(basename "${t%.dat}") + test_number=${base:0:3} + test_name=${base:4} + test_desc="Test #$test_number: ${test_name}... " + nb_lines=$(wc -l < "$t") + if [[ $nb_lines -eq 0 ]]; then + nb_lines=1 + fi + + # Arguments can be provided to run only a specified range of tests + if [[ 10#$test_number -lt 10#$MIN_TEST ]]; then + continue + fi + if [[ 10#$test_number -gt 10#$MAX_TEST ]]; then + break + fi + + # Run pre test script if required + if [[ -x "$TEST_DIR/$test_number setup.sh" ]]; then + . "$TEST_DIR/$test_number setup.sh" > /dev/null 2>&1 + fi + + echo -n "$test_desc" + num_blanks=$((LINE_LEN - ${#test_desc})) + if [[ $num_blanks -gt 0 ]]; then + padding="$(printf '%*s' $num_blanks)" + echo -n "$padding" + fi + # Run qemu with a timeout + rm -f output.txt error.txt + timeout --foreground $TIMEOUT bash -c "${QEMU_CMD} 1>output.txt 2>error.txt" + + err=$? + if [[ $err -eq 124 ]]; then + echo "[ERROR] (Time out)" + NUM_ERROR=$((NUM_ERROR + 1)) + elif [[ $err -ne 0 ]]; then + echo "[ERROR] ($err)" + cat error.txt + NUM_ERROR=$((NUM_ERROR + 1)) + else + tail -n $nb_lines output.txt | diff -Z --strip-trailing-cr -q "$t" - >/dev/null 2>&1 + if [[ $? -eq 0 ]]; then + echo "[PASS]" + NUM_PASS=$((NUM_PASS + 1)) + else + echo "[FAIL]" + NUM_FAIL=$((NUM_FAIL + 1)) + echo "Output of failed test was:" + echo "-------------------------------------------------------------------------------" + tail -n +3 output.txt + echo "-------------------------------------------------------------------------------" + fi + fi + + # Run post test script if required + if [[ -x "$TEST_DIR/$test_number teardown.sh" ]]; then + . "$TEST_DIR/$test_number teardown.sh" > /dev/null 2>&1 + fi + +done + +echo +echo "===============================================================================" +echo "# Test summary for gnu-efi" +echo "===============================================================================" +echo "# TOTAL: $((NUM_PASS + NUM_FAIL + NUM_ERROR))" +echo "# PASS: $NUM_PASS" +echo "# FAIL: $NUM_FAIL" +echo "# ERROR: $NUM_ERROR" +echo "===============================================================================" + +if [[ $NUM_FAIL -ne 0 || $NUM_ERROR -ne 0 ]]; then + exit 1 +fi diff --git a/tests/test_list.txt b/tests/test_list.txt new file mode 100644 index 0000000..9d32b12 --- /dev/null +++ b/tests/test_list.txt @@ -0,0 +1,40 @@ +# ConOut text output +> cp t.efi $UEFI_DIR +> echo "@echo -off" > $UEFI_DIR/startup.nsh +> echo "FS0:\t.efi" >> $UEFI_DIR/startup.nsh +> echo "reset -s" >> $UEFI_DIR/startup.nsh +Hello World! +Hello World! +< rm $UEFI_DIR/t.efi + +# Test args +> cp tcc.efi $UEFI_DIR +> echo "@echo -off" > $UEFI_DIR/startup.nsh +> echo "FS0:\tcc.efi" >> $UEFI_DIR/startup.nsh +> echo "reset -s" >> $UEFI_DIR/startup.nsh +Hello +Returning Failure works +0 args works just fine here. +1 arg works just fine here. +2 args works just fine here. +3 args works just fine here. +4 args works just fine here. +5 args works just fine here. +6 args works just fine here. +7 args works just fine here. +8 args works just fine here. +9 args works just fine here. +10 args works just fine here. +< rm $UEFI_DIR/tcc.efi + +# Print args +> cp t8.efi $UEFI_DIR +> echo "@echo -off" > $UEFI_DIR/startup.nsh +> echo "FS0:\t8.efi Test1 Test2" >> $UEFI_DIR/startup.nsh +> echo "reset -s" >> $UEFI_DIR/startup.nsh +Hello World, started with Argc=3 + Argv[0] = 'FS0:\t8.efi' + Argv[1] = 'Test1' + Argv[2] = 'Test2' +Bye. +< rm $UEFI_DIR/t8.efi