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 69*3c66bb19SArd 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 84b5f4a214SArd Biesheuvel#ifdef CONFIG_DEBUG_EFI 857919385bSArd Biesheuvel .long .Lefi_debug_table - .L_head // DebugTable 86b50a3225SArd Biesheuvel .long .Lefi_debug_table_size 87b5f4a214SArd Biesheuvel#endif 88b5f4a214SArd Biesheuvel 89b5f4a214SArd Biesheuvel // Section table 90b50a3225SArd Biesheuvel.Lsection_table: 91f1eb542fSArd Biesheuvel .ascii ".text\0\0\0" 92b50a3225SArd Biesheuvel .long __initdata_begin - .Lefi_header_end // VirtualSize 937919385bSArd Biesheuvel .long .Lefi_header_end - .L_head // VirtualAddress 94b50a3225SArd Biesheuvel .long __initdata_begin - .Lefi_header_end // SizeOfRawData 957919385bSArd Biesheuvel .long .Lefi_header_end - .L_head // PointerToRawData 96b5f4a214SArd Biesheuvel 97b5f4a214SArd Biesheuvel .long 0 // PointerToRelocations 98b5f4a214SArd Biesheuvel .long 0 // PointerToLineNumbers 99b5f4a214SArd Biesheuvel .short 0 // NumberOfRelocations 100b5f4a214SArd Biesheuvel .short 0 // NumberOfLineNumbers 101f1eb542fSArd Biesheuvel .long IMAGE_SCN_CNT_CODE | \ 102cad27ef2SArd Biesheuvel IMAGE_SCN_MEM_READ | \ 103cad27ef2SArd Biesheuvel IMAGE_SCN_MEM_EXECUTE // Characteristics 104cad27ef2SArd Biesheuvel 105cad27ef2SArd Biesheuvel .ascii ".data\0\0\0" 106cad27ef2SArd Biesheuvel .long __pecoff_data_size // VirtualSize 1077919385bSArd Biesheuvel .long __initdata_begin - .L_head // VirtualAddress 108cad27ef2SArd Biesheuvel .long __pecoff_data_rawsize // SizeOfRawData 1097919385bSArd Biesheuvel .long __initdata_begin - .L_head // PointerToRawData 110cad27ef2SArd Biesheuvel 111cad27ef2SArd Biesheuvel .long 0 // PointerToRelocations 112cad27ef2SArd Biesheuvel .long 0 // PointerToLineNumbers 113cad27ef2SArd Biesheuvel .short 0 // NumberOfRelocations 114cad27ef2SArd Biesheuvel .short 0 // NumberOfLineNumbers 115cad27ef2SArd Biesheuvel .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ 116f1eb542fSArd Biesheuvel IMAGE_SCN_MEM_READ | \ 117f1eb542fSArd Biesheuvel IMAGE_SCN_MEM_WRITE // Characteristics 118f1eb542fSArd Biesheuvel 119b50a3225SArd Biesheuvel .set .Lsection_count, (. - .Lsection_table) / 40 120b5f4a214SArd Biesheuvel 121b5f4a214SArd Biesheuvel#ifdef CONFIG_DEBUG_EFI 122b5f4a214SArd Biesheuvel /* 123b5f4a214SArd Biesheuvel * The debug table is referenced via its Relative Virtual Address (RVA), 124b5f4a214SArd Biesheuvel * which is only defined for those parts of the image that are covered 125b5f4a214SArd Biesheuvel * by a section declaration. Since this header is not covered by any 126b5f4a214SArd Biesheuvel * section, the debug table must be emitted elsewhere. So stick it in 127b5f4a214SArd Biesheuvel * the .init.rodata section instead. 128b5f4a214SArd Biesheuvel * 129b5f4a214SArd Biesheuvel * Note that the EFI debug entry itself may legally have a zero RVA, 130b5f4a214SArd Biesheuvel * which means we can simply put it right after the section headers. 131b5f4a214SArd Biesheuvel */ 132b5f4a214SArd Biesheuvel __INITRODATA 133b5f4a214SArd Biesheuvel 134b5f4a214SArd Biesheuvel .align 2 135b50a3225SArd Biesheuvel.Lefi_debug_table: 136b5f4a214SArd Biesheuvel // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY 137b5f4a214SArd Biesheuvel .long 0 // Characteristics 138b5f4a214SArd Biesheuvel .long 0 // TimeDateStamp 139b5f4a214SArd Biesheuvel .short 0 // MajorVersion 140b5f4a214SArd Biesheuvel .short 0 // MinorVersion 141f1eb542fSArd Biesheuvel .long IMAGE_DEBUG_TYPE_CODEVIEW // Type 142b50a3225SArd Biesheuvel .long .Lefi_debug_entry_size // SizeOfData 143b5f4a214SArd Biesheuvel .long 0 // RVA 1447919385bSArd Biesheuvel .long .Lefi_debug_entry - .L_head // FileOffset 145b5f4a214SArd Biesheuvel 146b50a3225SArd Biesheuvel .set .Lefi_debug_table_size, . - .Lefi_debug_table 147b5f4a214SArd Biesheuvel .previous 148b5f4a214SArd Biesheuvel 149b50a3225SArd Biesheuvel.Lefi_debug_entry: 150b5f4a214SArd Biesheuvel // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY 151b5f4a214SArd Biesheuvel .ascii "NB10" // Signature 152b5f4a214SArd Biesheuvel .long 0 // Unknown 153b5f4a214SArd Biesheuvel .long 0 // Unknown2 154b5f4a214SArd Biesheuvel .long 0 // Unknown3 155b5f4a214SArd Biesheuvel 156b5f4a214SArd Biesheuvel .asciz VMLINUX_PATH 157b5f4a214SArd Biesheuvel 158b50a3225SArd Biesheuvel .set .Lefi_debug_entry_size, . - .Lefi_debug_entry 159b5f4a214SArd Biesheuvel#endif 160b5f4a214SArd Biesheuvel 161a2d50c1cSArd Biesheuvel .balign SEGMENT_ALIGN 162b50a3225SArd Biesheuvel.Lefi_header_end: 1637919385bSArd Biesheuvel#else 1647919385bSArd Biesheuvel .set .Lpe_header_offset, 0x0 1657919385bSArd Biesheuvel#endif 166b5f4a214SArd Biesheuvel .endm 167