I understand it now. The article at <http://www.debuginfo.com/articles/debuginfomatch.html> was of great help.
On 07/05/17 15:29, Laszlo Ersek wrote: > On 07/05/17 14:42, Laszlo Ersek wrote: >> On 07/03/17 07:21, Liming Gao wrote: >>> @@ -2886,11 +2891,23 @@ Returns: >>> >>> if (DebugDirectoryEntryFileOffset != 0) { >>> DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (FileBuffer + >>> DebugDirectoryEntryFileOffset); >>> - DebugEntry->TimeDateStamp = 0; >>> - mImageTimeStamp = 0; >>> - if (ZeroDebugFlag) { >>> - memset (FileBuffer + DebugEntry->FileOffset, 0, >>> DebugEntry->SizeOfData); >>> - memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)); >>> + Index = 0; >>> + for (Index=0; Index < DebugDirectoryEntrySize / sizeof >>> (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); Index ++, DebugEntry ++) { >>> + DebugEntry->TimeDateStamp = 0; >>> + if (ZeroDebugFlag || DebugEntry->Type != >>> EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { >>> + memset (FileBuffer + DebugEntry->FileOffset, 0, >>> DebugEntry->SizeOfData); >> >> This memset() is the culprit. >> >> According to gdb (all values decimal), >> - Index = 1, >> - DebugDirectoryEntrySize = 237, >> - ZeroDebugFlag = 0. >> >> These values look suspicious, because >> sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) is 28, and >> DebugDirectoryEntrySize (237) is not an integral multiple of that. >> >> This is the first EFI_IMAGE_DEBUG_DIRECTORY_ENTRY element: >> >>> (gdb) print ((EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (FileBuffer + >>> DebugDirectoryEntryFileOffset))[0] >>> $11 = {Characteristics = 0, TimeDateStamp = 0, MajorVersion = 0, >>> MinorVersion = 0, Type = 2, SizeOfData = 209, RVA = 33292, FileOffset = >>> 33292} Notice this. The first entry (which is valid, with type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW), points at offset 33292, and the pointed-to data (which is a CodeView information block) has size 209. This means that the first byte *past* the CodeView information is at offset 33292 + 209 = 33501. Now, look at the data dictionary again: >>> (gdb) print Optional64Hdr->DataDirectory >>> $22 = {{VirtualAddress = 0, Size = 0}, // >>> EFI_IMAGE_DIRECTORY_ENTRY_EXPORT >>> {VirtualAddress = 0, Size = 0}, // >>> EFI_IMAGE_DIRECTORY_ENTRY_IMPORT >>> {VirtualAddress = 0, Size = 0}, // >>> EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE >>> {VirtualAddress = 0, Size = 0}, // >>> EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION >>> {VirtualAddress = 0, Size = 0}, // >>> EFI_IMAGE_DIRECTORY_ENTRY_SECURITY >>> {VirtualAddress = 36864, Size = 4096}, // >>> EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC >>> {VirtualAddress = 33264, Size = 237}, // >>> EFI_IMAGE_DIRECTORY_ENTRY_DEBUG Notice this: 33264 + 237 = 33501. The same end offset! And then: 237 - 209 = 28, which is exactly the size of EFI_IMAGE_DEBUG_DIRECTORY_ENTRY. So, what happens is that the GNU linker (or some other bin-util that produces the input file for GenFw) (1) creates a valid EFI_IMAGE_DEBUG_DIRECTORY_ENTRY, of type EFI_IMAGE_DEBUG_TYPE_CODEVIEW, with size = 28, (2) this element points to a valid CV_INFO_PDB20 structure (having NB10 for signature), with size = 209, (3) The CV_INFO_PDB20 structure *immediately* follows the EFI_IMAGE_DEBUG_DIRECTORY_ENTRY element that points to it -- this is all fine, (4) *however*, the pointed-to CV_INFO_PDB20 element (from (3)) is *also* included in the size of the debug directory, even though the size of the debug directory should *only* describe the debug directory entry from (1)! So, this is most certainly a GNU Binutils bug. We can catch it though: as soon as we find an EFI_IMAGE_DEBUG_DIRECTORY_ENTRY whose FileOffset field points into the debug directory itself, we know that the debug directory's size has to be truncated at once to that offset. Let me see if I can write a patch for this. Thanks Laszlo _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel