| /* SPDX-License-Identifier: GPL-2.0-only */ |
| /* |
| * Copyright (C) 2013 - 2017 Linaro, Ltd. |
| * Copyright (C) 2013, 2014 Red Hat, Inc. |
| */ |
| |
| #include <linux/pe.h> |
| #include <linux/sizes.h> |
| |
| .macro efi_signature_nop |
| #ifdef CONFIG_EFI |
| .L_head: |
| /* |
| * This ccmp instruction has no meaningful effect except that |
| * its opcode forms the magic "MZ" signature required by UEFI. |
| */ |
| ccmp x18, #0, #0xd, pl |
| #else |
| /* |
| * Bootloaders may inspect the opcode at the start of the kernel |
| * image to decide if the kernel is capable of booting via UEFI. |
| * So put an ordinary NOP here, not the "MZ.." pseudo-nop above. |
| */ |
| nop |
| #endif |
| .endm |
| |
| .macro __EFI_PE_HEADER |
| #ifdef CONFIG_EFI |
| .set .Lpe_header_offset, . - .L_head |
| .long PE_MAGIC |
| .short IMAGE_FILE_MACHINE_ARM64 // Machine |
| .short .Lsection_count // NumberOfSections |
| .long 0 // TimeDateStamp |
| .long 0 // PointerToSymbolTable |
| .long 0 // NumberOfSymbols |
| .short .Lsection_table - .Loptional_header // SizeOfOptionalHeader |
| .short IMAGE_FILE_DEBUG_STRIPPED | \ |
| IMAGE_FILE_EXECUTABLE_IMAGE | \ |
| IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics |
| |
| .Loptional_header: |
| .short PE_OPT_MAGIC_PE32PLUS // PE32+ format |
| .byte 0x02 // MajorLinkerVersion |
| .byte 0x14 // MinorLinkerVersion |
| .long __initdata_begin - .Lefi_header_end // SizeOfCode |
| .long __pecoff_data_size // SizeOfInitializedData |
| .long 0 // SizeOfUninitializedData |
| .long __efistub_efi_pe_entry - .L_head // AddressOfEntryPoint |
| .long .Lefi_header_end - .L_head // BaseOfCode |
| |
| .quad 0 // ImageBase |
| .long SEGMENT_ALIGN // SectionAlignment |
| .long PECOFF_FILE_ALIGNMENT // FileAlignment |
| .short 0 // MajorOperatingSystemVersion |
| .short 0 // MinorOperatingSystemVersion |
| .short LINUX_EFISTUB_MAJOR_VERSION // MajorImageVersion |
| .short LINUX_EFISTUB_MINOR_VERSION // MinorImageVersion |
| .short 0 // MajorSubsystemVersion |
| .short 0 // MinorSubsystemVersion |
| .long 0 // Win32VersionValue |
| |
| .long _end - .L_head // SizeOfImage |
| |
| // Everything before the kernel image is considered part of the header |
| .long .Lefi_header_end - .L_head // SizeOfHeaders |
| .long 0 // CheckSum |
| .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem |
| .short IMAGE_DLL_CHARACTERISTICS_NX_COMPAT // DllCharacteristics |
| .quad 0 // SizeOfStackReserve |
| .quad 0 // SizeOfStackCommit |
| .quad 0 // SizeOfHeapReserve |
| .quad 0 // SizeOfHeapCommit |
| .long 0 // LoaderFlags |
| .long (.Lsection_table - .) / 8 // NumberOfRvaAndSizes |
| |
| .quad 0 // ExportTable |
| .quad 0 // ImportTable |
| .quad 0 // ResourceTable |
| .quad 0 // ExceptionTable |
| .quad 0 // CertificationTable |
| .quad 0 // BaseRelocationTable |
| |
| #if defined(CONFIG_DEBUG_EFI) || defined(CONFIG_ARM64_BTI_KERNEL) |
| .long .Lefi_debug_table - .L_head // DebugTable |
| .long .Lefi_debug_table_size |
| |
| /* |
| * The debug table is referenced via its Relative Virtual Address (RVA), |
| * which is only defined for those parts of the image that are covered |
| * by a section declaration. Since this header is not covered by any |
| * section, the debug table must be emitted elsewhere. So stick it in |
| * the .init.rodata section instead. |
| * |
| * Note that the payloads themselves are permitted to have zero RVAs, |
| * which means we can simply put those right after the section headers. |
| */ |
| __INITRODATA |
| |
| .align 2 |
| .Lefi_debug_table: |
| #ifdef CONFIG_DEBUG_EFI |
| // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY |
| .long 0 // Characteristics |
| .long 0 // TimeDateStamp |
| .short 0 // MajorVersion |
| .short 0 // MinorVersion |
| .long IMAGE_DEBUG_TYPE_CODEVIEW // Type |
| .long .Lefi_debug_entry_size // SizeOfData |
| .long 0 // RVA |
| .long .Lefi_debug_entry - .L_head // FileOffset |
| #endif |
| #ifdef CONFIG_ARM64_BTI_KERNEL |
| .long 0 // Characteristics |
| .long 0 // TimeDateStamp |
| .short 0 // MajorVersion |
| .short 0 // MinorVersion |
| .long IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS // Type |
| .long 4 // SizeOfData |
| .long 0 // RVA |
| .long .Lefi_dll_characteristics_ex - .L_head // FileOffset |
| #endif |
| .set .Lefi_debug_table_size, . - .Lefi_debug_table |
| .previous |
| #endif |
| |
| // Section table |
| .Lsection_table: |
| .ascii ".text\0\0\0" |
| .long __initdata_begin - .Lefi_header_end // VirtualSize |
| .long .Lefi_header_end - .L_head // VirtualAddress |
| .long __initdata_begin - .Lefi_header_end // SizeOfRawData |
| .long .Lefi_header_end - .L_head // PointerToRawData |
| |
| .long 0 // PointerToRelocations |
| .long 0 // PointerToLineNumbers |
| .short 0 // NumberOfRelocations |
| .short 0 // NumberOfLineNumbers |
| .long IMAGE_SCN_CNT_CODE | \ |
| IMAGE_SCN_MEM_READ | \ |
| IMAGE_SCN_MEM_EXECUTE // Characteristics |
| |
| .ascii ".data\0\0\0" |
| .long __pecoff_data_size // VirtualSize |
| .long __initdata_begin - .L_head // VirtualAddress |
| .long __pecoff_data_rawsize // SizeOfRawData |
| .long __initdata_begin - .L_head // PointerToRawData |
| |
| .long 0 // PointerToRelocations |
| .long 0 // PointerToLineNumbers |
| .short 0 // NumberOfRelocations |
| .short 0 // NumberOfLineNumbers |
| .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ |
| IMAGE_SCN_MEM_READ | \ |
| IMAGE_SCN_MEM_WRITE // Characteristics |
| |
| .set .Lsection_count, (. - .Lsection_table) / 40 |
| |
| #ifdef CONFIG_DEBUG_EFI |
| .Lefi_debug_entry: |
| // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY |
| .ascii "NB10" // Signature |
| .long 0 // Unknown |
| .long 0 // Unknown2 |
| .long 0 // Unknown3 |
| |
| .asciz VMLINUX_PATH |
| |
| .set .Lefi_debug_entry_size, . - .Lefi_debug_entry |
| #endif |
| #ifdef CONFIG_ARM64_BTI_KERNEL |
| .Lefi_dll_characteristics_ex: |
| .long IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT |
| #endif |
| |
| .balign SEGMENT_ALIGN |
| .Lefi_header_end: |
| #else |
| .set .Lpe_header_offset, 0x0 |
| #endif |
| .endm |