diff --git a/Make.defaults b/Make.defaults index 9b40b7f4a..afbf44d0a 100644 --- a/Make.defaults +++ b/Make.defaults @@ -68,6 +68,7 @@ ifeq ($(ARCH),x86_64) ARCH_SUFFIX ?= x64 ARCH_SUFFIX_UPPER ?= X64 ARCH_LDFLAGS ?= + ARCH_SECTION_ALIGNMENT ?= 0x1000 endif ifeq ($(ARCH),ia32) ARCH_CFLAGS ?= -mno-mmx -mno-sse -mno-red-zone -nostdinc \ @@ -78,6 +79,7 @@ ifeq ($(ARCH),ia32) ARCH_SUFFIX_UPPER ?= IA32 ARCH_LDFLAGS ?= ARCH_CFLAGS ?= -m32 + ARCH_SECTION_ALIGNMENT ?= 0x1000 endif ifeq ($(ARCH),aarch64) ARCH_CFLAGS ?= -DMDE_CPU_AARCH64 -DPAGE_SIZE=4096 -mstrict-align @@ -86,6 +88,7 @@ ifeq ($(ARCH),aarch64) ARCH_SUFFIX_UPPER ?= AA64 ARCH_LDFLAGS ?= ARCH_CFLAGS ?= + ARCH_SECTION_ALIGNMENT ?= 0x10000 endif ifeq ($(ARCH),arm) ARCH_CFLAGS ?= -DMDE_CPU_ARM -DPAGE_SIZE=4096 -mno-unaligned-access @@ -95,6 +98,7 @@ ifeq ($(ARCH),arm) FORMAT := -O binary SUBSYSTEM := 0xa ARCH_LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM) + ARCH_SECTION_ALIGNMENT ?= 0x1000 endif DEFINES = -DDEFAULT_LOADER='L"$(DEFAULT_LOADER)"' \ diff --git a/Makefile b/Makefile index 9a39cd13f..f03b7f386 100644 --- a/Makefile +++ b/Makefile @@ -282,6 +282,7 @@ endif -j .rela* -j .dyn -j .reloc -j .eh_frame \ -j .vendor_cert -j .sbat -j .sbatlevel \ --file-alignment 0x1000 \ + --section-alignment $(ARCH_SECTION_ALIGNMENT) \ $(FORMAT) $< $@ ./post-process-pe -vv $(POST_PROCESS_PE_FLAGS) $@ @@ -302,6 +303,7 @@ endif -j .debug_line -j .debug_str -j .debug_ranges \ -j .note.gnu.build-id \ --file-alignment 0x1000 \ + --section-alignment $(ARCH_SECTION_ALIGNMENT) \ $< $@ ifneq ($(origin ENABLE_SBSIGN),undefined) diff --git a/elf_aarch64_efi.lds b/elf_aarch64_efi.lds index 0861f5e8a..ff2e408ae 100644 --- a/elf_aarch64_efi.lds +++ b/elf_aarch64_efi.lds @@ -6,12 +6,12 @@ SECTIONS . = 0; ImageBase = .; .hash : { *(.hash) } /* this MUST come first! */ - . = ALIGN(4096); + . = ALIGN(65536); .eh_frame : { *(.eh_frame) } - . = ALIGN(4096); + . = ALIGN(65536); .text : { _text = .; @@ -20,26 +20,26 @@ SECTIONS *(.gnu.linkonce.t.*) _etext = .; } - . = ALIGN(4096); + . = ALIGN(65536); .reloc : { *(.reloc) } - . = ALIGN(4096); + . = ALIGN(65536); .note.gnu.build-id : { *(.note.gnu.build-id) } - . = ALIGN(4096); + . = ALIGN(65536); .data.ident : { *(.data.ident) } - . = ALIGN(4096); + . = ALIGN(65536); .sbatlevel : { *(.sbatlevel) } - . = ALIGN(4096); + . = ALIGN(65536); .data : { _data = .; @@ -58,14 +58,14 @@ SECTIONS *(.rel.local) } - . = ALIGN(4096); + . = ALIGN(65536); .vendor_cert : { *(.vendor_cert) } - . = ALIGN(4096); + . = ALIGN(65536); .dynamic : { *(.dynamic) } - . = ALIGN(4096); + . = ALIGN(65536); .rela : { *(.rela.data*) @@ -74,7 +74,7 @@ SECTIONS } _edata = .; _data_size = . - _data; - . = ALIGN(4096); + . = ALIGN(65536); .sbat : { _sbat = .; @@ -84,11 +84,11 @@ SECTIONS _esbat = .; _sbat_size = . - _sbat; - . = ALIGN(4096); + . = ALIGN(65536); .dynsym : { *(.dynsym) } - . = ALIGN(4096); + . = ALIGN(65536); .dynstr : { *(.dynstr) } - . = ALIGN(4096); + . = ALIGN(65536); .ignored.reloc : { *(.rela.reloc) diff --git a/include/peimage.h b/include/peimage.h index 5d049686e..8c84d18f1 100644 --- a/include/peimage.h +++ b/include/peimage.h @@ -819,6 +819,7 @@ typedef struct { UINTN SizeOfHeaders; UINT16 ImageType; UINT16 NumberOfSections; + UINT32 FileAlignment; UINT32 SectionAlignment; EFI_IMAGE_SECTION_HEADER *FirstSection; EFI_IMAGE_DATA_DIRECTORY *RelocDir; diff --git a/post-process-pe.c b/post-process-pe.c index 008da93b8..4b71d8aa4 100644 --- a/post-process-pe.c +++ b/post-process-pe.c @@ -124,7 +124,6 @@ load_pe(const char *const file, void *const data, const size_t datasize, EFI_IMAGE_DOS_HEADER *DOSHdr = data; EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr = data; size_t HeaderWithoutDataDir, SectionHeaderOffset, OptHeaderSize; - size_t FileAlignment = 0; size_t sz0 = 0, sz1 = 0; uintptr_t loc = 0; @@ -164,7 +163,7 @@ load_pe(const char *const file, void *const data, const size_t datasize, ctx->SectionAlignment = PEHdr->Pe32Plus.OptionalHeader.SectionAlignment; ctx->DllCharacteristics = PEHdr->Pe32Plus.OptionalHeader.DllCharacteristics; - FileAlignment = PEHdr->Pe32Plus.OptionalHeader.FileAlignment; + ctx->FileAlignment = PEHdr->Pe32Plus.OptionalHeader.FileAlignment; OptHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64); } else { debug(NOISE, "image is 32bit\n"); @@ -175,19 +174,19 @@ load_pe(const char *const file, void *const data, const size_t datasize, ctx->SectionAlignment = PEHdr->Pe32.OptionalHeader.SectionAlignment; ctx->DllCharacteristics = PEHdr->Pe32.OptionalHeader.DllCharacteristics; - FileAlignment = PEHdr->Pe32.OptionalHeader.FileAlignment; + ctx->FileAlignment = PEHdr->Pe32.OptionalHeader.FileAlignment; OptHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32); } - if (FileAlignment % 2 != 0) - errx(1, "%s: Invalid file alignment %zu", file, FileAlignment); + if (ctx->FileAlignment % 2 != 0) + errx(1, "%s: Invalid file alignment 0x%08x", file, ctx->FileAlignment); - if (FileAlignment == 0) - FileAlignment = 0x200; + if (ctx->FileAlignment == 0) + ctx->FileAlignment = 0x200; if (ctx->SectionAlignment == 0) ctx->SectionAlignment = PAGE_SIZE; - if (ctx->SectionAlignment < FileAlignment) - ctx->SectionAlignment = FileAlignment; + if (ctx->SectionAlignment < ctx->FileAlignment) + ctx->SectionAlignment = ctx->FileAlignment; ctx->NumberOfSections = PEHdr->Pe32.FileHeader.NumberOfSections; @@ -382,10 +381,19 @@ validate_nx_compat(PE_COFF_LOADER_IMAGE_CONTEXT *ctx) ret = -1; } + debug(NOISE, "File alignment is 0x%x, page size is 0x%x\n", + ctx->FileAlignment, PAGE_SIZE); + if (ctx->FileAlignment % PAGE_SIZE != 0) { + debug(level, "File alignment is not a multiple of page size\n"); + if (require_nx_compat) + ret = -1; + } + debug(NOISE, "Section alignment is 0x%x, page size is 0x%x\n", ctx->SectionAlignment, PAGE_SIZE); - if (ctx->SectionAlignment != PAGE_SIZE) { - debug(level, "Section alignment is not page aligned\n"); + if (ctx->SectionAlignment & (PAGE_SIZE - 1)) { + debug(level, "Section alignment is not page aligned: SectionAlignment & PAGE_MASK = 0x%08x & 0x%08x = 0x%08x\n", + ctx->SectionAlignment, PAGE_SIZE-1, ctx->SectionAlignment & (PAGE_SIZE-1)); if (require_nx_compat) ret = -1; } @@ -402,6 +410,13 @@ validate_nx_compat(PE_COFF_LOADER_IMAGE_CONTEXT *ctx) if (require_nx_compat) ret = -1; } + + debug(NOISE, "Section %d has VA of 0x%08x\n", i, Section->VirtualAddress); + if (Section->VirtualAddress != 0 && + ((Section->VirtualAddress) & (ctx->SectionAlignment - 1))) { + debug(level, "Section %d has Virtual Address 0x%08x that isn't section aligned (0x%08x)\n", + i, Section->VirtualAddress, ctx->SectionAlignment); + } } return ret; @@ -590,6 +605,9 @@ int main(int argc, char **argv) case 'x': require_nx_compat = true; break; + default: + usage(1); + break; } }