diff options
author | Michael Brown | 2009-03-10 18:50:01 +0100 |
---|---|---|
committer | Michael Brown | 2009-03-26 08:27:19 +0100 |
commit | 1c67623e37dada045e9b5d1f5e19b414cc79c3e3 (patch) | |
tree | 6baaac3371a85232dbfe0faa5e7530eb76fa7413 /src | |
parent | [3c90x] Remove src/drivers/3c90x.txt (diff) | |
download | ipxe-1c67623e37dada045e9b5d1f5e19b414cc79c3e3.tar.gz ipxe-1c67623e37dada045e9b5d1f5e19b414cc79c3e3.tar.xz ipxe-1c67623e37dada045e9b5d1f5e19b414cc79c3e3.zip |
[build] Enable building with the Intel C compiler (icc)
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 3 | ||||
-rw-r--r-- | src/Makefile.housekeeping | 84 | ||||
-rw-r--r-- | src/arch/i386/Makefile | 19 | ||||
-rw-r--r-- | src/arch/i386/drivers/net/undiload.c | 5 | ||||
-rw-r--r-- | src/arch/i386/drivers/net/undinet.c | 5 | ||||
-rw-r--r-- | src/crypto/md5.c | 12 | ||||
-rw-r--r-- | src/include/compiler.h | 3 | ||||
-rw-r--r-- | src/include/gpxe/efi/efi.h | 7 | ||||
-rw-r--r-- | src/include/gpxe/tables.h | 95 | ||||
-rw-r--r-- | src/libgcc/icc.c | 8 | ||||
-rw-r--r-- | src/net/udp.c | 2 | ||||
-rw-r--r-- | src/util/.gitignore | 1 | ||||
-rw-r--r-- | src/util/iccfix.c | 156 |
13 files changed, 363 insertions, 37 deletions
diff --git a/src/Makefile b/src/Makefile index 22a4586d..1693b4ac 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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 ############################################################################### diff --git a/src/Makefile.housekeeping b/src/Makefile.housekeeping index 2ab842e6..23ef8c60 100644 --- a/src/Makefile.housekeeping +++ b/src/Makefile.housekeeping @@ -62,6 +62,22 @@ hostos : ############################################################################### # +# 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 # .toolcheck : @@ -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' ) ) \ @@ -745,6 +804,15 @@ 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 # build targets to get a serial number printed at the end of the # build. Enable -DBUILD_SERIAL in order to see it when the code runs. diff --git a/src/arch/i386/Makefile b/src/arch/i386/Makefile index 1392bbac..ca8ba1b2 100644 --- a/src/arch/i386/Makefile +++ b/src/arch/i386/Makefile @@ -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 diff --git a/src/arch/i386/drivers/net/undiload.c b/src/arch/i386/drivers/net/undiload.c index dbd9e7c2..6f34404b 100644 --- a/src/arch/i386/drivers/net/undiload.c +++ b/src/arch/i386/drivers/net/undiload.c @@ -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 diff --git a/src/arch/i386/drivers/net/undinet.c b/src/arch/i386/drivers/net/undinet.c index d6db6f7c..708fc274 100644 --- a/src/arch/i386/drivers/net/undinet.c +++ b/src/arch/i386/drivers/net/undinet.c @@ -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" ); diff --git a/src/crypto/md5.c b/src/crypto/md5.c index 76fb8a69..72b291ac 100644 --- a/src/crypto/md5.c +++ b/src/crypto/md5.c @@ -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 ) ); } diff --git a/src/include/compiler.h b/src/include/compiler.h index 889c2404..be3ce46f 100644 --- a/src/include/compiler.h +++ b/src/include/compiler.h @@ -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 ) /** diff --git a/src/include/gpxe/efi/efi.h b/src/include/gpxe/efi/efi.h index 1f5b8856..a71a29e2 100644 --- a/src/include/gpxe/efi/efi.h +++ b/src/include/gpxe/efi/efi.h @@ -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) ) ), \ } diff --git a/src/include/gpxe/tables.h b/src/include/gpxe/tables.h index a0b6f113..39b4777f 100644 --- a/src/include/gpxe/tables.h +++ b/src/include/gpxe/tables.h @@ -234,10 +234,22 @@ * @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 * * @v table 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 */ diff --git a/src/libgcc/icc.c b/src/libgcc/icc.c new file mode 100644 index 00000000..7540bf0e --- /dev/null +++ b/src/libgcc/icc.c @@ -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 */ +} diff --git a/src/net/udp.c b/src/net/udp.c index c3a1eba3..1b83518e 100644 --- a/src/net/udp.c +++ b/src/net/udp.c @@ -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 ) { diff --git a/src/util/.gitignore b/src/util/.gitignore index c2567012..a3752470 100644 --- a/src/util/.gitignore +++ b/src/util/.gitignore @@ -5,3 +5,4 @@ prototester elf2efi32 elf2efi64 efirom +iccfix diff --git a/src/util/iccfix.c b/src/util/iccfix.c new file mode 100644 index 00000000..303ae9ca --- /dev/null +++ b/src/util/iccfix.c @@ -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 */ |