On 7 December 2015 at 16:23, Laszlo Ersek <[email protected]> wrote:
> On 12/07/15 10:52, Ard Biesheuvel wrote:
>> The default behavior of the GCC compiler is to emit uninitialized globals
>> into a COMMON section, where duplicate definitions are merged. This may
>> result in unexpected behavior, since global variables defined under the
>> same name in different C files may not refer to the same logical data item.
>>
>> For instance, the definitions of EFI_EVENT mVirtualAddressChangeEvent that
>> [used to] appear in the following files:
>>
>>   CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c
>>   MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
>>
>> will be folded into a single instance of the variable when the latter
>> module includes the former library, which can lead to unexpected results.
>>
>> Even if some may argue that there are legal uses for COMMON allocation, the
>> high modularity of EDK2 combined with the low level of awareness of the
>> intracicies surrounding common allocation and the generally poor EDK2
>> developer discipline regarding the use of the STATIC keyword* make a strong
>> case for disabling it by default, and re-enabling it explicitly for packages
>> that depend on it.
>>
>> So prevent GCC from emitting variables into the COMMON section, by passing
>> -fno-common to the compiler, and discarding the section in the GNU ld linker
>> script.
>>
>> * Any function or variable that is only referenced from the translation unit
>>   that defines it could be made STATIC. This does not only prevent issues 
>> like
>>   the above, it also allows the compiler to generate better code, e.g., drop
>>   out of line function definitions after inlining all invocations or perform
>>   constant propagation on variables.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <[email protected]>
>> Reviewed-by: Liming Gao <[email protected]>
>> Reviewed-by: Laszlo Ersek <[email protected]>
>> ---
>> v2: added the -fno-common argument to GCC44_ALL_CC_FLAGS as well, since GCC4x
>>     for X64 and IA32 does not include GCC_ALL_CC_FLAGS
>>
>>  BaseTools/Conf/tools_def.template | 4 ++--
>>  BaseTools/Scripts/GccBase.lds     | 3 ++-
>>  2 files changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/BaseTools/Conf/tools_def.template 
>> b/BaseTools/Conf/tools_def.template
>> index d6b0af43d772..1a44fbd1d3eb 100644
>> --- a/BaseTools/Conf/tools_def.template
>> +++ b/BaseTools/Conf/tools_def.template
>> @@ -4318,7 +4318,7 @@ NOOPT_DDK3790xASL_IPF_DLINK_FLAGS    = /NOLOGO 
>> /NODEFAULTLIB /LTCG /DLL /OPT:REF
>>  DEBUG_*_*_OBJCOPY_ADDDEBUGFLAG     = 
>> --add-gnu-debuglink=$(DEBUG_DIR)/$(MODULE_NAME).debug
>>  RELEASE_*_*_OBJCOPY_ADDDEBUGFLAG   =
>>
>> -DEFINE GCC_ALL_CC_FLAGS            = -g -Os -fshort-wchar 
>> -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -c -include AutoGen.h
>> +DEFINE GCC_ALL_CC_FLAGS            = -g -Os -fshort-wchar 
>> -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -c -include AutoGen.h 
>> -fno-common
>>  DEFINE GCC_IA32_CC_FLAGS           = DEF(GCC_ALL_CC_FLAGS) -m32 
>> -malign-double -freorder-blocks -freorder-blocks-and-partition -O2 
>> -mno-stack-arg-probe
>>  DEFINE GCC_X64_CC_FLAGS            = DEF(GCC_ALL_CC_FLAGS) -mno-red-zone 
>> -Wno-address -mno-stack-arg-probe
>>  DEFINE GCC_IPF_CC_FLAGS            = DEF(GCC_ALL_CC_FLAGS) 
>> -minline-int-divide-min-latency
>> @@ -4349,7 +4349,7 @@ DEFINE GCC_IPF_RC_FLAGS            = -I binary -O 
>> elf64-ia64-little   -B ia64
>>  DEFINE GCC_ARM_RC_FLAGS            = -I binary -O elf32-littlearm     -B 
>> arm     --rename-section .data=.hii
>>  DEFINE GCC_AARCH64_RC_FLAGS        = -I binary -O elf64-littleaarch64 -B 
>> aarch64 --rename-section .data=.hii
>>
>> -DEFINE GCC44_ALL_CC_FLAGS            = -g -fshort-wchar 
>> -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections 
>> -fdata-sections -c -include AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings
>> +DEFINE GCC44_ALL_CC_FLAGS            = -g -fshort-wchar 
>> -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections 
>> -fdata-sections -c -include AutoGen.h -fno-common 
>> -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings
>>  DEFINE GCC44_IA32_CC_FLAGS           = DEF(GCC44_ALL_CC_FLAGS) -m32 
>> -malign-double -fno-stack-protector -D EFI32 -fno-asynchronous-unwind-tables
>>  DEFINE GCC44_X64_CC_FLAGS            = DEF(GCC44_ALL_CC_FLAGS) -m64 
>> -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" 
>> -DNO_BUILTIN_VA_FUNCS -mno-red-zone -Wno-address -mcmodel=large 
>> -fno-asynchronous-unwind-tables
>>  DEFINE GCC44_IA32_X64_DLINK_COMMON   = -nostdlib -n -q --gc-sections -z 
>> common-page-size=0x20
>> diff --git a/BaseTools/Scripts/GccBase.lds b/BaseTools/Scripts/GccBase.lds
>> index 4ee6d998532c..32310bc75dcc 100644
>> --- a/BaseTools/Scripts/GccBase.lds
>> +++ b/BaseTools/Scripts/GccBase.lds
>> @@ -46,7 +46,7 @@ SECTIONS {
>>     */
>>    .data ALIGN(ALIGNOF(.text)) : ALIGN(CONSTANT(COMMONPAGESIZE)) {
>>      *(.data .data.* .gnu.linkonce.d.*)
>> -    *(.bss .bss.* *COM*)
>> +    *(.bss .bss.*)
>>    }
>>
>>    .eh_frame ALIGN(CONSTANT(COMMONPAGESIZE)) : {
>> @@ -66,5 +66,6 @@ SECTIONS {
>>      *(.dynamic)
>>      *(.hash)
>>      *(.comment)
>> +    *(COMMON)
>>    }
>>  }
>>
>
> I build tested this patch with the following OVMF settings:
>
> #  DSC      SECURE_BOOT_ENABLE  NETWORK_IP6_ENABLE  HTTP_BOOT_ENABLE  
> SMM_REQUIRE
> -  -------  ------------------  ------------------  ----------------  
> -----------
> 1  X64                                              X
> 2  X64      X                   X                   X
> 3  X64      X                                       X                 X
> 4  Ia32     X                                       X                 X
> 5  Ia32X64  X                                       X                 X
>
> In my local tree the FatPkg driver is also built from source (currently
> at SVN r96), so the above should cover that as well.
>
> Tested-by: Laszlo Ersek <[email protected]>
>

Committed as SVN r19164

Thanks everyone,
Ard.
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to