Jose,toggle quoted messageShow quoted text
Caveat Emptor as Xcode clang is my daily driver, so I don’t really use GCC.
As Ard mentioned the ELF image is converted to a PE/COFF executable for EFI, and the symbols are stripped so the build ID is not going to help you. In PE/COFF there is something called a Debug Directory Entry. It can point to a .debug section, or info in any section. The Debug Directory Entry starts with a 4 byte structure that defines its layout .
The 2nd issue you will have is the PE/COFF images are relocatable executables so they are not loaded at their linked address. Thus to load symbols you need to know the slide (delta of load address to link address) which you can derive from the load address of the image, and a path to the external symbols file. PE/COFF has the property that all the PE/COFF headers are loaded into memory when a PE/COFF image is loaded, this will be important later.
When you get past early PEI and code is no longer XIP (eXecute In Place) you need to know the load address of the code to load symbols. So you end up with these options:
1) Load symbols for PC (This works for XIP too).
2) Load symbols for frame. Really just 1) for each frame PC.
3) Load symbols based on some table that has all the load info. This is the example from the EFI Spec .
To implement 1) you start with the PC and walk backwards in memory looking for the PE/COFF (or DOS) header. That header is the load address of the module. From the headers you can find the debug directory entry. The Debug Directory entry can then be decoded and that gives you (maybe) a unique identifier and the file name of the symbols the debugger needs to load. At that point you can tell the debugger this debug info matches the module loaded at this address. If your debugger knows PE/COFF you just have to point at the DOS or PE/COFF header.
So given I use lldb and the macOS flavor of lldb does not parse PE/COFF we had to write lldb Python to do all of the above and some more. So above is the how to do everything yourself, or theory of operation.
There is also the primitive look at the serial logs and load symbols by hand using debugger commands.
In terms of `git grep` in the edk2 look for EFI_IMAGE_DEBUG_DIRECTORY_ENTRY. There is a lib function called PeCoffLoaderGetPdbPointer() that returns a pointer to the PE/COFF Debug Directory Entry, it has the name pdb as that is the name of the windows symbols file that the Debug Directory Entry generally points to for VC++. For Xcode/clang the Debug Directory Entry entry has the UUID of mach-O executable (that got converted into a PE/COFF) and lldb can look up the symbols that way, other toolchains need the path to the debug file to load. So for example the OVMF exception handler  will dump out info about the faulting PC.
Sorry for the very generic answer, but I though it might be helpful for other folks too. You might want to ask a question about your target architecture, toolchain, and debugger on the mailing to find out what of the above is available for your toolchain with the edk2 for free. If you are interested in adding more features above is an outline of how it works and you can always ask more detailed questions on the mailing list.
 The build kicks out an <FvName>.Fv.map file that contains the info you need to load symbols.
For example: Build/OvmfX64/DEBUG_XCODE5/FV/PEIFV.Fv.map
EFI_FV_TOTAL_SIZE = 0xe0000
EFI_FV_TAKEN_SIZE = 0x43728
EFI_FV_SPACE_SIZE = 0x9c8d8
PeiCore (Fixed Flash Address, BaseAddress=0x0000820120, EntryPoint=0x000082b012)
(GUID=52C05B14-0B98-496C-BC3B-04B50211D680 .textbaseaddress=0x0000820360 .databaseaddress=0x000082e420)
PcdPeim (Fixed Flash Address, BaseAddress=0x000082ed00, EntryPoint=0x0000831a62)
(GUID=9B3ADA4F-AE56-4C24-8DEA-F03B7558AE50 .textbaseaddress=0x000082ef40 .databaseaddress=0x0000834ac0)
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c:130: PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
On Mar 24, 2021, at 8:25 AM, Ard Biesheuvel <email@example.com> wrote: