From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from ma1-aaemail-dr-lapp03.apple.com (ma1-aaemail-dr-lapp03.apple.com [17.171.2.72]) by mx.groups.io with SMTP id smtpd.web10.11639.1642093950624704628 for ; Thu, 13 Jan 2022 09:12:31 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@apple.com header.s=20180706 header.b=oB/2xFDT; spf=pass (domain: apple.com, ip: 17.171.2.72, mailfrom: afish@apple.com) Received: from pps.filterd (ma1-aaemail-dr-lapp03.apple.com [127.0.0.1]) by ma1-aaemail-dr-lapp03.apple.com (8.16.0.42/8.16.0.42) with SMTP id 20DH9MD2063513; Thu, 13 Jan 2022 09:12:29 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apple.com; h=from : content-type : mime-version : subject : date : references : to : in-reply-to : message-id; s=20180706; bh=UH5fvPklCZzJvEVwsMjktKhOhdsWmiL3jpFUDuRytX8=; b=oB/2xFDTFiQzgjDQckG7Pw1Y3F49eoDG1LZUEnHn2694JV2r1MR8CJ1N9C4zZ3OO73nS uMFL7jijHojxTwRY4etu1OqKe5yEbQ8W+ViIlAYXB18kS8C1vvQHpC5KLfiznfxksZtf UHM/XAOUdq76/LawzUYtmPqcVR1fAKwbloPL4VjzUs64LsiUZ2NzVXIwuQpH3Ky0Em6p U5vwtdEZm9v89XzhyrxQIBoKIxb1SbRLV1hmbhGJM6uVvIm3fx2KCoY+4w+8qbw7tcgA 6/AvY+Nr+S8X/dSR7n5tGZl8tIIsMj3kM5eKWhdv3cRFEc8/3h5yR6vW298CFZNk8ify fQ== Received: from rn-mailsvcp-mta-lapp01.rno.apple.com (rn-mailsvcp-mta-lapp01.rno.apple.com [10.225.203.149]) by ma1-aaemail-dr-lapp03.apple.com with ESMTP id 3dfag0tujp-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Thu, 13 Jan 2022 09:12:28 -0800 Received: from rn-mailsvcp-mmp-lapp03.rno.apple.com (rn-mailsvcp-mmp-lapp03.rno.apple.com [17.179.253.16]) by rn-mailsvcp-mta-lapp01.rno.apple.com (Oracle Communications Messaging Server 8.1.0.12.20210903 64bit (built Sep 3 2021)) with ESMTPS id <0R5N00EKNRSQKI30@rn-mailsvcp-mta-lapp01.rno.apple.com>; Thu, 13 Jan 2022 09:12:26 -0800 (PST) Received: from process_milters-daemon.rn-mailsvcp-mmp-lapp03.rno.apple.com by rn-mailsvcp-mmp-lapp03.rno.apple.com (Oracle Communications Messaging Server 8.1.0.12.20210903 64bit (built Sep 3 2021)) id <0R5N00800REVG100@rn-mailsvcp-mmp-lapp03.rno.apple.com>; Thu, 13 Jan 2022 09:12:26 -0800 (PST) X-Va-A: X-Va-T-CD: 252d230b7cfb6436468d3f05b630adb0 X-Va-E-CD: 6a253ddc243577a0def0dc64e87ee50c X-Va-R-CD: d971937c15f2509bfa398a067ed45849 X-Va-CD: 0 X-Va-ID: cbc8aff8-faf2-413c-9ecb-7e5d48ed744e X-V-A: X-V-T-CD: 252d230b7cfb6436468d3f05b630adb0 X-V-E-CD: 6a253ddc243577a0def0dc64e87ee50c X-V-R-CD: d971937c15f2509bfa398a067ed45849 X-V-CD: 0 X-V-ID: 88226d3c-62fc-42d6-b92b-96408174f424 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.425,18.0.816 definitions=2022-01-13_06:2022-01-12,2022-01-13 signatures=0 Received: from smtpclient.apple (unknown [17.235.39.111]) by rn-mailsvcp-mmp-lapp03.rno.apple.com (Oracle Communications Messaging Server 8.1.0.12.20210903 64bit (built Sep 3 2021)) with ESMTPSA id <0R5N001HIRSP2M00@rn-mailsvcp-mmp-lapp03.rno.apple.com>; Thu, 13 Jan 2022 09:12:26 -0800 (PST) From: "Andrew Fish" MIME-version: 1.0 (Mac OS X Mail 15.0 \(3693.20.0.1.32\)) Subject: Re: [edk2-devel] Issues with CLANGDWARF tool specification and X64 -- am I nuts or what? Date: Thu, 13 Jan 2022 09:12:25 -0800 References: <1670021.xRuIxZukmv@core> <1919126.R0FQcr2YjX@core> To: edk2-devel-groups-io , wpaul@windriver.com In-reply-to: <1919126.R0FQcr2YjX@core> Message-id: <82BBE0CA-8378-4323-84CB-4AE023F6580D@apple.com> X-Mailer: Apple Mail (2.3693.20.0.1.32) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.425,18.0.816 definitions=2022-01-13_06:2022-01-12,2022-01-13 signatures=0 Content-type: multipart/alternative; boundary="Apple-Mail=_A7C6FD16-BB5E-4B70-994A-BC850EAAEA24" --Apple-Mail=_A7C6FD16-BB5E-4B70-994A-BC850EAAEA24 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On Jan 11, 2022, at 10:02 AM, Bill Paul wrote: >=20 > BTW, regarding 3) below, it looks like this is expected behavior from Cla= ng/ > LLVM. Dereferencing a NULL pointer is technically undefined in C, and by= =20 > default the Clang optimizer will cause a trap to occur if you try to do i= t=20 > (because it assumes it's not safe for programs to do that). >=20 > The flag -fno-delete-null-pointer-checks can be used to avoid this behavi= or.=20 > This flag seems to be valid for Clang 9 and later. This is slightly more= =20 > efficient than using the volatile keyword to defeat the optimizer. This f= lag=20 > is also for GCC. >=20 Given it is undefined behavior and the compiler is behaving correctly I thi= nk it is better to write correct C code and use volatile if you mean to use= a NULL pointer.=20 Not to mention I worked hard to get clang to emit the trap. If was very pai= nful debugging issues like this when the function just ends in the middle a= nd you fall into the next function.=20 Thanks, Andrew Fish > -Bill >=20 >> Hello all: >>=20 >> Recently I discovered that you can enable CSM compatibility mode in OVMF= and >> decided to build some images with this feature Because Of Reasons (tm). = My >> platform is: >>=20 >> FreeBSD/amd64 12.2-RELEASE >> Clang/LLVM 10.0.1 >> QEMU 6.2.0 >>=20 >> These days FreeBSD uses Clang as its native compiler. 12.2-RELEASE comes >> with version 10.0.1, but you also have the option of installing more rec= ent >> Clang/ LLVM versions up to 12.0.1 as supplemental packages. I noticed th= at >> CLANGDWARF is a supported tool spec for the X64 and IA32 build targets s= o I >> decided to try that. >>=20 >> Unfortunately I ran into a couple of problems: >>=20 >> 1) Compilation of OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c fails du= e to >> uninitialized local variable. >>=20 >> /mnt/home/wpaul/edk2/edk2/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c: >> 1875:9: error: variable 'Compacted' is used uninitialized whenever 'if' >> condition is false [-Werror,-Wsometimes-uninitialized] >> if (EcxIn =3D=3D 1) { >> ^~~~~~~~~~ >> /mnt/home/wpaul/edk2/edk2/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c: >> 1895:12: note: uninitialized use occurs here >> Compacted >> ^~~~~~~~~ >> /mnt/home/wpaul/edk2/edk2/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c: >> 1875:5: note: remove the 'if' if its condition is always true >> if (EcxIn =3D=3D 1) { >> ^~~~~~~~~~~~~~~~ >> /mnt/home/wpaul/edk2/edk2/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c: >> 1871:37: note: initialize the variable 'Compacted' to silence this warni= ng >> BOOLEAN Compacted; >> ^ >> =3D '\0' >>=20 >> I changed line 1871 to: >>=20 >> BOOLEAN Compacted =3D FALSE; >>=20 >> and that fixed it. I suspect this may be a case where Clang is being a b= it >> more strict than GCC about uninitialized variables. >>=20 >> 2) Linking fails with numerous errors of the following kind: >>=20 >> ld.lld: error: can't create dynamic relocation R_X86_64_64 against local >> symbol in readonly segment; recompile object files with -fPIC or pass '-= Wl,- >> z,notext' to allow text relocations in the output >>=20 >>>>> defined in >>>>> /mnt/home/wpaul/edk2/edk2/Build/OvmfX64/RELEASE_CLANGDWARF/X64/ >>=20 >> UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib/O= UTPU >> T/ SecPeiCpuExceptionHandlerLib.lib(ExceptionHandlerAsm.obj) >>=20 >> If I edit tools_def.txt and change RELEASE_CLANGDWARF_X64_DLINK_FLAGS so >> that it includes -Wl,-z,notext as the error suggests, then everything li= nks >> as expected. (The same thing is needed for DEBUG_CLANGDWARF_X64_DLINK_FL= AGS >> and probably NOOPT_CLANGDWARF_X64_DLINK_FLAGS.) >>=20 >> This problem only occurs when building for X64. IA32 seems ok. >>=20 >> Is there any particular reason why these flags aren't there already? >>=20 >> 3) Although fixing the above two problems allows me to produce a complet= e >> OVMF.fd image, it crashes at start-up with the runtime error: >>=20 >> !!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 000000= 00 >> !!!! >> RIP - 000000007EC8A7DB, CS - 0000000000000038, RFLAGS - 00000000000102= 06 >> RAX - 0000000000000000, RCX - 000000007F5A0880, RDX - 000000007FF2BAE0 >> RBX - 000000007FF2BBF0, RSP - 000000007FF2BB20, RBP - 000000005A1C5000 >> RSI - 000000007FF2BB48, RDI - 0000000000000000 >> R8 - 0000000000000008, R9 - 0000000000000000, R10 - 0000000000000000 >> R11 - 000000007FF41C90, R12 - 0000000000058080, R13 - 000000007FF2BC20 >> R14 - 00000000000F6DB0, R15 - 0000000000000000 >> DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030 >> GS - 0000000000000030, SS - 0000000000000030 >> CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 000000007FC01000 >> CR4 - 0000000000000668, CR8 - 0000000000000000 >> DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000 >> DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400 >> GDTR - 000000007F9EC000 0000000000000047, LDTR - 0000000000000000 >> IDTR - 000000007F5A4018 0000000000000FFF, TR - 0000000000000000 >> FXSAVE_STATE - 000000007FF2B780 >> !!!! Find image based on IP(0x7EC8A7DB) (No PDB)=20 >> (ImageBase=3D000000007EC87000, EntryPoint=3D000000007EC8D7A6) !!!! >>=20 >> The same thing occurs for IA32: >>=20 >> !!!! IA32 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000= 000 >> !!!! >> EIP - 7ECF72D4, CS - 00000010, EFLAGS - 00010206 >> EAX - 00000008, ECX - 00000000, EDX - 7F8EEE10, EBX - 5000A19D >> ESP - 7FF33D44, EBP - 7FF33E4C, ESI - 7FF33D4C, EDI - 7ECFB04C >> DS - 00000008, ES - 00000008, FS - 00000008, GS - 00000008, SS - >> 00000008 CR0 - 80010033, CR2 - 00000000, CR3 - 7FC01000, CR4 - 00000660 >> DR0 - 00000000, DR1 - 00000000, DR2 - 00000000, DR3 - 00000000 >> DR6 - FFFF0FF0, DR7 - 00000400 >> GDTR - 7F9EC000 00000047, IDTR - 7F5E5010 000007FF >> LDTR - 00000000, TR - 00000000 >> FXSAVE_STATE - 7FF33A80 >> !!!! Find image based on IP(0x7ECF72D4) (No PDB)=20 >> (ImageBase=3D000000007ECF4000, EntryPoint=3D000000007ECF9FBD) !!!! >>=20 >> This one had me going for a while, but I eventually traced it down to >> LegacyBiosInt86() in OvmfPkg/Csm/LegacyBiosDxe/Thunk.c. >>=20 >> In that function, there is this code: >>=20 >> UINT16 Segment; >> UINT16 Offset; >> [...] >> // >> // The base address of legacy interrupt vector table is 0. >> // We use this base address to get the legacy interrupt handler. >> // >> ACCESS_PAGE0_CODE ( >> Segment =3D (UINT16)(((UINT32 *)0)[BiosInt] >> 16); >> Offset =3D (UINT16)((UINT32 *)0)[BiosInt]; >> ); >>=20 >> As the comment notes, here, we're trying to directly read from address 0 >> using BiosInt as an offset. This seems to trigger a problem with the Cla= ng >> optimizer. The disassembled output looks like this: >>=20 >> 0000000000003786 : >> 3786: 56 push %rsi >> 3787: 48 83 ec 60 sub $0x60,%rsp >> 378b: 41 0f b7 40 18 movzwl 0x18(%r8),%eax >> 3790: 25 d4 0c 00 00 and $0xcd4,%eax >> 3795: 0d 02 30 00 00 or $0x3002,%eax >> 379a: 66 41 89 40 18 mov %ax,0x18(%r8) >> 379f: 48 8d 74 24 28 lea 0x28(%rsp),%rsi >> 37a4: 48 83 66 18 00 andq $0x0,0x18(%rsi) >> 37a9: 48 8b 05 a8 59 00 00 mov 0x59a8(%rip),%rax # >> 9158 >> 37b0: 31 c9 xor %ecx,%ecx >> 37b2: 48 89 f2 mov %rsi,%rdx >> 37b5: ff 50 38 call *0x38(%rax) >> 37b8: 4c 8b 46 18 mov 0x18(%rsi),%r8 >> 37bc: 41 0f ba e0 0d bt $0xd,%r8d >> 37c1: 73 18 jae 37db >> 37c3: 48 8b 05 8e 59 00 00 mov 0x598e(%rip),%rax # >> 9158 >> 37ca: 49 81 e0 ff df ff ff and $0xffffffffffffdfff,%r8 >> 37d1: ba 00 10 00 00 mov $0x1000,%edx >> 37d6: 31 c9 xor %ecx,%ecx >> 37d8: ff 50 40 call *0x40(%rax) >> 37db: 0f 0b ud2 <--- er... what? >>=20 >> Note the "ud2" instruction. I have no idea what that's supposed to be, b= ut >> it looks like Clang just gives up generating any further instructions on= ce >> it hits this code. >>=20 >> I reduced this to a very simple sample C program that also reproduces th= e >> problem: >>=20 >> #include >>=20 >> extern int somefunc (uint16_t s, uint16_t o); >>=20 >> int >> foo (uint8_t BiosInt) >> { >> uint16_t Segment; >> uint16_t Offset; >>=20 >> Segment =3D (uint16_t)(((uint32_t *)0)[BiosInt] >> 16); >> Offset =3D (uint16_t)((uint32_t *)0)[BiosInt]; >>=20 >> return somefunc (Segment, Offset); >> } >>=20 >> If I compile this with: >>=20 >> % clang -O2 -c edk.c >>=20 >> then I get this: >>=20 >> 0000000000000000 : >> 0: 55 push %rbp >> 1: 48 89 e5 mov %rsp,%rbp >> 4: 0f 0b ud2 >>=20 >> If I compile with GCC instead: >>=20 >> % gcc10 -O2 -c edk.c >>=20 >> then I get this: >>=20 >> 0000000000000000 : >> 0: 40 0f b6 ff movzbl %dil,%edi >> 4: 8b 3c bd 00 00 00 00 mov 0x0(,%rdi,4),%edi >> b: 0f b7 f7 movzwl %di,%esi >> e: c1 ef 10 shr $0x10,%edi >> 11: e9 00 00 00 00 jmp 16 >>=20 >> If I compile with Clang using -O0 to disable optimization, then it produ= ces >> code: >>=20 >> 0000000000000000 : >> 0: 55 push %rbp >> 1: 48 89 e5 mov %rsp,%rbp >> 4: 48 83 ec 10 sub $0x10,%rsp >> 8: 31 c0 xor %eax,%eax >> a: 89 c1 mov %eax,%ecx >> c: 40 88 7d ff mov %dil,-0x1(%rbp) >> 10: 0f b6 45 ff movzbl -0x1(%rbp),%eax >> 14: 89 c2 mov %eax,%edx >> 16: 8b 04 91 mov (%rcx,%rdx,4),%eax >> 19: c1 e8 10 shr $0x10,%eax >> 1c: 66 89 45 fc mov %ax,-0x4(%rbp) >> 20: 0f b6 75 ff movzbl -0x1(%rbp),%esi >> 24: 89 f2 mov %esi,%edx >> 26: 8b 34 91 mov (%rcx,%rdx,4),%esi >> 29: 66 89 75 fa mov %si,-0x6(%rbp) >> 2d: 66 8b 45 fc mov -0x4(%rbp),%ax >> 31: 0f b7 f8 movzwl %ax,%edi >> 34: 0f b7 75 fa movzwl -0x6(%rbp),%esi >> 38: e8 00 00 00 00 call 3d >> 3d: 48 83 c4 10 add $0x10,%rsp >> 41: 5d pop %rbp >> 42: c3 ret >>=20 >> Note that this is with Clang 10.0.1, however I observe exactly the same >> results with Clang 12.0.1. >>=20 >> I was able to fix this locally (for both X64 and IA32 targets) this by d= oing >> this: >>=20 >> UINT16 Segment; >> UINT16 Offset; >> volatile UINT32 * Page0 =3D NULL; >> [...] >> ACCESS_PAGE0_CODE ( >> Segment =3D (UINT16)(Page0[BiosInt] >> 16); >> Offset =3D (UINT16)Page0[BiosInt]; >> ); >>=20 >> Note that the addition of the volatile keyword seems to be the key. If y= ou >> wanted to make the change simpler, you could also just do this: >>=20 >> ACCESS_PAGE0_CODE ( >> Segment =3D (UINT16)(((volatile UINT32 *)0)[BiosInt] >> 16); >> Offset =3D (UINT16)((volatile UINT32 *)0)[BiosInt]; >> ); >>=20 >> (To my eyes, the other way is more readable, but others may disagree.) >>=20 >> With these three issues fixed, I'm able to boot and run my OVMF.fd image= s >> for both X64 and IA32, and they're able to also boot and run the loaders >> and OS images that I'm testing. >>=20 >> I'm not sure how much testing the CLANGDWARF toolspec is getting these d= ays, >> but maybe it should get a little more. Is there any chance these issues >> could be addressed? >>=20 >> -Bill >=20 >=20 > --=20 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > -Bill Paul (510) 749-2329 | VxWorks Software Architect, > wpaul@windriver.com | Master of Unix-Fu - Wind River Syst= ems > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > "I put a dollar in a change machine. Nothing changed." - George Carlin > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >=20 >=20 >=20 >=20 >=20 >=20 --Apple-Mail=_A7C6FD16-BB5E-4B70-994A-BC850EAAEA24 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii
On Jan 11,= 2022, at 10:02 AM, Bill Paul <wpaul@windriver.com> wrote:

BTW= , regarding 3) below, it looks like this is expected behavior from Clang/
LLVM. Dereferencing a NU= LL pointer is technically undefined in C, and by 
default the Clang optimizer will cause a trap to occur if you try to do i= t 

(because it assumes it's not safe for program= s to do that).

The flag -fno-delete-null-pointer-checks can= be used to avoid this behavior. = ;
This flag seem= s to be valid for Clang 9 and later. This is slightly more 
efficient than using the volatile keyword to defeat the optimi= zer. This flag is also for GCC.

=

Given it is undefined behavior = and the compiler is behaving correctly I think it is better to write correc= t C code and use volatile if you mean to use a NULL pointer. 

Not to mention I worked hard to get clang to em= it the trap. If was very painful debugging issues like this when the functi= on just ends in the middle and you fall into the next function. 
=

Thanks,

= Andrew Fish

-Bill

Hello all:

Recently I discovered that you can enable CSM compatibilit= y mode in OVMF and
decided to build some images with this fea= ture Because Of Reasons (tm). My
platform is:
<= br class=3D"">FreeBSD/amd64 12.2-RELEASE
Clang/LLVM 10.0.1QEMU 6.2.0

These days FreeBSD uses= Clang as its native compiler. 12.2-RELEASE comes
with versio= n 10.0.1, but you also have the option of installing more recent
Clang/ LLVM versions up to 12.0.1 as supplemental packages. I noticed= that
CLANGDWARF is a supported tool spec for the X64 and IA3= 2 build targets so I
decided to try that.

Unfortunately I ran into a couple of problems:

1) Compilation of OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c = fails due to
uninitialized local variable.

/mnt/home/wpaul/edk2/edk2/OvmfPkg/Library/VmgExitLib/VmgExitVcHa= ndler.c:
1875:9: error: variable 'Compacted' is used uninitia= lized whenever 'if'
condition is false [-Werror,-Wsometimes-u= ninitialized]
   if (EcxIn =3D=3D 1) {
       ^~~~~~~~~~
/= mnt/home/wpaul/edk2/edk2/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c:
1895:12: note: uninitialized use occurs here
 = ;         Compacted
          ^~~~~~~~~=
/mnt/home/wpaul/edk2/edk2/OvmfPkg/Library/VmgExitLib/VmgExit= VcHandler.c:
1875:5: note: remove the 'if' if its condition i= s always true
   if (EcxIn =3D=3D 1) {
   ^~~~~~~~~~~~~~~~
/mnt/home/wpaul/edk= 2/edk2/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c:
1871:37= : note: initialize the variable 'Compacted' to silence this warning
   BOOLEAN        =         Compacted;
&n= bsp;            = ;            &n= bsp;         ^
&= nbsp;           &nbs= p;            &= nbsp;          =3D '\0'
I changed line 1871 to:

   BOOLEAN        &= nbsp;       Compacted =3D FALSE;

and that fixed it. I suspect this may be a case where= Clang is being a bit
more strict than GCC about uninitialize= d variables.

2) Linking fails with numerous er= rors of the following kind:

ld.lld: error: can= 't create dynamic relocation R_X86_64_64 against local
symbol= in readonly segment; recompile object files with -fPIC or pass '-Wl,-
z,notext' to allow text relocations in the output
<= br class=3D"">
defined in
= /mnt/home/wpaul/edk2/edk2/Build/OvmfX64/RELEASE_CLANGDWARF/X64/

UefiCpuPkg/Library= /CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib/OUTPU
T/= SecPeiCpuExceptionHandlerLib.lib(ExceptionHandlerAsm.obj)
If I edit tools_def.txt and change RELEASE_CLANGDWARF_X64_DLIN= K_FLAGS so
that it includes -Wl,-z,notext as the error sugges= ts, then everything links
as expected. (The same thing is nee= ded for DEBUG_CLANGDWARF_X64_DLINK_FLAGS
and probably NOOPT_C= LANGDWARF_X64_DLINK_FLAGS.)

This problem only = occurs when building for X64. IA32 seems ok.

I= s there any particular reason why these flags aren't there already?

3) Although fixing the above two problems allows me t= o produce a complete
OVMF.fd image, it crashes at start-up wi= th the runtime error:

!!!! X64 Exception Type = - 06(#UD - Invalid Opcode)  CPU Apic ID - 00000000
!!!!<= br class=3D"">RIP  - 000000007EC8A7DB, CS  - 0000000000000038, RF= LAGS - 0000000000010206
RAX  - 0000000000000000, RCX - 0= 00000007F5A0880, RDX - 000000007FF2BAE0
RBX  - 000000007= FF2BBF0, RSP - 000000007FF2BB20, RBP - 000000005A1C5000
RSI &= nbsp;- 000000007FF2BB48, RDI - 0000000000000000
R8  &nbs= p;- 0000000000000008, R9  - 0000000000000000, R10 - 0000000000000000R11  - 000000007FF41C90, R12 - 0000000000058080, R13 - 00= 0000007FF2BC20
R14  - 00000000000F6DB0, R15 - 0000000000= 000000
DS   - 0000000000000030, ES  - 00000000= 00000030, FS  - 0000000000000030
GS   - 000000= 0000000030, SS  - 0000000000000030
CR0  - 000000008= 0010033, CR2 - 0000000000000000, CR3 - 000000007FC01000
CR4 &= nbsp;- 0000000000000668, CR8 - 0000000000000000
DR0  - 0= 000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 000000000000= 0400
GDTR - 000000007F9EC000 0000000000000047, LDTR - 0000000= 000000000
IDTR - 000000007F5A4018 0000000000000FFF,  &nb= sp;TR - 0000000000000000
FXSAVE_STATE - 000000007FF2B780
!!!! Find image based on IP(0x7EC8A7DB) (No PDB) 
(ImageBase=3D000000007EC87= 000, EntryPoint=3D000000007EC8D7A6) !!!!

The s= ame thing occurs for IA32:

!!!! IA32 Exception= Type - 06(#UD - Invalid Opcode)  CPU Apic ID - 00000000
!!!!
EIP  - 7ECF72D4, CS  - 00000010, EFLAGS - 000= 10206
EAX  - 00000008, ECX - 00000000, EDX - 7F8EEE10, E= BX - 5000A19D
ESP  - 7FF33D44, EBP - 7FF33E4C, ESI - 7FF= 33D4C, EDI - 7ECFB04C
DS   - 00000008, ES  - 0= 0000008, FS  - 00000008, GS  - 00000008, SS -
00000= 008 CR0  - 80010033, CR2 - 00000000, CR3 - 7FC01000, CR4 - 00000660DR0  - 00000000, DR1 - 00000000, DR2 - 00000000, DR3 - 000= 00000
DR6  - FFFF0FF0, DR7 - 00000400
GDTR= - 7F9EC000 00000047, IDTR - 7F5E5010 000007FF
LDTR - 0000000= 0, TR - 00000000
FXSAVE_STATE - 7FF33A80
!!!! F= ind image based on IP(0x7ECF72D4) (No PDB) 
(ImageBase=3D000000007ECF4000, EntryPoint= =3D000000007ECF9FBD) !!!!

This one had me goin= g for a while, but I eventually traced it down to
LegacyBiosI= nt86() in OvmfPkg/Csm/LegacyBiosDxe/Thunk.c.

I= n that function, there is this code:

 UIN= T16  Segment;
 UINT16  Offset;
[= ...]
 //
 // The base address of lega= cy interrupt vector table is 0.
 // We use this base add= ress to get the legacy interrupt handler.
 //
 ACCESS_PAGE0_CODE (
   Segment =3D= (UINT16)(((UINT32 *)0)[BiosInt] >> 16);
  &n= bsp;Offset  =3D (UINT16)((UINT32 *)0)[BiosInt];
 &n= bsp; );

As the comment notes, here, we're= trying to directly read from address 0
using BiosInt as an o= ffset. This seems to trigger a problem with the Clang
optimiz= er. The disassembled output looks like this:

0= 000000000003786 <LegacyBiosInt86>:
   37= 86:       56      &n= bsp;            = ;   push   %rsi
   37= 87:       48 83 ec 60     = ;        sub    $0x6= 0,%rsp
   378b:      =  41 0f b7 40 18          = movzwl 0x18(%r8),%eax
   3790:   &nb= sp;   25 d4 0c 00 00       &nb= sp;  and    $0xcd4,%eax
  =  3795:       0d 02 30 00 00   =        or     $0x300= 2,%eax
   379a:      =  66 41 89 40 18          = mov    %ax,0x18(%r8)
   379f: &= nbsp;     48 8d 74 24 28     &= nbsp;    lea    0x28(%rsp),%rsi
   37a4:       48 83 66 = 18 00          andq  &nbs= p;$0x0,0x18(%rsi)
   37a9:    &= nbsp;  48 8b 05 a8 59 00 00    mov   &nb= sp;0x59a8(%rip),%rax        #
9158 <gDS>
   37b0:   &n= bsp;   31 c9         = ;          xor  &nbs= p; %ecx,%ecx
   37b2:    &= nbsp;  48 89 f2         &= nbsp;      mov    %rsi,%rdx   37b5:       ff = 50 38            &nb= sp;   call   *0x38(%rax)
  = ; 37b8:       4c 8b 46 18   &n= bsp;         mov   &= nbsp;0x18(%rsi),%r8
   37bc:    = ;   41 0f ba e0 0d        = ;  bt     $0xd,%r8d
  = ; 37c1:       73 18    &n= bsp;            = ;  jae    37db <LegacyBiosInt86+0x55>
   37c3:       48 8b 0= 5 8e 59 00 00    mov    0x598e(%rip),%rax &nb= sp;      #
9158 <gDS>
   37ca:       49 8= 1 e0 ff df ff ff    and    $0xffffffffffffdff= f,%r8
   37d1:      &= nbsp;ba 00 10 00 00          m= ov    $0x1000,%edx
   37d6: &nb= sp;     31 c9       =             xor=    %ecx,%ecx
   37d8:  &n= bsp;    ff 50 40       &n= bsp;        call   *0x40(= %rax)
   37db:      &= nbsp;0f 0b           &nbs= p;       ud2    <--- e= r... what?

Note the "ud2" instruction. I have = no idea what that's supposed to be, but
it looks like Clang j= ust gives up generating any further instructions once
it hits= this code.

I reduced this to a very simple sa= mple C program that also reproduces the
problem:

#include <stdint.h>

ext= ern int somefunc (uint16_t s, uint16_t o);

int=
foo (uint8_t BiosInt)
{
 &n= bsp;     uint16_t Segment;
 &nb= sp;     uint16_t Offset;

       Segment =3D (uint16_t)(((ui= nt32_t *)0)[BiosInt] >> 16);
    &n= bsp;  Offset  =3D (uint16_t)((uint32_t *)0)[BiosInt];

       return som= efunc (Segment, Offset);
}

If I = compile this with:

% clang -O2 -c edk.c

then I get this:

000000= 0000000000 <foo>:
  0:   55  &= nbsp;           &nbs= p;       push   %rbp
  1:   48 89 e5      &nb= sp;         mov   &n= bsp;%rsp,%rbp
  4:   0f 0b   &n= bsp;            = ;   ud2

If I compile with GCC i= nstead:

% gcc10 -O2 -c edk.c
then I get this:

0000000000000000 = <foo>:
  0:   40 0f b6 ff  &nb= sp;          movzbl %dil,= %edi
  4:   8b 3c bd 00 00 00 00  &n= bsp; mov    0x0(,%rdi,4),%edi
  = ;b:   0f b7 f7         &n= bsp;      movzwl %di,%esi
 = ; e:   c1 ef 10        &n= bsp;       shr    $0x10,%= edi
 11:   e9 00 00 00 00    &n= bsp;     jmp    16 <foo+0x16>=

If I compile with Clang using -O0 to disable = optimization, then it produces
code:

0000000000000000 <foo>:
  0:  &nbs= p;55            &nbs= p;         push   %r= bp
  1:   48 89 e5    &nbs= p;           mov &nb= sp;  %rsp,%rbp
  4:   48 83 ec = 10             = sub    $0x10,%rsp
  8:   3= 1 c0            &nbs= p;      xor    %eax,%eax
  a:   89 c1      &nb= sp;            = mov    %eax,%ecx
  c:   40= 88 7d ff            = ; mov    %dil,-0x1(%rbp)
 10:  =  0f b6 45 ff          &nb= sp;  movzbl -0x1(%rbp),%eax
 14:   8= 9 c2            &nbs= p;      mov    %eax,%edx
 16:   8b 04 91       = ;         mov   &nbs= p;(%rcx,%rdx,4),%eax
 19:   c1 e8 10  &nb= sp;            =  shr    $0x10,%eax
 1c:   = 66 89 45 fc           &nb= sp; mov    %ax,-0x4(%rbp)
 20:  = ; 0f b6 75 ff          &n= bsp;  movzbl -0x1(%rbp),%esi
 24:   = 89 f2            &nb= sp;      mov    %esi,%edx
 26:   8b 34 91      &nbs= p;         mov   &nb= sp;(%rcx,%rdx,4),%esi
 29:   66 89 75 fa  = ;           mov &nbs= p;  %si,-0x6(%rbp)
 2d:   66 8b 45 f= c             m= ov    -0x4(%rbp),%ax
 31:   0f = b7 f8            &nb= sp;   movzwl %ax,%edi
 34:   0f= b7 75 fa            = ; movzwl -0x6(%rbp),%esi
 38:   e8 00 00 = 00 00          call  &nbs= p;3d <foo+0x3d>
 3d:   48 83 c4 10  = ;           add &nbs= p;  $0x10,%rsp
 41:   5d   = ;            &n= bsp;      pop    %rbp
 42:   c3        &n= bsp;            = ; ret

Note that this is with Clang 10.0.1= , however I observe exactly the same
results with Clang 12.0.= 1.

I was able to fix this locally (for both X6= 4 and IA32 targets) this by doing
this:

 UINT16  Segment;
 UINT16  Offset= ;
 volatile UINT32 * Page0 =3D NULL;
[...]=
 ACCESS_PAGE0_CODE (
   Se= gment =3D (UINT16)(Page0[BiosInt] >> 16);
  &= nbsp;Offset  =3D (UINT16)Page0[BiosInt];
  &nb= sp;);

Note that the addition of the volatile k= eyword seems to be the key. If you
wanted to make the change = simpler, you could also just do this:

 AC= CESS_PAGE0_CODE (
   Segment =3D (UINT16)(((vo= latile UINT32 *)0)[BiosInt] >> 16);
   O= ffset  =3D (UINT16)((volatile UINT32 *)0)[BiosInt];
&nbs= p;  );

(To my eyes, the other way is= more readable, but others may disagree.)

With= these three issues fixed, I'm able to boot and run my OVMF.fd images
for both X64 and IA32, and they're able to also boot and run the l= oaders
and OS images that I'm testing.

I'm not sure how much testing the CLANGDWARF toolspec is getting the= se days,
but maybe it should get a little more. Is there any = chance these issues
could be addressed?

-Bill


-- 
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D
-Bill P= aul            (510)= 749-2329 | VxWorks Software Architect,
         &nbs= p;      wpaul@windriver.com | Master of Unix-Fu - Wind River Syste= ms
=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  "I put a dollar in a c= hange machine. Nothing changed." - George Carlin
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D






--Apple-Mail=_A7C6FD16-BB5E-4B70-994A-BC850EAAEA24--