From 65289dab529e8aefe6ef0e365739e05a8a574e0e Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Mon, 21 Oct 2013 14:22:17 +0000 Subject: [PATCH] ipxe: dont clobber ebp build fix https://bugs.gentoo.org/show_bug.cgi?id=487254 --- .../etherboot/patches/no-clobber-ebp.patch | 220 +++++++++++++++++++++ .../etherboot/patches/no-clobber-ebp2.patch | 26 +++ tools/firmware/etherboot/patches/series | 2 + 3 files changed, 248 insertions(+) create mode 100644 tools/firmware/etherboot/patches/no-clobber-ebp.patch create mode 100644 tools/firmware/etherboot/patches/no-clobber-ebp2.patch diff --git a/tools/firmware/etherboot/patches/no-clobber-ebp.patch b/tools/firmware/etherboot/patches/no-clobber-ebp.patch new file mode 100644 index 0000000..bbd8c06 --- /dev/null +++ b/tools/firmware/etherboot/patches/no-clobber-ebp.patch @@ -0,0 +1,220 @@ +From cba22d36b77da53890bd65fdadd0e63925687af0 Mon Sep 17 00:00:00 2001 +From: Michael Brown +Date: Wed, 25 Sep 2013 12:55:46 +0100 +Subject: [PATCH] [build] Work around bug in gcc >= 4.8 +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +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 +Signed-off-by: Michael Brown +--- + src/arch/i386/drivers/net/undiload.c | 8 +++++--- + src/arch/i386/firmware/pcbios/bios_console.c | 9 +++++---- + src/arch/i386/image/bootsector.c | 7 ++++++- + src/arch/i386/image/elfboot.c | 7 ++++--- + src/arch/i386/image/nbi.c | 16 ++++++++++------ + src/arch/i386/interface/pxeparent/pxeparent.c | 8 +++++--- + 6 files changed, 35 insertions(+), 20 deletions(-) + +diff --git a/src/arch/i386/drivers/net/undiload.c b/src/arch/i386/drivers/net/undiload.c +index f0f15e6..77134dc 100644 +--- a/src/arch/i386/drivers/net/undiload.c ++++ b/src/arch/i386/drivers/net/undiload.c +@@ -103,13 +103,15 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) { + + /* Call loader */ + undi_loader_entry = undirom->loader_entry; +- __asm__ __volatile__ ( REAL_CODE ( "pushw %%ds\n\t" ++ __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ ++ "pushw %%ds\n\t" + "pushw %%ax\n\t" + "lcall *undi_loader_entry\n\t" +- "addw $4, %%sp\n\t" ) ++ "popl %%ebp\n\t" /* discard */ ++ "popl %%ebp\n\t" /* gcc bug */ ) + : "=a" ( exit ) + : "a" ( __from_data16 ( &undi_loader ) ) +- : "ebx", "ecx", "edx", "esi", "edi", "ebp" ); ++ : "ebx", "ecx", "edx", "esi", "edi" ); + + if ( exit != PXENV_EXIT_SUCCESS ) { + /* Clear entry point */ +diff --git a/src/arch/i386/firmware/pcbios/bios_console.c b/src/arch/i386/firmware/pcbios/bios_console.c +index 213ebd9..79e4370 100644 +--- a/src/arch/i386/firmware/pcbios/bios_console.c ++++ b/src/arch/i386/firmware/pcbios/bios_console.c +@@ -167,7 +167,8 @@ static void bios_putchar ( int character ) { + return; + + /* Print character with attribute */ +- __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" ++ __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ ++ "sti\n\t" + /* Skip non-printable characters */ + "cmpb $0x20, %%al\n\t" + "jb 1f\n\t" +@@ -188,11 +189,11 @@ static void bios_putchar ( int character ) { + "xorw %%bx, %%bx\n\t" + "movb $0x0e, %%ah\n\t" + "int $0x10\n\t" +- "cli\n\t" ) ++ "cli\n\t" ++ "popl %%ebp\n\t" /* gcc bug */ ) + : "=a" ( discard_a ), "=b" ( discard_b ), + "=c" ( discard_c ) +- : "a" ( character ), "b" ( bios_attr ) +- : "ebp" ); ++ : "a" ( character ), "b" ( bios_attr ) ); + } + + /** +diff --git a/src/arch/i386/image/bootsector.c b/src/arch/i386/image/bootsector.c +index ab3cf94..cb164fd 100644 +--- a/src/arch/i386/image/bootsector.c ++++ b/src/arch/i386/image/bootsector.c +@@ -80,6 +80,8 @@ int call_bootsector ( unsigned int segment, unsigned int offset, + "movw %%ss, %%ax\n\t" + "movw %%ax, %%cs:saved_ss\n\t" + "movw %%sp, %%cs:saved_sp\n\t" ++ /* Save frame pointer (gcc bug) */ ++ "movl %%ebp, %%cs:saved_ebp\n\t" + /* Jump to boot sector */ + "pushw %%bx\n\t" + "pushw %%di\n\t" +@@ -99,11 +101,14 @@ int call_bootsector ( unsigned int segment, unsigned int offset, + "sti\n\t" + "lret\n\t" + /* Preserved variables */ ++ "\nsaved_ebp: .long 0\n\t" + "\nsaved_ss: .word 0\n\t" + "\nsaved_sp: .word 0\n\t" + "\nsaved_retaddr: .word 0\n\t" + /* Boot failure return point */ + "\nbootsector_exec_fail:\n\t" ++ /* Restore frame pointer (gcc bug) */ ++ "movl %%cs:saved_ebp, %%ebp\n\t" + /* Restore stack pointer */ + "movw %%cs:saved_ss, %%ax\n\t" + "movw %%ax, %%ss\n\t" +@@ -114,7 +119,7 @@ int call_bootsector ( unsigned int segment, unsigned int offset, + "=d" ( discard_d ) + : "b" ( segment ), "D" ( offset ), + "d" ( drive ) +- : "eax", "ecx", "esi", "ebp" ); ++ : "eax", "ecx", "esi" ); + + DBG ( "Booted disk returned via INT 18 or 19\n" ); + +diff --git a/src/arch/i386/image/elfboot.c b/src/arch/i386/image/elfboot.c +index a867a95..0f6957f 100644 +--- a/src/arch/i386/image/elfboot.c ++++ b/src/arch/i386/image/elfboot.c +@@ -60,10 +60,11 @@ static int elfboot_exec ( struct image *image ) { + + /* Jump to OS with flat physical addressing */ + DBGC ( image, "ELF %p starting execution at %lx\n", image, entry ); +- __asm__ __volatile__ ( PHYS_CODE ( "call *%%edi\n\t" ) ++ __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */ ++ "call *%%edi\n\t" ++ "popl %%ebp\n\t" /* gcc bug */ ) + : : "D" ( entry ) +- : "eax", "ebx", "ecx", "edx", "esi", "ebp", +- "memory" ); ++ : "eax", "ebx", "ecx", "edx", "esi", "memory" ); + + DBGC ( image, "ELF %p returned\n", image ); + +diff --git a/src/arch/i386/image/nbi.c b/src/arch/i386/image/nbi.c +index d3e523e..9904614 100644 +--- a/src/arch/i386/image/nbi.c ++++ b/src/arch/i386/image/nbi.c +@@ -248,7 +248,8 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) { + imgheader->execaddr.segoff.offset ); + + __asm__ __volatile__ ( +- REAL_CODE ( "pushw %%ds\n\t" /* far pointer to bootp data */ ++ REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ ++ "pushw %%ds\n\t" /* far pointer to bootp data */ + "pushw %%bx\n\t" + "pushl %%esi\n\t" /* location */ + "pushw %%cs\n\t" /* lcall execaddr */ +@@ -258,13 +259,14 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) { + "pushl %%edi\n\t" + "lret\n\t" + "\n2:\n\t" +- "addw $8,%%sp\n\t" /* clean up stack */ ) ++ "addw $8,%%sp\n\t" /* clean up stack */ ++ "popl %%ebp\n\t" /* gcc bug */ ) + : "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ), + "=b" ( discard_b ) + : "D" ( imgheader->execaddr.segoff ), + "S" ( imgheader->location ), + "b" ( __from_data16 ( basemem_packet ) ) +- : "ecx", "edx", "ebp" ); ++ : "ecx", "edx" ); + + return rc; + } +@@ -288,11 +290,13 @@ static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) { + + /* Jump to OS with flat physical addressing */ + __asm__ __volatile__ ( +- PHYS_CODE ( "pushl %%ebx\n\t" /* bootp data */ ++ PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */ ++ "pushl %%ebx\n\t" /* bootp data */ + "pushl %%esi\n\t" /* imgheader */ + "pushl %%eax\n\t" /* loaderinfo */ + "call *%%edi\n\t" +- "addl $12, %%esp\n\t" /* clean up stack */ ) ++ "addl $12, %%esp\n\t" /* clean up stack */ ++ "popl %%ebp\n\t" /* gcc bug */ ) + : "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ), + "=b" ( discard_b ) + : "D" ( imgheader->execaddr.linear ), +@@ -300,7 +304,7 @@ static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) { + imgheader->location.offset ), + "b" ( virt_to_phys ( basemem_packet ) ), + "a" ( virt_to_phys ( &loaderinfo ) ) +- : "ecx", "edx", "ebp", "memory" ); ++ : "ecx", "edx", "memory" ); + + return rc; + } +diff --git a/src/arch/i386/interface/pxeparent/pxeparent.c b/src/arch/i386/interface/pxeparent/pxeparent.c +index b2c6ffb..9d2948c 100644 +--- a/src/arch/i386/interface/pxeparent/pxeparent.c ++++ b/src/arch/i386/interface/pxeparent/pxeparent.c +@@ -143,16 +143,18 @@ int pxeparent_call ( SEGOFF16_t entry, unsigned int function, + /* Call real-mode entry point. This calling convention will + * work with both the !PXE and the PXENV+ entry points. + */ +- __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t" ++ __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ ++ "pushw %%es\n\t" + "pushw %%di\n\t" + "pushw %%bx\n\t" + "lcall *pxeparent_entry_point\n\t" +- "addw $6, %%sp\n\t" ) ++ "addw $6, %%sp\n\t" ++ "popl %%ebp\n\t" /* gcc bug */ ) + : "=a" ( exit ), "=b" ( discard_b ), + "=D" ( discard_D ) + : "b" ( function ), + "D" ( __from_data16 ( &pxeparent_params ) ) +- : "ecx", "edx", "esi", "ebp" ); ++ : "ecx", "edx", "esi" ); + + /* Determine return status code based on PXENV_EXIT and + * PXENV_STATUS +-- +1.7.9 + diff --git a/tools/firmware/etherboot/patches/no-clobber-ebp2.patch b/tools/firmware/etherboot/patches/no-clobber-ebp2.patch new file mode 100644 index 0000000..6b9ac07 --- /dev/null +++ b/tools/firmware/etherboot/patches/no-clobber-ebp2.patch @@ -0,0 +1,26 @@ +--- a/src/arch/i386/interface/pxe/pxe_call.c.orig ++++ b/src/arch/i386/interface/pxe/pxe_call.c +@@ -265,11 +265,13 @@ + + /* Far call to PXE NBP */ + __asm__ __volatile__ ( REAL_CODE ( "movw %%cx, %%es\n\t" ++ "pushl %%ebp\n\t" /* gcc bug */ + "pushw %%es\n\t" + "pushw %%di\n\t" + "sti\n\t" + "lcall $0, $0x7c00\n\t" +- "addw $4, %%sp\n\t" ) ++ "addw $4, %%sp\n\t" ++ "popl %%ebp\n\t" ) /* gcc bug */ + : "=a" ( rc ), "=b" ( discard_b ), + "=c" ( discard_c ), "=d" ( discard_d ), + "=D" ( discard_D ) +@@ -277,7 +279,7 @@ + "c" ( rm_cs ), + "d" ( virt_to_phys ( &pxenv ) ), + "D" ( __from_text16 ( &ppxe ) ) +- : "esi", "ebp", "memory" ); ++ : "esi", "memory" ); + + return rc; + } diff --git a/tools/firmware/etherboot/patches/series b/tools/firmware/etherboot/patches/series index 5bd7df8..154e65b 100644 --- a/tools/firmware/etherboot/patches/series +++ b/tools/firmware/etherboot/patches/series @@ -2,3 +2,5 @@ boot_prompt_option.patch build_fix_1.patch build_fix_2.patch build_fix_3.patch +no-clobber-ebp.patch +no-clobber-ebp2.patch -- 1.8.4.1