Sfoglia il codice sorgente

[zbin] Change fixup semantics to support ROMs over 128k uncompressed

The option ROM header contains a one-byte field indicating the number
of 512-byte sectors in the ROM image.  Currently it is linked to
contain the number of uncompressed sectors, with an instruction to the
compressor to correct it.  This causes link failure when the
uncompressed size of the ROM image is over 128k.

Fix by replacing the SUBx compressor fixup with an ADDx fixup that
adds the total compressed output length, scaled as requested, to an
addend stored in the field where the final length value will be
placed.  This is similar to the behavior of ELF relocations, and
ensures that an overflow error will not be generated unless the
compressed size is still too large for the field.

This also allows us to do away with the _filesz_pgh and _filesz_sect
calculations exported by the linker script.

Output tested bitwise identical to the old SUBx mechanism on hd, dsk,
lkrn, and rom prefixes, on both 32-bit and 64-bit processors.

Modified-by: Michael Brown <mcb30@etherboot.org>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
tags/v0.9.8
Joshua Oreman 15 anni fa
parent
commit
d5d68b2e31

+ 2
- 2
src/arch/i386/prefix/dskprefix.S Vedi File

146
 	/* Jump to loaded copy */
146
 	/* Jump to loaded copy */
147
 	ljmp	$SYSSEG, $start_runtime
147
 	ljmp	$SYSSEG, $start_runtime
148
 
148
 
149
-endseg:	.word SYSSEG + _filesz_pgh
149
+endseg:	.word SYSSEG
150
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
150
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
151
-	.ascii	"SUBW"
151
+	.ascii	"ADDW"
152
 	.long	endseg
152
 	.long	endseg
153
 	.long	16
153
 	.long	16
154
 	.long	0
154
 	.long	0

+ 2
- 2
src/arch/i386/prefix/hdprefix.S Vedi File

65
 max_head:
65
 max_head:
66
 	.byte	0
66
 	.byte	0
67
 load_length:
67
 load_length:
68
-	.long	_filesz_sect
68
+	.long	0
69
 	
69
 	
70
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
70
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
71
-	.ascii	"SUBL"
71
+	.ascii	"ADDL"
72
 	.long	load_length
72
 	.long	load_length
73
 	.long	512
73
 	.long	512
74
 	.long	0
74
 	.long	0

+ 2
- 2
src/arch/i386/prefix/lkrnprefix.S Vedi File

94
 root_flags: 
94
 root_flags: 
95
 	.word	0
95
 	.word	0
96
 syssize: 
96
 syssize: 
97
-	.long	_filesz_pgh - PREFIXPGH
97
+	.long	-PREFIXPGH
98
 
98
 
99
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
99
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
100
-	.ascii	"SUBL"
100
+	.ascii	"ADDL"
101
 	.long	syssize
101
 	.long	syssize
102
 	.long	16
102
 	.long	16
103
 	.long	0
103
 	.long	0

+ 4
- 4
src/arch/i386/prefix/nbiprefix.S Vedi File

30
 	.byte	0
30
 	.byte	0
31
 	.byte	0x04		/* Last segment */
31
 	.byte	0x04		/* Last segment */
32
 	.long	0x00007e00
32
 	.long	0x00007e00
33
-imglen:	.long	_filesz - 512
34
-memlen:	.long	_filesz - 512
33
+imglen:	.long	-512
34
+memlen:	.long	-512
35
 	.size	segment_header, . - segment_header
35
 	.size	segment_header, . - segment_header
36
 
36
 
37
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
37
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
38
-	.ascii	"SUBL"
38
+	.ascii	"ADDL"
39
 	.long	imglen
39
 	.long	imglen
40
 	.long	1
40
 	.long	1
41
 	.long	0
41
 	.long	0
42
-	.ascii	"SUBL"
42
+	.ascii	"ADDL"
43
 	.long	memlen
43
 	.long	memlen
44
 	.long	1
44
 	.long	1
45
 	.long	0
45
 	.long	0

+ 6
- 6
src/arch/i386/prefix/romprefix.S Vedi File

33
 	.org	0x00
33
 	.org	0x00
34
 romheader:
34
 romheader:
35
 	.word	0xAA55			/* BIOS extension signature */
35
 	.word	0xAA55			/* BIOS extension signature */
36
-romheader_size:	.byte _filesz_sect	/* Size in 512-byte blocks */
36
+romheader_size:	.byte 0			/* Size in 512-byte blocks */
37
 	jmp	init			/* Initialisation vector */
37
 	jmp	init			/* Initialisation vector */
38
 checksum:
38
 checksum:
39
 	.byte	0
39
 	.byte	0
46
 	.size romheader, . - romheader
46
 	.size romheader, . - romheader
47
 	
47
 	
48
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
48
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
49
-	.ascii	"SUBB"
49
+	.ascii	"ADDB"
50
 	.long	romheader_size
50
 	.long	romheader_size
51
 	.long	512
51
 	.long	512
52
 	.long	0
52
 	.long	0
61
 	.byte	0x03			/* PCI data structure revision */
61
 	.byte	0x03			/* PCI data structure revision */
62
 	.byte	0x02, 0x00, 0x00	/* Class code */
62
 	.byte	0x02, 0x00, 0x00	/* Class code */
63
 pciheader_image_length:
63
 pciheader_image_length:
64
-	.word	_filesz_sect		/* Image length */
64
+	.word	0			/* Image length */
65
 	.word	0x0001			/* Revision level */
65
 	.word	0x0001			/* Revision level */
66
 	.byte	0x00			/* Code type */
66
 	.byte	0x00			/* Code type */
67
 	.byte	0x80			/* Last image indicator */
67
 	.byte	0x80			/* Last image indicator */
68
 pciheader_runtime_length:
68
 pciheader_runtime_length:
69
-	.word	_filesz_sect		/* Maximum run-time image length */
69
+	.word	0			/* Maximum run-time image length */
70
 	.word	0x0000			/* Configuration utility code header */
70
 	.word	0x0000			/* Configuration utility code header */
71
 	.word	0x0000			/* DMTF CLP entry point */
71
 	.word	0x0000			/* DMTF CLP entry point */
72
 	.equ pciheader_len, . - pciheader
72
 	.equ pciheader_len, . - pciheader
73
 	.size pciheader, . - pciheader
73
 	.size pciheader, . - pciheader
74
 	
74
 	
75
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
75
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
76
-	.ascii	"SUBW"
76
+	.ascii	"ADDW"
77
 	.long	pciheader_image_length
77
 	.long	pciheader_image_length
78
 	.long	512
78
 	.long	512
79
 	.long	0
79
 	.long	0
80
-	.ascii	"SUBW"
80
+	.ascii	"ADDW"
81
 	.long	pciheader_runtime_length
81
 	.long	pciheader_runtime_length
82
 	.long	512
82
 	.long	512
83
 	.long	0
83
 	.long	0

+ 0
- 9
src/arch/i386/scripts/i386.lds Vedi File

197
     _prefix_memsz_sect	= ( ( _prefix_memsz + 511 ) / 512 );
197
     _prefix_memsz_sect	= ( ( _prefix_memsz + 511 ) / 512 );
198
     _text16_memsz_pgh	= ( ( _text16_memsz + 15 ) / 16 );
198
     _text16_memsz_pgh	= ( ( _text16_memsz + 15 ) / 16 );
199
     _data16_memsz_pgh	= ( ( _data16_memsz + 15 ) / 16 );
199
     _data16_memsz_pgh	= ( ( _data16_memsz + 15 ) / 16 );
200
-
201
-    /*
202
-     * File size in paragraphs and sectors.  Note that wherever the
203
-     * _filesz variables are used, there must be a corresponding
204
-     * .zinfo.fixup section.
205
-     *
206
-     */
207
-    _filesz_pgh		= ( ( _filesz + 15 ) / 16 );
208
-    _filesz_sect	= ( ( _filesz + 511 ) / 512 );
209
 }
200
 }

+ 76
- 50
src/util/zbin.c Vedi File

38
 	uint32_t align;
38
 	uint32_t align;
39
 };
39
 };
40
 
40
 
41
-struct zinfo_subtract {
41
+struct zinfo_add {
42
 	char type[4];
42
 	char type[4];
43
 	uint32_t offset;
43
 	uint32_t offset;
44
 	uint32_t divisor;
44
 	uint32_t divisor;
49
 	struct zinfo_common common;
49
 	struct zinfo_common common;
50
 	struct zinfo_copy copy;
50
 	struct zinfo_copy copy;
51
 	struct zinfo_pack pack;
51
 	struct zinfo_pack pack;
52
-	struct zinfo_subtract subtract;
52
+	struct zinfo_add add;
53
 };
53
 };
54
 
54
 
55
 struct zinfo_file {
55
 struct zinfo_file {
157
 	}
157
 	}
158
 
158
 
159
 	if ( DEBUG ) {
159
 	if ( DEBUG ) {
160
-		fprintf ( stderr, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n", offset, ( offset + len ),
161
-			  output->len, ( output->len + len ) );
160
+		fprintf ( stderr, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n",
161
+			  offset, ( offset + len ), output->len,
162
+			  ( output->len + len ) );
162
 	}
163
 	}
163
 
164
 
164
 	memcpy ( ( output->buf + output->len ),
165
 	memcpy ( ( output->buf + output->len ),
194
 	}
195
 	}
195
 
196
 
196
 	if ( DEBUG ) {
197
 	if ( DEBUG ) {
197
-		fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n", offset, ( offset + len ),
198
-			  output->len, ( output->len + packed_len ) );
198
+		fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n",
199
+			  offset, ( offset + len ), output->len,
200
+			  ( output->len + packed_len ) );
199
 	}
201
 	}
200
 
202
 
201
 	output->len += packed_len;
203
 	output->len += packed_len;
207
 	return 0;
209
 	return 0;
208
 }
210
 }
209
 
211
 
210
-static int process_zinfo_subtract ( struct input_file *input,
211
-				    struct output_file *output,
212
-				    struct zinfo_subtract *subtract,
213
-				    size_t datasize ) {
214
-	size_t offset = subtract->offset;
212
+static int process_zinfo_add ( struct input_file *input,
213
+			       struct output_file *output,
214
+			       struct zinfo_add *add,
215
+			       size_t datasize ) {
216
+	size_t offset = add->offset;
215
 	void *target;
217
 	void *target;
216
-	signed long raw_delta;
217
-	signed long delta;
218
-	unsigned long old;
219
-	unsigned long new;
218
+	signed long addend;
219
+	unsigned long size;
220
+	signed long val;
221
+	unsigned long mask;
220
 
222
 
221
 	if ( ( offset + datasize ) > output->len ) {
223
 	if ( ( offset + datasize ) > output->len ) {
222
-		fprintf ( stderr, "Subtract at %#zx outside output buffer\n",
224
+		fprintf ( stderr, "Add at %#zx outside output buffer\n",
223
 			  offset );
225
 			  offset );
224
 		return -1;
226
 		return -1;
225
 	}
227
 	}
226
 
228
 
227
 	target = ( output->buf + offset );
229
 	target = ( output->buf + offset );
228
-	raw_delta = ( align ( output->len, subtract->divisor ) -
229
-		      align ( input->len, subtract->divisor ) );
230
-	delta = ( raw_delta / ( ( signed long ) subtract->divisor ) );
230
+	size = ( align ( output->len, add->divisor ) / add->divisor );
231
 
231
 
232
 	switch ( datasize ) {
232
 	switch ( datasize ) {
233
-	case 1: {
234
-		uint8_t *byte = target;
235
-		old = *byte;
236
-		*byte += delta;
237
-		new = *byte;
238
-		break; }
239
-	case 2: {
240
-		uint16_t *word = target;
241
-		old = *word;
242
-		*word += delta;
243
-		new = *word;
244
-		break; }
245
-	case 4: {
246
-		uint32_t *dword = target;
247
-		old = *dword;
248
-		*dword += delta;
249
-		new = *dword;
250
-		break; }
233
+	case 1:
234
+		addend = *( ( int8_t * ) target );
235
+		break;
236
+	case 2:
237
+		addend = *( ( int16_t * ) target );
238
+		break;
239
+	case 4:
240
+		addend = *( ( int32_t * ) target );
241
+		break;
251
 	default:
242
 	default:
252
-		fprintf ( stderr, "Unsupported subtract datasize %d\n",
243
+		fprintf ( stderr, "Unsupported add datasize %d\n",
253
 			  datasize );
244
 			  datasize );
254
 		return -1;
245
 		return -1;
255
 	}
246
 	}
256
 
247
 
248
+	val = size + addend;
249
+
250
+	/* The result of 1UL << ( 8 * sizeof(unsigned long) ) is undefined */
251
+	mask = ( ( datasize < sizeof ( mask ) ) ?
252
+		 ( ( 1UL << ( 8 * datasize ) ) - 1 ) : ~0UL );
253
+
254
+	if ( val < 0 ) {
255
+		fprintf ( stderr, "Add %s%#lx+%#lx at %#zx %sflows field\n",
256
+			  ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
257
+			  offset, ( ( addend < 0 ) ? "under" : "over" ) );
258
+		return -1;
259
+	}
260
+
261
+	if ( val & ~mask ) {
262
+		fprintf ( stderr, "Add %s%#lx+%#lx at %#zx overflows %d-byte "
263
+			  "field (%d bytes too big)\n",
264
+			  ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
265
+			  offset, datasize,
266
+			  ( ( val - mask - 1 ) * add->divisor ) );
267
+		return -1;
268
+	}
269
+
270
+	switch ( datasize ) {
271
+	case 1:
272
+		*( ( uint8_t * ) target ) = val;
273
+		break;
274
+	case 2:
275
+		*( ( uint16_t * ) target ) = val;
276
+		break;
277
+	case 4:
278
+		*( ( uint32_t * ) target ) = val;
279
+		break;
280
+	}
281
+
257
 	if ( DEBUG ) {
282
 	if ( DEBUG ) {
258
-		fprintf ( stderr, "SUBx [%#zx,%#zx) (%#lx+(%#lx/%#x)-(%#lx/%#x)) = %#lx\n",
259
-			  offset, ( offset + datasize ), old, output->len, subtract->divisor,
260
-			  input->len, subtract->divisor, new );
283
+		fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#lx+(%#lx/%#x)) = "
284
+			  "%#lx\n", offset, ( offset + datasize ),
285
+			  ( ( addend < 0 ) ? "-" : "" ), abs ( addend ),
286
+			  output->len, add->divisor, val );
261
 	}
287
 	}
262
 
288
 
263
 	return 0;
289
 	return 0;
264
 }
290
 }
265
 
291
 
266
-static int process_zinfo_subb ( struct input_file *input,
292
+static int process_zinfo_addb ( struct input_file *input,
267
 				struct output_file *output,
293
 				struct output_file *output,
268
 				union zinfo_record *zinfo ) {
294
 				union zinfo_record *zinfo ) {
269
-	return process_zinfo_subtract ( input, output, &zinfo->subtract, 1 );
295
+	return process_zinfo_add ( input, output, &zinfo->add, 1 );
270
 }
296
 }
271
 
297
 
272
-static int process_zinfo_subw ( struct input_file *input,
298
+static int process_zinfo_addw ( struct input_file *input,
273
 				struct output_file *output,
299
 				struct output_file *output,
274
 				union zinfo_record *zinfo ) {
300
 				union zinfo_record *zinfo ) {
275
-	return process_zinfo_subtract ( input, output, &zinfo->subtract, 2 );
301
+	return process_zinfo_add ( input, output, &zinfo->add, 2 );
276
 }
302
 }
277
 
303
 
278
-static int process_zinfo_subl ( struct input_file *input,
304
+static int process_zinfo_addl ( struct input_file *input,
279
 				struct output_file *output,
305
 				struct output_file *output,
280
 				union zinfo_record *zinfo ) {
306
 				union zinfo_record *zinfo ) {
281
-	return process_zinfo_subtract ( input, output, &zinfo->subtract, 4 );
307
+	return process_zinfo_add ( input, output, &zinfo->add, 4 );
282
 }
308
 }
283
 
309
 
284
 struct zinfo_processor {
310
 struct zinfo_processor {
291
 static struct zinfo_processor zinfo_processors[] = {
317
 static struct zinfo_processor zinfo_processors[] = {
292
 	{ "COPY", process_zinfo_copy },
318
 	{ "COPY", process_zinfo_copy },
293
 	{ "PACK", process_zinfo_pack },
319
 	{ "PACK", process_zinfo_pack },
294
-	{ "SUBB", process_zinfo_subb },
295
-	{ "SUBW", process_zinfo_subw },
296
-	{ "SUBL", process_zinfo_subl },
320
+	{ "ADDB", process_zinfo_addb },
321
+	{ "ADDW", process_zinfo_addw },
322
+	{ "ADDL", process_zinfo_addl },
297
 };
323
 };
298
 
324
 
299
 static int process_zinfo ( struct input_file *input,
325
 static int process_zinfo ( struct input_file *input,

Loading…
Annulla
Salva