]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[build] Work around bug in gcc >= 4.8
authorMichael Brown <mcb30@ipxe.org>
Fri, 7 Jun 2013 12:46:27 +0000 (13:46 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 7 Jun 2013 12:59:58 +0000 (13:59 +0100)
gcc 4.8 and 4.9 fail to compile pxe_call.c with the error "bp cannot
be used in asm here".  Other points in the codebase which use "ebp" in
the asm clobber list do not seem to be affected.

Unfortunately gcc provides no way to specify %ebp as an output
register, so we cannot use this as a workaround.  The only viable
solution is to explicitly push/pop %ebp within the asm itself.  This
is ugly for two reasons: firstly, it may be unnecessary; secondly, it
may cause gcc to generate invalid %esp-relative addresses if the asm
happens to use memory operands.  This specific block of asm uses no
memory operands and so will not generate invalid code.

Reported-by: Daniel P. Berrange <berrange@redhat.com>
Reported-by: Christian Hesse <list@eworm.de>
Originally-fixed-by: Christian Hesse <list@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/interface/pxe/pxe_call.c

index 7fce75a9337ea06c5c6ddbf4132327ee164a9ac0..a074333687cd331d0b45ddccdf2d8ad927084d0a 100644 (file)
@@ -271,12 +271,14 @@ int pxe_start_nbp ( void ) {
                DBG ( "Restarting NBP (%x)\n", jmp );
 
        /* Far call to PXE NBP */
-       __asm__ __volatile__ ( REAL_CODE ( "movw %%cx, %%es\n\t"
+       __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
+                                          "movw %%cx, %%es\n\t"
                                           "pushw %%es\n\t"
                                           "pushw %%di\n\t"
                                           "sti\n\t"
                                           "lcall $0, $0x7c00\n\t"
-                                          "addw $4, %%sp\n\t" )
+                                          "popl %%ebp\n\t" /* discard */
+                                          "popl %%ebp\n\t" /* gcc bug */ )
                               : "=a" ( status ), "=b" ( discard_b ),
                                 "=c" ( discard_c ), "=d" ( discard_d ),
                                 "=D" ( discard_D )
@@ -284,7 +286,7 @@ int pxe_start_nbp ( void ) {
                                 "c" ( rm_cs ),
                                 "d" ( virt_to_phys ( &pxenv ) ),
                                 "D" ( __from_text16 ( &ppxe ) )
-                              : "esi", "ebp", "memory" );
+                              : "esi", "memory" );
        if ( status )
                return -EPXENBP ( status );