1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 2b5f4a214SArd Biesheuvel/* 3b5f4a214SArd Biesheuvel * Copyright (C) 2013 - 2017 Linaro, Ltd. 4b5f4a214SArd Biesheuvel * Copyright (C) 2013, 2014 Red Hat, Inc. 5b5f4a214SArd Biesheuvel */ 6b5f4a214SArd Biesheuvel 7f1eb542fSArd Biesheuvel#include <linux/pe.h> 8f1eb542fSArd Biesheuvel#include <linux/sizes.h> 9f1eb542fSArd Biesheuvel 107919385bSArd Biesheuvel .macro efi_signature_nop 117919385bSArd Biesheuvel#ifdef CONFIG_EFI 127919385bSArd Biesheuvel.L_head: 137919385bSArd Biesheuvel /* 147919385bSArd Biesheuvel * This ccmp instruction has no meaningful effect except that 157919385bSArd Biesheuvel * its opcode forms the magic "MZ" signature required by UEFI. 167919385bSArd Biesheuvel */ 177919385bSArd Biesheuvel ccmp x18, #0, #0xd, pl 187919385bSArd Biesheuvel#else 197919385bSArd Biesheuvel /* 207919385bSArd Biesheuvel * Bootloaders may inspect the opcode at the start of the kernel 217919385bSArd Biesheuvel * image to decide if the kernel is capable of booting via UEFI. 227919385bSArd Biesheuvel * So put an ordinary NOP here, not the "MZ.." pseudo-nop above. 237919385bSArd Biesheuvel */ 247919385bSArd Biesheuvel nop 257919385bSArd Biesheuvel#endif 267919385bSArd Biesheuvel .endm 277919385bSArd Biesheuvel 28b5f4a214SArd Biesheuvel .macro __EFI_PE_HEADER 297919385bSArd Biesheuvel#ifdef CONFIG_EFI 307919385bSArd Biesheuvel .set .Lpe_header_offset, . - .L_head 31f1eb542fSArd Biesheuvel .long PE_MAGIC 32f1eb542fSArd Biesheuvel .short IMAGE_FILE_MACHINE_ARM64 // Machine 33b50a3225SArd Biesheuvel .short .Lsection_count // NumberOfSections 34b5f4a214SArd Biesheuvel .long 0 // TimeDateStamp 35b5f4a214SArd Biesheuvel .long 0 // PointerToSymbolTable 36f328ba47SArd Biesheuvel .long 0 // NumberOfSymbols 37b50a3225SArd Biesheuvel .short .Lsection_table - .Loptional_header // SizeOfOptionalHeader 38f1eb542fSArd Biesheuvel .short IMAGE_FILE_DEBUG_STRIPPED | \ 39f1eb542fSArd Biesheuvel IMAGE_FILE_EXECUTABLE_IMAGE | \ 40f1eb542fSArd Biesheuvel IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics 41f1eb542fSArd Biesheuvel 42b50a3225SArd Biesheuvel.Loptional_header: 43f1eb542fSArd Biesheuvel .short PE_OPT_MAGIC_PE32PLUS // PE32+ format 44b5f4a214SArd Biesheuvel .byte 0x02 // MajorLinkerVersion 45b5f4a214SArd Biesheuvel .byte 0x14 // MinorLinkerVersion 46b50a3225SArd Biesheuvel .long __initdata_begin - .Lefi_header_end // SizeOfCode 47cad27ef2SArd Biesheuvel .long __pecoff_data_size // SizeOfInitializedData 48b5f4a214SArd Biesheuvel .long 0 // SizeOfUninitializedData 497919385bSArd Biesheuvel .long __efistub_efi_pe_entry - .L_head // AddressOfEntryPoint 507919385bSArd Biesheuvel .long .Lefi_header_end - .L_head // BaseOfCode 51b5f4a214SArd Biesheuvel 52b5f4a214SArd Biesheuvel .quad 0 // ImageBase 5376085affSArd Biesheuvel .long SEGMENT_ALIGN // SectionAlignment 54b5f4a214SArd Biesheuvel .long PECOFF_FILE_ALIGNMENT // FileAlignment 55b5f4a214SArd Biesheuvel .short 0 // MajorOperatingSystemVersion 56b5f4a214SArd Biesheuvel .short 0 // MinorOperatingSystemVersion 57148d3f71SArd Biesheuvel .short LINUX_EFISTUB_MAJOR_VERSION // MajorImageVersion 58148d3f71SArd Biesheuvel .short LINUX_EFISTUB_MINOR_VERSION // MinorImageVersion 59b5f4a214SArd Biesheuvel .short 0 // MajorSubsystemVersion 60b5f4a214SArd Biesheuvel .short 0 // MinorSubsystemVersion 61b5f4a214SArd Biesheuvel .long 0 // Win32VersionValue 62b5f4a214SArd Biesheuvel 637919385bSArd Biesheuvel .long _end - .L_head // SizeOfImage 64b5f4a214SArd Biesheuvel 65b5f4a214SArd Biesheuvel // Everything before the kernel image is considered part of the header 667919385bSArd Biesheuvel .long .Lefi_header_end - .L_head // SizeOfHeaders 67b5f4a214SArd Biesheuvel .long 0 // CheckSum 68f1eb542fSArd Biesheuvel .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem 693c66bb19SArd Biesheuvel .short IMAGE_DLL_CHARACTERISTICS_NX_COMPAT // DllCharacteristics 70b5f4a214SArd Biesheuvel .quad 0 // SizeOfStackReserve 71b5f4a214SArd Biesheuvel .quad 0 // SizeOfStackCommit 72b5f4a214SArd Biesheuvel .quad 0 // SizeOfHeapReserve 73b5f4a214SArd Biesheuvel .quad 0 // SizeOfHeapCommit 74b5f4a214SArd Biesheuvel .long 0 // LoaderFlags 75b50a3225SArd Biesheuvel .long (.Lsection_table - .) / 8 // NumberOfRvaAndSizes 76b5f4a214SArd Biesheuvel 77b5f4a214SArd Biesheuvel .quad 0 // ExportTable 78b5f4a214SArd Biesheuvel .quad 0 // ImportTable 79b5f4a214SArd Biesheuvel .quad 0 // ResourceTable 80b5f4a214SArd Biesheuvel .quad 0 // ExceptionTable 81b5f4a214SArd Biesheuvel .quad 0 // CertificationTable 82b5f4a214SArd Biesheuvel .quad 0 // BaseRelocationTable 83b5f4a214SArd Biesheuvel 84*8358098bSArd Biesheuvel#if defined(CONFIG_DEBUG_EFI) || defined(CONFIG_ARM64_BTI_KERNEL) 857919385bSArd Biesheuvel .long .Lefi_debug_table - .L_head // DebugTable 86b50a3225SArd Biesheuvel .long .Lefi_debug_table_size 87*8358098bSArd Biesheuvel 88*8358098bSArd Biesheuvel /* 89*8358098bSArd Biesheuvel * The debug table is referenced via its Relative Virtual Address (RVA), 90*8358098bSArd Biesheuvel * which is only defined for those parts of the image that are covered 91*8358098bSArd Biesheuvel * by a section declaration. Since this header is not covered by any 92*8358098bSArd Biesheuvel * section, the debug table must be emitted elsewhere. So stick it in 93*8358098bSArd Biesheuvel * the .init.rodata section instead. 94*8358098bSArd Biesheuvel * 95*8358098bSArd Biesheuvel * Note that the payloads themselves are permitted to have zero RVAs, 96*8358098bSArd Biesheuvel * which means we can simply put those right after the section headers. 97*8358098bSArd Biesheuvel */ 98*8358098bSArd Biesheuvel __INITRODATA 99*8358098bSArd Biesheuvel 100*8358098bSArd Biesheuvel .align 2 101*8358098bSArd Biesheuvel.Lefi_debug_table: 102*8358098bSArd Biesheuvel#ifdef CONFIG_DEBUG_EFI 103*8358098bSArd Biesheuvel // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY 104*8358098bSArd Biesheuvel .long 0 // Characteristics 105*8358098bSArd Biesheuvel .long 0 // TimeDateStamp 106*8358098bSArd Biesheuvel .short 0 // MajorVersion 107*8358098bSArd Biesheuvel .short 0 // MinorVersion 108*8358098bSArd Biesheuvel .long IMAGE_DEBUG_TYPE_CODEVIEW // Type 109*8358098bSArd Biesheuvel .long .Lefi_debug_entry_size // SizeOfData 110*8358098bSArd Biesheuvel .long 0 // RVA 111*8358098bSArd Biesheuvel .long .Lefi_debug_entry - .L_head // FileOffset 112*8358098bSArd Biesheuvel#endif 113*8358098bSArd Biesheuvel#ifdef CONFIG_ARM64_BTI_KERNEL 114*8358098bSArd Biesheuvel .long 0 // Characteristics 115*8358098bSArd Biesheuvel .long 0 // TimeDateStamp 116*8358098bSArd Biesheuvel .short 0 // MajorVersion 117*8358098bSArd Biesheuvel .short 0 // MinorVersion 118*8358098bSArd Biesheuvel .long IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS // Type 119*8358098bSArd Biesheuvel .long 4 // SizeOfData 120*8358098bSArd Biesheuvel .long 0 // RVA 121*8358098bSArd Biesheuvel .long .Lefi_dll_characteristics_ex - .L_head // FileOffset 122*8358098bSArd Biesheuvel#endif 123*8358098bSArd Biesheuvel .set .Lefi_debug_table_size, . - .Lefi_debug_table 124*8358098bSArd Biesheuvel .previous 125b5f4a214SArd Biesheuvel#endif 126b5f4a214SArd Biesheuvel 127b5f4a214SArd Biesheuvel // Section table 128b50a3225SArd Biesheuvel.Lsection_table: 129f1eb542fSArd Biesheuvel .ascii ".text\0\0\0" 130b50a3225SArd Biesheuvel .long __initdata_begin - .Lefi_header_end // VirtualSize 1317919385bSArd Biesheuvel .long .Lefi_header_end - .L_head // VirtualAddress 132b50a3225SArd Biesheuvel .long __initdata_begin - .Lefi_header_end // SizeOfRawData 1337919385bSArd Biesheuvel .long .Lefi_header_end - .L_head // PointerToRawData 134b5f4a214SArd Biesheuvel 135b5f4a214SArd Biesheuvel .long 0 // PointerToRelocations 136b5f4a214SArd Biesheuvel .long 0 // PointerToLineNumbers 137b5f4a214SArd Biesheuvel .short 0 // NumberOfRelocations 138b5f4a214SArd Biesheuvel .short 0 // NumberOfLineNumbers 139f1eb542fSArd Biesheuvel .long IMAGE_SCN_CNT_CODE | \ 140cad27ef2SArd Biesheuvel IMAGE_SCN_MEM_READ | \ 141cad27ef2SArd Biesheuvel IMAGE_SCN_MEM_EXECUTE // Characteristics 142cad27ef2SArd Biesheuvel 143cad27ef2SArd Biesheuvel .ascii ".data\0\0\0" 144cad27ef2SArd Biesheuvel .long __pecoff_data_size // VirtualSize 1457919385bSArd Biesheuvel .long __initdata_begin - .L_head // VirtualAddress 146cad27ef2SArd Biesheuvel .long __pecoff_data_rawsize // SizeOfRawData 1477919385bSArd Biesheuvel .long __initdata_begin - .L_head // PointerToRawData 148cad27ef2SArd Biesheuvel 149cad27ef2SArd Biesheuvel .long 0 // PointerToRelocations 150cad27ef2SArd Biesheuvel .long 0 // PointerToLineNumbers 151cad27ef2SArd Biesheuvel .short 0 // NumberOfRelocations 152cad27ef2SArd Biesheuvel .short 0 // NumberOfLineNumbers 153cad27ef2SArd Biesheuvel .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ 154f1eb542fSArd Biesheuvel IMAGE_SCN_MEM_READ | \ 155f1eb542fSArd Biesheuvel IMAGE_SCN_MEM_WRITE // Characteristics 156f1eb542fSArd Biesheuvel 157b50a3225SArd Biesheuvel .set .Lsection_count, (. - .Lsection_table) / 40 158b5f4a214SArd Biesheuvel 159b5f4a214SArd Biesheuvel#ifdef CONFIG_DEBUG_EFI 160b50a3225SArd Biesheuvel.Lefi_debug_entry: 161b5f4a214SArd Biesheuvel // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY 162b5f4a214SArd Biesheuvel .ascii "NB10" // Signature 163b5f4a214SArd Biesheuvel .long 0 // Unknown 164b5f4a214SArd Biesheuvel .long 0 // Unknown2 165b5f4a214SArd Biesheuvel .long 0 // Unknown3 166b5f4a214SArd Biesheuvel 167b5f4a214SArd Biesheuvel .asciz VMLINUX_PATH 168b5f4a214SArd Biesheuvel 169b50a3225SArd Biesheuvel .set .Lefi_debug_entry_size, . - .Lefi_debug_entry 170b5f4a214SArd Biesheuvel#endif 171*8358098bSArd Biesheuvel#ifdef CONFIG_ARM64_BTI_KERNEL 172*8358098bSArd Biesheuvel.Lefi_dll_characteristics_ex: 173*8358098bSArd Biesheuvel .long IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 174*8358098bSArd Biesheuvel#endif 175b5f4a214SArd Biesheuvel 176a2d50c1cSArd Biesheuvel .balign SEGMENT_ALIGN 177b50a3225SArd Biesheuvel.Lefi_header_end: 1787919385bSArd Biesheuvel#else 1797919385bSArd Biesheuvel .set .Lpe_header_offset, 0x0 1807919385bSArd Biesheuvel#endif 181b5f4a214SArd Biesheuvel .endm 182