我在使用EDK2 ( Linux应用程序)下使用变量参数时遇到了问题,因为我是在x64主机上和gcc一起构建的。程序会构建,但在执行时,它会在执行点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;
}发布于 2021-11-03 10:25:33
我已经找到了一个修复方法,那就是用EFIAPI标签定义函数,这样就解决了这个问题。
VOID EFIAPI PrintInts(UINTN n, ...)创建32位UEFI应用程序时,EFIAPI为空;GCC将使用标准的C调用约定编译"efi_main“函数。在创建64位的UEFI应用程序时,EFIAPI会扩展为"__attribute__((ms_abi))“,而根据UEFI的指定,GCC将使用微软的x64调用约定来编译"efi_main”函数。只有将直接从UEFI调用的函数(包括main,但也包括回调)需要使用UEFI调用约定。
而且,这似乎只是GCC的一个问题,因为如果我使用CLANG,我不需要指定EFIAPI。
https://stackoverflow.com/questions/69813701
复制相似问题