From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from ma1-aaemail-dr-lapp01.apple.com (ma1-aaemail-dr-lapp01.apple.com [17.171.2.60]) by mx.groups.io with SMTP id smtpd.web08.1378.1628620606670367217 for ; Tue, 10 Aug 2021 11:36:47 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@apple.com header.s=20180706 header.b=p6PLMZ1X; spf=pass (domain: apple.com, ip: 17.171.2.60, mailfrom: afish@apple.com) Received: from pps.filterd (ma1-aaemail-dr-lapp01.apple.com [127.0.0.1]) by ma1-aaemail-dr-lapp01.apple.com (8.16.0.42/8.16.0.42) with SMTP id 17AHWXY5006829; Tue, 10 Aug 2021 10:36:37 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apple.com; h=from : message-id : content-type : mime-version : subject : date : in-reply-to : cc : to : references; s=20180706; bh=6IWOAl7znC1V+MLjQYpNjpm4b83ksZsUsvyP7g25WlU=; b=p6PLMZ1X6ae0vsCIL/1K9b1t5S/A1rEzk1iwMt8xCkvVaG5MkAjliPok9I4ug3gtKDJT appuPIXILlCZu7b0pWghx8gOHcpRswM7TdgzmJSxaNb7aUECe3WK3RO6rTeP6+12MDqi x2AlmjOvL1XKaP81tN0V1UXM6s/JUaQaF0j9BlGmmuIEXjKXYHwX8hAW5DWvO8V1Erz+ jSXEn+9hloCmcRDp6JAU8oge64N4s1bFJtfee7wn0pZMEAhO8zDBWoWA2j2OW+1r+nLZ 9Jc3aNPZKfXhHx9QWDr9eCl3CYfBpkVh9eIemJGgSqCgQBX1mNrc+HorW9WdHAVOAZnG 8w== Received: from rn-mailsvcp-mta-lapp01.rno.apple.com (rn-mailsvcp-mta-lapp01.rno.apple.com [10.225.203.149]) by ma1-aaemail-dr-lapp01.apple.com with ESMTP id 3a9ru41mbq-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Tue, 10 Aug 2021 10:36:37 -0700 Received: from rn-mailsvcp-mmp-lapp01.rno.apple.com (rn-mailsvcp-mmp-lapp01.rno.apple.com [17.179.253.14]) by rn-mailsvcp-mta-lapp01.rno.apple.com (Oracle Communications Messaging Server 8.1.0.9.20210415 64bit (built Apr 15 2021)) with ESMTPS id <0QXM00QNDWX0B780@rn-mailsvcp-mta-lapp01.rno.apple.com>; Tue, 10 Aug 2021 10:36:36 -0700 (PDT) Received: from process_milters-daemon.rn-mailsvcp-mmp-lapp01.rno.apple.com by rn-mailsvcp-mmp-lapp01.rno.apple.com (Oracle Communications Messaging Server 8.1.0.9.20210415 64bit (built Apr 15 2021)) id <0QXM00C00WWADJ00@rn-mailsvcp-mmp-lapp01.rno.apple.com>; Tue, 10 Aug 2021 10:36:36 -0700 (PDT) X-Va-A: X-Va-T-CD: cb83049425a79c8a5fb9f1dafa0fda92 X-Va-E-CD: 8b34a1551387158475b014d243cdc9ad X-Va-R-CD: 6def9d696c04dce24c572ed8b427a545 X-Va-CD: 0 X-Va-ID: 7b99ef04-7f64-4742-80cc-17ba7cf8ab32 X-V-A: X-V-T-CD: cb83049425a79c8a5fb9f1dafa0fda92 X-V-E-CD: 8b34a1551387158475b014d243cdc9ad X-V-R-CD: 6def9d696c04dce24c572ed8b427a545 X-V-CD: 0 X-V-ID: 5ed36a94-f932-4212-a96e-57b817a4ba3c X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.790 definitions=2021-08-10_08:2021-08-10,2021-08-10 signatures=0 Received: from [17.235.18.207] (unknown [17.235.18.207]) by rn-mailsvcp-mmp-lapp01.rno.apple.com (Oracle Communications Messaging Server 8.1.0.9.20210415 64bit (built Apr 15 2021)) with ESMTPSA id <0QXM00PELWWZKD00@rn-mailsvcp-mmp-lapp01.rno.apple.com>; Tue, 10 Aug 2021 10:36:36 -0700 (PDT) From: "Andrew Fish" Message-id: MIME-version: 1.0 (Mac OS X Mail 14.0 \(3654.20.0.2.1\)) Subject: Re: [edk2-devel] [PATCH v2 1/2] MdePkg/BaseLib: Fix unaligned API prototypes Date: Tue, 10 Aug 2021 10:36:34 -0700 In-reply-to: <54883a88-199b-2ba7-3d18-db02636358c7@posteo.de> Cc: devel@edk2.groups.io, Mike Kinney , Liming Gao , "Liu, Zhiguang" , Vitaly Cheptsov To: =?utf-8?Q?Marvin_H=C3=A4user?= References: <54883a88-199b-2ba7-3d18-db02636358c7@posteo.de> X-Mailer: Apple Mail (2.3654.20.0.2.1) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.790 definitions=2021-08-10_08:2021-08-10,2021-08-10 signatures=0 Content-type: multipart/alternative; boundary="Apple-Mail=_F822D05F-0017-4037-B959-C9F9BE09A281" --Apple-Mail=_F822D05F-0017-4037-B959-C9F9BE09A281 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Aug 10, 2021, at 1:53 AM, Marvin H=C3=A4user wrot= e: >=20 > On 09/08/2021 23:32, Andrew Fish via groups.io wrote: >>=20 >>=20 >>> On Aug 9, 2021, at 9:15 AM, Michael D Kinney >> wrote: >>>=20 >>> Hi Marvin, >>>=20 >>> Can you provide an example of which C compiler is flagging this as >>> an error and what error message is generated. >>>=20 >>> Please enter a BZ with this background information and add link to the >>> BZ in the commit message. >>>=20 >>> This is a change to the BaseLib class, so we need to make sure there >>> are no impacts to any existing code. I looks like a safe change >>> because changing from a pointer to a fixed size type to VOID * >>> should be compatible. Please add that analysis to the background >>> in the BZ as well. >>>=20 >>=20 >> MIke, >>=20 >> I want to say we had a discussion about this years ago? I don=E2=80=99t = remember the outcome. >>=20 >> Dereferencing a misaligned pointer is UB (Undefined Behavior) in C [1], = but historically x86 compilers have let it slide. >>=20 >> I think the situation we are in is the BaseLib functions don=E2=80=99t c= ontain UB, but it is UB for the caller to use the returned pointer directly= . >=20 > They do contain UB, inherently from the combination of their prototype an= d their usage. > Please refer to the new BZ added for V2: https://bugzilla.tianocore.org/s= how_bug.cgi?id=3D3542 >=20 I think we are saying the same thing. My point is it is possible to use the= library API correctly, but likely no one does. Changing the API to a VOID = also does not fix every issue, actually it is a drop in to existing code so= it does not really force any fixes... > I could only speculate why UBsan does not check cast safety... > To be fair, I don't know a real-world platform that has issues with this = UB, but the fix is simple enough in my opinion. >=20 Cast is compile time UB, not runtime. UBSan is doing runtime checks. You ca= n catch compile time UB with warnings. I've have had way too many talks wit= h the clang folks about UB and firmware :). > Actually, enabling "-Wcast-align" some day would be great either way. :) >=20 In my example this gets you past the -Wcast-align. We have the same type of= casts for the size of pointers and casting through UINTN.=20 UINT16 *pointer =3D (UINT16 *)(void *)(buffer+1); Actually I=E2=80=99m starting to remember why we chose not to fix this befo= re. It does not really help=E2=80=A6. Notice if we change the API to use `V= OID *` vs. `UINT16 *` nothing really changed [1] ? It is still up to the c= aller to do the right thing. The real issue is the functions are not really= useful given strict UB in C=E2=80=A6. A better solution is to just tell the compiler this pointer is not aligned,= and at that point you DON'T need the lib functions=E2=80=A6. This code passes -Wcast-align and -fsanitize=3Dundefined runtime checks: =20 typedef UINT16 UUINT16 __attribute__ ((aligned (1))); int main() { UINT8 *buffer =3D malloc(64); UUINT16 *pointer =3D (UUINT16 *)(buffer+1); =09 *pointer =3D 42; return *pointer; } So a better solution maybe to defined unaligned basic types? I=E2=80=99m no= t sure if __declspec(align(1)) does the right thing for VC++, __attribute__= ((aligned (1))); does the right thing for GCC and clang. Assuming this wor= ks we could defined unaligned version of our basic types, and over time obs= olete the current alignment lib functions. We could start with a warning co= mment to use the unaligned types vs. current library functions.=20 I=E2=80=99m thinking for the types in ProcessorBind.h[2] and Base.h[3] we c= ould have a byte aligned versions. For example given UINT16 we add UUINT16 = to Base.h. I guess we could also look into a #define abstraction for ` __a= ttribute__ ((aligned (1)))` so new could could use that in a portable way? Just to be clear if we define UUINT16 then the compiler will do the the wor= k of WriteUnaligned16() in the code generation, if it is needed by the CPU = arch. Given that it is much harder for the coder to =E2=80=9Cmess it up=E2= =80=9D.=20 Actually I changed my mind I think we will want to keep the Unaligned libra= ry functions, but update them to use the unaligned pointers. The reason we = need the function is the compiler is generating code that follow the rules = of the CPU, so we need the library functions to talk to hardware devices th= at have stricter alignment rules than the CPU. For example on x86 UUINT16 w= ill end up being a word operation in assembler. This is the reason the curr= ent lib functions use volatile. Sorry figuring this out as I type. So looks= like we need to add unaligned types and update the libs to use those types= ? For memory operations you can use the new unaligned types, and for hardwa= re access use the lib functions.=20 [1] ~/work/Compiler>cat ub.c #include #define EFIAPI #define IN #define OUT #define VOID void typedef unsigned char UINT8; typedef unsigned short UINT16; UINT16 EFIAPI WriteUnaligned16 ( OUT VOID *Buffer, IN UINT16 Value ) { // ASSERT (Buffer !=3D NULL); ((volatile UINT8*)Buffer)[0] =3D (UINT8)Value; ((volatile UINT8*)Buffer)[1] =3D (UINT8)(Value >> 8); return Value; } int main() { UINT8 *buffer =3D malloc(64); UINT16 *pointer =3D (UINT16 *)(void *)(buffer+1); =09 WriteUnaligned16 (pointer, 42); =09 // *pointer =3D 42; // Error: misaligned integer pointer assignment return *pointer; } ~/work/Compiler>clang -fsanitize=3Dundefined -Wcast-align ub.c ~/work/Compiler>./a.out ub.c:35:9: runtime error: load of misaligned address 0x7fdd9d405aa1 for typ= e 'UINT16' (aka 'unsigned short'), which requires 2 byte alignment 0x7fdd9d405aa1: note: pointer points here 00 00 00 64 2a 00 79 6d 28 52 54 4c 44 5f 44 45 46 41 55 4c 54 2c 20 73= 77 69 66 74 5f 64 65 6d ^=20 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ub.c:35:9 in=20 ~/work/Compiler> [2] https://github.com/tianocore/edk2/blob/master/MdePkg/Include/X64/Proces= sorBind.h#L127=20 [3] https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Base.h Thanks, Andrew Fish > Best regards, > Marvin >=20 >>=20 >> Here is a simple example with clang UndefinedBehaviorSanitizer (UBSan) . >>=20 >> ~/work/Compiler>cat ub.c >> #include >>=20 >> #define EFIAPI >> #define IN >> #define OUT >>=20 >> typedef unsigned char UINT8; >> typedef unsigned short UINT16; >>=20 >> UINT16 >> EFIAPI >> WriteUnaligned16 ( >> OUT UINT16 *Buffer, >> IN UINT16 Value >> ) >> { >> // ASSERT (Buffer !=3D NULL); >>=20 >> ((volatile UINT8*)Buffer)[0] =3D (UINT8)Value; >> ((volatile UINT8*)Buffer)[1] =3D (UINT8)(Value >> 8); >>=20 >> return Value; >> } >>=20 >>=20 >> int main() >> { >> UINT8 *buffer =3D malloc(64); >> UINT16 *pointer =3D (UINT16 *)(buffer + 1); >>=20 >>=20 >> WriteUnaligned16 (pointer, 42); >>=20 >>=20 >> // *pointer =3D 42; // Error: misaligned integer pointer assignment >> return *pointer; >> } >> ~/work/Compiler>clang -fsanitize=3Dundefined ub.c >> ~/work/Compiler>./a.out >> *ub.c:34:9:**runtime error: **load of misaligned address 0x7feac6405aa1 = for type 'UINT16' (aka 'unsigned short'), which requires 2 byte alignment* >> *0x7feac6405aa1: note: *pointer points here >> 00 00 00 64 2a 00 79 6d 28 52 54 4c 44 5f 44 45 46 41 55 4c 54 2c 20= 73 77 69 66 74 5f 64 65 6d >> * ^ * >> SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ub.c:34:9 in >>=20 >> FYI line 39 is `return *pointer`and 42 is 0x2A. So reading an writing to= *pointer is UB. >>=20 >>=20 >> As you can see in [1] the general advice is to take code that looks like= : >> int8_t *buffer =3D malloc(64);int32_t *pointer =3D (int32_t *)(buffer + = 1);*pointer =3D 42; // Error: misaligned integer pointer assignment >> And replace it with; >> int8_t *buffer =3D malloc(64);int32_t value =3D 42;memcpy(buffer + 1, &v= alue, sizeof(int32_t)); // Correct >>=20 >> But in these cases the result is in a byte aligned buffer=E2=80=A6. >>=20 >> [1] https://developer.apple.com/documentation/xcode/misaligned-pointer <= https://developer.apple.com/documentation/xcode/misaligned-pointer> > >>=20 >> Thanks, >>=20 >> Andrew Fish >>=20 >>> Thanks, >>>=20 >>> Mike >>>=20 >>>=20 >>>> -----Original Message----- >>>> From: Marvin H=C3=A4user >> >>>> Sent: Monday, August 9, 2021 2:51 AM >>>> To:devel@edk2.groups.io > >>>> Cc: Kinney, Michael D >>; Liming Gao >>; Liu, Zhiguang >>>> >>; Vitaly Cheptsov >> >>>> Subject: [PATCH v2 1/2] MdePkg/BaseLib: Fix unaligned API prototypes >>>>=20 >>>> C prohibits not only dereferencing but also casting to unaligned >>>> pointers. Thus, the current set of unaligned APIs cannot be called >>>> safely. Update their prototypes to take VOID * pointers, which must >>>> be able to represent any valid pointer. >>>>=20 >>>> Cc: Michael D Kinney >> >>>> Cc: Liming Gao >> >>>> Cc: Zhiguang Liu >> >>>> Cc: Vitaly Cheptsov >> >>>> Signed-off-by: Marvin H=C3=A4user >> >>>> --- >>>> MdePkg/Library/BaseLib/Arm/Unaligned.c | 14 ++++----- >>>> MdePkg/Library/BaseLib/Unaligned.c | 32 ++++++++++---------- >>>> MdePkg/Include/Library/BaseLib.h | 16 +++++----- >>>> 3 files changed, 31 insertions(+), 31 deletions(-) >>>>=20 >>>> diff --git a/MdePkg/Library/BaseLib/Arm/Unaligned.c b/MdePkg/Library/B= aseLib/Arm/Unaligned.c >>>> index e9934e7003cb..57f19fc44e0b 100644 >>>> --- a/MdePkg/Library/BaseLib/Arm/Unaligned.c >>>> +++ b/MdePkg/Library/BaseLib/Arm/Unaligned.c >>>> @@ -59,7 +59,7 @@ ReadUnaligned16 ( >>>> UINT16 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned16 ( >>>>=20 >>>> - OUT UINT16 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT16 Value >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> @@ -87,7 +87,7 @@ WriteUnaligned16 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned24 ( >>>>=20 >>>> - IN CONST UINT32 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>> @@ -116,7 +116,7 @@ ReadUnaligned24 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned24 ( >>>>=20 >>>> - OUT UINT32 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT32 Value >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> @@ -143,7 +143,7 @@ WriteUnaligned24 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned32 ( >>>>=20 >>>> - IN CONST UINT32 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> UINT16 LowerBytes; >>>>=20 >>>> @@ -175,7 +175,7 @@ ReadUnaligned32 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned32 ( >>>>=20 >>>> - OUT UINT32 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT32 Value >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> @@ -202,7 +202,7 @@ WriteUnaligned32 ( >>>> UINT64 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned64 ( >>>>=20 >>>> - IN CONST UINT64 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> UINT32 LowerBytes; >>>>=20 >>>> @@ -234,7 +234,7 @@ ReadUnaligned64 ( >>>> UINT64 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned64 ( >>>>=20 >>>> - OUT UINT64 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT64 Value >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> diff --git a/MdePkg/Library/BaseLib/Unaligned.c b/MdePkg/Library/BaseL= ib/Unaligned.c >>>> index a419cb85e53c..3041adcde606 100644 >>>> --- a/MdePkg/Library/BaseLib/Unaligned.c >>>> +++ b/MdePkg/Library/BaseLib/Unaligned.c >>>> @@ -26,12 +26,12 @@ >>>> UINT16 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned16 ( >>>>=20 >>>> - IN CONST UINT16 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>>=20 >>>>=20 >>>> - return *Buffer; >>>>=20 >>>> + return *(CONST UINT16 *) Buffer; >>>>=20 >>>> } >>>>=20 >>>>=20 >>>>=20 >>>> /** >>>>=20 >>>> @@ -52,13 +52,13 @@ ReadUnaligned16 ( >>>> UINT16 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned16 ( >>>>=20 >>>> - OUT UINT16 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT16 Value >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>>=20 >>>>=20 >>>> - return *Buffer =3D Value; >>>>=20 >>>> + return *(UINT16 *) Buffer =3D Value; >>>>=20 >>>> } >>>>=20 >>>>=20 >>>>=20 >>>> /** >>>>=20 >>>> @@ -77,12 +77,12 @@ WriteUnaligned16 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned24 ( >>>>=20 >>>> - IN CONST UINT32 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>>=20 >>>>=20 >>>> - return *Buffer & 0xffffff; >>>>=20 >>>> + return *(CONST UINT32 *) Buffer & 0xffffff; >>>>=20 >>>> } >>>>=20 >>>>=20 >>>>=20 >>>> /** >>>>=20 >>>> @@ -103,13 +103,13 @@ ReadUnaligned24 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned24 ( >>>>=20 >>>> - OUT UINT32 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT32 Value >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>>=20 >>>>=20 >>>> - *Buffer =3D BitFieldWrite32 (*Buffer, 0, 23, Value); >>>>=20 >>>> + *(UINT32 *) Buffer =3D BitFieldWrite32 (*(CONST UINT32 *) Buffer, 0= , 23, Value); >>>>=20 >>>> return Value; >>>>=20 >>>> } >>>>=20 >>>>=20 >>>>=20 >>>> @@ -129,12 +129,12 @@ WriteUnaligned24 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned32 ( >>>>=20 >>>> - IN CONST UINT32 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>>=20 >>>>=20 >>>> - return *Buffer; >>>>=20 >>>> + return *(CONST UINT32 *) Buffer; >>>>=20 >>>> } >>>>=20 >>>>=20 >>>>=20 >>>> /** >>>>=20 >>>> @@ -155,13 +155,13 @@ ReadUnaligned32 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned32 ( >>>>=20 >>>> - OUT UINT32 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT32 Value >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>>=20 >>>>=20 >>>> - return *Buffer =3D Value; >>>>=20 >>>> + return *(UINT32 *) Buffer =3D Value; >>>>=20 >>>> } >>>>=20 >>>>=20 >>>>=20 >>>> /** >>>>=20 >>>> @@ -180,12 +180,12 @@ WriteUnaligned32 ( >>>> UINT64 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned64 ( >>>>=20 >>>> - IN CONST UINT64 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>>=20 >>>>=20 >>>> - return *Buffer; >>>>=20 >>>> + return *(CONST UINT64 *) Buffer; >>>>=20 >>>> } >>>>=20 >>>>=20 >>>>=20 >>>> /** >>>>=20 >>>> @@ -206,11 +206,11 @@ ReadUnaligned64 ( >>>> UINT64 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned64 ( >>>>=20 >>>> - OUT UINT64 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT64 Value >>>>=20 >>>> ) >>>>=20 >>>> { >>>>=20 >>>> ASSERT (Buffer !=3D NULL); >>>>=20 >>>>=20 >>>>=20 >>>> - return *Buffer =3D Value; >>>>=20 >>>> + return *(UINT64 *) Buffer =3D Value; >>>>=20 >>>> } >>>>=20 >>>> diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library= /BaseLib.h >>>> index 2452c1d92e51..4d30f0539c6b 100644 >>>> --- a/MdePkg/Include/Library/BaseLib.h >>>> +++ b/MdePkg/Include/Library/BaseLib.h >>>> @@ -3420,7 +3420,7 @@ DivS64x64Remainder ( >>>> UINT16 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned16 ( >>>>=20 >>>> - IN CONST UINT16 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ); >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -3442,7 +3442,7 @@ ReadUnaligned16 ( >>>> UINT16 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned16 ( >>>>=20 >>>> - OUT UINT16 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT16 Value >>>>=20 >>>> ); >>>>=20 >>>>=20 >>>>=20 >>>> @@ -3463,7 +3463,7 @@ WriteUnaligned16 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned24 ( >>>>=20 >>>> - IN CONST UINT32 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ); >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -3485,7 +3485,7 @@ ReadUnaligned24 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned24 ( >>>>=20 >>>> - OUT UINT32 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT32 Value >>>>=20 >>>> ); >>>>=20 >>>>=20 >>>>=20 >>>> @@ -3506,7 +3506,7 @@ WriteUnaligned24 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned32 ( >>>>=20 >>>> - IN CONST UINT32 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ); >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -3528,7 +3528,7 @@ ReadUnaligned32 ( >>>> UINT32 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned32 ( >>>>=20 >>>> - OUT UINT32 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT32 Value >>>>=20 >>>> ); >>>>=20 >>>>=20 >>>>=20 >>>> @@ -3549,7 +3549,7 @@ WriteUnaligned32 ( >>>> UINT64 >>>>=20 >>>> EFIAPI >>>>=20 >>>> ReadUnaligned64 ( >>>>=20 >>>> - IN CONST UINT64 *Buffer >>>>=20 >>>> + IN CONST VOID *Buffer >>>>=20 >>>> ); >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -3571,7 +3571,7 @@ ReadUnaligned64 ( >>>> UINT64 >>>>=20 >>>> EFIAPI >>>>=20 >>>> WriteUnaligned64 ( >>>>=20 >>>> - OUT UINT64 *Buffer, >>>>=20 >>>> + OUT VOID *Buffer, >>>>=20 >>>> IN UINT64 Value >>>>=20 >>>> ); >>>>=20 >>>>=20 >>>>=20 >>>> -- >>>> 2.31.1 >>>=20 >>>=20 >>>=20 >>=20 >>=20 --Apple-Mail=_F822D05F-0017-4037-B959-C9F9BE09A281 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8

On Aug 10, 20= 21, at 1:53 AM, Marvin H=C3=A4user <mhaeuser@posteo.de> wrote:

= On 09/08/2021 23:32, Andrew Fish via&= nbsp;groups.io wrote:


On Aug 9, 2021, at 9:15 AM, Michael D Kinney <michael.d.kinney@intel.com <mailto:michael.d.kinney@intel.com>> = wrote:

Hi Marvin,

Can you provide an example of which C compiler is flagging this as
an error and what error message is generated.

Please enter a BZ with this background information and add link to t= he
BZ in the commit message.

Thi= s is a change to the BaseLib class, so we need to make sure there
are no impacts to any existing code.  I looks like a safe change=
because changing from a pointer to a fixed size type to VOID= *
should be compatible.  Please add that analysis to th= e background
in the BZ as well.

=

MIke,

I want to sa= y we had a discussion about this years ago? I don=E2=80=99t remember the ou= tcome.

Dereferencing a misaligned pointer is U= B (Undefined Behavior) in C [1], but historically x86 compilers have let it= slide.

I think the situation we are in is the= BaseLib functions don=E2=80=99t contain UB, but it is UB for the caller to= use the returned pointer directly.

They do contain UB, inherently from the c= ombination of their prototype and their usage.
Please refer to the new BZ added for V2: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3542

=

I think we are saying the same = thing. My point is it is possible to use the library API correctly, but lik= ely no one does. Changing the API to a VOID also does not fix every issue, = actually it is a drop in to existing code so it does not really force any f= ixes...

I could only speculate why UBsan does not check cast safety...=
To be fair, I don't kn= ow a real-world platform that has issues with this UB, but the fix is simpl= e enough in my opinion.


Cast is compile time UB, not runtime. UBSan is doing runtime checks= . You can catch compile time UB with warnings. I've have had way too many t= alks with the clang folks about UB and firmware :).

Actually, enabling= "-Wcast-align" some day would be great either way. :)


In my example this gets you past the=  -Wcas= t-align. We have the same type of casts for the size of pointers and= casting through UINTN. 
UINT16 *pointer =3D (UINT16 *)(void *)(b= uffer+1);

Actuall= y I=E2=80=99m starting to remember why we chose not to fix this before. It = does not really help=E2=80=A6. Notice if we change the API to use `VOID *` = vs. `UINT16 *` nothing really changed [1] ?  It is still up to the cal= ler to do the right thing. The real issue is the functions are not really u= seful given strict UB in C=E2=80=A6.

A better solution is to just tell the compiler this poi= nter is not aligned, and at that point you DON'T need the lib functions=E2= =80=A6.

This code= passes -Wcast-align and -fsanitize=3Dundefined runtime checks:
 
typedef UINT16 UUINT16= __attribute__ ((aligned (1)));

<= /div>
int main()
{
= UINT8 *buffer =3D malloc(64);
  UUINT16 *pointer =3D= (UUINT16 *)(buffer+1);
*pointer =3D 42;
= return *pointer;
}

So a better solution maybe to defined unaligne= d basic types? I=E2=80=99m not sure if __declspec(align(1)) does the r= ight thing for VC++, __attribute__ ((aligned (1))); does the right thing fo= r GCC and clang. Assuming this works we could defined unaligned version of = our basic types, and over time obsolete the current alignment lib functions= . We could start with a warning comment to use the unaligned types vs. curr= ent library functions. 

I=E2=80=99m thinking for the types in ProcessorBind.h[2] and Ba= se.h[3] we could have a byte aligned versions. For example given UINT16 we = add UUINT16 to Base.h. I guess we could also  look into a #define abst= raction for ` __attribute__ ((aligned (1)))` so new could could use that in= a portable way?

= Just to be clear if we define UUINT16 then the compiler will do the the wor= k of WriteUnaligned16() in the code generation, if it is needed by the= CPU arch. Given that it is much harder for the coder to =E2=80=9Cmess it u= p=E2=80=9D. 

Actually I changed my mind I think we will want to keep the Unaligned libr= ary functions, but update them to use the unaligned pointers. The reason we= need the function is the compiler is generating code that follow the rules= of the CPU, so we need the library functions to talk to hardware devices t= hat have stricter alignment rules than the CPU. For example on x86 UUINT16 = will end up being a word operation in assembler. This is the reason the cur= rent lib functions use volatile. Sorry figuring this out as I type. So look= s like we need to add unaligned types and update the libs to use those type= s? For memory operations you can use the new unaligned types, and for hardw= are access use the lib functions. 

[1] ~/work/Compiler>cat ub.= c
<= span style=3D"font-variant-ligatures: no-common-ligatures" class=3D"">#incl= ude <stdlib.h>

#define EFIAPI
#define IN
#define OU= T
#define VOID void
<= br class=3D"">
typedef unsigne= d char UIN= T8;
typedef unsigned sh= ort UINT16= ;

UINT16
EFIAPI
WriteUnaligned16 (
  OUT VOID        &n= bsp;             *Buffer,
  IN  UINT16     =               Value
  )
{
&n= bsp; // ASSERT (Buffer !=3D NULL);

  ((volatile UINT8*)Buffer)[0] =3D (UINT8)Value= ;
  ((volatile UIN= T8*)Buffer)[1] =3D (UINT8)(Value >> 8);

  return Value;
}


int main()
{
UINT8 *b= uffer =3D malloc(64);
<= span class=3D"Apple-tab-span" style=3D"white-space:pre"> UINT16 *poi= nter =3D (UINT16 *)(void *)(buffer+1);


WriteUnaligned16 (pointer, 42);

// *pointer =3D 42; // Er= ror: misaligned integer pointer assignment
return *pointer;
}
~/work/Compiler>clang -fsanitize=3Dundefined -Wca= st-align  ub.c
~/work/Compiler>./a.out
ub.c:35:9: runtime error: load of misaligned address 0x7fdd9d405aa1 for type 'UINT16' = (aka 'unsigned short'), which requires 2 byte alignment
0x7fdd9d405aa1: note: pointer points here
&= nbsp;00 00 00  64 2a 00 79 6d 28 52 54  4c 44 5f 44 45 46 41 55&n= bsp; 4c 54 2c 20 73 77 69 66  74 5f 64 65 6d
  &n= bsp;           ^ 
SUMMARY: UndefinedBehaviorSanitizer: undefine= d-behavior ub.c:35:9 in 
~/work/Compiler>


[2] https://github.com/tianocore/edk2/blob/master/MdePkg/Include/X64/Processor= Bind.h#L127 

Thanks,

Andrew Fish

Best regards,
M= arvin


Here is a simple example = with clang UndefinedBehaviorSanitizer (UBSan) .

~/work/Compiler>cat ub.c
#include <stdlib.h><= br class=3D"">
#define EFIAPI
#define IN
#define OUT

typedef unsigned char UINT= 8;
typedef unsigned short UINT16;

UINT16
EFIAPI
WriteUnaligned16 (
  OUT UINT16                =     *Buffer,
  IN  UINT16    &n= bsp;               Value
&= nbsp; )
{
  // ASSERT (Buffer !=3D NULL);<= br class=3D"">
  ((volatile UINT8*)Buffer)[0] =3D (UINT8= )Value;
  ((volatile UINT8*)Buffer)[1] =3D (UINT8)(Value= >> 8);

  return Value;
}


int main()
{=
UINT8 *buffer =3D malloc(64);
UINT16 *pointer = =3D (UINT16 *)(buffer + 1);


Wri= teUnaligned16 (pointer, 42);


//= *pointer =3D 42; // Error: misaligned integer pointer assignment
return *pointer;
}
~/work/Compiler>cla= ng -fsanitize=3Dundefined  ub.c
~/work/Compiler>./a.o= ut
*ub.c:34:9:**runtime error: **load of misaligned address 0= x7feac6405aa1 for type 'UINT16' (aka 'unsigned short'), which requires 2 by= te alignment*
*0x7feac6405aa1: note: *pointer points here
 00 00 00  64 2a 00 79 6d 28 52 54  4c 44 5f 44 4= 5 46 41 55  4c 54 2c 20 73 77 69 66  74 5f 64 65 6d
*              ^ *
SUMMAR= Y: UndefinedBehaviorSanitizer: undefined-behavior ub.c:34:9 in

FYI line 39 is `return *pointer`and 42 is 0x2A. So reading= an writing to *pointer is UB.


= As you can see in [1] the general advice is to take code that looks like:int8_t *buffer =3D malloc(64);int32_t *pointer =3D (int32_t *)= (buffer + 1);*pointer =3D 42; // Error: misaligned integer pointer assignme= nt
And replace it with;
int8_t *buffer =3D mall= oc(64);int32_t value =3D 42;memcpy(buffer + 1, &value, sizeof(int32_t))= ; // Correct

But in these cases the result is = in a byte aligned buffer=E2=80=A6.

[1] https://developer= .apple.com/documentation/xcode/misaligned-pointer <https://developer.apple.com= /documentation/xcode/misaligned-pointer>

Thanks,

Andrew Fish

Thanks,

Mike


-----Original Message-----
From: Marvin H=C3= =A4user <mhaeuser@poste= o.de <mailto:mhaeuser@posteo.de>><= br class=3D"">Sent: Monday, August 9, 2021 2:51 AM
To:devel@edk2.groups.io <mailto:devel@edk2.groups.io>
C= c: Kinney, Michael D <michael.d.kinney@intel.com=  <m= ailto:michael.d.kinney@intel.com>>; Liming Gao <gaoliming@byosoft.com.cn <mailto:gaoliming@byosoft.com.cn>>; L= iu, Zhiguang
<zhiguang.liu@intel.com&n= bsp;<mailto:= zhiguang.liu@intel.com>>; Vitaly Cheptsov <vit9696@protonmail.com <mailto:vit9696@protonmail.com>>
S= ubject: [PATCH v2 1/2] MdePkg/BaseLib: Fix unaligned API prototypes

C prohibits not only dereferencing but also casting t= o unaligned
pointers. Thus, the current set of unaligned APIs= cannot be called
safely. Update their prototypes to take VOI= D * pointers, which must
be able to represent any valid point= er.

Cc: Michael D Kinney <michael.d.kinney@intel.com <mailto:michael.d.kinney@intel.com>&g= t;
Cc: Liming Gao <gaoliming@byosoft.com.cn <mailto:gaoliming@byosoft.com.cn>>
Cc: Zhiguan= g Liu <zhiguang.liu= @intel.com <mailto:zhiguang.liu@intel.co= m>>
Cc: Vitaly Cheptsov <vit9696@protonmail.com <mailto:vit9696@protonmail.com>>
Signe= d-off-by: Marvin H=C3=A4user <mhaeuser@posteo.de <mailto:mhaeuser@p= osteo.de>>
---
MdePkg/Library/BaseLib= /Arm/Unaligned.c | 14 ++++-----
MdePkg/Library/BaseLib/Unalig= ned.c     | 32 ++++++++++----------
MdePk= g/Include/Library/BaseLib.h       | 16 +++++-= ----
3 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/MdePkg/Library/BaseLib/Arm/Unaligned.c= b/MdePkg/Library/BaseLib/Arm/Unaligned.c
index e9934e7003cb.= .57f19fc44e0b 100644
--- a/MdePkg/Library/BaseLib/Arm/Unalign= ed.c
+++ b/MdePkg/Library/BaseLib/Arm/Unaligned.c
@@ -59,7 +59,7 @@ ReadUnaligned16 (
UINT16
<= br class=3D"">EFIAPI

WriteUnaligned16 (

-  OUT UINT16      &nb= sp;            =  *Buffer,

+  OUT VOID   &n= bsp;            = ;      *Buffer,

=   IN  UINT16         = ;           Value
  )

{

@@ -87,7 +87,7 @@ WriteUnaligned16 (
UINT32

EFIAPI

R= eadUnaligned24 (

-  IN CONST UINT32  = ;            *B= uffer

+  IN CONST VOID    =             *Bu= ffer

  )

{

  ASSERT (Buffer !=3D NULL);

@@ -116,7 +116,7 @@ ReadUnaligned24 (
UINT32

EFIAPI

= WriteUnaligned24 (

-  OUT UINT32  &n= bsp;            = ;     *Buffer,

+ &nbs= p;OUT VOID           &nbs= p;          *Buffer,

  IN  UINT32    &nbs= p;            &= nbsp;  Value

  )

{

@@ -143,7 +143,7 @@ Wri= teUnaligned24 (
UINT32

EFIAPI
ReadUnaligned32 (

-=  IN CONST UINT32         &nbs= p;    *Buffer

+  IN C= ONST VOID            = ;    *Buffer

  )=

{

  UI= NT16  LowerBytes;

@@ -175,7 +175,7 @@ Rea= dUnaligned32 (
UINT32

EFIAPI

WriteUnaligned32 (

-=  OUT UINT32          &nb= sp;         *Buffer,

+  OUT VOID       &= nbsp;           &nbs= p;  *Buffer,

  IN  UI= NT32            &nbs= p;       Value

  )

{

@@ -202,7 +202,7 @@ WriteUnaligned32 (
UINT64

EFIAPI

ReadUnaligned64 (<= br class=3D"">
-  IN CONST UINT64    &nbs= p;         *Buffer

+  IN CONST VOID       = ;         *Buffer

  )

{

  UINT32  LowerBytes;

@@ -234,7 +234,7 @@ ReadUnaligned64 (
UINT64

EFIAPI

WriteUnaligned64 (=

-  OUT UINT64     &n= bsp;            = ;  *Buffer,

+  OUT VOID  &= nbsp;           &nbs= p;       *Buffer,

  IN  UINT64       &nbs= p;            V= alue

  )

{

diff --git a/MdePkg/Library/BaseLib/Unalig= ned.c b/MdePkg/Library/BaseLib/Unaligned.c
index a419cb85e53c= ..3041adcde606 100644
--- a/MdePkg/Library/BaseLib/Unaligned.= c
+++ b/MdePkg/Library/BaseLib/Unaligned.c
@@ -= 26,12 +26,12 @@
UINT16

EFIAPI
ReadUnaligned16 (

-=  IN CONST UINT16         &nbs= p;    *Buffer

+  IN C= ONST VOID            = ;    *Buffer

  )=

{

  AS= SERT (Buffer !=3D NULL);



-  return *Buffer;

+  retur= n *(CONST UINT16 *) Buffer;

}


/**

@@ -52,13 +52,13 @@ ReadUnaligned16 (
UINT16
<= br class=3D"">EFIAPI

WriteUnaligned16 (

-  OUT UINT16      &nb= sp;            =  *Buffer,

+  OUT VOID   &n= bsp;            = ;      *Buffer,

=   IN  UINT16         = ;           Value
  )

{

  ASSERT (Buffer !=3D NULL);



-  return *Buffer = =3D Value;

+  return *(UINT16 *) Buffer = =3D Value;

}



/**

@@ -77,12 +77,12= @@ WriteUnaligned16 (
UINT32

EF= IAPI

ReadUnaligned24 (

-  IN CONST UINT32        &nb= sp;     *Buffer

+ &nb= sp;IN CONST VOID          &nbs= p;     *Buffer

 =  )

{

 &= nbsp;ASSERT (Buffer !=3D NULL);



-  return *Buffer & 0xffffff;

+  return *(CONST UINT32 *) Buffer & 0xffffff;

}



/**

@@ -103,13 +103,13 @@ ReadUnaligned= 24 (
UINT32

EFIAPI

WriteUnaligned24 (

-  OUT= UINT32            &= nbsp;       *Buffer,

+  OUT VOID         =             &nb= sp;*Buffer,

  IN  UINT32  =             &nb= sp;     Value

 &= nbsp;)

{

 &n= bsp;ASSERT (Buffer !=3D NULL);


=
-  *Buffer =3D BitFieldWrite32 (*Buffer, 0, 23, Value);=

+  *(UINT32 *) Buffer =3D BitFieldWrite3= 2 (*(CONST UINT32 *) Buffer, 0, 23, Value);

&n= bsp; return Value;

}



@@ -129,12 +129,12 @@ WriteUnaligned= 24 (
UINT32

EFIAPI

ReadUnaligned32 (

-  IN C= ONST UINT32           &nb= sp;  *Buffer

+  IN CONST VOID &= nbsp;           &nbs= p;  *Buffer

  )

{

  ASSERT (Buf= fer !=3D NULL);



= -  return *Buffer;

+  return *(CONST= UINT32 *) Buffer;

}



/**

@@ -15= 5,13 +155,13 @@ ReadUnaligned32 (
UINT32

EFIAPI

WriteUnaligned32 (

-  OUT UINT32       &n= bsp;            = ;*Buffer,

+  OUT VOID    &= nbsp;           &nbs= p;     *Buffer,

 = ; IN  UINT32         &nbs= p;          Value

  )

{

  ASSERT (Buffer !=3D NULL);
<= br class=3D"">

-  return *Buffer =3D Valu= e;

+  return *(UINT32 *) Buffer =3D Value= ;

}



/**

@@ -180,12 +180,12 @@ Wri= teUnaligned32 (
UINT64

EFIAPI
ReadUnaligned64 (

-=  IN CONST UINT64         &nbs= p;    *Buffer

+  IN C= ONST VOID            = ;    *Buffer

  )=

{

  AS= SERT (Buffer !=3D NULL);



-  return *Buffer;

+  retur= n *(CONST UINT64 *) Buffer;

}


/**

@@ -206,11 +206,11 @@ ReadUnaligned64 (
UINT64

EFIAPI

WriteUnaligned64 (

-  OUT UINT64      &= nbsp;           &nbs= p; *Buffer,

+  OUT VOID   =             &nb= sp;      *Buffer,

  IN  UINT64        &nb= sp;           Value<= br class=3D"">
  )

{
  ASSERT (Buffer !=3D NULL);



-  return *Buffer = =3D Value;

+  return *(UINT64 *) Buffer = =3D Value;

}

diff= --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.= h
index 2452c1d92e51..4d30f0539c6b 100644
--- a= /MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Librar= y/BaseLib.h
@@ -3420,7 +3420,7 @@ DivS64x64Remainder (
UINT16

EFIAPI

ReadUnaligned16 (

-  IN CONST UINT1= 6             &= nbsp;*Buffer

+  IN CONST VOID   = ;            &n= bsp;*Buffer

  );





@@ -3= 442,7 +3442,7 @@ ReadUnaligned16 (
UINT16

EFIAPI

WriteUnaligned16 (

-  OUT UINT16       = ;            &n= bsp;*Buffer,

+  OUT VOID   &nbs= p;            &= nbsp;     *Buffer,

&n= bsp; IN  UINT16         &= nbsp;          Value

  );



@@ -3463,7 +3463,7 @@ WriteUnaligned16 (
UINT32

EFIAPI

ReadUnaligned24 (

-  IN CONST UINT32 &= nbsp;           &nbs= p;*Buffer

+  IN CONST VOID   &n= bsp;            = ;*Buffer

  );





@@ -3485= ,7 +3485,7 @@ ReadUnaligned24 (
UINT32

EFIAPI

WriteUnaligned24 (

-  OUT UINT32       &nbs= p;            *= Buffer,

+  OUT VOID    &nb= sp;            =      *Buffer,

 &= nbsp;IN  UINT32          =           Value

  );



@@ -3506,7 +3506,7 @@ WriteUnaligned24 (
UINT32

EFIAPI

Re= adUnaligned32 (

-  IN CONST UINT32  =             *Bu= ffer

+  IN CONST VOID    &= nbsp;           *Buf= fer

  );





@@ -3528,7 +3= 528,7 @@ ReadUnaligned32 (
UINT32

EFIAPI

WriteUnaligned32 (

-  OUT UINT32        &nb= sp;           *Buffe= r,

+  OUT VOID     &n= bsp;            = ;    *Buffer,

  = IN  UINT32           = ;         Value
=
  );


<= br class=3D"">@@ -3549,7 +3549,7 @@ WriteUnaligned32 (
UINT64=

EFIAPI

ReadUnali= gned64 (

-  IN CONST UINT64   &= nbsp;          *Buffer
+  IN CONST VOID     &n= bsp;          *Buffer

  );





@@ -3571,7 +3571,7 @= @ ReadUnaligned64 (
UINT64

EFIAP= I

WriteUnaligned64 (

-  OUT UINT64         &n= bsp;          *Buffer,
+  OUT VOID      &= nbsp;           &nbs= p;   *Buffer,

  IN &n= bsp;UINT64           &nbs= p;        Value

  );



--
2.31.1

=


--Apple-Mail=_F822D05F-0017-4037-B959-C9F9BE09A281--