david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[build] Enable building with the Intel C compiler (icc)

This commit is contained in:
Michael Brown 2009-03-10 17:50:01 +00:00
parent 16aa435567
commit 1c67623e37
13 changed files with 363 additions and 37 deletions

View File

@ -22,7 +22,7 @@ ECHO := echo
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
@ -40,6 +40,7 @@ ZBIN := ./util/zbin
ELF2EFI32 := ./util/elf2efi32
ELF2EFI64 := ./util/elf2efi64
EFIROM := ./util/efirom
ICCFIX := ./util/iccfix
DOXYGEN := doxygen
###############################################################################

View File

@ -60,6 +60,22 @@ HOST_OS := $(shell uname -s)
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
@ -103,10 +119,12 @@ oldgas :
# 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)
endif
###############################################################################
#
@ -279,9 +297,38 @@ ifdef BIN
# Common flags
#
CFLAGS += -I include -I arch/$(ARCH)/include -I .
CFLAGS += -Os -ffreestanding
CFLAGS += -Wall -W -Wformat-nonliteral
CFLAGS += -Os
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)
@ -314,11 +361,21 @@ OBJ_CFLAGS = $(CFLAGS_$(OBJECT)) -DOBJECT=$(subst -,_,$(OBJECT))
$(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)
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 $@
@ -364,15 +421,17 @@ endef
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$$(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' ) ) \
@ -743,6 +802,15 @@ $(EFIROM) : util/efirom.c $(MAKEDEPS)
$(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

View File

@ -4,22 +4,33 @@ CFLAGS += -march=i386
# 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.
#
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
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
endif
# 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)
ifeq ($(CCTYPE),gcc)
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

View 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"
"lcall *%c2\n\t"
"lcall *undi_loader_entry\n\t"
"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

View 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"
"lcall *%c3\n\t"
"lcall *undinet_entry_point\n\t"
"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" );

View File

@ -26,30 +26,28 @@
#include <gpxe/crypto.h>
#include <gpxe/md5.h>
#define __md5step __attribute__ (( regparm ( 3 ) ))
struct md5_step {
u32 __md5step ( * f ) ( u32 b, u32 c, u32 d );
u32 ( * f ) ( u32 b, u32 c, u32 d );
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 ) ) );
}
static u32 __md5step f2(u32 b, u32 c, u32 d)
static u32 f2(u32 b, u32 c, u32 d)
{
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 );
}
static u32 __md5step f4(u32 b, u32 c, u32 d)
static u32 f4(u32 b, u32 c, u32 d)
{
return ( c ^ ( b | ~d ) );
}

View File

@ -212,7 +212,8 @@ int __debug_disable;
* @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 )
/**

View File

@ -31,6 +31,11 @@
/* 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>
@ -69,7 +74,7 @@ struct efi_protocol {
struct efi_protocol __ ## _protocol __efi_protocol = { \
.u.guid = _protocol ## _GUID, \
.protocol = ( ( void ** ) ( void * ) \
( ( (_ptr) == ( ( _protocol ** ) NULL ) ) ? \
( ( (_ptr) == ( ( _protocol ** ) (_ptr) ) ) ? \
(_ptr) : (_ptr) ) ), \
}

View File

@ -234,9 +234,21 @@
* @endcode
*/
#define __table_entry( table, idx ) \
__attribute__ (( __section__ ( __table_section ( table, idx ) ) \
__attribute__ (( __section__ ( __table_section ( table, idx ) ),\
__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
*
@ -253,10 +265,7 @@
*
* @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
@ -274,10 +283,7 @@
*
* @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
@ -352,4 +358,75 @@
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 */

8
src/libgcc/icc.c Normal file
View File

@ -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 */
}

View 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 ) {
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 ) {

1
src/util/.gitignore vendored
View File

@ -5,3 +5,4 @@ prototester
elf2efi32
elf2efi64
efirom
iccfix

156
src/util/iccfix.c Normal file
View File

@ -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 */