1*f1de0317SLoGin ------------------------------------------------- 2*f1de0317SLoGin Building EFI Applications Using the GNU Toolchain 3*f1de0317SLoGin ------------------------------------------------- 4*f1de0317SLoGin 5*f1de0317SLoGin David Mosberger <davidm@hpl.hp.com> 6*f1de0317SLoGin 7*f1de0317SLoGin 23 September 1999 8*f1de0317SLoGin 9*f1de0317SLoGin 10*f1de0317SLoGin Copyright (c) 1999-2007 Hewlett-Packard Co. 11*f1de0317SLoGin Copyright (c) 2006-2010 Intel Co. 12*f1de0317SLoGin 13*f1de0317SLoGinLast update: 04/09/2007 14*f1de0317SLoGin 15*f1de0317SLoGin* Introduction 16*f1de0317SLoGin 17*f1de0317SLoGinThis document has two parts: the first part describes how to develop 18*f1de0317SLoGinEFI applications for IA-64,x86 and x86_64 using the GNU toolchain and the EFI 19*f1de0317SLoGindevelopment environment contained in this directory. The second part 20*f1de0317SLoGindescribes some of the more subtle aspects of how this development 21*f1de0317SLoGinenvironment works. 22*f1de0317SLoGin 23*f1de0317SLoGin 24*f1de0317SLoGin 25*f1de0317SLoGin* Part 1: Developing EFI Applications 26*f1de0317SLoGin 27*f1de0317SLoGin 28*f1de0317SLoGin** Prerequisites: 29*f1de0317SLoGin 30*f1de0317SLoGin To develop x86 and x86_64 EFI applications, the following tools are needed: 31*f1de0317SLoGin 32*f1de0317SLoGin - gcc-3.0 or newer (gcc 2.7.2 is NOT sufficient!) 33*f1de0317SLoGin As of gnu-efi-3.0b, the Redhat 8.0 toolchain is known to work, 34*f1de0317SLoGin but the Redhat 9.0 toolchain is not currently supported. 35*f1de0317SLoGin 36*f1de0317SLoGin - A version of "objcopy" that supports EFI applications. To 37*f1de0317SLoGin check if your version includes EFI support, issue the 38*f1de0317SLoGin command: 39*f1de0317SLoGin 40*f1de0317SLoGin objcopy --help 41*f1de0317SLoGin 42*f1de0317SLoGin Verify that the line "supported targets" contains the string 43*f1de0317SLoGin "efi-app-ia32" and "efi-app-x86_64" and that the "-j" option 44*f1de0317SLoGin accepts wildcards. The binutils release binutils-2.24 45*f1de0317SLoGin supports Intel64 EFI and accepts wildcard section names. 46*f1de0317SLoGin 47*f1de0317SLoGin - For debugging purposes, it's useful to have a version of 48*f1de0317SLoGin "objdump" that supports EFI applications as well. This 49*f1de0317SLoGin allows inspect and disassemble EFI binaries. 50*f1de0317SLoGin 51*f1de0317SLoGin To develop IA-64 EFI applications, the following tools are needed: 52*f1de0317SLoGin 53*f1de0317SLoGin - A version of gcc newer than July 30th 1999 (older versions 54*f1de0317SLoGin had problems with generating position independent code). 55*f1de0317SLoGin As of gnu-efi-3.0b, gcc-3.1 is known to work well. 56*f1de0317SLoGin 57*f1de0317SLoGin - A version of "objcopy" that supports EFI applications. To 58*f1de0317SLoGin check if your version includes EFI support, issue the 59*f1de0317SLoGin command: 60*f1de0317SLoGin 61*f1de0317SLoGin objcopy --help 62*f1de0317SLoGin 63*f1de0317SLoGin Verify that the line "supported targets" contains the string 64*f1de0317SLoGin "efi-app-ia64" and that the "-j" option accepts wildcards. 65*f1de0317SLoGin 66*f1de0317SLoGin - For debugging purposes, it's useful to have a version of 67*f1de0317SLoGin "objdump" that supports EFI applications as well. This 68*f1de0317SLoGin allows inspect and disassemble EFI binaries. 69*f1de0317SLoGin 70*f1de0317SLoGin 71*f1de0317SLoGin** Directory Structure 72*f1de0317SLoGin 73*f1de0317SLoGinThis EFI development environment contains the following 74*f1de0317SLoGinsubdirectories: 75*f1de0317SLoGin 76*f1de0317SLoGin inc: This directory contains the EFI-related include files. The 77*f1de0317SLoGin files are taken from Intel's EFI source distribution, except 78*f1de0317SLoGin that various fixes were applied to make it compile with the 79*f1de0317SLoGin GNU toolchain. 80*f1de0317SLoGin 81*f1de0317SLoGin lib: This directory contains the source code for Intel's EFI library. 82*f1de0317SLoGin Again, the files are taken from Intel's EFI source 83*f1de0317SLoGin distribution, with changes to make them compile with the GNU 84*f1de0317SLoGin toolchain. 85*f1de0317SLoGin 86*f1de0317SLoGin gnuefi: This directory contains the glue necessary to convert ELF64 87*f1de0317SLoGin binaries to EFI binaries. Various runtime code bits, such as 88*f1de0317SLoGin a self-relocator are included as well. This code has been 89*f1de0317SLoGin contributed by the Hewlett-Packard Company and is distributed 90*f1de0317SLoGin under the GNU GPL. 91*f1de0317SLoGin 92*f1de0317SLoGin apps: This directory contains a few simple EFI test apps. 93*f1de0317SLoGin 94*f1de0317SLoGin** Setup 95*f1de0317SLoGin 96*f1de0317SLoGinIt is necessary to edit the Makefile in the directory containing this 97*f1de0317SLoGinREADME file before EFI applications can be built. Specifically, you 98*f1de0317SLoGinshould verify that macros CC, AS, LD, AR, RANLIB, and OBJCOPY point to 99*f1de0317SLoGinthe appropriate compiler, assembler, linker, ar, and ranlib binaries, 100*f1de0317SLoGinrespectively. 101*f1de0317SLoGin 102*f1de0317SLoGinIf you're working in a cross-development environment, be sure to set 103*f1de0317SLoGinmacro ARCH to the desired target architecture ("ia32" for x86, "x86_64" for 104*f1de0317SLoGinx86_64 and "ia64" for IA-64). For convenience, this can also be done from 105*f1de0317SLoGinthe make command line (e.g., "make ARCH=ia64"). 106*f1de0317SLoGin 107*f1de0317SLoGin 108*f1de0317SLoGin** Building 109*f1de0317SLoGin 110*f1de0317SLoGinTo build the sample EFI applications provided in subdirectory "apps", 111*f1de0317SLoGinsimply invoke "make" in the toplevel directory (the directory 112*f1de0317SLoGincontaining this README file). This should build lib/libefi.a and 113*f1de0317SLoGingnuefi/libgnuefi.a first and then all the EFI applications such as a 114*f1de0317SLoGinapps/t6.efi. 115*f1de0317SLoGin 116*f1de0317SLoGin 117*f1de0317SLoGin** Running 118*f1de0317SLoGin 119*f1de0317SLoGinJust copy the EFI application (e.g., apps/t6.efi) to the EFI 120*f1de0317SLoGinfilesystem, boot EFI, and then select "Invoke EFI application" to run 121*f1de0317SLoGinthe application you want to test. Alternatively, you can invoke the 122*f1de0317SLoGinIntel-provided "nshell" application and then invoke your test binary 123*f1de0317SLoGinvia the command line interface that "nshell" provides. 124*f1de0317SLoGin 125*f1de0317SLoGin 126*f1de0317SLoGin** Writing Your Own EFI Application 127*f1de0317SLoGin 128*f1de0317SLoGinSuppose you have your own EFI application in a file called 129*f1de0317SLoGin"apps/myefiapp.c". To get this application built by the GNU EFI build 130*f1de0317SLoGinenvironment, simply add "myefiapp.efi" to macro TARGETS in 131*f1de0317SLoGinapps/Makefile. Once this is done, invoke "make" in the top level 132*f1de0317SLoGindirectory. This should result in EFI application apps/myefiapp.efi, 133*f1de0317SLoGinready for execution. 134*f1de0317SLoGin 135*f1de0317SLoGinThe GNU EFI build environment allows to write EFI applications as 136*f1de0317SLoGindescribed in Intel's EFI documentation, except for two differences: 137*f1de0317SLoGin 138*f1de0317SLoGin - The EFI application's entry point is always called "efi_main". The 139*f1de0317SLoGin declaration of this routine is: 140*f1de0317SLoGin 141*f1de0317SLoGin EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab); 142*f1de0317SLoGin 143*f1de0317SLoGin - UNICODE string literals must be written as W2U(L"Sample String") 144*f1de0317SLoGin instead of just L"Sample String". The W2U() macro is defined in 145*f1de0317SLoGin <efilib.h>. This header file also declares the function W2UCpy() 146*f1de0317SLoGin which allows to convert a wide string into a UNICODE string and 147*f1de0317SLoGin store the result in a programmer-supplied buffer. 148*f1de0317SLoGin 149*f1de0317SLoGin - Calls to EFI services should be made via uefi_call_wrapper(). This 150*f1de0317SLoGin ensures appropriate parameter passing for the architecture. 151*f1de0317SLoGin 152*f1de0317SLoGin 153*f1de0317SLoGin* Part 2: Inner Workings 154*f1de0317SLoGin 155*f1de0317SLoGinWARNING: This part contains all the gory detail of how the GNU EFI 156*f1de0317SLoGintoolchain works. Normal users do not have to worry about such 157*f1de0317SLoGindetails. Reading this part incurs a definite risk of inducing severe 158*f1de0317SLoGinheadaches or other maladies. 159*f1de0317SLoGin 160*f1de0317SLoGinThe basic idea behind the GNU EFI build environment is to use the GNU 161*f1de0317SLoGintoolchain to build a normal ELF binary that, at the end, is converted 162*f1de0317SLoGinto an EFI binary. EFI binaries are really just PE32+ binaries. PE 163*f1de0317SLoGinstands for "Portable Executable" and is the object file format 164*f1de0317SLoGinMicrosoft is using on its Windows platforms. PE is basically the COFF 165*f1de0317SLoGinobject file format with an MS-DOS2.0 compatible header slapped on in 166*f1de0317SLoGinfront of it. The "32" in PE32+ stands for 32 bits, meaning that PE32 167*f1de0317SLoGinis a 32-bit object file format. The plus in "PE32+" indicates that 168*f1de0317SLoGinthis format has been hacked to allow loading a 4GB binary anywhere in 169*f1de0317SLoGina 64-bit address space (unlike ELF64, however, this is not a full 170*f1de0317SLoGin64-bit object file format because the entire binary cannot span more 171*f1de0317SLoGinthan 4GB of address space). EFI binaries are plain PE32+ binaries 172*f1de0317SLoGinexcept that the "subsystem id" differs from normal Windows binaries. 173*f1de0317SLoGinThere are two flavors of EFI binaries: "applications" and "drivers" 174*f1de0317SLoGinand each has there own subsystem id and are identical otherwise. At 175*f1de0317SLoGinpresent, the GNU EFI build environment supports the building of EFI 176*f1de0317SLoGinapplications only, though it would be trivial to generate drivers, as 177*f1de0317SLoGinthe only difference is the subsystem id. For more details on PE32+, 178*f1de0317SLoGinsee the spec at 179*f1de0317SLoGin 180*f1de0317SLoGin http://msdn.microsoft.com/library/specs/msdn_pecoff.htm. 181*f1de0317SLoGin 182*f1de0317SLoGinIn theory, converting a suitable ELF64 binary to PE32+ is easy and 183*f1de0317SLoGincould be accomplished with the "objcopy" utility by specifying option 184*f1de0317SLoGin--target=efi-app-ia32 (x86) or --target=efi-app-ia64 (IA-64). But 185*f1de0317SLoGinlife never is that easy, so here some complicating factors: 186*f1de0317SLoGin 187*f1de0317SLoGin (1) COFF sections are very different from ELF sections. 188*f1de0317SLoGin 189*f1de0317SLoGin ELF binaries distinguish between program headers and sections. 190*f1de0317SLoGin The program headers describe the memory segments that need to 191*f1de0317SLoGin be loaded/initialized, whereas the sections describe what 192*f1de0317SLoGin constitutes those segments. In COFF (and therefore PE32+) no 193*f1de0317SLoGin such distinction is made. Thus, COFF sections need to be page 194*f1de0317SLoGin aligned and have a size that is a multiple of the page size 195*f1de0317SLoGin (4KB for EFI), whereas ELF allows sections at arbitrary 196*f1de0317SLoGin addresses and with arbitrary sizes. 197*f1de0317SLoGin 198*f1de0317SLoGin (2) EFI binaries should be relocatable. 199*f1de0317SLoGin 200*f1de0317SLoGin Since EFI binaries are executed in physical mode, EFI cannot 201*f1de0317SLoGin guarantee that a given binary can be loaded at its preferred 202*f1de0317SLoGin address. EFI does _try_ to load a binary at it's preferred 203*f1de0317SLoGin address, but if it can't do so, it will load it at another 204*f1de0317SLoGin address and then relocate the binary using the contents of the 205*f1de0317SLoGin .reloc section. 206*f1de0317SLoGin 207*f1de0317SLoGin (3) On IA-64, the EFI entry point needs to point to a function 208*f1de0317SLoGin descriptor, not to the code address of the entry point. 209*f1de0317SLoGin 210*f1de0317SLoGin (4) The EFI specification assumes that wide characters use UNICODE 211*f1de0317SLoGin encoding. 212*f1de0317SLoGin 213*f1de0317SLoGin ANSI C does not specify the size or encoding that a wide 214*f1de0317SLoGin character uses. These choices are "implementation defined". 215*f1de0317SLoGin On most UNIX systems, the GNU toolchain uses a wchar_t that is 216*f1de0317SLoGin 4 bytes in size. The encoding used for such characters is 217*f1de0317SLoGin (mostly) UCS4. 218*f1de0317SLoGin 219*f1de0317SLoGinIn the following sections, we address how the GNU EFI build 220*f1de0317SLoGinenvironment addresses each of these issues. 221*f1de0317SLoGin 222*f1de0317SLoGin 223*f1de0317SLoGin** (1) Accommodating COFF Sections 224*f1de0317SLoGin 225*f1de0317SLoGinIn order to satisfy the COFF constraint of page-sized and page-aligned 226*f1de0317SLoGinsections, the GNU EFI build environment uses the special linker script 227*f1de0317SLoGinin gnuefi/elf_$(ARCH)_efi.lds where $(ARCH) is the target architecture 228*f1de0317SLoGin("ia32" for x86, "x86_64" for x86_64 and "ia64" for IA-64). 229*f1de0317SLoGinThis script is set up to create only eight COFF section, each page aligned 230*f1de0317SLoGinand page sized.These eight sections are used to group together the much 231*f1de0317SLoGingreater number of sections that are typically present in ELF object files. 232*f1de0317SLoGinSpecifically: 233*f1de0317SLoGin 234*f1de0317SLoGin .hash (and/or .gnu.hash) 235*f1de0317SLoGin Collects the ELF .hash info (this section _must_ be the first 236*f1de0317SLoGin section in order to build a shared object file; the section is 237*f1de0317SLoGin not actually loaded or used at runtime). 238*f1de0317SLoGin 239*f1de0317SLoGin GNU binutils provides a mechanism to generate different hash info 240*f1de0317SLoGin via --hash-style=<sysv|gnu|both> option. In this case output 241*f1de0317SLoGin shared object will contain .hash section, .gnu.hash section or 242*f1de0317SLoGin both. In order to generate correct output linker script preserves 243*f1de0317SLoGin both types of hash sections. 244*f1de0317SLoGin 245*f1de0317SLoGin .text 246*f1de0317SLoGin Collects all sections containing executable code. 247*f1de0317SLoGin 248*f1de0317SLoGin .data 249*f1de0317SLoGin Collects read-only and read-write data, literal string data, 250*f1de0317SLoGin global offset tables, the uninitialized data segment (bss) and 251*f1de0317SLoGin various other sections containing data. 252*f1de0317SLoGin 253*f1de0317SLoGin The reason read-only data is placed here instead of the in 254*f1de0317SLoGin .text is to make it possible to disassemble the .text section 255*f1de0317SLoGin without getting garbage due to read-only data. Besides, since 256*f1de0317SLoGin EFI binaries execute in physical mode, differences in page 257*f1de0317SLoGin protection do not matter. 258*f1de0317SLoGin 259*f1de0317SLoGin The reason the uninitialized data is placed in this section is 260*f1de0317SLoGin that the EFI loader appears to be unable to handle sections 261*f1de0317SLoGin that are allocated but not loaded from the binary. 262*f1de0317SLoGin 263*f1de0317SLoGin .dynamic, .dynsym, .rela, .rel, .reloc 264*f1de0317SLoGin These sections contains the dynamic information necessary to 265*f1de0317SLoGin self-relocate the binary (see below). 266*f1de0317SLoGin 267*f1de0317SLoGinA couple of more points worth noting about the linker script: 268*f1de0317SLoGin 269*f1de0317SLoGin o On IA-64, the global pointer symbol (__gp) needs to be placed such 270*f1de0317SLoGin that the _entire_ EFI binary can be addressed using the signed 271*f1de0317SLoGin 22-bit offset that the "addl" instruction affords. Specifically, 272*f1de0317SLoGin this means that __gp should be placed at ImageBase + 0x200000. 273*f1de0317SLoGin Strictly speaking, only a couple of symbols need to be addressable 274*f1de0317SLoGin in this fashion, so with some care it should be possible to build 275*f1de0317SLoGin binaries much larger than 4MB. To get a list of symbols that need 276*f1de0317SLoGin to be addressable in this fashion, grep the assembly files in 277*f1de0317SLoGin directory gnuefi for the string "@gprel". 278*f1de0317SLoGin 279*f1de0317SLoGin o The link address (ImageBase) of the binary is (arbitrarily) set to 280*f1de0317SLoGin zero. This could be set to something larger to increase the chance 281*f1de0317SLoGin of EFI being able to load the binary without requiring relocation. 282*f1de0317SLoGin However, a start address of 0 makes debugging a wee bit easier 283*f1de0317SLoGin (great for those of us who can add, but not subtract... ;-). 284*f1de0317SLoGin 285*f1de0317SLoGin o The relocation related sections (.dynamic, .rel, .rela, .reloc) 286*f1de0317SLoGin cannot be placed inside .data because some tools in the GNU 287*f1de0317SLoGin toolchain rely on the existence of these sections. 288*f1de0317SLoGin 289*f1de0317SLoGin o Some sections in the ELF binary intentionally get dropped when 290*f1de0317SLoGin building the EFI binary. Particularly noteworthy are the dynamic 291*f1de0317SLoGin relocation sections for the .plabel and .reloc sections. It would 292*f1de0317SLoGin be _wrong_ to include these sections in the EFI binary because it 293*f1de0317SLoGin would result in .reloc and .plabel being relocated twice (once by 294*f1de0317SLoGin the EFI loader and once by the self-relocator; see below for a 295*f1de0317SLoGin description of the latter). Specifically, only the sections 296*f1de0317SLoGin mentioned with the -j option in the final "objcopy" command are 297*f1de0317SLoGin retained in the EFI binary (see Make.rules). 298*f1de0317SLoGin 299*f1de0317SLoGin 300*f1de0317SLoGin** (2) Building Relocatable Binaries 301*f1de0317SLoGin 302*f1de0317SLoGinELF binaries are normally linked for a fixed load address and are thus 303*f1de0317SLoGinnot relocatable. The only kind of ELF object that is relocatable are 304*f1de0317SLoGinshared objects ("shared libraries"). However, even those objects are 305*f1de0317SLoGinusually not completely position independent and therefore require 306*f1de0317SLoGinruntime relocation by the dynamic loader. For example, IA-64 binaries 307*f1de0317SLoGinnormally require relocation of the global offset table. 308*f1de0317SLoGin 309*f1de0317SLoGinThe approach to building relocatable binaries in the GNU EFI build 310*f1de0317SLoGinenvironment is to: 311*f1de0317SLoGin 312*f1de0317SLoGin (a) build an ELF shared object 313*f1de0317SLoGin 314*f1de0317SLoGin (b) link it together with a self-relocator that takes care of 315*f1de0317SLoGin applying the dynamic relocations that may be present in the 316*f1de0317SLoGin ELF shared object 317*f1de0317SLoGin 318*f1de0317SLoGin (c) convert the resulting image to an EFI binary 319*f1de0317SLoGin 320*f1de0317SLoGinThe self-relocator is of course architecture dependent. The x86 321*f1de0317SLoGinversion can be found in gnuefi/reloc_ia32.c, the x86_64 version 322*f1de0317SLoGincan be found in gnuefi/reloc_x86_64.c and the IA-64 version can be 323*f1de0317SLoGinfound in gnuefi/reloc_ia64.S. 324*f1de0317SLoGin 325*f1de0317SLoGinThe self-relocator operates as follows: the startup code invokes it 326*f1de0317SLoGinright after EFI has handed off control to the EFI binary at symbol 327*f1de0317SLoGin"_start". Upon activation, the self-relocator searches the .dynamic 328*f1de0317SLoGinsection (whose starting address is given by symbol _DYNAMIC) for the 329*f1de0317SLoGindynamic relocation information, which can be found in the DT_REL, 330*f1de0317SLoGinDT_RELSZ, and DT_RELENT entries of the dynamic table (DT_RELA, 331*f1de0317SLoGinDT_RELASZ, and DT_RELAENT in the case of rela relocations, as is the 332*f1de0317SLoGincase for IA-64). The dynamic relocation information points to the ELF 333*f1de0317SLoGinrelocation table. Once this table is found, the self-relocator walks 334*f1de0317SLoGinthrough it, applying each relocation one by one. Since the EFI 335*f1de0317SLoGinbinaries are fully resolved shared objects, only a subset of all 336*f1de0317SLoGinpossible relocations need to be supported. Specifically, on x86 only 337*f1de0317SLoGinthe R_386_RELATIVE relocation is needed. On IA-64, the relocations 338*f1de0317SLoGinR_IA64_DIR64LSB, R_IA64_REL64LSB, and R_IA64_FPTR64LSB are needed. 339*f1de0317SLoGinNote that the R_IA64_FPTR64LSB relocation requires access to the 340*f1de0317SLoGindynamic symbol table. This is why the .dynsym section is included in 341*f1de0317SLoGinthe EFI binary. Another complication is that this relocation requires 342*f1de0317SLoGinmemory to hold the function descriptors (aka "procedure labels" or 343*f1de0317SLoGin"plabels"). Each function descriptor uses 16 bytes of memory. The 344*f1de0317SLoGinIA-64 self-relocator currently reserves a static memory area that can 345*f1de0317SLoGinhold 100 of these descriptors. If the self-relocator runs out of 346*f1de0317SLoGinspace, it causes the EFI binary to fail with error code 5 347*f1de0317SLoGin(EFI_BUFFER_TOO_SMALL). When this happens, the manifest constant 348*f1de0317SLoGinMAX_FUNCTION_DESCRIPTORS in gnuefi/reloc_ia64.S should be increased 349*f1de0317SLoGinand the application recompiled. An easy way to count the number of 350*f1de0317SLoGinfunction descriptors required by an EFI application is to run the 351*f1de0317SLoGincommand: 352*f1de0317SLoGin 353*f1de0317SLoGin objdump --dynamic-reloc example.so | fgrep FPTR64 | wc -l 354*f1de0317SLoGin 355*f1de0317SLoGinassuming "example" is the name of the desired EFI application. 356*f1de0317SLoGin 357*f1de0317SLoGin 358*f1de0317SLoGin** (3) Creating the Function Descriptor for the IA-64 EFI Binaries 359*f1de0317SLoGin 360*f1de0317SLoGinAs mentioned above, the IA-64 PE32+ format assumes that the entry 361*f1de0317SLoGinpoint of the binary is a function descriptor. A function descriptors 362*f1de0317SLoGinconsists of two double words: the first one is the code entry point 363*f1de0317SLoGinand the second is the global pointer that should be loaded before 364*f1de0317SLoGincalling the entry point. Since the ELF toolchain doesn't know how to 365*f1de0317SLoGingenerate a function descriptor for the entry point, the startup code 366*f1de0317SLoGinin gnuefi/crt0-efi-ia64.S crafts one manually by with the code: 367*f1de0317SLoGin 368*f1de0317SLoGin .section .plabel, "a" 369*f1de0317SLoGin _start_plabel: 370*f1de0317SLoGin data8 _start 371*f1de0317SLoGin data8 __gp 372*f1de0317SLoGin 373*f1de0317SLoGinthis places the procedure label for entry point _start in a section 374*f1de0317SLoGincalled ".plabel". Now, the only problem is that _start and __gp need 375*f1de0317SLoGinto be relocated _before_ EFI hands control over to the EFI binary. 376*f1de0317SLoGinFortunately, PE32+ defines a section called ".reloc" that can achieve 377*f1de0317SLoGinthis. Thus, in addition to manually crafting the function descriptor, 378*f1de0317SLoGinthe startup code also crafts a ".reloc" section that has will cause 379*f1de0317SLoGinthe EFI loader to relocate the function descriptor before handing over 380*f1de0317SLoGincontrol to the EFI binary (again, see the PECOFF spec mentioned above 381*f1de0317SLoGinfor details). 382*f1de0317SLoGin 383*f1de0317SLoGinA final question may be why .plabel and .reloc need to go in their own 384*f1de0317SLoGinCOFF sections. The answer is simply: we need to be able to discard 385*f1de0317SLoGinthe relocation entries that are generated for these sections. By 386*f1de0317SLoGinplacing them in these sections, the relocations end up in sections 387*f1de0317SLoGin".rela.plabel" and ".rela.reloc" which makes it easy to filter them 388*f1de0317SLoGinout in the filter script. Also, the ".reloc" section needs to be in 389*f1de0317SLoGinits own section so that the objcopy program can recognize it and can 390*f1de0317SLoGincreate the correct directory entries in the PE32+ binary. 391*f1de0317SLoGin 392*f1de0317SLoGin 393*f1de0317SLoGin** (4) Convenient and Portable Generation of UNICODE String Literals 394*f1de0317SLoGin 395*f1de0317SLoGinAs of gnu-efi-3.0, we make use (and somewhat abuse) the gcc option 396*f1de0317SLoGinthat forces wide characters (WCHAR_T) to use short integers (2 bytes) 397*f1de0317SLoGininstead of integers (4 bytes). This way we match the Unicode character 398*f1de0317SLoGinsize. By abuse, we mean that we rely on the fact that the regular ASCII 399*f1de0317SLoGincharacters are encoded the same way between (short) wide characters 400*f1de0317SLoGinand Unicode and basically only use the first byte. This allows us 401*f1de0317SLoGinto just use them interchangeably. 402*f1de0317SLoGin 403*f1de0317SLoGinThe gcc option to force short wide characters is : -fshort-wchar 404*f1de0317SLoGin 405*f1de0317SLoGin * * * The End * * * 406