From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 99D6621C943F2 for ; Wed, 5 Jul 2017 08:28:14 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 84F36624DD; Wed, 5 Jul 2017 15:29:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 84F36624DD Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=lersek@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 84F36624DD Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-25.phx2.redhat.com [10.3.116.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id 124D91712E; Wed, 5 Jul 2017 15:29:51 +0000 (UTC) From: Laszlo Ersek To: Liming Gao , edk2-devel@lists.01.org Cc: Ard Biesheuvel , "Leif Lindholm (Linaro address)" , "Zhu, Yonghong" References: <1499059281-11744-1-git-send-email-liming.gao@intel.com> <751fb308-e7b2-c15c-42c0-cade9ffe98bd@redhat.com> Message-ID: Date: Wed, 5 Jul 2017 17:29:51 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 MIME-Version: 1.0 In-Reply-To: <751fb308-e7b2-c15c-42c0-cade9ffe98bd@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 05 Jul 2017 15:29:53 +0000 (UTC) Subject: Re: [Patch] BaseTools: Update GenFw to clear unused debug entry generated by VS tool chain X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Jul 2017 15:28:14 -0000 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit I understand it now. The article at 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