Cannot link against BaseSynchronizationLib
Hi, thanks for your work on this!
The following code will fail to link:
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/SynchronizationLib.h>
CONST UINT32 _gUefiDriverRevision = 0;
CHAR8 *gEfiCallerBaseName = "LinkMe";
EFI_STATUS
EFIAPI
UefiUnload (
IN EFI_HANDLE ImageHandle
)
{
ASSERT(FALSE);
}
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE* SystemTable
)
{
InterlockedCompareExchange32(NULL, 0, 0);
return EFI_SUCCESS;
}
I'm using MSVC 2017. Output:
1>Target Link:
1> BaseSynchronizationLib.lib(SynchronizationMsc.obj) : error LNK2001: unresolved external symbol InternalGetSpinLockProperties
1> BaseSynchronizationLib.lib(SynchronizationMsc.obj) : error LNK2001: unresolved external symbol GetPerformanceCounter
1> BaseSynchronizationLib.lib(SynchronizationMsc.obj) : error LNK2001: unresolved external symbol GetPerformanceCounterProperties
1> C:\Users\Matti\Desktop\VisualUefi\samples\x64\Release\UefiApplication.efi : fatal error LNK1120: 3 unresolved externals
After checking out BaseSynchronizationLib.inf in the edk2 directory, it seems that the culprit is Ia32/InternalGetSpinLockProperties.c which is not in the project. Confusingly, despite being under /Ia32, this file is used for both Ia32 and X64 targets on MSVC:
# BaseSynchronizationLib.inf
[Sources.X64]
Ia32/InternalGetSpinLockProperties.c | MSFT
I added this file to BaseSynchronizationLib.vcxproj and was immediately greeted with another error, because this file has the following include:
#include "BaseSynchronizationLibInternals.h"
This file is one level up from the source file, and its path is not in the standard include paths for the project. I worked around this by adding the 3 extra characters needed (../) that the original author could have added in the first place, because I didn't want to modify the include paths for the entire solution just for one file.
After this, BaseSynchronizationLib compiled once again, but the sample still fails to link with GetPerformanceCounter and GetPerformanceCounterProperties from TimerLib missing (of which there are many implementations). After some grepping it seemed to me that SecPeiDxeTimerLibCpu would probably be best suited for most use cases on X64. I added its single source file X86TimerLib.c to the project. The result:
1>edk2\mdepkg\library\secpeidxetimerlibcpu\x86timerlib.c(100): error C2065: '_PCD_GET_MODE_32_PcdFSBClock': undeclared identifier
Because this PCD blatantly exists in pcd.c, I added yet another hack by redeclaring this as a top level extern variable in X86TimerLib.c. After this, BaseSynchronizationLib compiled once more! However, upon trying to finally get my sample to link, I got:
1>Target Link:
1> BaseSynchronizationLib.lib(X86TimerLib.obj) : error LNK2001: unresolved external symbol MmioRead32
1> BaseSynchronizationLib.lib(X86TimerLib.obj) : error LNK2001: unresolved external symbol MmioBitFieldRead32
1> C:\Users\Matti\Desktop\VisualUefi\samples\x64\Release\UefiApplication.efi : fatal error LNK1120: 2 unresolved externals
At this point I finally gave up and started swearing a lot. This helped a little, but not enough to get my sample to work. Any suggestions?
Heya,
Looks like I just need to add a few missing things to make this work. I'm very busy this week, but I'll try to get to this before too long. Thanks for the patience!
Best regards, Alex Ionescu
On Fri, Nov 9, 2018 at 4:25 PM Matthijs Lavrijsen [email protected] wrote:
Hi, thanks for your work on this!
The following code will fail to link:
#include <Uefi.h> #include <Library/DebugLib.h> #include <Library/SynchronizationLib.h>
CONST UINT32 _gUefiDriverRevision = 0;
CHAR8 *gEfiCallerBaseName = "LinkMe";
EFI_STATUS EFIAPIUefiUnload ( IN EFI_HANDLE ImageHandle ) { ASSERT(FALSE); }
EFI_STATUS EFIAPIUefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE* SystemTable ) { InterlockedCompareExchange32(NULL, 0, 0);
return EFI_SUCCESS;}
I'm using MSVC 2017. Output:
1>Target Link: 1> BaseSynchronizationLib.lib(SynchronizationMsc.obj) : error LNK2001: unresolved external symbol InternalGetSpinLockProperties 1> BaseSynchronizationLib.lib(SynchronizationMsc.obj) : error LNK2001: unresolved external symbol GetPerformanceCounter 1> BaseSynchronizationLib.lib(SynchronizationMsc.obj) : error LNK2001: unresolved external symbol GetPerformanceCounterProperties 1> C:\Users\Matti\Desktop\VisualUefi\samples\x64\Release\UefiApplication.efi : fatal error LNK1120: 3 unresolved externals
After checking out BaseSynchronizationLib.inf in the edk2 directory, it seems that the culprit is Ia32/InternalGetSpinLockProperties.c which is not in the project. Confusingly, despite being under /Ia32, this file is used for both Ia32 and X64 targets on MSVC:
BaseSynchronizationLib.inf
[Sources.X64] Ia32/InternalGetSpinLockProperties.c | MSFT
I added this file to BaseSynchronizationLib.vcxproj and was immediately greeted with another error, because this file has the following include:
#include "BaseSynchronizationLibInternals.h"
This file is one level up from the source file, and its path is not in the standard include paths for the project. I worked around this by adding the 3 extra characters needed (../) that the original author could have added in the first place, because I didn't want to modify the include paths for the entire solution just for one file.
After this, BaseSynchronizationLib compiled once again, but the sample still fails to link with GetPerformanceCounter and GetPerformanceCounterProperties from TimerLib missing (of which there are many implementations). After some grepping it seemed to me that SecPeiDxeTimerLibCpu would probably be best suited for most use cases on X64. I added its single source file X86TimerLib.c to the project. The result:
1>edk2\mdepkg\library\secpeidxetimerlibcpu\x86timerlib.c(100): error C2065: '_PCD_GET_MODE_32_PcdFSBClock': undeclared identifier
Because this PCD blatantly exists in pcd.c, I added yet another hack by redeclaring this as a top level extern variable in X86TimerLib.c. After this, BaseSynchronizationLib compiled once more! However, upon trying to finally get my sample to link, I got:
1>Target Link: 1> BaseSynchronizationLib.lib(X86TimerLib.obj) : error LNK2001: unresolved external symbol MmioRead32 1> BaseSynchronizationLib.lib(X86TimerLib.obj) : error LNK2001: unresolved external symbol MmioBitFieldRead32 1> C:\Users\Matti\Desktop\VisualUefi\samples\x64\Release\UefiApplication.efi : fatal error LNK1120: 2 unresolved externals
At this point I finally gave up and started swearing a lot. This helped a little, but not enough to get my sample to work. Any suggestions?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ionescu007/VisualUefi/issues/25, or mute the thread https://github.com/notifications/unsubscribe-auth/AFxIeLBExNXye3kSKJwY2C-EqNRZxGPnks5utZ5igaJpZM4YWxXt .