[build] Enable building with the Intel C compiler (icc)
authorMichael Brown <mcb30@etherboot.org>
Tue, 10 Mar 2009 17:50:01 +0000 (17:50 +0000)
committerMichael Brown <mcb30@etherboot.org>
Thu, 26 Mar 2009 07:27:19 +0000 (07:27 +0000)
13 files changed:
src/Makefile
src/Makefile.housekeeping
src/arch/i386/Makefile
src/arch/i386/drivers/net/undiload.c
src/arch/i386/drivers/net/undinet.c
src/crypto/md5.c
src/include/compiler.h
src/include/gpxe/efi/efi.h
src/include/gpxe/tables.h
src/libgcc/icc.c [new file with mode: 0644]
src/net/udp.c
src/util/.gitignore
src/util/iccfix.c [new file with mode: 0644]

index 22a4586..1693b4a 100644 (file)
@@ -22,7 +22,7 @@ ECHO          := echo
 PRINTF         := printf
 PERL           := /usr/bin/perl
 CC             := $(CROSS_COMPILE)gcc
 PRINTF         := printf
 PERL           := /usr/bin/perl
 CC             := $(CROSS_COMPILE)gcc
-CPP            := $(CROSS_COMPILE)gcc -E -Wp,-Wall
+CPP            := $(CC) -E
 AS             := $(CROSS_COMPILE)as
 LD             := $(CROSS_COMPILE)ld
 SIZE           := $(CROSS_COMPILE)size
 AS             := $(CROSS_COMPILE)as
 LD             := $(CROSS_COMPILE)ld
 SIZE           := $(CROSS_COMPILE)size
@@ -40,6 +40,7 @@ ZBIN          := ./util/zbin
 ELF2EFI32      := ./util/elf2efi32
 ELF2EFI64      := ./util/elf2efi64
 EFIROM         := ./util/efirom
 ELF2EFI32      := ./util/elf2efi32
 ELF2EFI64      := ./util/elf2efi64
 EFIROM         := ./util/efirom
+ICCFIX         := ./util/iccfix
 DOXYGEN                := doxygen
 
 ###############################################################################
 DOXYGEN                := doxygen
 
 ###############################################################################
index 2ab842e..23ef8c6 100644 (file)
@@ -60,6 +60,22 @@ HOST_OS              := $(shell uname -s)
 hostos :
        @$(ECHO) $(HOST_OS)
 
 hostos :
        @$(ECHO) $(HOST_OS)
 
+###############################################################################
+#
+# Determine compiler
+
+CCDEFS         := $(shell $(CC) -E -x c -c /dev/null -dM | cut -d" " -f2)
+ccdefs:
+       @$(ECHO) $(CCDEFS)
+
+ifeq ($(filter __ICC,$(CCDEFS)),__ICC)
+CCTYPE         := icc
+else
+CCTYPE         := gcc
+endif
+cctype:
+       @$(ECHO) $(CCTYPE)
+
 ###############################################################################
 #
 # Check for tools that can cause failed builds
 ###############################################################################
 #
 # Check for tools that can cause failed builds
@@ -103,10 +119,12 @@ oldgas :
 # default, even when -ffreestanding is specified.  We therefore need
 # to disable -fstack-protector if the compiler supports it.
 #
 # default, even when -ffreestanding is specified.  We therefore need
 # to disable -fstack-protector if the compiler supports it.
 #
+ifeq ($(CCTYPE),gcc)
 SP_TEST = $(CC) -fno-stack-protector -x c -c /dev/null \
                -o /dev/null >/dev/null 2>&1
 SP_FLAGS := $(shell $(SP_TEST) && $(ECHO) '-fno-stack-protector')
 CFLAGS += $(SP_FLAGS)
 SP_TEST = $(CC) -fno-stack-protector -x c -c /dev/null \
                -o /dev/null >/dev/null 2>&1
 SP_FLAGS := $(shell $(SP_TEST) && $(ECHO) '-fno-stack-protector')
 CFLAGS += $(SP_FLAGS)
+endif
 
 ###############################################################################
 #
 
 ###############################################################################
 #
@@ -279,9 +297,38 @@ ifdef BIN
 # Common flags
 #
 CFLAGS         += -I include -I arch/$(ARCH)/include -I .
 # Common flags
 #
 CFLAGS         += -I include -I arch/$(ARCH)/include -I .
-CFLAGS         += -Os -ffreestanding
-CFLAGS         += -Wall -W -Wformat-nonliteral
+CFLAGS         += -Os
 CFLAGS         += -g
 CFLAGS         += -g
+ifeq ($(CCTYPE),gcc)
+CFLAGS         += -ffreestanding
+CFLAGS         += -Wall -W -Wformat-nonliteral
+endif
+ifeq ($(CCTYPE),icc)
+CFLAGS         += -fno-builtin
+CFLAGS         += -no-ip
+CFLAGS         += -no-gcc
+CFLAGS         += -diag-disable 111 # Unreachable code
+CFLAGS         += -diag-disable 128 # Unreachable loop
+CFLAGS         += -diag-disable 170 # Array boundary checks
+CFLAGS         += -diag-disable 177 # Unused functions
+CFLAGS         += -diag-disable 181 # printf() format checks
+CFLAGS         += -diag-disable 188 # enum strictness
+CFLAGS         += -diag-disable 193 # Undefined preprocessor identifiers
+CFLAGS         += -diag-disable 280 # switch ( constant )
+CFLAGS         += -diag-disable 310 # K&R parameter lists
+CFLAGS         += -diag-disable 424 # Extra semicolon
+CFLAGS         += -diag-disable 589 # Declarations mid-code
+CFLAGS         += -diag-disable 593 # Unused variables
+CFLAGS         += -diag-disable 810 # Casting ints to smaller ints
+CFLAGS         += -diag-disable 981 # Sequence point violations
+CFLAGS         += -diag-disable 1292 # Ignored attributes
+CFLAGS         += -diag-disable 1338 # void pointer arithmetic
+CFLAGS         += -diag-disable 1361 # Variable-length arrays
+CFLAGS         += -diag-disable 1418 # Missing prototypes
+CFLAGS         += -diag-disable 1419 # Missing prototypes
+CFLAGS         += -diag-disable 1599 # Hidden variables
+CFLAGS         += -Wall -Wmissing-declarations
+endif
 CFLAGS         += $(EXTRA_CFLAGS)
 ASFLAGS                += $(EXTRA_ASFLAGS)
 LDFLAGS                += $(EXTRA_LDFLAGS)
 CFLAGS         += $(EXTRA_CFLAGS)
 ASFLAGS                += $(EXTRA_ASFLAGS)
 LDFLAGS                += $(EXTRA_LDFLAGS)
@@ -314,11 +361,21 @@ OBJ_CFLAGS        = $(CFLAGS_$(OBJECT)) -DOBJECT=$(subst -,_,$(OBJECT))
 $(BIN)/%.flags :
        @$(ECHO) $(OBJ_CFLAGS)
 
 $(BIN)/%.flags :
        @$(ECHO) $(OBJ_CFLAGS)
 
+# ICC requires postprocessing objects to fix up table alignments
+#
+ifeq ($(CCTYPE),icc)
+POST_O         = && $(ICCFIX) $@
+POST_O_DEPS    := $(ICCFIX)
+else
+POST_O         :=
+POST_O_DEPS    :=
+endif
+
 # Rules for specific object types.
 #
 COMPILE_c      = $(CC) $(CFLAGS) $(CFLAGS_c) $(OBJ_CFLAGS)
 # Rules for specific object types.
 #
 COMPILE_c      = $(CC) $(CFLAGS) $(CFLAGS_c) $(OBJ_CFLAGS)
-RULE_c         = $(Q)$(COMPILE_c) -c $< -o $@
-RULE_c_to_dbg%.o = $(Q)$(COMPILE_c) -Ddebug_$(OBJECT)=$* -c $< -o $@
+RULE_c         = $(Q)$(COMPILE_c) -c $< -o $@ $(POST_O)
+RULE_c_to_dbg%.o = $(Q)$(COMPILE_c) -Ddebug_$(OBJECT)=$* -c $< -o $@ $(POST_O)
 RULE_c_to_c    = $(Q)$(COMPILE_c) -E -c $< > $@
 RULE_c_to_s    = $(Q)$(COMPILE_c) -S -g0 -c $< -o $@
 
 RULE_c_to_c    = $(Q)$(COMPILE_c) -E -c $< > $@
 RULE_c_to_s    = $(Q)$(COMPILE_c) -S -g0 -c $< -o $@
 
@@ -364,15 +421,17 @@ endef
 define obj_template
 
        @$(CPP) $(CFLAGS) $(CFLAGS_$(3)) $(CFLAGS_$(4)) -DOBJECT=$(4) \
 define obj_template
 
        @$(CPP) $(CFLAGS) $(CFLAGS_$(3)) $(CFLAGS_$(4)) -DOBJECT=$(4) \
-               -Wno-error -MM $(1) -MT "$(4)_DEPS" -MG -MP | \
-               sed 's/_DEPS\s*:/_DEPS =/' >> $(2)
-       @$(ECHO_E) '\n$$(BIN)/$(4).o : $(1) $$(MAKEDEPS) $$($(4)_DEPS)' \
+               -Wno-error -MM $(1) -MG -MP | \
+               sed 's/\.o\s*:/_DEPS =/' >> $(2)
+       @$(ECHO_E) '\n$$(BIN)/$(4).o :' \
+                '$(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(4)_DEPS)' \
                 '\n\t$$(QM)$(ECHO) "  [BUILD] $$@"' \
                 '\n\t$$(RULE_$(3))\n' \
                 '\nBOBJS += $$(BIN)/$(4).o\n' \
                 $(foreach TGT,$(DEBUG_TARGETS), \
                    $(if $(RULE_$(3)_to_$(TGT)), \
                 '\n\t$$(QM)$(ECHO) "  [BUILD] $$@"' \
                 '\n\t$$(RULE_$(3))\n' \
                 '\nBOBJS += $$(BIN)/$(4).o\n' \
                 $(foreach TGT,$(DEBUG_TARGETS), \
                    $(if $(RULE_$(3)_to_$(TGT)), \
-                   '\n$$(BIN)/$(4).$(TGT) : $(1) $$(MAKEDEPS) $$($(4)_DEPS)' \
+                   '\n$$(BIN)/$(4).$(TGT) :' \
+                   '$(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(4)_DEPS)' \
                    '\n\t$$(QM)$(ECHO) "  [BUILD] $$@"' \
                    '\n\t$$(RULE_$(3)_to_$(TGT))\n' \
                    '\n$(TGT)_OBJS += $$(BIN)/$(4).$(TGT)\n' ) ) \
                    '\n\t$$(QM)$(ECHO) "  [BUILD] $$@"' \
                    '\n\t$$(RULE_$(3)_to_$(TGT))\n' \
                    '\n$(TGT)_OBJS += $$(BIN)/$(4).$(TGT)\n' ) ) \
@@ -743,6 +802,15 @@ $(EFIROM) : util/efirom.c $(MAKEDEPS)
        $(Q)$(HOST_CC) -idirafter include -O2 -o $@ $<
 CLEANUP += $(EFIROM)
 
        $(Q)$(HOST_CC) -idirafter include -O2 -o $@ $<
 CLEANUP += $(EFIROM)
 
+###############################################################################
+#
+# The ICC fixup utility
+#
+$(ICCFIX) : util/iccfix.c $(MAKEDEPS)
+       $(QM)$(ECHO) "  [HOSTCC] $@"
+       $(Q)$(HOST_CC) -idirafter include -O2 -o $@ $<
+CLEANUP += $(ICCFIX)
+
 ###############################################################################
 #
 # Auto-incrementing build serial number.  Append "bs" to your list of
 ###############################################################################
 #
 # Auto-incrementing build serial number.  Append "bs" to your list of
index 1392bba..ca8ba1b 100644 (file)
@@ -4,22 +4,33 @@ CFLAGS                += -march=i386
 
 # Code size reduction.
 #
 
 # Code size reduction.
 #
-CFLAGS         += -fstrength-reduce -fomit-frame-pointer
+CFLAGS         += -fomit-frame-pointer
+
+# Code size reduction.
+#
+ifeq ($(CCTYPE),gcc)
+CFLAGS         += -fstrength-reduce
+endif
 
 # Code size reduction.  gcc3 needs a different syntax to gcc2 if you
 # want to avoid spurious warnings.
 #
 
 # Code size reduction.  gcc3 needs a different syntax to gcc2 if you
 # want to avoid spurious warnings.
 #
+ifeq ($(CCTYPE),gcc)
 GCC_VERSION    := $(subst ., ,$(shell $(CC) -dumpversion))
 GCC_MAJOR      := $(firstword $(GCC_VERSION))
 ifeq ($(GCC_MAJOR),2)
 CFLAGS         += -malign-jumps=1 -malign-loops=1 -malign-functions=1
 else
 CFLAGS         += -falign-jumps=1 -falign-loops=1 -falign-functions=1
 GCC_VERSION    := $(subst ., ,$(shell $(CC) -dumpversion))
 GCC_MAJOR      := $(firstword $(GCC_VERSION))
 ifeq ($(GCC_MAJOR),2)
 CFLAGS         += -malign-jumps=1 -malign-loops=1 -malign-functions=1
 else
 CFLAGS         += -falign-jumps=1 -falign-loops=1 -falign-functions=1
-endif
+endif # gcc2
+endif # gcc
 
 
-# Code size reduction.  This is almost always a win.  The kernel uses it, too.
+# Code size reduction.  This is almost always a win.  The kernel uses
+# it, too.
 #
 #
+ifeq ($(CCTYPE),gcc)
 CFLAGS         += -mpreferred-stack-boundary=2
 CFLAGS         += -mpreferred-stack-boundary=2
+endif
 
 # Code size reduction.  Use regparm for all functions - C functions
 # called from assembly (or vice versa) need __asmcall now
 
 # Code size reduction.  Use regparm for all functions - C functions
 # called from assembly (or vice versa) need __asmcall now
@@ -27,7 +38,9 @@ CFLAGS                += -mpreferred-stack-boundary=2
 CFLAGS         += -mregparm=3
 
 # Code size reduction.  Use -mrtd (same __asmcall requirements as above)
 CFLAGS         += -mregparm=3
 
 # Code size reduction.  Use -mrtd (same __asmcall requirements as above)
+ifeq ($(CCTYPE),gcc)
 CFLAGS         += -mrtd
 CFLAGS         += -mrtd
+endif
 
 # Code size reduction.  This is the logical complement to -mregparm=3.
 # It doesn't currently buy us anything, but if anything ever tries to
 
 # Code size reduction.  This is the logical complement to -mregparm=3.
 # It doesn't currently buy us anything, but if anything ever tries to
index dbd9e7c..6f34404 100644 (file)
@@ -90,11 +90,10 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
        undi_loader_entry = undirom->loader_entry;
        __asm__ __volatile__ ( REAL_CODE ( "pushw %%ds\n\t"
                                           "pushw %%ax\n\t"
        undi_loader_entry = undirom->loader_entry;
        __asm__ __volatile__ ( REAL_CODE ( "pushw %%ds\n\t"
                                           "pushw %%ax\n\t"
-                                          "lcall *%c2\n\t"
+                                          "lcall *undi_loader_entry\n\t"
                                           "addw $4, %%sp\n\t" )
                               : "=a" ( exit )
                                           "addw $4, %%sp\n\t" )
                               : "=a" ( exit )
-                              : "a" ( __from_data16 ( &undi_loader ) ),
-                                "p" ( __from_data16 ( &undi_loader_entry ) )
+                              : "a" ( __from_data16 ( &undi_loader ) )
                               : "ebx", "ecx", "edx", "esi", "edi", "ebp" );
 
        /* UNDI API calls may rudely change the status of A20 and not
                               : "ebx", "ecx", "edx", "esi", "edi", "ebp" );
 
        /* UNDI API calls may rudely change the status of A20 and not
index d6db6f7..708fc27 100644 (file)
@@ -173,12 +173,11 @@ static int undinet_call ( struct undi_nic *undinic, unsigned int function,
        __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
                                           "pushw %%di\n\t"
                                           "pushw %%bx\n\t"
        __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
                                           "pushw %%di\n\t"
                                           "pushw %%bx\n\t"
-                                          "lcall *%c3\n\t"
+                                          "lcall *undinet_entry_point\n\t"
                                           "addw $6, %%sp\n\t" )
                               : "=a" ( exit ), "=b" ( discard_b ),
                                 "=D" ( discard_D )
                                           "addw $6, %%sp\n\t" )
                               : "=a" ( exit ), "=b" ( discard_b ),
                                 "=D" ( discard_D )
-                              : "p" ( __from_data16 ( &undinet_entry_point )),
-                                "b" ( function ),
+                              : "b" ( function ),
                                 "D" ( __from_data16 ( &undinet_params ) )
                               : "ecx", "edx", "esi", "ebp" );
 
                                 "D" ( __from_data16 ( &undinet_params ) )
                               : "ecx", "edx", "esi", "ebp" );
 
index 76fb8a6..72b291a 100644 (file)
 #include <gpxe/crypto.h>
 #include <gpxe/md5.h>
 
 #include <gpxe/crypto.h>
 #include <gpxe/md5.h>
 
-#define __md5step __attribute__ (( regparm ( 3 ) ))
-
 struct md5_step {
 struct md5_step {
-       u32 __md5step ( * f ) ( u32 b, u32 c, u32 d );
+       u32 ( * f ) ( u32 b, u32 c, u32 d );
        u8 coefficient;
        u8 constant;
 };
 
        u8 coefficient;
        u8 constant;
 };
 
-static u32 __md5step f1(u32 b, u32 c, u32 d)
+static u32 f1(u32 b, u32 c, u32 d)
 {
        return ( d ^ ( b & ( c ^ d ) ) );
 }
 
 {
        return ( d ^ ( b & ( c ^ d ) ) );
 }
 
-static u32 __md5step f2(u32 b, u32 c, u32 d)
+static u32 f2(u32 b, u32 c, u32 d)
 {
        return ( c ^ ( d & ( b ^ c ) ) );
 }
 
 {
        return ( c ^ ( d & ( b ^ c ) ) );
 }
 
-static u32 __md5step f3(u32 b, u32 c, u32 d)
+static u32 f3(u32 b, u32 c, u32 d)
 {
        return ( b ^ c ^ d );
 }
 
 {
        return ( b ^ c ^ d );
 }
 
-static u32 __md5step f4(u32 b, u32 c, u32 d)
+static u32 f4(u32 b, u32 c, u32 d)
 {
        return ( c ^ ( b | ~d ) );
 }
 {
        return ( c ^ ( b | ~d ) );
 }
index 889c240..be3ce46 100644 (file)
@@ -212,7 +212,8 @@ int __debug_disable;
  * @v len              Length of data
  */
 #define DBG_HD_IF( level, data, len ) do {                     \
  * @v len              Length of data
  */
 #define DBG_HD_IF( level, data, len ) do {                     \
-               DBG_HDA_IF ( level, data, data, len );          \
+               const void *_data = data;                       \
+               DBG_HDA_IF ( level, _data, _data, len );        \
        } while ( 0 )
 
 /**
        } while ( 0 )
 
 /**
index 1f5b885..a71a29e 100644 (file)
 /* EFI headers rudely redefine NULL */
 #undef NULL
 
 /* EFI headers rudely redefine NULL */
 #undef NULL
 
+/* EFI headers expect ICC to define __GNUC__ */
+#if defined ( __ICC ) && ! defined ( __GNUC__ )
+#define __GNUC__ 1
+#endif
+
 /* Include the top-level EFI header files */
 #include <gpxe/efi/Uefi.h>
 #include <gpxe/efi/PiDxe.h>
 /* Include the top-level EFI header files */
 #include <gpxe/efi/Uefi.h>
 #include <gpxe/efi/PiDxe.h>
@@ -69,7 +74,7 @@ struct efi_protocol {
        struct efi_protocol __ ## _protocol __efi_protocol = {               \
                .u.guid = _protocol ## _GUID,                                \
                .protocol = ( ( void ** ) ( void * )                         \
        struct efi_protocol __ ## _protocol __efi_protocol = {               \
                .u.guid = _protocol ## _GUID,                                \
                .protocol = ( ( void ** ) ( void * )                         \
-                             ( ( (_ptr) == ( ( _protocol ** ) NULL ) ) ?    \
+                             ( ( (_ptr) == ( ( _protocol ** ) (_ptr) ) ) ?  \
                                (_ptr) : (_ptr) ) ),                         \
        }
 
                                (_ptr) : (_ptr) ) ),                         \
        }
 
index a0b6f11..39b4777 100644 (file)
  * @endcode
  */
 #define __table_entry( table, idx )                                    \
  * @endcode
  */
 #define __table_entry( table, idx )                                    \
-       __attribute__ (( __section__ ( __table_section ( table, idx ) ) \
+       __attribute__ (( __section__ ( __table_section ( table, idx ) ),\
                         __aligned__ ( __table_alignment ( table ) ) ))
 
                         __aligned__ ( __table_alignment ( table ) ) ))
 
+/**
+ * Get start of linker table entries
+ *
+ * @v table            Linker table
+ * @v idx              Sub-table index
+ * @ret entries                Start of entries
+ */
+#define __table_entries( table, idx ) ( {                              \
+       static __table_type ( table ) __table_entries[0]                \
+               __table_entry ( table, idx );                           \
+       __table_entries; } )
+
 /**
  * Get start of linker table
  *
 /**
  * Get start of linker table
  *
  *
  * @endcode
  */
  *
  * @endcode
  */
-#define table_start( table ) ( {                                       \
-       static __table_type ( table ) __table_start[0]                  \
-               __table_entry ( table, 00 );                            \
-       __table_start; } )
+#define table_start( table ) __table_entries ( table, 00 )
 
 /**
  * Get end of linker table
 
 /**
  * Get end of linker table
  *
  * @endcode
  */
  *
  * @endcode
  */
-#define table_end( table ) ( {                                         \
-       static __table_type ( table ) __table_end[0]                    \
-               __table_entry ( table, 99 );                            \
-       __table_end; } )
+#define table_end( table ) __table_entries ( table, 99 )
 
 /**
  * Get number of entries in linker table
 
 /**
  * Get number of entries in linker table
              pointer >= table_start ( table ) ;                        \
              pointer-- )
 
              pointer >= table_start ( table ) ;                        \
              pointer-- )
 
+/******************************************************************************
+ *
+ * Intel's C compiler chokes on several of the constructs used in this
+ * file.  The workarounds are ugly, so we use them only for an icc
+ * build.
+ *
+ */
+#define ICC_ALIGN_HACK_FACTOR 128
+#ifdef __ICC
+
+/*
+ * icc miscompiles zero-length arrays by inserting padding to a length
+ * of two array elements.  We therefore have to generate the
+ * __table_entries() symbols by hand in asm.
+ *
+ */
+#undef __table_entries
+#define __table_entries( table, idx ) ( {                              \
+       extern __table_type ( table )                                   \
+               __table_temp_sym ( idx, __LINE__ ) []                   \
+               __table_entry ( table, idx )                            \
+               asm ( __table_entries_sym ( table, idx ) );             \
+       __asm__ ( ".ifndef %c0\n\t"                                     \
+                 ".section " __table_section ( table, idx ) "\n\t"     \
+                 ".align %c1\n\t"                                      \
+                 "\n%c0:\n\t"                                          \
+                 ".previous\n\t"                                       \
+                 ".endif\n\t"                                          \
+                 : : "i" ( __table_temp_sym ( idx, __LINE__ ) ),       \
+                     "i" ( __table_alignment ( table ) ) );            \
+       __table_temp_sym ( idx, __LINE__ ); } )
+#define __table_entries_sym( table, idx )                              \
+       "__tbl_" __table_name ( table ) "_" #idx
+#define __table_temp_sym( a, b )                                       \
+       ___table_temp_sym( __table_, a, _, b )
+#define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d
+
+/*
+ * icc ignores __attribute__ (( aligned (x) )) when it is used to
+ * decrease the compiler's default choice of alignment (which may be
+ * higher than the alignment actually required by the structure).  We
+ * work around this by forcing the alignment to a large multiple of
+ * the required value (so that we are never attempting to decrease the
+ * default alignment) and then postprocessing the object file to
+ * reduce the alignment back down to the "real" value.
+ *
+ */
+#undef __table_alignment
+#define __table_alignment( table ) \
+       ( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) )
+
+/*
+ * Because of the alignment hack, we must ensure that the compiler
+ * never tries to place multiple objects within the same section,
+ * otherwise the assembler will insert padding to the (incorrect)
+ * alignment boundary.  Do this by appending the line number to table
+ * section names.
+ *
+ * Note that we don't need to worry about padding between array
+ * elements, since the alignment is declared on the variable (i.e. the
+ * whole array) rather than on the type (i.e. on all individual array
+ * elements).
+ */
+#undef __table_section
+#define __table_section( table, idx ) \
+       ".tbl." __table_name ( table ) "." __table_str ( idx ) \
+       "." __table_xstr ( __LINE__ )
+#define __table_xstr( x ) __table_str ( x )
+
+#endif /* __ICC */
+
 #endif /* _GPXE_TABLES_H */
 #endif /* _GPXE_TABLES_H */
diff --git a/src/libgcc/icc.c b/src/libgcc/icc.c
new file mode 100644 (file)
index 0000000..7540bf0
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * Intel's compiler creates an implicit call to this function at the
+ * start of main().
+ *
+ */
+void __attribute__ (( cdecl )) __intel_new_proc_init ( void ) {
+       /* Do nothing */
+}
index c3a1eba..1b83518 100644 (file)
@@ -238,7 +238,7 @@ static int udp_tx ( struct udp_connection *udp, struct io_buffer *iobuf,
  * @ret udp            UDP connection, or NULL
  */
 static struct udp_connection * udp_demux ( struct sockaddr_tcpip *local ) {
  * @ret udp            UDP connection, or NULL
  */
 static struct udp_connection * udp_demux ( struct sockaddr_tcpip *local ) {
-       static const struct sockaddr_tcpip empty_sockaddr;
+       static const struct sockaddr_tcpip empty_sockaddr = { .pad = { 0, } };
        struct udp_connection *udp;
 
        list_for_each_entry ( udp, &udp_conns, list ) {
        struct udp_connection *udp;
 
        list_for_each_entry ( udp, &udp_conns, list ) {
index c256701..a375247 100644 (file)
@@ -5,3 +5,4 @@ prototester
 elf2efi32
 elf2efi64
 efirom
 elf2efi32
 elf2efi64
 efirom
+iccfix
diff --git a/src/util/iccfix.c b/src/util/iccfix.c
new file mode 100644 (file)
index 0000000..303ae9c
--- /dev/null
@@ -0,0 +1,156 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <elf.h>
+#include <gpxe/tables.h>
+
+#define DEBUG 0
+
+#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
+
+#define dprintf(...) do {                                              \
+       if ( DEBUG )                                                    \
+               fprintf ( stderr, __VA_ARGS__ );                        \
+       } while ( 0 )
+
+#ifdef SELF_INCLUDED
+
+/**
+ * Fix up ICC alignments
+ *
+ * @v elf              ELF header
+ * @ret rc             Return status code
+ *
+ * See comments in tables.h for an explanation of why this monstrosity
+ * is necessary.
+ */
+static int ICCFIX ( void *elf ) {
+       ELF_EHDR *ehdr = elf;
+       ELF_SHDR *shdr = ( elf + ehdr->e_shoff );
+       size_t shentsize = ehdr->e_shentsize;
+       unsigned int shnum = ehdr->e_shnum;
+       ELF_SHDR *strtab = ( ( ( void * ) shdr ) +
+                            ( ehdr->e_shstrndx * shentsize ) );
+       char *strings = ( elf + strtab->sh_offset );
+
+       for ( ; shnum-- ; shdr = ( ( ( void * ) shdr ) + shentsize ) ) {
+               char *name = ( strings + shdr->sh_name );
+               unsigned long align = shdr->sh_addralign;
+               unsigned long new_align;
+
+               if ( ( strncmp ( name, ".tbl.", 5 ) == 0 ) &&
+                    ( align >= ICC_ALIGN_HACK_FACTOR ) ) {
+                       new_align = ( align / ICC_ALIGN_HACK_FACTOR );
+                       shdr->sh_addralign = new_align;
+                       dprintf ( "Section \"%s\": alignment %d->%d\n",
+                                 name, align, new_align );
+               }
+       }
+       return 0;
+}
+
+#else /* SELF_INCLUDED */
+
+#define SELF_INCLUDED
+
+/* Include iccfix32() function */
+#define ELF_EHDR Elf32_Ehdr
+#define ELF_SHDR Elf32_Shdr
+#define ICCFIX iccfix32
+#include "iccfix.c"
+#undef ELF_EHDR
+#undef ELF_SHDR
+#undef ICCFIX
+
+/* Include iccfix64() function */
+#define ELF_EHDR Elf64_Ehdr
+#define ELF_SHDR Elf64_Shdr
+#define ICCFIX iccfix64
+#include "iccfix.c"
+#undef ELF_EHDR
+#undef ELF_SHDR
+#undef ICCFIX
+
+static int iccfix ( const char *filename ) {
+       int fd;
+       struct stat stat;
+       void *elf;
+       unsigned char *eident;
+       int rc;
+
+       /* Open and mmap file */
+       fd = open ( filename, O_RDWR );
+       if ( fd < 0 ) {
+               eprintf ( "Could not open %s: %s\n",
+                         filename, strerror ( errno ) );
+               rc = -1;
+               goto err_open;
+       }
+       if ( fstat ( fd, &stat ) < 0 ) {
+               eprintf ( "Could not determine size of %s: %s\n",
+                         filename, strerror ( errno ) );
+               rc = -1;
+               goto err_fstat;
+       }
+       elf = mmap ( NULL, stat.st_size, ( PROT_READ | PROT_WRITE ),
+                    MAP_SHARED, fd, 0 );
+       if ( elf == MAP_FAILED ) {
+               eprintf ( "Could not map %s: %s\n",
+                         filename, strerror ( errno ) );
+               rc = -1;
+               goto err_mmap;
+       }
+
+       /* Perform fixups */
+       eident = elf;
+       switch ( eident[EI_CLASS] ) {
+       case ELFCLASS32:
+               rc = iccfix32 ( elf );
+               break;
+       case ELFCLASS64:
+               rc = iccfix64 ( elf );
+               break;
+       default:
+               eprintf ( "Unknown ELF class %d in %s\n",
+                         eident[EI_CLASS], filename );
+               rc = -1;
+               break;
+       }
+
+       munmap ( elf, stat.st_size );
+ err_mmap:
+ err_fstat:
+       close ( fd );
+ err_open:
+       return rc;
+}
+
+int main ( int argc, char **argv ) {
+       int i;
+       int rc;
+
+       /* Parse command line */
+       if ( argc < 2 ) {
+               eprintf ( "Syntax: %s <object_file>...\n", argv[0] );
+               exit ( 1 );
+       }
+
+       /* Process each object in turn */
+       for ( i = 1 ; i < argc ; i++ ) {
+               if ( ( rc = iccfix ( argv[i] ) ) != 0 ) {
+                       eprintf ( "Could not fix up %s\n", argv[i] );
+                       exit ( 1 );
+               }
+       }
+
+       return 0;
+}
+
+#endif /* SELF_INCLUDED */