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