Skip to content

Commit cba22d3

Browse files
committed
[build] Work around bug in gcc >= 4.8
Commit 238050d ("[build] Work around bug in gcc >= 4.8") works around one instance of a bug in recent versions of gcc, in which "ebp" cannot be specified within an asm clobber list. Some versions of gcc seem to exhibit the same bug on other points in the codebase. Fix by changing all instances of "ebp" in a clobber list to use the push/pop %ebp workaround instead. Originally-implemented-by: Víctor Román Archidona <contacto@victor-roman.es> Signed-off-by: Michael Brown <mcb30@ipxe.org>
1 parent a9fa0d5 commit cba22d3

File tree

6 files changed

+35
-20
lines changed

6 files changed

+35
-20
lines changed

src/arch/i386/drivers/net/undiload.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,15 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
103103

104104
/* Call loader */
105105
undi_loader_entry = undirom->loader_entry;
106-
__asm__ __volatile__ ( REAL_CODE ( "pushw %%ds\n\t"
106+
__asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
107+
"pushw %%ds\n\t"
107108
"pushw %%ax\n\t"
108109
"lcall *undi_loader_entry\n\t"
109-
"addw $4, %%sp\n\t" )
110+
"popl %%ebp\n\t" /* discard */
111+
"popl %%ebp\n\t" /* gcc bug */ )
110112
: "=a" ( exit )
111113
: "a" ( __from_data16 ( &undi_loader ) )
112-
: "ebx", "ecx", "edx", "esi", "edi", "ebp" );
114+
: "ebx", "ecx", "edx", "esi", "edi" );
113115

114116
if ( exit != PXENV_EXIT_SUCCESS ) {
115117
/* Clear entry point */

src/arch/i386/firmware/pcbios/bios_console.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ static void bios_putchar ( int character ) {
167167
return;
168168

169169
/* Print character with attribute */
170-
__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
170+
__asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
171+
"sti\n\t"
171172
/* Skip non-printable characters */
172173
"cmpb $0x20, %%al\n\t"
173174
"jb 1f\n\t"
@@ -188,11 +189,11 @@ static void bios_putchar ( int character ) {
188189
"xorw %%bx, %%bx\n\t"
189190
"movb $0x0e, %%ah\n\t"
190191
"int $0x10\n\t"
191-
"cli\n\t" )
192+
"cli\n\t"
193+
"popl %%ebp\n\t" /* gcc bug */ )
192194
: "=a" ( discard_a ), "=b" ( discard_b ),
193195
"=c" ( discard_c )
194-
: "a" ( character ), "b" ( bios_attr )
195-
: "ebp" );
196+
: "a" ( character ), "b" ( bios_attr ) );
196197
}
197198

198199
/**

src/arch/i386/image/bootsector.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ int call_bootsector ( unsigned int segment, unsigned int offset,
8080
"movw %%ss, %%ax\n\t"
8181
"movw %%ax, %%cs:saved_ss\n\t"
8282
"movw %%sp, %%cs:saved_sp\n\t"
83+
/* Save frame pointer (gcc bug) */
84+
"movl %%ebp, %%cs:saved_ebp\n\t"
8385
/* Prepare jump to boot sector */
8486
"pushw %%bx\n\t"
8587
"pushw %%di\n\t"
@@ -99,11 +101,14 @@ int call_bootsector ( unsigned int segment, unsigned int offset,
99101
"sti\n\t"
100102
"lret\n\t"
101103
/* Preserved variables */
104+
"\nsaved_ebp: .long 0\n\t"
102105
"\nsaved_ss: .word 0\n\t"
103106
"\nsaved_sp: .word 0\n\t"
104107
"\nsaved_retaddr: .word 0\n\t"
105108
/* Boot failure return point */
106109
"\nbootsector_exec_fail:\n\t"
110+
/* Restore frame pointer (gcc bug) */
111+
"movl %%cs:saved_ebp, %%ebp\n\t"
107112
/* Restore stack pointer */
108113
"movw %%cs:saved_ss, %%ax\n\t"
109114
"movw %%ax, %%ss\n\t"
@@ -114,7 +119,7 @@ int call_bootsector ( unsigned int segment, unsigned int offset,
114119
"=d" ( discard_d )
115120
: "b" ( segment ), "D" ( offset ),
116121
"d" ( drive )
117-
: "eax", "ecx", "esi", "ebp" );
122+
: "eax", "ecx", "esi" );
118123

119124
DBG ( "Booted disk returned via INT 18 or 19\n" );
120125

src/arch/i386/image/elfboot.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ static int elfboot_exec ( struct image *image ) {
6060

6161
/* Jump to OS with flat physical addressing */
6262
DBGC ( image, "ELF %p starting execution at %lx\n", image, entry );
63-
__asm__ __volatile__ ( PHYS_CODE ( "call *%%edi\n\t" )
63+
__asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */
64+
"call *%%edi\n\t"
65+
"popl %%ebp\n\t" /* gcc bug */ )
6466
: : "D" ( entry )
65-
: "eax", "ebx", "ecx", "edx", "esi", "ebp",
66-
"memory" );
67+
: "eax", "ebx", "ecx", "edx", "esi", "memory" );
6768

6869
DBGC ( image, "ELF %p returned\n", image );
6970

src/arch/i386/image/nbi.c

+10-6
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
248248
imgheader->execaddr.segoff.offset );
249249

250250
__asm__ __volatile__ (
251-
REAL_CODE ( "pushw %%ds\n\t" /* far pointer to bootp data */
251+
REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
252+
"pushw %%ds\n\t" /* far pointer to bootp data */
252253
"pushw %%bx\n\t"
253254
"pushl %%esi\n\t" /* location */
254255
"pushw %%cs\n\t" /* lcall execaddr */
@@ -258,13 +259,14 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
258259
"pushl %%edi\n\t"
259260
"lret\n\t"
260261
"\n2:\n\t"
261-
"addw $8,%%sp\n\t" /* clean up stack */ )
262+
"addw $8,%%sp\n\t" /* clean up stack */
263+
"popl %%ebp\n\t" /* gcc bug */ )
262264
: "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ),
263265
"=b" ( discard_b )
264266
: "D" ( imgheader->execaddr.segoff ),
265267
"S" ( imgheader->location ),
266268
"b" ( __from_data16 ( basemem_packet ) )
267-
: "ecx", "edx", "ebp" );
269+
: "ecx", "edx" );
268270

269271
return rc;
270272
}
@@ -288,19 +290,21 @@ static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
288290

289291
/* Jump to OS with flat physical addressing */
290292
__asm__ __volatile__ (
291-
PHYS_CODE ( "pushl %%ebx\n\t" /* bootp data */
293+
PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */
294+
"pushl %%ebx\n\t" /* bootp data */
292295
"pushl %%esi\n\t" /* imgheader */
293296
"pushl %%eax\n\t" /* loaderinfo */
294297
"call *%%edi\n\t"
295-
"addl $12, %%esp\n\t" /* clean up stack */ )
298+
"addl $12, %%esp\n\t" /* clean up stack */
299+
"popl %%ebp\n\t" /* gcc bug */ )
296300
: "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ),
297301
"=b" ( discard_b )
298302
: "D" ( imgheader->execaddr.linear ),
299303
"S" ( ( imgheader->location.segment << 4 ) +
300304
imgheader->location.offset ),
301305
"b" ( virt_to_phys ( basemem_packet ) ),
302306
"a" ( virt_to_phys ( &loaderinfo ) )
303-
: "ecx", "edx", "ebp", "memory" );
307+
: "ecx", "edx", "memory" );
304308

305309
return rc;
306310
}

src/arch/i386/interface/pxeparent/pxeparent.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,18 @@ int pxeparent_call ( SEGOFF16_t entry, unsigned int function,
143143
/* Call real-mode entry point. This calling convention will
144144
* work with both the !PXE and the PXENV+ entry points.
145145
*/
146-
__asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
146+
__asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
147+
"pushw %%es\n\t"
147148
"pushw %%di\n\t"
148149
"pushw %%bx\n\t"
149150
"lcall *pxeparent_entry_point\n\t"
150-
"addw $6, %%sp\n\t" )
151+
"addw $6, %%sp\n\t"
152+
"popl %%ebp\n\t" /* gcc bug */ )
151153
: "=a" ( exit ), "=b" ( discard_b ),
152154
"=D" ( discard_D )
153155
: "b" ( function ),
154156
"D" ( __from_data16 ( &pxeparent_params ) )
155-
: "ecx", "edx", "esi", "ebp" );
157+
: "ecx", "edx", "esi" );
156158

157159
/* Determine return status code based on PXENV_EXIT and
158160
* PXENV_STATUS

0 commit comments

Comments
 (0)