Feng -
Our compiler options are the same as yours for VS2008. Here is a small function
which duplicates the problem.
Compile with:
cl /c /GL /O1b2is /Gy /GF /GS- x.c aa.c
link /DEBUG /LTCG /OPT:REF /OPT:ICF=10 /SECTION:.xdata,D /SECTION:.pdata,D
/IGNORE:4254 /MERGE:.data=.text /MERGE:.rdata=.text x.obj aa.obj
dumpbin /disasm x.exe >output.txt
Here is the code generated for main:
main:
00000001400076D0: 48 81 EC 98 00 00 sub rsp,98h
00
00000001400076D7: BA 4F 8B FE FF mov edx,0FFFE8B4Fh
00000001400076DC: 33 C0 xor eax,eax
00000001400076DE: 38 02 cmp byte ptr [rdx],al
00000001400076E0: 74 18 je 00000001400076FA
00000001400076E2: 48 FF C0 inc rax
00000001400076E5: 80 B8 4F 8B FE FF cmp byte ptr [rax-174B1h],0
00
00000001400076EC: 75 F4 jne 00000001400076E2
00000001400076EE: 83 F8 32 cmp eax,32h
00000001400076F1: 7E 07 jle 00000001400076FA
00000001400076F3: B8 FB FF FF FF mov eax,0FFFFFFFBh
00000001400076F8: EB 2A jmp 0000000140007724
00000001400076FA: 4C 8D 44 24 20 lea r8,[rsp+20h]
00000001400076FF: 0F BE 0A movsx ecx,byte ptr [rdx]
0000000140007702: 48 FF C2 inc rdx
0000000140007705: 66 41 89 08 mov word ptr [r8],cx
0000000140007709: 4D 8D 40 02 lea r8,[r8+2]
000000014000770D: 84 C9 test cl,cl
000000014000770F: 75 EE jne 00000001400076FF
0000000140007711: 48 8D 54 24 20 lea rdx,[rsp+20h]
0000000140007716: 48 8D 0D DB FE FF lea
rcx,[??_C@_03NNECAHIM@?$CFS?6?$AA@]
FF
000000014000771D: E8 22 00 00 00 call printf
0000000140007722: 33 C0 xor eax,eax
0000000140007724: 48 81 C4 98 00 00 add rsp,98h
00
000000014000772B: C3 ret
From: Tian, Feng [mailto:feng.t...@intel.com]
Sent: Thursday, May 23, 2013 12:08 AM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] LTCG and fixed address pointers.
Hi, Tim
It's weird why I didn't meet your issue?
VariableDxe.c.patch is what I modified to emulate your case.
The pcd definition is updated to:
## 64-bit Base address of the NV variable range in flash device
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0xFFE00008|UINT64|0x80000001
The CC flag is:
DEBUG_VS2008x86_X64_CC_FLAGS = /nologo /c /WX /GS- /X /W4 /Gs32768 /D
UNICODE /O1ib2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gm
The Link flag is:
DEBUG_VS2008x86_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001
/OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D
/Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT)
/SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
[From above build flag, we can know LTO feature is enabled as /GL and /LTCG has
been used]
The output.txt is the disassembly file of "dmpbin.exe", in which line 26 ~28, I
don't see the assembly code segment like you shown. (due to 512k mail size
limitation, I have to trim some output in output.txt)
The disassembly code is:
0000000000000A12: B8 08 01 E0 FF mov eax,0FFE00108h
0000000000000A17: B9 08 00 E0 FF mov ecx,0FFE00008h
0000000000000A1C: 80 38 00 cmp byte ptr [rax],0
So what build flag are you using?
Thanks
Feng
From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Thursday, May 23, 2013 09:30
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: Re: [edk2] LTCG and fixed address pointers.
To follow up further, the problem appears to be an encoding error:
The bytes for the encoding are below. The value of the PCD was
0x00000000ffe8b00e
0000000000063B24: 44 38 B0 0E B0 E8 FF cmp byte ptr [rax-174FF2h],r14b
44 = extend the R field in the mod R/M byte.
38 = compare
B0 = modrm = [rax+disp32], and r = r14
Disp32 = ffe8b0038
Notice that the PCD value is encoded directly as a displacement. But, in 64-bit
modes, displacements are sign-extended (see 2.2.1.3 in Vol 2 of the Intel Ref)
to 64-bits, which means it acts, -effectively, like a subtraction. For an
unsigned integer, it must be encoded with a register. In fact, a few
instructions before, you can see:
0000000000063B14: BA 0E B0 E8 FF mov edx,0FFE8B00Eh
So this would have been better encoded as cmp byte ptr [rax + rdx], r14b
Tim
From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Tuesday, May 21, 2013 9:41 PM
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: Re: [edk2] LTCG and fixed address pointers.
We tried as a UINT64. Same result. Tim
From: Tian, Feng [mailto:feng.t...@intel.com]
Sent: Tuesday, May 21, 2013 8:26 PM
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: Re: [edk2] LTCG and fixed address pointers.
How about defining this Pcd as UINT64? We defined PcdPciExpressBaseAddress like
this way.
So your code should be:
In Dec file:
gXxxTokenSpaceGuid.PcdXxxAddress|0xFFe8B00E|UINT64|0x12345678
In C code:
StrPtr = PcdGet64 (PcdXXX) + 0x100;
From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Wednesday, May 22, 2013 01:16
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: [edk2] LTCG and fixed address pointers.
We are having trouble with link-time code generation under Visual Studio when
using PCDs to specify a specific address and convert it to a pointer, when
accessed from a library. In a library, the FixedAtBuild PCDs (on x64) are
defned as extern const UINT32 PcdXXXX; and PcdXXXX contains 0xffe8b00e. The
code generated by VS2008/2010/2012 linker shows:
xor r12d,r12d // r12d = 0
mov eax,r12d // eax = r12d == 0 rax = ?
cmp byte ptr [rax-174FF2h],r12b
Notice LTCG is trying to optimize by using a relative offset from 0. "0 -
174ff2" is FFFFFFFFFFE8B00E (not FFe8B00e).
The code in question is in the form:
CHAR8 *StrPtr;
StrPtr = (CHAR8 *)(UINTN) (PcdGet(PcdXXXX) + 0x100))
while (*StrPtr != '\0') {
...
}
We have tried nearly everything we can think of, other than turning off LTCG
for the module or even the specific lines. I am worried about what happens with
MMIO and other "fixed" addresses. I have tried (CHAR8 *)(UINTN) (UINT32) and
almost every possible combination of typecases on the PCD result and the 0x100,
etc. Even did & 0xffffffff. No effect.
If I turn off LTCG, it correctly creates a 32-bit address.
I haven't been able to get any response on the MS forums.
Anyone have any experience with this?
Tim
#include <stdlib.h>
#include <stdio.h>
typedef struct _y {
void *k;
} y;
extern const unsigned __int32 x;
static
unsigned short *
BvdtLibAscii2Unicode (
unsigned short *UnicodeStr,
char *AsciiStr
)
{
unsigned short *Str;
Str = UnicodeStr;
while (1) {
*(UnicodeStr++) = (unsigned short) *AsciiStr;
if (*(AsciiStr++) == '\0') {
return Str;
}
}
}
int main()
{
char *y;
int i;
unsigned short output[50];
y = (char *)(unsigned __int64)(x + 0x41);
i = TestLen(y);
if (i > 50) {
return -5;
} else {
BvdtLibAscii2Unicode (output, y);
printf ("%S\n",output);
}
return 0;
}
const unsigned __int32 x = 0xFFFE8B0EUL;
const unsigned int PcdMaximumAsciiStringLength = 32000;
unsigned __int64 TestLen(char *y)
{
unsigned __int64 Length;
for (Length = 0; *y != '\0'; y++, Length++) {
}
return Length;
}
------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel