Переглянути джерело

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

tags/v0.9.8
Michael Brown 15 роки тому
джерело
коміт
1c67623e37

+ 2
- 1
src/Makefile Переглянути файл

@@ -22,7 +22,7 @@ ECHO		:= echo
22 22
 PRINTF		:= printf
23 23
 PERL		:= /usr/bin/perl
24 24
 CC		:= $(CROSS_COMPILE)gcc
25
-CPP		:= $(CROSS_COMPILE)gcc -E -Wp,-Wall
25
+CPP		:= $(CC) -E
26 26
 AS		:= $(CROSS_COMPILE)as
27 27
 LD		:= $(CROSS_COMPILE)ld
28 28
 SIZE		:= $(CROSS_COMPILE)size
@@ -40,6 +40,7 @@ ZBIN		:= ./util/zbin
40 40
 ELF2EFI32	:= ./util/elf2efi32
41 41
 ELF2EFI64	:= ./util/elf2efi64
42 42
 EFIROM		:= ./util/efirom
43
+ICCFIX		:= ./util/iccfix
43 44
 DOXYGEN		:= doxygen
44 45
 
45 46
 ###############################################################################

+ 76
- 8
src/Makefile.housekeeping Переглянути файл

@@ -60,6 +60,22 @@ HOST_OS		:= $(shell uname -s)
60 60
 hostos :
61 61
 	@$(ECHO) $(HOST_OS)
62 62
 
63
+###############################################################################
64
+#
65
+# Determine compiler
66
+
67
+CCDEFS		:= $(shell $(CC) -E -x c -c /dev/null -dM | cut -d" " -f2)
68
+ccdefs:
69
+	@$(ECHO) $(CCDEFS)
70
+
71
+ifeq ($(filter __ICC,$(CCDEFS)),__ICC)
72
+CCTYPE		:= icc
73
+else
74
+CCTYPE		:= gcc
75
+endif
76
+cctype:
77
+	@$(ECHO) $(CCTYPE)
78
+
63 79
 ###############################################################################
64 80
 #
65 81
 # Check for tools that can cause failed builds
@@ -103,10 +119,12 @@ oldgas :
103 119
 # default, even when -ffreestanding is specified.  We therefore need
104 120
 # to disable -fstack-protector if the compiler supports it.
105 121
 #
122
+ifeq ($(CCTYPE),gcc)
106 123
 SP_TEST = $(CC) -fno-stack-protector -x c -c /dev/null \
107 124
 		-o /dev/null >/dev/null 2>&1
108 125
 SP_FLAGS := $(shell $(SP_TEST) && $(ECHO) '-fno-stack-protector')
109 126
 CFLAGS	+= $(SP_FLAGS)
127
+endif
110 128
 
111 129
 ###############################################################################
112 130
 #
@@ -279,9 +297,38 @@ ifdef BIN
279 297
 # Common flags
280 298
 #
281 299
 CFLAGS		+= -I include -I arch/$(ARCH)/include -I .
282
-CFLAGS		+= -Os -ffreestanding
283
-CFLAGS		+= -Wall -W -Wformat-nonliteral
300
+CFLAGS		+= -Os
284 301
 CFLAGS		+= -g
302
+ifeq ($(CCTYPE),gcc)
303
+CFLAGS		+= -ffreestanding
304
+CFLAGS		+= -Wall -W -Wformat-nonliteral
305
+endif
306
+ifeq ($(CCTYPE),icc)
307
+CFLAGS		+= -fno-builtin
308
+CFLAGS		+= -no-ip
309
+CFLAGS		+= -no-gcc
310
+CFLAGS		+= -diag-disable 111 # Unreachable code
311
+CFLAGS		+= -diag-disable 128 # Unreachable loop
312
+CFLAGS		+= -diag-disable 170 # Array boundary checks
313
+CFLAGS		+= -diag-disable 177 # Unused functions
314
+CFLAGS		+= -diag-disable 181 # printf() format checks
315
+CFLAGS		+= -diag-disable 188 # enum strictness
316
+CFLAGS		+= -diag-disable 193 # Undefined preprocessor identifiers
317
+CFLAGS		+= -diag-disable 280 # switch ( constant )
318
+CFLAGS		+= -diag-disable 310 # K&R parameter lists
319
+CFLAGS		+= -diag-disable 424 # Extra semicolon
320
+CFLAGS		+= -diag-disable 589 # Declarations mid-code
321
+CFLAGS		+= -diag-disable 593 # Unused variables
322
+CFLAGS		+= -diag-disable 810 # Casting ints to smaller ints
323
+CFLAGS		+= -diag-disable 981 # Sequence point violations
324
+CFLAGS		+= -diag-disable 1292 # Ignored attributes
325
+CFLAGS		+= -diag-disable 1338 # void pointer arithmetic
326
+CFLAGS		+= -diag-disable 1361 # Variable-length arrays
327
+CFLAGS		+= -diag-disable 1418 # Missing prototypes
328
+CFLAGS		+= -diag-disable 1419 # Missing prototypes
329
+CFLAGS		+= -diag-disable 1599 # Hidden variables
330
+CFLAGS		+= -Wall -Wmissing-declarations
331
+endif
285 332
 CFLAGS		+= $(EXTRA_CFLAGS)
286 333
 ASFLAGS		+= $(EXTRA_ASFLAGS)
287 334
 LDFLAGS		+= $(EXTRA_LDFLAGS)
@@ -314,11 +361,21 @@ OBJ_CFLAGS	= $(CFLAGS_$(OBJECT)) -DOBJECT=$(subst -,_,$(OBJECT))
314 361
 $(BIN)/%.flags :
315 362
 	@$(ECHO) $(OBJ_CFLAGS)
316 363
 
364
+# ICC requires postprocessing objects to fix up table alignments
365
+#
366
+ifeq ($(CCTYPE),icc)
367
+POST_O		= && $(ICCFIX) $@
368
+POST_O_DEPS	:= $(ICCFIX)
369
+else
370
+POST_O		:=
371
+POST_O_DEPS	:=
372
+endif
373
+
317 374
 # Rules for specific object types.
318 375
 #
319 376
 COMPILE_c	= $(CC) $(CFLAGS) $(CFLAGS_c) $(OBJ_CFLAGS)
320
-RULE_c		= $(Q)$(COMPILE_c) -c $< -o $@
321
-RULE_c_to_dbg%.o = $(Q)$(COMPILE_c) -Ddebug_$(OBJECT)=$* -c $< -o $@
377
+RULE_c		= $(Q)$(COMPILE_c) -c $< -o $@ $(POST_O)
378
+RULE_c_to_dbg%.o = $(Q)$(COMPILE_c) -Ddebug_$(OBJECT)=$* -c $< -o $@ $(POST_O)
322 379
 RULE_c_to_c	= $(Q)$(COMPILE_c) -E -c $< > $@
323 380
 RULE_c_to_s	= $(Q)$(COMPILE_c) -S -g0 -c $< -o $@
324 381
 
@@ -364,15 +421,17 @@ endef
364 421
 define obj_template
365 422
 
366 423
 	@$(CPP) $(CFLAGS) $(CFLAGS_$(3)) $(CFLAGS_$(4)) -DOBJECT=$(4) \
367
-		-Wno-error -MM $(1) -MT "$(4)_DEPS" -MG -MP | \
368
-		sed 's/_DEPS\s*:/_DEPS =/' >> $(2)
369
-	@$(ECHO_E) '\n$$(BIN)/$(4).o : $(1) $$(MAKEDEPS) $$($(4)_DEPS)' \
424
+		-Wno-error -MM $(1) -MG -MP | \
425
+		sed 's/\.o\s*:/_DEPS =/' >> $(2)
426
+	@$(ECHO_E) '\n$$(BIN)/$(4).o :' \
427
+		 '$(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(4)_DEPS)' \
370 428
 		 '\n\t$$(QM)$(ECHO) "  [BUILD] $$@"' \
371 429
 		 '\n\t$$(RULE_$(3))\n' \
372 430
 		 '\nBOBJS += $$(BIN)/$(4).o\n' \
373 431
 		 $(foreach TGT,$(DEBUG_TARGETS), \
374 432
 		    $(if $(RULE_$(3)_to_$(TGT)), \
375
-		    '\n$$(BIN)/$(4).$(TGT) : $(1) $$(MAKEDEPS) $$($(4)_DEPS)' \
433
+		    '\n$$(BIN)/$(4).$(TGT) :' \
434
+		    '$(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(4)_DEPS)' \
376 435
 		    '\n\t$$(QM)$(ECHO) "  [BUILD] $$@"' \
377 436
 		    '\n\t$$(RULE_$(3)_to_$(TGT))\n' \
378 437
 		    '\n$(TGT)_OBJS += $$(BIN)/$(4).$(TGT)\n' ) ) \
@@ -743,6 +802,15 @@ $(EFIROM) : util/efirom.c $(MAKEDEPS)
743 802
 	$(Q)$(HOST_CC) -idirafter include -O2 -o $@ $<
744 803
 CLEANUP += $(EFIROM)
745 804
 
805
+###############################################################################
806
+#
807
+# The ICC fixup utility
808
+#
809
+$(ICCFIX) : util/iccfix.c $(MAKEDEPS)
810
+	$(QM)$(ECHO) "  [HOSTCC] $@"
811
+	$(Q)$(HOST_CC) -idirafter include -O2 -o $@ $<
812
+CLEANUP += $(ICCFIX)
813
+
746 814
 ###############################################################################
747 815
 #
748 816
 # Auto-incrementing build serial number.  Append "bs" to your list of

+ 16
- 3
src/arch/i386/Makefile Переглянути файл

@@ -4,22 +4,33 @@ CFLAGS		+= -march=i386
4 4
 
5 5
 # Code size reduction.
6 6
 #
7
-CFLAGS		+= -fstrength-reduce -fomit-frame-pointer
7
+CFLAGS		+= -fomit-frame-pointer
8
+
9
+# Code size reduction.
10
+#
11
+ifeq ($(CCTYPE),gcc)
12
+CFLAGS		+= -fstrength-reduce
13
+endif
8 14
 
9 15
 # Code size reduction.  gcc3 needs a different syntax to gcc2 if you
10 16
 # want to avoid spurious warnings.
11 17
 #
18
+ifeq ($(CCTYPE),gcc)
12 19
 GCC_VERSION	:= $(subst ., ,$(shell $(CC) -dumpversion))
13 20
 GCC_MAJOR	:= $(firstword $(GCC_VERSION))
14 21
 ifeq ($(GCC_MAJOR),2)
15 22
 CFLAGS		+= -malign-jumps=1 -malign-loops=1 -malign-functions=1
16 23
 else
17 24
 CFLAGS		+= -falign-jumps=1 -falign-loops=1 -falign-functions=1
18
-endif
25
+endif # gcc2
26
+endif # gcc
19 27
 
20
-# Code size reduction.  This is almost always a win.  The kernel uses it, too.
28
+# Code size reduction.  This is almost always a win.  The kernel uses
29
+# it, too.
21 30
 #
31
+ifeq ($(CCTYPE),gcc)
22 32
 CFLAGS		+= -mpreferred-stack-boundary=2
33
+endif
23 34
 
24 35
 # Code size reduction.  Use regparm for all functions - C functions
25 36
 # called from assembly (or vice versa) need __asmcall now
@@ -27,7 +38,9 @@ CFLAGS		+= -mpreferred-stack-boundary=2
27 38
 CFLAGS		+= -mregparm=3
28 39
 
29 40
 # Code size reduction.  Use -mrtd (same __asmcall requirements as above)
41
+ifeq ($(CCTYPE),gcc)
30 42
 CFLAGS		+= -mrtd
43
+endif
31 44
 
32 45
 # Code size reduction.  This is the logical complement to -mregparm=3.
33 46
 # It doesn't currently buy us anything, but if anything ever tries to

+ 2
- 3
src/arch/i386/drivers/net/undiload.c Переглянути файл

@@ -90,11 +90,10 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
90 90
 	undi_loader_entry = undirom->loader_entry;
91 91
 	__asm__ __volatile__ ( REAL_CODE ( "pushw %%ds\n\t"
92 92
 					   "pushw %%ax\n\t"
93
-					   "lcall *%c2\n\t"
93
+					   "lcall *undi_loader_entry\n\t"
94 94
 					   "addw $4, %%sp\n\t" )
95 95
 			       : "=a" ( exit )
96
-			       : "a" ( __from_data16 ( &undi_loader ) ),
97
-			         "p" ( __from_data16 ( &undi_loader_entry ) )
96
+			       : "a" ( __from_data16 ( &undi_loader ) )
98 97
 			       : "ebx", "ecx", "edx", "esi", "edi", "ebp" );
99 98
 
100 99
 	/* UNDI API calls may rudely change the status of A20 and not

+ 2
- 3
src/arch/i386/drivers/net/undinet.c Переглянути файл

@@ -173,12 +173,11 @@ static int undinet_call ( struct undi_nic *undinic, unsigned int function,
173 173
 	__asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
174 174
 					   "pushw %%di\n\t"
175 175
 					   "pushw %%bx\n\t"
176
-					   "lcall *%c3\n\t"
176
+					   "lcall *undinet_entry_point\n\t"
177 177
 					   "addw $6, %%sp\n\t" )
178 178
 			       : "=a" ( exit ), "=b" ( discard_b ),
179 179
 			         "=D" ( discard_D )
180
-			       : "p" ( __from_data16 ( &undinet_entry_point )),
181
-			         "b" ( function ),
180
+			       : "b" ( function ),
182 181
 			         "D" ( __from_data16 ( &undinet_params ) )
183 182
 			       : "ecx", "edx", "esi", "ebp" );
184 183
 

+ 5
- 7
src/crypto/md5.c Переглянути файл

@@ -26,30 +26,28 @@
26 26
 #include <gpxe/crypto.h>
27 27
 #include <gpxe/md5.h>
28 28
 
29
-#define __md5step __attribute__ (( regparm ( 3 ) ))
30
-
31 29
 struct md5_step {
32
-	u32 __md5step ( * f ) ( u32 b, u32 c, u32 d );
30
+	u32 ( * f ) ( u32 b, u32 c, u32 d );
33 31
 	u8 coefficient;
34 32
 	u8 constant;
35 33
 };
36 34
 
37
-static u32 __md5step f1(u32 b, u32 c, u32 d)
35
+static u32 f1(u32 b, u32 c, u32 d)
38 36
 {
39 37
 	return ( d ^ ( b & ( c ^ d ) ) );
40 38
 }
41 39
 
42
-static u32 __md5step f2(u32 b, u32 c, u32 d)
40
+static u32 f2(u32 b, u32 c, u32 d)
43 41
 {
44 42
 	return ( c ^ ( d & ( b ^ c ) ) );
45 43
 }
46 44
 
47
-static u32 __md5step f3(u32 b, u32 c, u32 d)
45
+static u32 f3(u32 b, u32 c, u32 d)
48 46
 {
49 47
 	return ( b ^ c ^ d );
50 48
 }
51 49
 
52
-static u32 __md5step f4(u32 b, u32 c, u32 d)
50
+static u32 f4(u32 b, u32 c, u32 d)
53 51
 {
54 52
 	return ( c ^ ( b | ~d ) );
55 53
 }

+ 2
- 1
src/include/compiler.h Переглянути файл

@@ -212,7 +212,8 @@ int __debug_disable;
212 212
  * @v len		Length of data
213 213
  */
214 214
 #define DBG_HD_IF( level, data, len ) do {			\
215
-		DBG_HDA_IF ( level, data, data, len );		\
215
+		const void *_data = data;			\
216
+		DBG_HDA_IF ( level, _data, _data, len );	\
216 217
 	} while ( 0 )
217 218
 
218 219
 /**

+ 6
- 1
src/include/gpxe/efi/efi.h Переглянути файл

@@ -31,6 +31,11 @@
31 31
 /* EFI headers rudely redefine NULL */
32 32
 #undef NULL
33 33
 
34
+/* EFI headers expect ICC to define __GNUC__ */
35
+#if defined ( __ICC ) && ! defined ( __GNUC__ )
36
+#define __GNUC__ 1
37
+#endif
38
+
34 39
 /* Include the top-level EFI header files */
35 40
 #include <gpxe/efi/Uefi.h>
36 41
 #include <gpxe/efi/PiDxe.h>
@@ -69,7 +74,7 @@ struct efi_protocol {
69 74
 	struct efi_protocol __ ## _protocol __efi_protocol = {		     \
70 75
 		.u.guid = _protocol ## _GUID,				     \
71 76
 		.protocol = ( ( void ** ) ( void * )			     \
72
-			      ( ( (_ptr) == ( ( _protocol ** ) NULL ) ) ?    \
77
+			      ( ( (_ptr) == ( ( _protocol ** ) (_ptr) ) ) ?  \
73 78
 				(_ptr) : (_ptr) ) ),			     \
74 79
 	}
75 80
 

+ 86
- 9
src/include/gpxe/tables.h Переглянути файл

@@ -234,9 +234,21 @@
234 234
  * @endcode
235 235
  */
236 236
 #define __table_entry( table, idx )					\
237
-	__attribute__ (( __section__ ( __table_section ( table, idx ) )	\
237
+	__attribute__ (( __section__ ( __table_section ( table, idx ) ),\
238 238
 			 __aligned__ ( __table_alignment ( table ) ) ))
239 239
 
240
+/**
241
+ * Get start of linker table entries
242
+ *
243
+ * @v table		Linker table
244
+ * @v idx		Sub-table index
245
+ * @ret entries		Start of entries
246
+ */
247
+#define __table_entries( table, idx ) ( {				\
248
+	static __table_type ( table ) __table_entries[0]		\
249
+		__table_entry ( table, idx ); 				\
250
+	__table_entries; } )
251
+
240 252
 /**
241 253
  * Get start of linker table
242 254
  *
@@ -253,10 +265,7 @@
253 265
  *
254 266
  * @endcode
255 267
  */
256
-#define table_start( table ) ( {					\
257
-	static __table_type ( table ) __table_start[0]			\
258
-		__table_entry ( table, 00 ); 				\
259
-	__table_start; } )
268
+#define table_start( table ) __table_entries ( table, 00 )
260 269
 
261 270
 /**
262 271
  * Get end of linker table
@@ -274,10 +283,7 @@
274 283
  *
275 284
  * @endcode
276 285
  */
277
-#define table_end( table ) ( {						\
278
-	static __table_type ( table ) __table_end[0]			\
279
-		__table_entry ( table, 99 ); 				\
280
-	__table_end; } )
286
+#define table_end( table ) __table_entries ( table, 99 )
281 287
 
282 288
 /**
283 289
  * Get number of entries in linker table
@@ -352,4 +358,75 @@
352 358
 	      pointer >= table_start ( table ) ;			\
353 359
 	      pointer-- )
354 360
 
361
+/******************************************************************************
362
+ *
363
+ * Intel's C compiler chokes on several of the constructs used in this
364
+ * file.  The workarounds are ugly, so we use them only for an icc
365
+ * build.
366
+ *
367
+ */
368
+#define ICC_ALIGN_HACK_FACTOR 128
369
+#ifdef __ICC
370
+
371
+/*
372
+ * icc miscompiles zero-length arrays by inserting padding to a length
373
+ * of two array elements.  We therefore have to generate the
374
+ * __table_entries() symbols by hand in asm.
375
+ *
376
+ */
377
+#undef __table_entries
378
+#define __table_entries( table, idx ) ( {				\
379
+	extern __table_type ( table )					\
380
+		__table_temp_sym ( idx, __LINE__ ) []			\
381
+		__table_entry ( table, idx ) 				\
382
+		asm ( __table_entries_sym ( table, idx ) );		\
383
+	__asm__ ( ".ifndef %c0\n\t"					\
384
+		  ".section " __table_section ( table, idx ) "\n\t"	\
385
+		  ".align %c1\n\t"					\
386
+	          "\n%c0:\n\t"						\
387
+		  ".previous\n\t" 					\
388
+		  ".endif\n\t"						\
389
+		  : : "i" ( __table_temp_sym ( idx, __LINE__ ) ),	\
390
+		      "i" ( __table_alignment ( table ) ) );		\
391
+	__table_temp_sym ( idx, __LINE__ ); } )
392
+#define __table_entries_sym( table, idx )				\
393
+	"__tbl_" __table_name ( table ) "_" #idx
394
+#define __table_temp_sym( a, b )					\
395
+	___table_temp_sym( __table_, a, _, b )
396
+#define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d
397
+
398
+/*
399
+ * icc ignores __attribute__ (( aligned (x) )) when it is used to
400
+ * decrease the compiler's default choice of alignment (which may be
401
+ * higher than the alignment actually required by the structure).  We
402
+ * work around this by forcing the alignment to a large multiple of
403
+ * the required value (so that we are never attempting to decrease the
404
+ * default alignment) and then postprocessing the object file to
405
+ * reduce the alignment back down to the "real" value.
406
+ *
407
+ */
408
+#undef __table_alignment
409
+#define __table_alignment( table ) \
410
+	( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) )
411
+
412
+/*
413
+ * Because of the alignment hack, we must ensure that the compiler
414
+ * never tries to place multiple objects within the same section,
415
+ * otherwise the assembler will insert padding to the (incorrect)
416
+ * alignment boundary.  Do this by appending the line number to table
417
+ * section names.
418
+ *
419
+ * Note that we don't need to worry about padding between array
420
+ * elements, since the alignment is declared on the variable (i.e. the
421
+ * whole array) rather than on the type (i.e. on all individual array
422
+ * elements).
423
+ */
424
+#undef __table_section
425
+#define __table_section( table, idx ) \
426
+	".tbl." __table_name ( table ) "." __table_str ( idx ) \
427
+	"." __table_xstr ( __LINE__ )
428
+#define __table_xstr( x ) __table_str ( x )
429
+
430
+#endif /* __ICC */
431
+
355 432
 #endif /* _GPXE_TABLES_H */

+ 8
- 0
src/libgcc/icc.c Переглянути файл

@@ -0,0 +1,8 @@
1
+/*
2
+ * Intel's compiler creates an implicit call to this function at the
3
+ * start of main().
4
+ *
5
+ */
6
+void __attribute__ (( cdecl )) __intel_new_proc_init ( void ) {
7
+	/* Do nothing */
8
+}

+ 1
- 1
src/net/udp.c Переглянути файл

@@ -238,7 +238,7 @@ static int udp_tx ( struct udp_connection *udp, struct io_buffer *iobuf,
238 238
  * @ret udp		UDP connection, or NULL
239 239
  */
240 240
 static struct udp_connection * udp_demux ( struct sockaddr_tcpip *local ) {
241
-	static const struct sockaddr_tcpip empty_sockaddr;
241
+	static const struct sockaddr_tcpip empty_sockaddr = { .pad = { 0, } };
242 242
 	struct udp_connection *udp;
243 243
 
244 244
 	list_for_each_entry ( udp, &udp_conns, list ) {

+ 1
- 0
src/util/.gitignore Переглянути файл

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

+ 156
- 0
src/util/iccfix.c Переглянути файл

@@ -0,0 +1,156 @@
1
+#include <stdint.h>
2
+#include <stddef.h>
3
+#include <stdio.h>
4
+#include <stdlib.h>
5
+#include <unistd.h>
6
+#include <fcntl.h>
7
+#include <errno.h>
8
+#include <sys/types.h>
9
+#include <sys/stat.h>
10
+#include <sys/mman.h>
11
+#include <elf.h>
12
+#include <gpxe/tables.h>
13
+
14
+#define DEBUG 0
15
+
16
+#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
17
+
18
+#define dprintf(...) do {						\
19
+	if ( DEBUG )							\
20
+		fprintf ( stderr, __VA_ARGS__ );			\
21
+	} while ( 0 )
22
+
23
+#ifdef SELF_INCLUDED
24
+
25
+/**
26
+ * Fix up ICC alignments
27
+ *
28
+ * @v elf		ELF header
29
+ * @ret rc		Return status code
30
+ *
31
+ * See comments in tables.h for an explanation of why this monstrosity
32
+ * is necessary.
33
+ */
34
+static int ICCFIX ( void *elf ) {
35
+	ELF_EHDR *ehdr = elf;
36
+	ELF_SHDR *shdr = ( elf + ehdr->e_shoff );
37
+	size_t shentsize = ehdr->e_shentsize;
38
+	unsigned int shnum = ehdr->e_shnum;
39
+	ELF_SHDR *strtab = ( ( ( void * ) shdr ) +
40
+			     ( ehdr->e_shstrndx * shentsize ) );
41
+	char *strings = ( elf + strtab->sh_offset );
42
+
43
+	for ( ; shnum-- ; shdr = ( ( ( void * ) shdr ) + shentsize ) ) {
44
+		char *name = ( strings + shdr->sh_name );
45
+		unsigned long align = shdr->sh_addralign;
46
+		unsigned long new_align;
47
+
48
+		if ( ( strncmp ( name, ".tbl.", 5 ) == 0 ) &&
49
+		     ( align >= ICC_ALIGN_HACK_FACTOR ) ) {
50
+			new_align = ( align / ICC_ALIGN_HACK_FACTOR );
51
+			shdr->sh_addralign = new_align;
52
+			dprintf ( "Section \"%s\": alignment %d->%d\n",
53
+				  name, align, new_align );
54
+		}
55
+	}
56
+	return 0;
57
+}
58
+
59
+#else /* SELF_INCLUDED */
60
+
61
+#define SELF_INCLUDED
62
+
63
+/* Include iccfix32() function */
64
+#define ELF_EHDR Elf32_Ehdr
65
+#define ELF_SHDR Elf32_Shdr
66
+#define ICCFIX iccfix32
67
+#include "iccfix.c"
68
+#undef ELF_EHDR
69
+#undef ELF_SHDR
70
+#undef ICCFIX
71
+
72
+/* Include iccfix64() function */
73
+#define ELF_EHDR Elf64_Ehdr
74
+#define ELF_SHDR Elf64_Shdr
75
+#define ICCFIX iccfix64
76
+#include "iccfix.c"
77
+#undef ELF_EHDR
78
+#undef ELF_SHDR
79
+#undef ICCFIX
80
+
81
+static int iccfix ( const char *filename ) {
82
+	int fd;
83
+	struct stat stat;
84
+	void *elf;
85
+	unsigned char *eident;
86
+	int rc;
87
+
88
+	/* Open and mmap file */
89
+	fd = open ( filename, O_RDWR );
90
+	if ( fd < 0 ) {
91
+		eprintf ( "Could not open %s: %s\n",
92
+			  filename, strerror ( errno ) );
93
+		rc = -1;
94
+		goto err_open;
95
+	}
96
+	if ( fstat ( fd, &stat ) < 0 ) {
97
+		eprintf ( "Could not determine size of %s: %s\n",
98
+			  filename, strerror ( errno ) );
99
+		rc = -1;
100
+		goto err_fstat;
101
+	}
102
+	elf = mmap ( NULL, stat.st_size, ( PROT_READ | PROT_WRITE ),
103
+		     MAP_SHARED, fd, 0 );
104
+	if ( elf == MAP_FAILED ) {
105
+		eprintf ( "Could not map %s: %s\n",
106
+			  filename, strerror ( errno ) );
107
+		rc = -1;
108
+		goto err_mmap;
109
+	}
110
+
111
+	/* Perform fixups */
112
+	eident = elf;
113
+	switch ( eident[EI_CLASS] ) {
114
+	case ELFCLASS32:
115
+		rc = iccfix32 ( elf );
116
+		break;
117
+	case ELFCLASS64:
118
+		rc = iccfix64 ( elf );
119
+		break;
120
+	default:
121
+		eprintf ( "Unknown ELF class %d in %s\n",
122
+			  eident[EI_CLASS], filename );
123
+		rc = -1;
124
+		break;
125
+	}
126
+
127
+	munmap ( elf, stat.st_size );
128
+ err_mmap:
129
+ err_fstat:
130
+	close ( fd );
131
+ err_open:
132
+	return rc;
133
+}
134
+
135
+int main ( int argc, char **argv ) {
136
+	int i;
137
+	int rc;
138
+
139
+	/* Parse command line */
140
+	if ( argc < 2 ) {
141
+		eprintf ( "Syntax: %s <object_file>...\n", argv[0] );
142
+		exit ( 1 );
143
+	}
144
+
145
+	/* Process each object in turn */
146
+	for ( i = 1 ; i < argc ; i++ ) {
147
+		if ( ( rc = iccfix ( argv[i] ) ) != 0 ) {
148
+			eprintf ( "Could not fix up %s\n", argv[i] );
149
+			exit ( 1 );
150
+		}
151
+	}
152
+
153
+	return 0;
154
+}
155
+
156
+#endif /* SELF_INCLUDED */

Завантаження…
Відмінити
Зберегти