When building the x86_64 gdbidt with newer gcc it fails recognizing
the segment registers FS/GS being too short for pushq/popq.
  arch/x86_64/core/gdbidt.S:109: Error: operand type mismatch for `push'
  arch/x86_64/core/gdbidt.S:110: Error: operand type mismatch for `push'
  arch/x86_64/core/gdbidt.S:161: Error: operand type mismatch for `pop'
  arch/x86_64/core/gdbidt.S:162: Error: operand type mismatch for `pop'

It seems gcc considers the segment registers as 16 bit, so we'd have to
use pushw/popw and fill the rest with zeros as gdb expects no change in
size.

I failed to find a trustworthy resource clearly stating the how the sizes
of GS/FS are in .code64 as in src/arch/x86_64/core/gdbidt.S so I'm
unsure. But I fixed the build assuming it would stay 16, so it might be
enough to start the discussion with it.

Yet OTOH we already have pushw $0; pushw %gs (safe with zeroes in
between) in src/arch/i386/core/gdbidt.S restored by non 16bit popl.
Why doesn't that break on the same size check at least for the popl? Might
it be a false detection in gcc (actually as)?

References:
- full failing build log
  
https://launchpadlibrarian.net/441262285/buildlog_ubuntu-eoan-amd64.ipxe_1.0.0+git-20190109.133f4c4-0ubuntu2_BUILDING.txt.gz
- Ubuntu bug
  https://bugs.launchpad.net/ubuntu/+source/ipxe/+bug/1843394

Signed-off-by: Christian Ehrhardt <christian.ehrha...@canonical.com>
---
 src/arch/x86_64/core/gdbidt.S | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/arch/x86_64/core/gdbidt.S b/src/arch/x86_64/core/gdbidt.S
index 89280bf8..ac5b9e86 100644
--- a/src/arch/x86_64/core/gdbidt.S
+++ b/src/arch/x86_64/core/gdbidt.S
@@ -106,8 +106,14 @@ gdbmach_sigill:
 gdbmach_interrupt:
 
        /* Create register dump */
-       pushq   %gs
-       pushq   %fs
+       pushw   $0
+       pushw   $0
+       pushw   $0
+       pushw   %gs
+       pushw   $0
+       pushw   $0
+       pushw   $0
+       pushw   %fs
        pushq   $0              /* %es unused in long mode */
        pushq   $0              /* %ds unused in long mode */
        pushq   ( frame_ss      - regs_ss       - SIZEOF_REG )(%rsp)
@@ -158,8 +164,10 @@ gdbmach_interrupt:
        popq    ( frame_cs      - regs_cs       - SIZEOF_REG )(%rsp)
        popq    ( frame_ss      - regs_ss       - SIZEOF_REG )(%rsp)
        addq    $( regs_fs - regs_ds ), %rsp    /* skip %ds, %es */
-       popq    %fs
-       popq    %gs
+       popw    %fs
+       add             %rsp,6
+       popw    %gs
+       add             %rsp,6
 
        /* Skip code */
        addq    $( gdb_end - gdb_code ), %rsp   /* skip code */
-- 
2.23.0

_______________________________________________
ipxe-devel mailing list
ipxe-devel@lists.ipxe.org
https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel

Reply via email to