[ipxe-devel] [RFC] [gdb] fix compilation error with gcc 9.2

Christian Ehrhardt christian.ehrhardt at canonical.com
Tue Sep 10 10:10:53 UTC 2019


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.ehrhardt at 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




More information about the ipxe-devel mailing list