[edk2,v2,3/7] MdePkg: Enable new MS VA intrinsics for GNUC x86 64bits build

Message ID CAKv+Gu9UHxQdZ27KOFaAB+2c8SLZoCLg=ogxB6n1AxJDDQAovA@mail.gmail.com
State New
Headers show

Commit Message

Ard Biesheuvel July 13, 2016, 3:57 p.m.
On 13 July 2016 at 16:35, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 8 July 2016 at 10:42, Shi, Steven <steven.shi@intel.com> wrote:
>> Both GCC and LLVM 3.8 64bits support new variable argument (VA)
>> intrinsics for Microsoft ABI, enable these new VA intrinsics for
>> GNUC family 64bits code build. These VA intrinsics are only
>> permitted use in 64bits code, so not use them in 32bits code build.
>> The original 32bits GNU VA intrinsics has the same calling conversion
>> as MS, so we don’t need change them.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Steven Shi <steven.shi@intel.com>
>> ---
>>  MdePkg/Include/Base.h | 27 +++++++++++++++++++++++++--
>>  1 file changed, 25 insertions(+), 2 deletions(-)
>>  mode change 100644 => 100755 MdePkg/Include/Base.h
>>
>> diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h
>> old mode 100644
>> new mode 100755
>> index cbd9e55..5129b64
>> --- a/MdePkg/Include/Base.h
>> +++ b/MdePkg/Include/Base.h
>> @@ -588,9 +588,32 @@ struct _LIST_ENTRY {
>>
>>  #define VA_COPY(Dest, Start)          __va_copy (Dest, Start)
>>
>> -#elif defined(__GNUC__) && !defined(NO_BUILTIN_VA_FUNCS)
>> +
>> +#elif defined(__GNUC__) && !defined(NO_BUILTIN_VA_FUNCS) && !defined (MDE_CPU_IA32)
>
> This will affect all other architectures as well, so you should
> probably change the second proposition to
>
> defined(MDE_CPU_X64)
>
> instead.
>
>
>> +//
>> +// 64bits build only. Use GCC built-in macros for variable argument lists.
>> +//
>> +///
>> +/// Both GCC and LLVM 3.8 64bits support new variable argument intrinsics for Microsoft ABI
>> +///
>> +
>> +///
>> +/// Variable used to traverse the list of arguments. This type can vary by
>> +/// implementation and could be an array or structure.
>> +///
>> +typedef __builtin_ms_va_list VA_LIST;
>> +
>> +#define VA_START(Marker, Parameter)  __builtin_ms_va_start (Marker, Parameter)
>> +
>> +#define VA_ARG(Marker, TYPE)         ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE)))
>> +
>> +#define VA_END(Marker)               __builtin_ms_va_end (Marker)
>> +
>> +#define VA_COPY(Dest, Start)         __builtin_ms_va_copy (Dest, Start)
>> +
>> +#elif defined(__GNUC__) && !defined(NO_BUILTIN_VA_FUNCS) && defined (MDE_CPU_IA32)
>
> likewise here
>
>>  //
>> -// Use GCC built-in macros for variable argument lists.
>> +// 32bits build only. Use GCC built-in macros for variable argument lists.
>>  //
>>
>
> Note that with this change alone, I managed to build EmulatorPkg/X64
> and Ovmf/X64 successfully using '-fpic -mcmodel=small -O2' (and
> removing -DNO_BUILTIN_VA_FUNCS), using versions of GCC all the way
> back to v4.7.4, which results in much smaller binaries.

OK, that is not entirely true. To support -fpic code (but linked
without -pie) you will also need either your patch

BaseTools-GenFw:Add new x86_64 Elf relocation types for PIC/PIE code

or the following hunk

"""
"""

Note that there is no benefit to having a GOT in a bare metal binary:
it only increases the number of absolute references, and binaries are
not shared between processes, which means there is no need to
concentrate relocatable quantities in as few pages as possible in
order to keep the remaining pages clean.

Patch

--- a/MdePkg/Include/X64/ProcessorBind.h
+++ b/MdePkg/Include/X64/ProcessorBind.h
@@ -27,6 +27,16 @@ 
 #pragma pack()
 #endif

+#if defined(__GNUC__) && defined(__pic__)
+//
+// Mark all symbol declarations and references as hidden, meaning they will not
+// be exported from a shared library, and thus will not be subject to symbol
+// preemption. This allows the compiler to refer to symbols directly using
+// relative references rather than via the GOT, which contains absolute symbol
+// addresses that are subject to runtime relocation.
+//
+#pragma GCC visibility push (hidden)
+#endif

 #if defined(__INTEL_COMPILER)
 //