使用 GCC 构建的变量参数的 EDK2 Shell 应用程序在运行时会导致页面错误
Posted
技术标签:
【中文标题】使用 GCC 构建的变量参数的 EDK2 Shell 应用程序在运行时会导致页面错误【英文标题】:EDK2 Shell Application using Variable Arguments built with GCC causes Page Fault when run 【发布时间】:2021-12-17 04:11:23 【问题描述】:在使用 gcc 的 Linux 主机下构建时,我在 EDK2(x64 shell 应用程序)下使用变量参数时遇到问题。程序构建,但在执行时会在执行 VA_ARG() 时导致页面错误。
在带有 VS2015 的 Windows 主机下构建的相同代码可以正常工作。
这似乎与GCC bug 50818 有关,但我找不到解决方案。
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/PrintLib.h>
#include <Library/ShellCEntryLib.h>
VOID PrintInts(UINTN n, ...)
VA_LIST vl;
VA_START(vl, n);
Print(L"Printing integers:");
for (UINTN i=0; i<n; i++)
UINTN val = 0;
val = VA_ARG(vl, UINTN);
Print(L" [%d]", val);
VA_END(vl);
Print(L"\n");
INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv)
UINTN a = 3;
UINTN b = 10;
UINTN c = 9;
PrintInts(3, a, b, c);
return 0;
【问题讨论】:
【参考方案1】:我找到了一个解决方法,那就是用EFIAPI
标签定义函数,这解决了这个问题,即
VOID EFIAPI PrintInts(UINTN n, ...)
From this link:
创建32位UEFI应用时,EFIAPI为空; GCC 将使用标准 C 调用约定编译“efi_main”函数。创建 64 位 UEFI 应用程序时,EFIAPI 扩展为“__attribute__((ms_abi))”,GCC 将使用 UEFI 指定的 Microsoft 的 x64 调用约定编译“efi_main”函数。只有直接从 UEFI 调用的函数(包括主函数,也包括回调函数)才需要使用 UEFI 调用约定。
而且它似乎只是 GCC 的一个问题,好像我使用 CLANG 我不需要指定 EFIAPI。
【讨论】:
以上是关于使用 GCC 构建的变量参数的 EDK2 Shell 应用程序在运行时会导致页面错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Qt Creator 中启用自定义 gcc 参数? [复制]