summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2008-11-18 23:30:37 +0100
committerMichael Brown2008-12-05 01:06:27 +0100
commitce0a0ccf5c2b99be684f13a9418d1556bae5f0ed (patch)
tree965c86dafc3fbdca8e46ee22b94387242cc0e288
parent[hermon] Fix permissions broken in 3a799e9 ("Add PCI ID for ConnectX QDR card") (diff)
downloadipxe-ce0a0ccf5c2b99be684f13a9418d1556bae5f0ed.tar.gz
ipxe-ce0a0ccf5c2b99be684f13a9418d1556bae5f0ed.tar.xz
ipxe-ce0a0ccf5c2b99be684f13a9418d1556bae5f0ed.zip
[x86_64] Add support for compilation as an x86_64 binary
Currently the only supported platform for x86_64 is EFI. Building an EFI64 gPXE requires a version of gcc that supports __attribute__((ms_abi)). This currently means a development build of gcc; the feature should be present when gcc 4.4 is released. In the meantime; you can grab a suitable gcc tree from git://git.etherboot.org/scm/people/mcb30/gcc/.git
-rw-r--r--src/arch/i386/Makefile6
-rw-r--r--src/arch/i386/include/bits/byteswap.h45
-rw-r--r--src/arch/i386/include/bits/stdint.h4
-rw-r--r--src/arch/x86/Makefile8
-rw-r--r--src/arch/x86/core/pcidirect.c (renamed from src/arch/i386/core/pcidirect.c)1
-rw-r--r--src/arch/x86/core/x86_string.c (renamed from src/arch/i386/core/i386_string.c)4
-rw-r--r--src/arch/x86/include/bits/pci_io.h (renamed from src/arch/i386/include/bits/pci_io.h)0
-rw-r--r--src/arch/x86/include/bits/string.h (renamed from src/arch/i386/include/bits/string.h)4
-rw-r--r--src/arch/x86/include/gpxe/efi/efix86_nap.h (renamed from src/arch/i386/include/gpxe/efi/efix86_nap.h)0
-rw-r--r--src/arch/x86/include/gpxe/pcibios.h (renamed from src/arch/i386/include/gpxe/pcibios.h)0
-rw-r--r--src/arch/x86/include/gpxe/pcidirect.h (renamed from src/arch/i386/include/gpxe/pcidirect.h)0
-rw-r--r--src/arch/x86/interface/efi/efix86_nap.c (renamed from src/arch/i386/interface/efi/efix86_nap.c)0
-rw-r--r--src/arch/x86_64/Makefile41
-rw-r--r--src/arch/x86_64/Makefile.efi28
-rw-r--r--src/arch/x86_64/include/bits/byteswap.h22
-rw-r--r--src/arch/x86_64/include/bits/compiler.h14
-rw-r--r--src/arch/x86_64/include/bits/endian.h6
-rw-r--r--src/arch/x86_64/include/bits/errfile.h11
-rw-r--r--src/arch/x86_64/include/bits/io.h10
-rw-r--r--src/arch/x86_64/include/bits/nap.h12
-rw-r--r--src/arch/x86_64/include/bits/smbios.h10
-rw-r--r--src/arch/x86_64/include/bits/stdint.h21
-rw-r--r--src/arch/x86_64/include/bits/timer.h10
-rw-r--r--src/arch/x86_64/include/bits/uaccess.h10
-rw-r--r--src/arch/x86_64/include/bits/umalloc.h10
-rw-r--r--src/arch/x86_64/include/gdbmach.h51
-rw-r--r--src/arch/x86_64/include/limits.h59
-rw-r--r--src/arch/x86_64/prefix/efiprefix.S174
-rw-r--r--src/arch/x86_64/scripts/efi.lds180
-rw-r--r--src/include/byteswap.h35
-rw-r--r--src/include/compiler.h9
-rw-r--r--src/include/gpxe/efi/ProcessorBind.h4
-rw-r--r--src/include/gpxe/efi/X64/ProcessorBind.h247
-rw-r--r--src/util/efilink.c12
34 files changed, 997 insertions, 51 deletions
diff --git a/src/arch/i386/Makefile b/src/arch/i386/Makefile
index e376b481..1392bbac 100644
--- a/src/arch/i386/Makefile
+++ b/src/arch/i386/Makefile
@@ -68,7 +68,6 @@ SRCDIRS += arch/i386/drivers/net
SRCDIRS += arch/i386/interface/pcbios
SRCDIRS += arch/i386/interface/pxe
SRCDIRS += arch/i386/interface/syslinux
-SRCDIRS += arch/i386/interface/efi
# The various xxx_loader.c files are #included into core/loader.c and
# should not be compiled directly.
@@ -82,6 +81,11 @@ NON_AUTO_SRCS += arch/i386/core/wince_loader.c
OBJS_unnrv2b = unnrv2b unnrv2b16
CFLAGS_unnrv2b16 = -DCODE16
+# Include common x86 Makefile
+#
+MAKEDEPS += arch/x86/Makefile
+include arch/x86/Makefile
+
# Include platform-specific Makefile
#
MAKEDEPS += arch/i386/Makefile.$(PLATFORM)
diff --git a/src/arch/i386/include/bits/byteswap.h b/src/arch/i386/include/bits/byteswap.h
index 54b93ab9..98418c29 100644
--- a/src/arch/i386/include/bits/byteswap.h
+++ b/src/arch/i386/include/bits/byteswap.h
@@ -2,7 +2,7 @@
#define ETHERBOOT_BITS_BYTESWAP_H
static inline __attribute__ ((always_inline, const)) uint16_t
-__i386_bswap_16(uint16_t x)
+__bswap_variable_16(uint16_t x)
{
__asm__("xchgb %b0,%h0\n\t"
: "=q" (x)
@@ -11,7 +11,7 @@ __i386_bswap_16(uint16_t x)
}
static inline __attribute__ ((always_inline, const)) uint32_t
-__i386_bswap_32(uint32_t x)
+__bswap_variable_32(uint32_t x)
{
__asm__("xchgb %b0,%h0\n\t"
"rorl $16,%0\n\t"
@@ -22,7 +22,7 @@ __i386_bswap_32(uint32_t x)
}
static inline __attribute__ ((always_inline, const)) uint64_t
-__i386_bswap_64(uint64_t x)
+__bswap_variable_64(uint64_t x)
{
union {
uint64_t qword;
@@ -30,47 +30,12 @@ __i386_bswap_64(uint64_t x)
} u;
u.qword = x;
- u.dword[0] = __i386_bswap_32(u.dword[0]);
- u.dword[1] = __i386_bswap_32(u.dword[1]);
+ u.dword[0] = __bswap_variable_32(u.dword[0]);
+ u.dword[1] = __bswap_variable_32(u.dword[1]);
__asm__("xchgl %0,%1"
: "=r" ( u.dword[0] ), "=r" ( u.dword[1] )
: "0" ( u.dword[0] ), "1" ( u.dword[1] ) );
return u.qword;
}
-#define __bswap_constant_16(x) \
- ((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
- (((uint16_t)(x) & 0xff00) >> 8)))
-
-#define __bswap_constant_32(x) \
- ((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
- (((uint32_t)(x) & 0x0000ff00U) << 8) | \
- (((uint32_t)(x) & 0x00ff0000U) >> 8) | \
- (((uint32_t)(x) & 0xff000000U) >> 24)))
-
-#define __bswap_constant_64(x) \
- ((uint64_t)((((uint64_t)(x) & 0x00000000000000ffULL) << 56) | \
- (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
- (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
- (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
- (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
- (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
- (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
- (((uint64_t)(x) & 0xff00000000000000ULL) >> 56)))
-
-#define __bswap_16(x) \
- ((uint16_t)(__builtin_constant_p(x) ? \
- __bswap_constant_16(x) : \
- __i386_bswap_16(x)))
-
-#define __bswap_32(x) \
- ((uint32_t)(__builtin_constant_p(x) ? \
- __bswap_constant_32(x) : \
- __i386_bswap_32(x)))
-
-#define __bswap_64(x) \
- ((uint64_t)(__builtin_constant_p(x) ? \
- __bswap_constant_64(x) : \
- __i386_bswap_64(x)))
-
#endif /* ETHERBOOT_BITS_BYTESWAP_H */
diff --git a/src/arch/i386/include/bits/stdint.h b/src/arch/i386/include/bits/stdint.h
index 1c9706c1..6ccf0971 100644
--- a/src/arch/i386/include/bits/stdint.h
+++ b/src/arch/i386/include/bits/stdint.h
@@ -1,8 +1,8 @@
#ifndef _BITS_STDINT_H
#define _BITS_STDINT_H
-typedef typeof(sizeof(int)) size_t;
-typedef signed long ssize_t;
+typedef unsigned int size_t;
+typedef signed int ssize_t;
typedef signed long off_t;
typedef unsigned char uint8_t;
diff --git a/src/arch/x86/Makefile b/src/arch/x86/Makefile
new file mode 100644
index 00000000..9ac75b45
--- /dev/null
+++ b/src/arch/x86/Makefile
@@ -0,0 +1,8 @@
+# Include common x86 headers
+#
+CFLAGS += -Iarch/x86/include
+
+# x86-specific directories containing source files
+#
+SRCDIRS += arch/x86/core
+SRCDIRS += arch/x86/interface/efi
diff --git a/src/arch/i386/core/pcidirect.c b/src/arch/x86/core/pcidirect.c
index fec2e3c1..db17215e 100644
--- a/src/arch/i386/core/pcidirect.c
+++ b/src/arch/x86/core/pcidirect.c
@@ -16,6 +16,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <gpxe/io.h>
#include <gpxe/pci.h>
/** @file
diff --git a/src/arch/i386/core/i386_string.c b/src/arch/x86/core/x86_string.c
index 9917363a..c0224c7a 100644
--- a/src/arch/i386/core/i386_string.c
+++ b/src/arch/x86/core/x86_string.c
@@ -32,9 +32,7 @@
* @v len Length
* @ret dest Destination address
*/
-__attribute__ (( regparm ( 3 ) )) void * __memcpy ( void *dest,
- const void *src,
- size_t len ) {
+void * __memcpy ( void *dest, const void *src, size_t len ) {
void *edi = dest;
const void *esi = src;
int discard_ecx;
diff --git a/src/arch/i386/include/bits/pci_io.h b/src/arch/x86/include/bits/pci_io.h
index 0fbb439d..0fbb439d 100644
--- a/src/arch/i386/include/bits/pci_io.h
+++ b/src/arch/x86/include/bits/pci_io.h
diff --git a/src/arch/i386/include/bits/string.h b/src/arch/x86/include/bits/string.h
index c05a7df8..42ddeddf 100644
--- a/src/arch/i386/include/bits/string.h
+++ b/src/arch/x86/include/bits/string.h
@@ -23,9 +23,7 @@
#define __HAVE_ARCH_MEMCPY
-extern __attribute__ (( regparm ( 3 ) )) void * __memcpy ( void *dest,
- const void *src,
- size_t len );
+extern void * __memcpy ( void *dest, const void *src, size_t len );
#if 0
static inline __attribute__ (( always_inline )) void *
diff --git a/src/arch/i386/include/gpxe/efi/efix86_nap.h b/src/arch/x86/include/gpxe/efi/efix86_nap.h
index 91424c54..91424c54 100644
--- a/src/arch/i386/include/gpxe/efi/efix86_nap.h
+++ b/src/arch/x86/include/gpxe/efi/efix86_nap.h
diff --git a/src/arch/i386/include/gpxe/pcibios.h b/src/arch/x86/include/gpxe/pcibios.h
index b86f5abd..b86f5abd 100644
--- a/src/arch/i386/include/gpxe/pcibios.h
+++ b/src/arch/x86/include/gpxe/pcibios.h
diff --git a/src/arch/i386/include/gpxe/pcidirect.h b/src/arch/x86/include/gpxe/pcidirect.h
index fe433c6f..fe433c6f 100644
--- a/src/arch/i386/include/gpxe/pcidirect.h
+++ b/src/arch/x86/include/gpxe/pcidirect.h
diff --git a/src/arch/i386/interface/efi/efix86_nap.c b/src/arch/x86/interface/efi/efix86_nap.c
index 45e99a68..45e99a68 100644
--- a/src/arch/i386/interface/efi/efix86_nap.c
+++ b/src/arch/x86/interface/efi/efix86_nap.c
diff --git a/src/arch/x86_64/Makefile b/src/arch/x86_64/Makefile
new file mode 100644
index 00000000..d2c2ff53
--- /dev/null
+++ b/src/arch/x86_64/Makefile
@@ -0,0 +1,41 @@
+# Code size reduction.
+#
+CFLAGS += -fstrength-reduce -fomit-frame-pointer
+
+# Code size reduction. gcc3 needs a different syntax to gcc2 if you
+# want to avoid spurious warnings.
+#
+CFLAGS += -falign-jumps=1 -falign-loops=1 -falign-functions=1
+
+# Use %rip-relative addressing wherever possible.
+#
+CFLAGS += -fpie
+
+# Force 64-bit code
+#
+CFLAGS += -m64
+ASFLAGS += --64
+LDFLAGS += -m elf_x86_64
+
+# EFI requires -fshort-wchar, and nothing else currently uses wchar_t
+#
+CFLAGS += -fshort-wchar
+
+# We need to undefine the default macro "i386" when compiling .S
+# files, otherwise ".arch i386" translates to ".arch 1"...
+#
+CFLAGS += -Ui386
+
+# x86_64-specific directories containing source files
+#
+SRCDIRS += arch/x86_64/prefix
+
+# Include common x86 Makefile
+#
+MAKEDEPS += arch/x86/Makefile
+include arch/x86/Makefile
+
+# Include platform-specific Makefile
+#
+MAKEDEPS += arch/x86_64/Makefile.$(PLATFORM)
+include arch/x86_64/Makefile.$(PLATFORM)
diff --git a/src/arch/x86_64/Makefile.efi b/src/arch/x86_64/Makefile.efi
new file mode 100644
index 00000000..7e07088d
--- /dev/null
+++ b/src/arch/x86_64/Makefile.efi
@@ -0,0 +1,28 @@
+# -*- makefile -*- : Force emacs to use Makefile mode
+
+# EFI probably doesn't guarantee us a red zone, so let's not rely on it.
+#
+CFLAGS += -mno-red-zone
+
+# The EFI linker script
+#
+LDSCRIPT = arch/x86_64/scripts/efi.lds
+
+# Use a relocatable link; we perform final relocations in the efilink utility.
+#
+LDFLAGS += -r -d -S
+
+# Media types.
+#
+NON_AUTO_MEDIA += efi
+
+# Rule for building EFI files
+#
+$(BIN)/%.efi.tmp-reloc : $(BIN)/%.efi.tmp $(EFILINK)
+ $(QM)$(ECHO) " [EFILINK] $@"
+ $(Q)$(LD) -e 0 -o /dev/null $< # Check for unresolved symbols
+ $(Q)$(EFILINK) $< $@
+
+$(BIN)/%.efi : $(BIN)/%.efi.tmp-reloc
+ $(QM)$(ECHO) " [FINISH] $@"
+ $(Q)$(OBJCOPY) -Obinary $< $@
diff --git a/src/arch/x86_64/include/bits/byteswap.h b/src/arch/x86_64/include/bits/byteswap.h
new file mode 100644
index 00000000..9ed85e8f
--- /dev/null
+++ b/src/arch/x86_64/include/bits/byteswap.h
@@ -0,0 +1,22 @@
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H
+
+static inline __attribute__ (( always_inline, const )) uint16_t
+__bswap_variable_16 ( uint16_t x ) {
+ __asm__ ( "xchgb %b0,%h0" : "=Q" ( x ) : "0" ( x ) );
+ return x;
+}
+
+static inline __attribute__ (( always_inline, const )) uint32_t
+__bswap_variable_32 ( uint32_t x ) {
+ __asm__ ( "bswapl %k0" : "=r" ( x ) : "0" ( x ) );
+ return x;
+}
+
+static inline __attribute__ (( always_inline, const )) uint64_t
+__bswap_variable_64 ( uint64_t x ) {
+ __asm__ ( "bswapq %q0" : "=r" ( x ) : "0" ( x ) );
+ return x;
+}
+
+#endif /* _BITS_BYTESWAP_H */
diff --git a/src/arch/x86_64/include/bits/compiler.h b/src/arch/x86_64/include/bits/compiler.h
new file mode 100644
index 00000000..51a7eaae
--- /dev/null
+++ b/src/arch/x86_64/include/bits/compiler.h
@@ -0,0 +1,14 @@
+#ifndef _BITS_COMPILER_H
+#define _BITS_COMPILER_H
+
+#ifndef ASSEMBLY
+
+/** Declare a function with standard calling conventions */
+#define __asmcall __attribute__ (( regparm(0) ))
+
+/** Declare a function with libgcc implicit linkage */
+#define __libgcc
+
+#endif /* ASSEMBLY */
+
+#endif /* _BITS_COMPILER_H */
diff --git a/src/arch/x86_64/include/bits/endian.h b/src/arch/x86_64/include/bits/endian.h
new file mode 100644
index 00000000..413e702d
--- /dev/null
+++ b/src/arch/x86_64/include/bits/endian.h
@@ -0,0 +1,6 @@
+#ifndef ETHERBOOT_BITS_ENDIAN_H
+#define ETHERBOOT_BITS_ENDIAN_H
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+#endif /* ETHERBOOT_BITS_ENDIAN_H */
diff --git a/src/arch/x86_64/include/bits/errfile.h b/src/arch/x86_64/include/bits/errfile.h
new file mode 100644
index 00000000..dcda26ba
--- /dev/null
+++ b/src/arch/x86_64/include/bits/errfile.h
@@ -0,0 +1,11 @@
+#ifndef _BITS_ERRFILE_H
+#define _BITS_ERRFILE_H
+
+/**
+ * @addtogroup errfile Error file identifiers
+ * @{
+ */
+
+/** @} */
+
+#endif /* _BITS_ERRFILE_H */
diff --git a/src/arch/x86_64/include/bits/io.h b/src/arch/x86_64/include/bits/io.h
new file mode 100644
index 00000000..921fdcc0
--- /dev/null
+++ b/src/arch/x86_64/include/bits/io.h
@@ -0,0 +1,10 @@
+#ifndef _BITS_IO_H
+#define _BITS_IO_H
+
+/** @file
+ *
+ * x86_64-specific I/O API implementations
+ *
+ */
+
+#endif /* _BITS_IO_H */
diff --git a/src/arch/x86_64/include/bits/nap.h b/src/arch/x86_64/include/bits/nap.h
new file mode 100644
index 00000000..0a0c8a24
--- /dev/null
+++ b/src/arch/x86_64/include/bits/nap.h
@@ -0,0 +1,12 @@
+#ifndef _BITS_NAP_H
+#define _BITS_NAP_H
+
+/** @file
+ *
+ * x86_64-specific CPU sleeping API implementations
+ *
+ */
+
+#include <gpxe/efi/efix86_nap.h>
+
+#endif /* _BITS_MAP_H */
diff --git a/src/arch/x86_64/include/bits/smbios.h b/src/arch/x86_64/include/bits/smbios.h
new file mode 100644
index 00000000..2f0118d0
--- /dev/null
+++ b/src/arch/x86_64/include/bits/smbios.h
@@ -0,0 +1,10 @@
+#ifndef _BITS_SMBIOS_H
+#define _BITS_SMBIOS_H
+
+/** @file
+ *
+ * i386-specific SMBIOS API implementations
+ *
+ */
+
+#endif /* _BITS_SMBIOS_H */
diff --git a/src/arch/x86_64/include/bits/stdint.h b/src/arch/x86_64/include/bits/stdint.h
new file mode 100644
index 00000000..23bae9c4
--- /dev/null
+++ b/src/arch/x86_64/include/bits/stdint.h
@@ -0,0 +1,21 @@
+#ifndef _BITS_STDINT_H
+#define _BITS_STDINT_H
+
+typedef unsigned long size_t;
+typedef signed long ssize_t;
+typedef signed long off_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+typedef signed long long int64_t;
+
+typedef unsigned long physaddr_t;
+typedef unsigned long intptr_t;
+
+#endif /* _BITS_STDINT_H */
diff --git a/src/arch/x86_64/include/bits/timer.h b/src/arch/x86_64/include/bits/timer.h
new file mode 100644
index 00000000..dfa6c270
--- /dev/null
+++ b/src/arch/x86_64/include/bits/timer.h
@@ -0,0 +1,10 @@
+#ifndef _BITS_TIMER_H
+#define _BITS_TIMER_H
+
+/** @file
+ *
+ * x86_64-specific timer API implementations
+ *
+ */
+
+#endif /* _BITS_TIMER_H */
diff --git a/src/arch/x86_64/include/bits/uaccess.h b/src/arch/x86_64/include/bits/uaccess.h
new file mode 100644
index 00000000..45582924
--- /dev/null
+++ b/src/arch/x86_64/include/bits/uaccess.h
@@ -0,0 +1,10 @@
+#ifndef _BITS_UACCESS_H
+#define _BITS_UACCESS_H
+
+/** @file
+ *
+ * x86_64-specific user access API implementations
+ *
+ */
+
+#endif /* _BITS_UACCESS_H */
diff --git a/src/arch/x86_64/include/bits/umalloc.h b/src/arch/x86_64/include/bits/umalloc.h
new file mode 100644
index 00000000..12bf949d
--- /dev/null
+++ b/src/arch/x86_64/include/bits/umalloc.h
@@ -0,0 +1,10 @@
+#ifndef _BITS_UMALLOC_H
+#define _BITS_UMALLOC_H
+
+/** @file
+ *
+ * x86_64-specific user memory allocation API implementations
+ *
+ */
+
+#endif /* _BITS_UMALLOC_H */
diff --git a/src/arch/x86_64/include/gdbmach.h b/src/arch/x86_64/include/gdbmach.h
new file mode 100644
index 00000000..fcf8e94e
--- /dev/null
+++ b/src/arch/x86_64/include/gdbmach.h
@@ -0,0 +1,51 @@
+#ifndef GDBMACH_H
+#define GDBMACH_H
+
+/** @file
+ *
+ * GDB architecture specifics
+ *
+ * This file declares functions for manipulating the machine state and
+ * debugging context.
+ *
+ */
+
+#include <stdint.h>
+
+typedef unsigned long gdbreg_t;
+
+/* The register snapshot, this must be in sync with interrupt handler and the
+ * GDB protocol. */
+enum {
+ // STUB: don't expect this to work!
+ GDBMACH_EIP,
+ GDBMACH_EFLAGS,
+ GDBMACH_NREGS,
+ GDBMACH_SIZEOF_REGS = GDBMACH_NREGS * sizeof ( gdbreg_t )
+};
+
+/* Breakpoint types */
+enum {
+ GDBMACH_BPMEM,
+ GDBMACH_BPHW,
+ GDBMACH_WATCH,
+ GDBMACH_RWATCH,
+ GDBMACH_AWATCH,
+};
+
+static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
+ regs [ GDBMACH_EIP ] = pc;
+}
+
+static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
+ regs [ GDBMACH_EFLAGS ] &= ~( 1 << 8 ); /* Trace Flag (TF) */
+ regs [ GDBMACH_EFLAGS ] |= ( step << 8 );
+}
+
+static inline void gdbmach_breakpoint ( void ) {
+ __asm__ __volatile__ ( "int $3\n" );
+}
+
+extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len, int enable );
+
+#endif /* GDBMACH_H */
diff --git a/src/arch/x86_64/include/limits.h b/src/arch/x86_64/include/limits.h
new file mode 100644
index 00000000..8cf87b47
--- /dev/null
+++ b/src/arch/x86_64/include/limits.h
@@ -0,0 +1,59 @@
+#ifndef LIMITS_H
+#define LIMITS_H 1
+
+/* Number of bits in a `char' */
+#define CHAR_BIT 8
+
+/* Minimum and maximum values a `signed char' can hold */
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+
+/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
+#define UCHAR_MAX 255
+
+/* Minimum and maximum values a `char' can hold */
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX SCHAR_MAX
+
+/* Minimum and maximum values a `signed short int' can hold */
+#define SHRT_MIN (-32768)
+#define SHRT_MAX 32767
+
+/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */
+#define USHRT_MAX 65535
+
+
+/* Minimum and maximum values a `signed int' can hold */
+#define INT_MIN (-INT_MAX - 1)
+#define INT_MAX 2147483647
+
+/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
+#define UINT_MAX 4294967295U
+
+
+/* Minimum and maximum values a `signed int' can hold */
+#define INT_MAX 2147483647
+#define INT_MIN (-INT_MAX - 1)
+
+
+/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
+#define UINT_MAX 4294967295U
+
+
+/* Minimum and maximum values a `signed long' can hold */
+#define LONG_MAX 9223372036854775807L
+#define LONG_MIN (-LONG_MAX - 1L)
+
+/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
+#define ULONG_MAX 18446744073709551615UL
+
+/* Minimum and maximum values a `signed long long' can hold */
+#define LLONG_MAX 9223372036854775807LL
+#define LLONG_MIN (-LONG_MAX - 1LL)
+
+
+/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */
+#define ULLONG_MAX 18446744073709551615ULL
+
+
+#endif /* LIMITS_H */
diff --git a/src/arch/x86_64/prefix/efiprefix.S b/src/arch/x86_64/prefix/efiprefix.S
new file mode 100644
index 00000000..a3b503b8
--- /dev/null
+++ b/src/arch/x86_64/prefix/efiprefix.S
@@ -0,0 +1,174 @@
+ .text
+ .code32
+ .arch i386
+ .section ".prefix", "a", @progbits
+ .org 0x00
+
+ /* DOS (.com) header
+ *
+ * EFI executables seem to leave most of this empty
+ */
+mzhdr:
+ .ascii "MZ" /* Magic number */
+ .word 0 /* Bytes on last page of file */
+ .word 0 /* Pages in file */
+ .word 0 /* Relocations */
+ .word 0 /* Size of header in paragraphs */
+ .word 0 /* Minimum extra paragraphs needed */
+ .word 0 /* Maximum extra paragraphs needed */
+ .word 0 /* Initial (relative) SS value */
+ .word 0 /* Initial SP value */
+ .word 0 /* "Checksum" */
+ .word 0 /* Initial IP value */
+ .word 0 /* Initial (relative) CS value */
+ .word 0 /* File address of relocation table */
+ .word 0 /* Ovesrlay number */
+ .word 0, 0, 0, 0 /* Reserved words */
+ .word 0 /* OEM identifier (for e_oeminfo) */
+ .word 0 /* OEM information; e_oemid specific */
+ .word 0, 0, 0, 0, 0 /* Reserved words */
+ .word 0, 0, 0, 0, 0 /* Reserved words */
+ .long pehdr_lma /* File address of new exe header */
+ .size mzhdr, . - mzhdr
+
+ /* PE header */
+ .org 0xc0 /* For compatibility with MS toolchain */
+pehdr:
+ .ascii "PE\0\0" /* Magic number */
+ .word 0x8664 /* CPU architecture: x86_64 */
+ .word num_pe_sections /* Number of sections */
+ .long 0x10d1a884 /* Timestamp */
+ .long 0 /* Symbol table */
+ .long 0 /* Number of symbols */
+ .word opthdr_size /* Size of optional header */
+ .word 0x2002 /* Characteristics */
+ .size pehdr, . - pehdr
+ .equ pehdr_lma, pehdr - mzhdr
+
+ /* "Optional" header */
+opthdr:
+ .word 0x020b /* Magic number */
+ .byte 0 /* Linker major version number */
+ .byte 0 /* Linker minor version number */
+ .long _text_filesz /* Size of text section */
+ .long _data_filesz /* Size of data section */
+ .long _bss_filesz /* Size of bss section */
+ .long efi_entry_lma /* Entry point */
+ .long _text_lma /* Text section start RVA */
+ .quad 0 /* Image base address */
+ .long _max_align /* Section alignment */
+ .long _max_align /* File alignment */
+ .word 0 /* Operating system major version number */
+ .word 0 /* Operating system minor version number */
+ .word 0 /* Image major version number */
+ .word 0 /* Image minor version number */
+ .word 0 /* Subsystem major version number */
+ .word 0 /* Subsystem minor version number */
+ .long 0 /* Reserved */
+ .long _filesz /* Total image size */
+ .long _prefix_filesz /* Total header size */
+ .long 0 /* "Checksum" */
+ .word 0x0a /* Subsystem: EFI */
+ .word 0 /* DLL characteristics */
+ .quad 0 /* Size of stack reserve */
+ .quad 0 /* Size of stack commit */
+ .quad 0 /* Size of heap reserve */
+ .quad 0 /* Size of heap commit */
+ .long 0 /* Loader flags */
+ .long 16 /* Number of data directory entries */
+ .long 0, 0 /* Export directory */
+ .long 0, 0 /* Import directory */
+ .long 0, 0 /* Resource directory */
+ .long 0, 0 /* Exception directory */
+ .long 0, 0 /* Security directory */
+ .long _reloc_lma, _reloc_filesz /* Base relocation directory */
+ .long debugdir_lma, debugdir_size /* Debug directory */
+ .long 0, 0 /* Description directory */
+ .long 0, 0 /* Special directory */
+ .long 0, 0 /* Thread storage directory */
+ .long 0, 0 /* Load configuration directory */
+ .long 0, 0 /* Bound import directory */
+ .long 0, 0 /* Import address table directory */
+ .long 0, 0 /* Delay import directory */
+ .long 0, 0 /* Reserved */
+ .long 0, 0 /* Reserved */
+ .size opthdr, . - opthdr
+ .equ opthdr_size, . - opthdr
+
+ /* PE sections */
+pe_sections:
+text_section:
+ .asciz ".text" /* Section name */
+ .align 8
+ .long _text_filesz /* Section size */
+ .long _text_lma /* Relative Virtual Address */
+ .long _text_filesz /* Section size (rounded up) */
+ .long _text_lma /* Pointer to raw data */
+ .long 0 /* Link-time relocations */
+ .long 0 /* Line numbers */
+ .word 0 /* Number of link-time relocations */
+ .word 0 /* Number of line numbers */
+ .long 0x68000020 /* Characteristics */
+rodata_section:
+ .asciz ".rodata" /* Section name */
+ .align 8
+ .long _rodata_filesz /* Section size */
+ .long _rodata_lma /* Relative Virtual Address */
+ .long _rodata_filesz /* Section size (rounded up) */
+ .long _rodata_lma /* Pointer to raw data */
+ .long 0 /* Link-time relocations */
+ .long 0 /* Line numbers */
+ .word 0 /* Number of link-time relocations */
+ .word 0 /* Number of line numbers */
+ .long 0x48000040 /* Characteristics */
+data_section:
+ .asciz ".data" /* Section name */
+ .align 8
+ .long _data_filesz /* Section size */
+ .long _data_lma /* Relative Virtual Address */
+ .long _data_filesz /* Section size (rounded up) */
+ .long _data_lma /* Pointer to raw data */
+ .long 0 /* Link-time relocations */
+ .long 0 /* Line numbers */
+ .word 0 /* Number of link-time relocations */
+ .word 0 /* Number of line numbers */
+ .long 0xc8000040 /* Characteristics */
+reloc_section:
+ .asciz ".reloc" /* Section name */
+ .align 8
+ .long _reloc_filesz /* Section size */
+ .long _reloc_lma /* Relative Virtual Address */
+ .long _reloc_filesz /* Section size (rounded up) */
+ .long _reloc_lma /* Pointer to raw data */
+ .long 0 /* Link-time relocations */
+ .long 0 /* Line numbers */
+ .word 0 /* Number of link-time relocations */
+ .word 0 /* Number of line numbers */
+ .long 0x42000040 /* Characteristics */
+
+pe_sections_end:
+ .size pe_sections, . - pe_sections
+ .equ num_pe_sections, ( ( . - pe_sections ) / 0x28 )
+
+ /* Debug directory */
+ .section ".rodata"
+ .globl debugdir
+debugdir:
+ .long 0 /* Characteristics */
+ .long 0x10d1a884 /* Timestamp */
+ .word 0 /* Major version */
+ .word 0 /* Minor version */
+ .long 0x02 /* RSDS? */
+ .long codeview_rsds_size /* Size of data */
+ .long codeview_rsds_lma /* RVA */
+ .long codeview_rsds_lma /* File offset */
+ .size debugdir, . - debugdir
+ .equ debugdir_size, . - debugdir
+ /* Codeview structure */
+ .globl codeview_rsds
+codeview_rsds:
+ .ascii "RSDS" /* Magic number */
+ .long 0, 0, 0, 0, 0 /* Unused by EFI */
+ .asciz "efiprefix.pdb"
+ .size codeview_rsds, . - codeview_rsds
+ .equ codeview_rsds_size, . - codeview_rsds
diff --git a/src/arch/x86_64/scripts/efi.lds b/src/arch/x86_64/scripts/efi.lds
new file mode 100644
index 00000000..833905c9
--- /dev/null
+++ b/src/arch/x86_64/scripts/efi.lds
@@ -0,0 +1,180 @@
+/* -*- sh -*- */
+
+/*
+ * Linker script for EFI images
+ *
+ */
+
+EXTERN ( efi_entry )
+
+SECTIONS {
+
+ /* The file starts at a virtual address of zero, and sections are
+ * contiguous. Each section is aligned to at least _max_align,
+ * which defaults to 32. Load addresses are equal to virtual
+ * addresses.
+ */
+
+ . = 0;
+ _max_align = 32;
+
+ /*
+ * The prefix
+ *
+ */
+
+ .prefix : {
+ _prefix = .;
+ *(.prefix)
+ *(.prefix.*)
+ _mprefix = .;
+ } .bss.prefix (NOLOAD) : {
+ _eprefix = .;
+ }
+ _prefix_filesz = ABSOLUTE ( _mprefix - _prefix );
+ _prefix_memsz = ABSOLUTE ( _eprefix - _prefix );
+
+ /*
+ * The text section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .text : {
+ _text = .;
+ *(.text)
+ *(.text.*)
+ _mtext = .;
+ } .bss.text (NOLOAD) : {
+ _etext = .;
+ }
+ _text_filesz = ABSOLUTE ( _mtext - _text );
+ _text_memsz = ABSOLUTE ( _etext - _text );
+
+ /*
+ * The rodata section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .rodata : {
+ _rodata = .;
+ *(.rodata)
+ *(.rodata.*)
+ _mrodata = .;
+ } .bss.rodata (NOLOAD) : {
+ _erodata = .;
+ }
+ _rodata_filesz = ABSOLUTE ( _mrodata - _rodata );
+ _rodata_memsz = ABSOLUTE ( _erodata - _rodata );
+
+ /*
+ * The data section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .data : {
+ _data = .;
+ *(.data)
+ *(.data.*)
+ *(SORT(.tbl.*)) /* Various tables. See include/tables.h */
+ /* EFI seems to not support proper bss sections */
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ *(.stack)
+ *(.stack.*)
+ _mdata = .;
+ } .bss.data (NOLOAD) : {
+ _edata = .;
+ }
+ _data_filesz = ABSOLUTE ( _mdata - _data );
+ _data_memsz = ABSOLUTE ( _edata - _data );
+
+ /*
+ * The bss section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .bss : {
+ _bss = .;
+ /* EFI seems to not support proper bss sections */
+ _mbss = .;
+ } .bss.bss (NOLOAD) : {
+ _ebss = .;
+ }
+ _bss_filesz = ABSOLUTE ( _mbss - _bss );
+ _bss_memsz = ABSOLUTE ( _ebss - _bss );
+
+ /*
+ * The reloc section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .reloc : {
+ _reloc = .;
+ /* Provide some dummy contents to force ld to include this
+ * section. It will be created by the efilink utility.
+ */
+ BYTE(0);
+ _mreloc = .;
+ } .bss.reloc (NOLOAD) : {
+ _ereloc = .;
+ }
+ _reloc_filesz = ABSOLUTE ( _mreloc - _reloc );
+ _reloc_memsz = ABSOLUTE ( _ereloc - _reloc );
+
+ _filesz = ABSOLUTE ( . );
+
+ /*
+ * Weak symbols that need zero values if not otherwise defined
+ *
+ */
+
+ .weak 0x0 : {
+ _weak = .;
+ *(.weak)
+ _eweak = .;
+ }
+ _assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" );
+
+ /*
+ * Dispose of the comment and note sections to make the link map
+ * easier to read
+ *
+ */
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.comment.*)
+ *(.note)
+ *(.note.*)
+ *(.eh_frame)
+ *(.eh_frame.*)
+ *(.rel)
+ *(.rel.*)
+ }
+
+ /*
+ * Load address calculations.
+ *
+ */
+
+ _prefix_lma = ABSOLUTE ( _prefix );
+ _text_lma = ABSOLUTE ( _text );
+ _rodata_lma = ABSOLUTE ( _rodata );
+ _data_lma = ABSOLUTE ( _data );
+ _bss_lma = ABSOLUTE ( _bss );
+ _reloc_lma = ABSOLUTE ( _reloc );
+
+ /*
+ * Load addresses required by the prefix
+ *
+ */
+ efi_entry_lma = ABSOLUTE ( efi_entry );
+ debugdir_lma = ABSOLUTE ( debugdir );
+ codeview_rsds_lma = ABSOLUTE ( codeview_rsds );
+}
diff --git a/src/include/byteswap.h b/src/include/byteswap.h
index 72b5a01d..6c3ced25 100644
--- a/src/include/byteswap.h
+++ b/src/include/byteswap.h
@@ -4,6 +4,41 @@
#include "endian.h"
#include "bits/byteswap.h"
+#define __bswap_constant_16(x) \
+ ((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
+ (((uint16_t)(x) & 0xff00) >> 8)))
+
+#define __bswap_constant_32(x) \
+ ((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
+ (((uint32_t)(x) & 0x0000ff00U) << 8) | \
+ (((uint32_t)(x) & 0x00ff0000U) >> 8) | \
+ (((uint32_t)(x) & 0xff000000U) >> 24)))
+
+#define __bswap_constant_64(x) \
+ ((uint64_t)((((uint64_t)(x) & 0x00000000000000ffULL) << 56) | \
+ (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
+ (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
+ (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
+ (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
+ (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
+ (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
+ (((uint64_t)(x) & 0xff00000000000000ULL) >> 56)))
+
+#define __bswap_16(x) \
+ ((uint16_t)(__builtin_constant_p(x) ? \
+ __bswap_constant_16(x) : \
+ __bswap_variable_16(x)))
+
+#define __bswap_32(x) \
+ ((uint32_t)(__builtin_constant_p(x) ? \
+ __bswap_constant_32(x) : \
+ __bswap_variable_32(x)))
+
+#define __bswap_64(x) \
+ ((uint64_t)(__builtin_constant_p(x) ? \
+ __bswap_constant_64(x) : \
+ __bswap_variable_64(x)))
+
#if __BYTE_ORDER == __LITTLE_ENDIAN
#include "little_bswap.h"
#endif
diff --git a/src/include/compiler.h b/src/include/compiler.h
index 4140a356..7b5a58d6 100644
--- a/src/include/compiler.h
+++ b/src/include/compiler.h
@@ -59,6 +59,15 @@ __asm__ ( ".equ\t" OBJECT_SYMBOL_STR ", 0" );
#define REQUIRE_OBJECT(object) \
__asm__ ( ".equ\tneed_" #object ", obj_" #object );
+/* Force visibility of all symbols to "hidden", i.e. inform gcc that
+ * all symbol references resolve strictly within our final binary.
+ * This avoids unnecessary PLT/GOT entries on x86_64.
+ *
+ * This is a stronger claim than specifying "-fvisibility=hidden",
+ * since it also affects symbols marked with "extern".
+ */
+#pragma GCC visibility push(hidden)
+
/** @def DBG
*
* Print a debugging message.
diff --git a/src/include/gpxe/efi/ProcessorBind.h b/src/include/gpxe/efi/ProcessorBind.h
index cc5a9852..3dbaf1b8 100644
--- a/src/include/gpxe/efi/ProcessorBind.h
+++ b/src/include/gpxe/efi/ProcessorBind.h
@@ -8,3 +8,7 @@
#if __i386__
#include <gpxe/efi/Ia32/ProcessorBind.h>
#endif
+
+#if __x86_64__
+#include <gpxe/efi/X64/ProcessorBind.h>
+#endif
diff --git a/src/include/gpxe/efi/X64/ProcessorBind.h b/src/include/gpxe/efi/X64/ProcessorBind.h
new file mode 100644
index 00000000..fe6c413b
--- /dev/null
+++ b/src/include/gpxe/efi/X64/ProcessorBind.h
@@ -0,0 +1,247 @@
+/** @file
+ Processor or Compiler specific defines and types x64 (Intel(r) EM64T, AMD64).
+
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+///
+/// Define the processor type so other code can make processor based choices
+///
+#define MDE_CPU_X64
+
+
+//
+// Make sure we are useing the correct packing rules per EFI specification
+//
+#ifndef __GNUC__
+#pragma pack()
+#endif
+
+
+#if __INTEL_COMPILER
+//
+// Disable ICC's remark #869: "Parameter" was never referenced warning.
+// This is legal ANSI C code so we disable the remark that is turned on with -Wall
+//
+#pragma warning ( disable : 869 )
+
+//
+// Disable ICC's remark #1418: external function definition with no prior declaration.
+// This is legal ANSI C code so we disable the remark that is turned on with /W4
+//
+#pragma warning ( disable : 1418 )
+
+//
+// Disable ICC's remark #1419: external declaration in primary source file
+// This is legal ANSI C code so we disable the remark that is turned on with /W4
+//
+#pragma warning ( disable : 1419 )
+
+#endif
+
+
+#if _MSC_EXTENSIONS
+
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning ( disable : 4214 )
+
+//
+// Disabling the unreferenced formal parameter warnings.
+//
+#pragma warning ( disable : 4100 )
+
+//
+// Disable slightly different base types warning as CHAR8 * can not be set
+// to a constant string.
+//
+#pragma warning ( disable : 4057 )
+
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning
+//
+#pragma warning ( disable : 4127 )
+
+//
+// This warning is caused by functions defined but not used. For precompiled header only.
+//
+#pragma warning ( disable : 4505 )
+
+//
+// This warning is caused by empty (after preprocessing) souce file. For precompiled header only.
+//
+#pragma warning ( disable : 4206 )
+
+#endif
+
+
+#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L)
+ //
+ // No ANSI C 2000 stdint.h integer width declarations, so define equivalents
+ //
+
+ #if _MSC_EXTENSIONS
+
+
+ //
+ // use Microsoft C complier dependent interger width types
+ //
+ typedef unsigned __int64 UINT64;
+ typedef __int64 INT64;
+ typedef unsigned __int32 UINT32;
+ typedef __int32 INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef char INT8;
+ #else
+ #ifdef _EFI_P64
+ //
+ // P64 - is Intel Itanium(TM) speak for pointers being 64-bit and longs and ints
+ // are 32-bits
+ //
+ typedef unsigned long long UINT64;
+ typedef long long INT64;
+ typedef unsigned int UINT32;
+ typedef int INT32;
+ typedef unsigned short CHAR16;
+ typedef unsigned short UINT16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef char INT8;
+ #else
+ //
+ // Assume LP64 - longs and pointers are 64-bit. Ints are 32-bit.
+ //
+ typedef unsigned long UINT64;
+ typedef long INT64;
+ typedef unsigned int UINT32;
+ typedef int INT32;
+ typedef unsigned short UINT16;
+ typedef unsigned short CHAR16;
+ typedef short INT16;
+ typedef unsigned char BOOLEAN;
+ typedef unsigned char UINT8;
+ typedef char CHAR8;
+ typedef char INT8;
+ #endif
+ #endif
+
+ #define UINT8_MAX 0xff
+
+#else
+ //
+ // Use ANSI C 2000 stdint.h integer width declarations
+ //
+ #include <stdint.h>
+ typedef uint8_t BOOLEAN;
+ typedef int8_t INT8;
+ typedef uint8_t UINT8;
+ typedef int16_t INT16;
+ typedef uint16_t UINT16;
+ typedef int32_t INT32;
+ typedef uint32_t UINT32;
+ typedef int64_t INT64;
+ typedef uint64_t UINT64;
+ typedef char CHAR8;
+ typedef uint16_t CHAR16;
+
+#endif
+
+typedef UINT64 UINTN;
+typedef INT64 INTN;
+
+
+//
+// Processor specific defines
+//
+#define MAX_BIT 0x8000000000000000ULL
+#define MAX_2_BITS 0xC000000000000000ULL
+
+//
+// Maximum legal X64 address
+//
+#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFFULL
+
+//
+// The stack alignment required for X64
+//
+#define CPU_STACK_ALIGNMENT 16
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify thier member functions with EFIAPI.
+//
+#if _MSC_EXTENSIONS
+ ///
+ /// Define the standard calling convention reguardless of optimization level.
+ /// __cdecl is Microsoft* specific C extension.
+ ///
+ #define EFIAPI __cdecl
+#elif __GNUC__
+ ///
+ /// Define the standard calling convention reguardless of optimization level.
+ /// The GCC support assumes a GCC compiler that supports the EFI ABI. The EFI
+ /// ABI is much closer to the x64 Microsoft* ABI than standard x64 (x86-64)
+ /// GCC ABI. Thus a standard x64 (x86-64) GCC compiler can not be used for
+ /// x64. Warning the assembly code in the MDE x64 does not follow the correct
+ /// ABI for the standard x64 (x86-64) GCC.
+ ///
+ #define EFIAPI __attribute__((ms_abi))
+#else
+ ///
+ /// The default for a non Microsoft* or GCC compiler is to assume the EFI ABI
+ /// is the standard.
+ ///
+ #define EFIAPI
+#endif
+
+//
+// The Microsoft* C compiler can removed references to unreferenced data items
+// if the /OPT:REF linker option is used. We defined a macro as this is a
+// a non standard extension
+//
+#if _MSC_EXTENSIONS
+ #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)
+#else
+ #define GLOBAL_REMOVE_IF_UNREFERENCED
+#endif
+
+//
+// For symbol name in GNU assembly code, an extra "_" is necessary
+//
+#if __GNUC__
+ #if defined(linux)
+ #define ASM_PFX(name) name
+ #else
+ #define ASM_PFX(name) _##name
+ #endif
+#endif
+
+#define FUNCTION_ENTRY_POINT(p) (p)
+
+#endif
+
diff --git a/src/util/efilink.c b/src/util/efilink.c
index e21f4a90..17b99d29 100644
--- a/src/util/efilink.c
+++ b/src/util/efilink.c
@@ -56,6 +56,9 @@ static void generate_pe_reloc ( struct pe_relocs **pe_reltab,
start_rva = ( rva & ~0xfff );
reloc = ( rva & 0xfff );
switch ( size ) {
+ case 8:
+ reloc |= 0xa000;
+ break;
case 4:
reloc |= 0x3000;
break;
@@ -385,13 +388,18 @@ static void process_reloc ( asection *section, arelent *rel,
/* Skip absolute symbols; the symbol value won't
* change when the object is loaded.
*/
- } else if ( strcmp ( howto->name, "R_386_32" ) == 0 ) {
+ } else if ( strcmp ( howto->name, "R_X86_64_64" ) == 0 ) {
+ /* Generate an 8-byte PE relocation */
+ generate_pe_reloc ( pe_reltab, offset, 8 );
+ } else if ( ( strcmp ( howto->name, "R_386_32" ) == 0 ) ||
+ ( strcmp ( howto->name, "R_X86_64_32" ) == 0 ) ) {
/* Generate a 4-byte PE relocation */
generate_pe_reloc ( pe_reltab, offset, 4 );
} else if ( strcmp ( howto->name, "R_386_16" ) == 0 ) {
/* Generate a 2-byte PE relocation */
generate_pe_reloc ( pe_reltab, offset, 2 );
- } else if ( strcmp ( howto->name, "R_386_PC32" ) == 0 ) {
+ } else if ( ( strcmp ( howto->name, "R_386_PC32" ) == 0 ) ||
+ ( strcmp ( howto->name, "R_X86_64_PC32" ) == 0 ) ) {
/* Skip PC-relative relocations; all relative offsets
* remain unaltered when the object is loaded.
*/