From 2bb2e22db82ab89547f01b957cf05cfd7e713857 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 28 Feb 2023 09:57:25 +0300 Subject: [PATCH] BaseTools: Reduced minimal alignment to 32 bytes. --- BaseTools/Conf/tools_def.template | 6 ++--- BaseTools/ImageTool/ElfScan.c | 28 +++++++++++++++------ BaseTools/ImageTool/PeEmit.c | 41 +++++++++++++++++-------------- BaseTools/Scripts/Base.lds | 4 ++- BaseTools/Scripts/Merge.lds | 4 ++- MdePkg/MdeBuildOptions.dsc.inc | 18 +++++++------- 6 files changed, 60 insertions(+), 41 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 601497dcf1..54218817e5 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -1858,7 +1858,7 @@ DEFINE GCC_ARM_CC_XIPFLAGS = -mno-unaligned-access DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 DEFINE GCC_AARCH64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only DEFINE GCC_DLINK_FLAGS_COMMON = -nostdlib --pie -DEFINE GCC_DLINK2_FLAGS_COMMON = -Wl,--default-script=$(EDK_TOOLS_PATH)/Scripts/Base.lds +DEFINE GCC_DLINK2_FLAGS_COMMON = -Wl,--defsym=ALIGNED_PE_HEADER_SIZE=0x400,--default-script=$(EDK_TOOLS_PATH)/Scripts/Base.lds DEFINE GCC_IA32_X64_DLINK_COMMON = DEF(GCC_DLINK_FLAGS_COMMON) --gc-sections DEFINE GCC_ARM_AARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map DEFINE GCC_LOONGARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map @@ -1961,7 +1961,7 @@ DEFINE GCC5_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -fno-lto DEFINE GCC5_RISCV_ALL_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -msmall-data-limit=0 DEFINE GCC5_RISCV_ALL_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z max-page-size=0x1000 DEFINE GCC5_RISCV_ALL_DLINK_FLAGS = DEF(GCC5_RISCV_ALL_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map -DEFINE GCC5_RISCV_ALL_DLINK2_FLAGS =,--default-script=$(EDK_TOOLS_PATH)/Scripts/Base.lds +DEFINE GCC5_RISCV_ALL_DLINK2_FLAGS = -Wl,--defsym=ALIGNED_PE_HEADER_SIZE=0x400,--default-script=$(EDK_TOOLS_PATH)/Scripts/Base.lds DEFINE GCC5_RISCV_ALL_ASM_FLAGS = -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h DEFINE GCC5_RISCV_ALL_CC_FLAGS_WARNING_DISABLE = -Wno-tautological-compare -Wno-pointer-compare @@ -2875,7 +2875,7 @@ DEFINE CLANGDWARF_IA32_PREFIX = ENV(CLANG_BIN) DEFINE CLANGDWARF_X64_PREFIX = ENV(CLANG_BIN) # LLVM/CLANG doesn't support -n link option. So, it can't share the same IA32_X64_DLINK_COMMON flag. -DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z max-page-size=0x1000 -Wl,-z,notext +DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z max-page-size=0x1000 -Wl,-z,notext,--defsym=ALIGNED_PE_HEADER_SIZE=0x400 DEFINE CLANGDWARF_IA32_X64_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable DEFINE CLANGDWARF_IA32_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive DEFINE CLANGDWARF_IA32_DLINK2_FLAGS = -no-pie diff --git a/BaseTools/ImageTool/ElfScan.c b/BaseTools/ImageTool/ElfScan.c index 49fefa1c7d..fae6b6b79b 100644 --- a/BaseTools/ImageTool/ElfScan.c +++ b/BaseTools/ImageTool/ElfScan.c @@ -459,6 +459,7 @@ CreateIntermediate ( SIndex = 0; Relocs = NULL; NumRelocs = 0; + Pointer = 0; for (Index = 0; Index < mEhdr->e_shnum; ++Index) { Shdr = GetShdrByIndex (Index); @@ -514,10 +515,6 @@ CreateIntermediate ( mImageInfo.RelocInfo.Relocs = Relocs; } - // - // Assume 4K alignment, which must be enough for all PE headers. - // - Pointer = mPeAlignment; for (Index = 0; Index < mEhdr->e_shnum; ++Index) { Shdr = GetShdrByIndex (Index); @@ -546,13 +543,18 @@ CreateIntermediate ( memcpy (Segments[SIndex].Data, (UINT8 *)mEhdr + Shdr->sh_offset, (size_t)Shdr->sh_size); - Segments[SIndex].ImageAddress = Pointer; + Segments[SIndex].ImageAddress = Shdr->sh_addr; Segments[SIndex].ImageSize = Segments[SIndex].DataSize; Segments[SIndex].Read = true; Segments[SIndex].Write = false; Segments[SIndex].Execute = true; Segments[SIndex].Type = ToolImageSectionTypeCode; - Pointer += Segments[SIndex].DataSize; + + if (Pointer == 0) { + Pointer = Shdr->sh_addr; + } + + Pointer += Segments[SIndex].DataSize; ++SIndex; continue; } @@ -583,13 +585,18 @@ CreateIntermediate ( memcpy (Segments[SIndex].Data, (UINT8 *)mEhdr + Shdr->sh_offset, (size_t)Shdr->sh_size); } - Segments[SIndex].ImageAddress = Pointer; + Segments[SIndex].ImageAddress = Shdr->sh_addr; Segments[SIndex].ImageSize = Segments[SIndex].DataSize; Segments[SIndex].Read = true; Segments[SIndex].Write = true; Segments[SIndex].Execute = false; Segments[SIndex].Type = ToolImageSectionTypeInitialisedData; - Pointer += Segments[SIndex].DataSize; + + if (Pointer == 0) { + Pointer = Shdr->sh_addr; + } + + Pointer += Segments[SIndex].DataSize; ++SIndex; continue; } @@ -605,6 +612,11 @@ CreateIntermediate ( if (Shdr->sh_type == SHT_PROGBITS) { memcpy (mImageInfo.HiiInfo.Data, (UINT8 *)mEhdr + Shdr->sh_offset, (size_t)Shdr->sh_size); + + if (Pointer == 0) { + Pointer = Shdr->sh_addr; + } + SetHiiResourceHeader (mImageInfo.HiiInfo.Data, (UINT32)Pointer); Pointer += mImageInfo.HiiInfo.DataSize; } diff --git a/BaseTools/ImageTool/PeEmit.c b/BaseTools/ImageTool/PeEmit.c index a756242a37..ecb727b5c1 100644 --- a/BaseTools/ImageTool/PeEmit.c +++ b/BaseTools/ImageTool/PeEmit.c @@ -284,7 +284,8 @@ bool ToolImageEmitPeSectionHeaders ( const image_tool_pe_emit_context_t *Context, uint8_t **Buffer, - uint32_t *BufferSize + uint32_t *BufferSize, + uint32_t AlignedHeaderSize ) { const image_tool_image_info_t *Image; @@ -299,7 +300,7 @@ ToolImageEmitPeSectionHeaders ( Image = Context->Image; SectionHeadersSize = (uint16_t) (Image->SegmentInfo.NumSegments * sizeof (EFI_IMAGE_SECTION_HEADER)); - SectionOffset = ALIGN_VALUE (Context->HdrInfo.SizeOfHeaders, Context->FileAlignment); + SectionOffset = AlignedHeaderSize; Sections = (void *) *Buffer; assert (SectionHeadersSize <= *BufferSize); @@ -359,7 +360,8 @@ bool ToolImageEmitPeExtraSectionHeaders ( image_tool_pe_emit_context_t *Context, uint8_t **Buffer, - uint32_t *BufferSize + uint32_t *BufferSize, + uint32_t AlignedHeaderSize ) { uint32_t SectionHeadersSize; @@ -382,7 +384,7 @@ ToolImageEmitPeExtraSectionHeaders ( Section->SizeOfRawData = Context->HiiTableSize; Section->VirtualSize = Context->HiiTableSize; Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ; - Section->PointerToRawData = ALIGN_VALUE (Context->HdrInfo.SizeOfHeaders, Context->FileAlignment) + Context->SectionsSize; + Section->PointerToRawData = AlignedHeaderSize + Context->SectionsSize; Section->VirtualAddress = Section->PointerToRawData; Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = Context->HiiTableSize; @@ -405,8 +407,7 @@ ToolImageEmitPeExtraSectionHeaders ( Section->VirtualSize = ALIGN_VALUE (Context->RelocTableSize, Context->FileAlignment); Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_DISCARDABLE | EFI_IMAGE_SCN_MEM_READ; - Section->PointerToRawData = ALIGN_VALUE (Context->HdrInfo.SizeOfHeaders, Context->FileAlignment) - + Context->SectionsSize + Context->HiiTableSize; + Section->PointerToRawData = AlignedHeaderSize + Context->SectionsSize + Context->HiiTableSize; Section->VirtualAddress = Section->PointerToRawData; Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Context->RelocTableSize; @@ -449,7 +450,8 @@ bool ToolImageEmitPeHeaders ( image_tool_pe_emit_context_t *Context, uint8_t **Buffer, - uint32_t *BufferSize + uint32_t *BufferSize, + uint32_t AlignedHeaderSize ) { const image_tool_image_info_t *Image; @@ -493,7 +495,7 @@ ToolImageEmitPeHeaders ( PePlusHdr->AddressOfEntryPoint = Image->HeaderInfo.EntryPointAddress; PePlusHdr->SectionAlignment = Image->SegmentInfo.SegmentAlignment; PePlusHdr->FileAlignment = Context->FileAlignment; - PePlusHdr->SizeOfHeaders = Context->HdrInfo.SizeOfHeaders; + PePlusHdr->SizeOfHeaders = AlignedHeaderSize; PePlusHdr->ImageBase = (UINTN)Image->HeaderInfo.PreferredAddress; PePlusHdr->Subsystem = Image->HeaderInfo.Subsystem; PePlusHdr->NumberOfRvaAndSizes = Context->HdrInfo.NumberOfRvaAndSizes; @@ -508,20 +510,17 @@ ToolImageEmitPeHeaders ( *BufferSize -= sizeof (EFI_IMAGE_NT_HEADERS) + PePlusHdr->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); *Buffer += sizeof (EFI_IMAGE_NT_HEADERS) + PePlusHdr->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); - Result = ToolImageEmitPeSectionHeaders (Context, Buffer, BufferSize); + Result = ToolImageEmitPeSectionHeaders (Context, Buffer, BufferSize, AlignedHeaderSize); if (!Result) { return false; } - Result = ToolImageEmitPeExtraSectionHeaders (Context, Buffer, BufferSize); + Result = ToolImageEmitPeExtraSectionHeaders (Context, Buffer, BufferSize, AlignedHeaderSize); if (!Result) { return false; } - HeaderPadding = ALIGN_VALUE_ADDEND( - Context->HdrInfo.SizeOfHeaders, - Context->FileAlignment - ); + HeaderPadding = AlignedHeaderSize - Context->HdrInfo.SizeOfHeaders; assert (HeaderPadding <= *BufferSize); @@ -897,6 +896,13 @@ ToolImageEmitPe ( return NULL; } + if (AlignedHeaderSize > Image->SegmentInfo.Segments[0].ImageAddress) { + raise (); + return NULL; + } + + AlignedHeaderSize = (uint32_t)Image->SegmentInfo.Segments[0].ImageAddress; + Result = EmitPeGetSectionsSize (&Context, &Context.SectionsSize); if (!Result) { raise (); @@ -939,7 +945,7 @@ ToolImageEmitPe ( RemainingSize = Context.UnsignedFileSize; ExpectedSize = Context.UnsignedFileSize; - Result = ToolImageEmitPeHeaders (&Context, &Buffer, &RemainingSize); + Result = ToolImageEmitPeHeaders (&Context, &Buffer, &RemainingSize, AlignedHeaderSize); if (!Result) { raise (); free (FileBuffer); @@ -971,12 +977,9 @@ ToolImageEmitPe ( ExpectedSize -= Context.ExtraSectionsSize; assert (RemainingSize == ExpectedSize); - assert (RemainingSize == 0); - Context.PeHdr->SizeOfHeaders = AlignedHeaderSize; - Context.PeHdr->SizeOfImage = Context.UnsignedFileSize; - + Context.PeHdr->SizeOfImage = Context.UnsignedFileSize; Context.PeHdr->SizeOfInitializedData += Context.ExtraSectionsSize; *FileSize = Context.UnsignedFileSize; diff --git a/BaseTools/Scripts/Base.lds b/BaseTools/Scripts/Base.lds index e30801f85e..2ed4ecd29f 100644 --- a/BaseTools/Scripts/Base.lds +++ b/BaseTools/Scripts/Base.lds @@ -13,7 +13,9 @@ SECTIONS { - .text CONSTANT(MAXPAGESIZE) : ALIGN(CONSTANT(MAXPAGESIZE)) { + . = ALIGNED_PE_HEADER_SIZE; + + .text : ALIGN(CONSTANT(MAXPAGESIZE)) { *(.text .text.* .stub .gnu.linkonce.t.*) } diff --git a/BaseTools/Scripts/Merge.lds b/BaseTools/Scripts/Merge.lds index 7bb9ea44ff..69598cb198 100644 --- a/BaseTools/Scripts/Merge.lds +++ b/BaseTools/Scripts/Merge.lds @@ -13,7 +13,9 @@ SECTIONS { - .text CONSTANT(MAXPAGESIZE) : ALIGN(CONSTANT(MAXPAGESIZE)) { + . = ALIGNED_PE_HEADER_SIZE; + + .text : ALIGN(CONSTANT(MAXPAGESIZE)) { *(.text .text.* .stub .gnu.linkonce.t.*) *(.rodata .rodata.* .data.rel.ro .data.rel.ro.* .gnu.linkonce.r.*) *(.got .got.*) diff --git a/MdePkg/MdeBuildOptions.dsc.inc b/MdePkg/MdeBuildOptions.dsc.inc index 18be6875d6..a3cc330eac 100644 --- a/MdePkg/MdeBuildOptions.dsc.inc +++ b/MdePkg/MdeBuildOptions.dsc.inc @@ -13,19 +13,19 @@ # # MDEPKG_REDUCE_FW_SIZE: -# Align boot-time images at a 1024 bytes boundary to reduce firmware size. +# Align boot-time images at a 32 bytes boundary to reduce firmware size. # !if $(MDEPKG_REDUCE_FW_SIZE) == TRUE [BuildOptions] - MSFT:*_*_*_DLINK_FLAGS = /ALIGN:1024 - INTEL:*_*_*_DLINK_FLAGS = /ALIGN:1024 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:1024 /FILEALIGN:1024 - GCC:*_*_*_DLINK_FLAGS = -z max-page-size=0x400 - CLANGGCC:*_*_*_DLINK_FLAGS = -z max-page-size=0x400 - XCODE:*_*_*_DLINK_FLAGS = -segalign 0x400 -seg1addr 0x400 - XCODE:*_*_*_ASLDLINK_FLAGS = -segalign 0x400 -seg1addr 0x400 - XCODE:*_*_*_MTOC_FLAGS = -align 0x400 + MSFT:*_*_*_DLINK_FLAGS = /ALIGN:32 + INTEL:*_*_*_DLINK_FLAGS = /ALIGN:32 + CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:32 /FILEALIGN:32 + GCC:*_*_*_DLINK_FLAGS = -z max-page-size=0x20 + CLANGGCC:*_*_*_DLINK_FLAGS = -z max-page-size=0x20 + XCODE:*_*_*_DLINK_FLAGS = -segalign 0x20 -seg1addr 0x400 + XCODE:*_*_*_ASLDLINK_FLAGS = -segalign 0x20 -seg1addr 0x400 + XCODE:*_*_*_MTOC_FLAGS = -align 0x20 !endif !if $(MDEPKG_MERGE_RODATA_INTO_TEXT) == TRUE