Make x86-64 multilib work again

Bo Thorsen bo@sonofthor.dk
Fri May 10 03:26:00 GMT 2002


Currently x86-64 needs a --disable-multilib since the 
MD_FALLBACK_FRAME_STATE_FOR macro is taken as the same for x86 and x86-64. 
This patch just copies the macro from linux.h to linux64.h and does an ifdef 
to choose.

The reason I've done this is to minimize the possible trouble it would be to 
include linux.h in linux64.h which would be a better solution. Moving the 
macro to linux-shared.h might be better though.

Currently there is a bit of a mess in the x86-64 support of x86 multilib. At 
some point it will probably be possible to compile to both architectures from 
both architectures (given the right libs of course) like it is on sparc. But 
to do that in a clean fashion, we need a more strict separation between 32 
and 64 bit files and the stuff that's shared between them.

I have bootstrapped and regtested both x86 and x86-64 with the patch installed 
(linux64.h isn't used at all in x86, so obviously this is affected. But I did 
it just in case). I've also bootstrapped and regtested x86-64 without 
--disable-multilib - this wasn't possible without the patch.

Can I commit the patch to both mainline and branch?

2002-05-10  Bo Thorsen  <bo@suse.co.uk>

	* config/i386/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Copy the
	i386 version of it here, so multilib works again.

Index: config/i386/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/linux64.h,v
retrieving revision 1.3.10.5
diff -u -r1.3.10.5 linux64.h
--- config/i386/linux64.h	26 Apr 2002 07:57:50 -0000	1.3.10.5
+++ config/i386/linux64.h	10 May 2002 08:54:15 -0000
@@ -76,6 +76,7 @@
 #include <sys/ucontext.h>
 #endif
 
+#ifdef __x86_64__
 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
   do {									\
     unsigned char *pc_ = (CONTEXT)->ra;					\
@@ -132,3 +133,58 @@
     (FS)->retaddr_column = 16;						\
     goto SUCCESS;							\
   } while (0)
+#else /* ifdef __x86_64__  */
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
+  do {									\
+    unsigned char *pc_ = (CONTEXT)->ra;					\
+    struct sigcontext *sc_;						\
+    long new_cfa_;							\
+									\
+    /* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80  */		\
+    if (*(unsigned short *)(pc_+0) == 0xb858				\
+	&& *(unsigned int *)(pc_+2) == 119				\
+	&& *(unsigned short *)(pc_+6) == 0x80cd)			\
+      sc_ = (CONTEXT)->cfa + 4;						\
+    /* movl $__NR_rt_sigreturn,%eax ; int $0x80  */			\
+    else if (*(unsigned char *)(pc_+0) == 0xb8				\
+	     && *(unsigned int *)(pc_+1) == 173				\
+	     && *(unsigned short *)(pc_+5) == 0x80cd)			\
+      {									\
+	struct rt_sigframe {						\
+	  int sig;							\
+	  struct siginfo *pinfo;					\
+	  void *puc;							\
+	  struct siginfo info;						\
+	  struct ucontext uc;						\
+	} *rt_ = (CONTEXT)->cfa;					\
+	sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext;		\
+      }									\
+    else								\
+      break;								\
+									\
+    new_cfa_ = sc_->esp;						\
+    (FS)->cfa_how = CFA_REG_OFFSET;					\
+    (FS)->cfa_reg = 4;							\
+    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
+									\
+    /* The SVR4 register numbering macros aren't usable in libgcc.  */	\
+    (FS)->regs.reg[0].how = REG_SAVED_OFFSET;				\
+    (FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_;		\
+    (FS)->regs.reg[3].how = REG_SAVED_OFFSET;				\
+    (FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_;		\
+    (FS)->regs.reg[1].how = REG_SAVED_OFFSET;				\
+    (FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_;		\
+    (FS)->regs.reg[2].how = REG_SAVED_OFFSET;				\
+    (FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_;		\
+    (FS)->regs.reg[6].how = REG_SAVED_OFFSET;				\
+    (FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_;		\
+    (FS)->regs.reg[7].how = REG_SAVED_OFFSET;				\
+    (FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_;		\
+    (FS)->regs.reg[5].how = REG_SAVED_OFFSET;				\
+    (FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_;		\
+    (FS)->regs.reg[8].how = REG_SAVED_OFFSET;				\
+    (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_;		\
+    (FS)->retaddr_column = 8;						\
+    goto SUCCESS;							\
+  } while (0)
+#endif /* ifdef __x86_64__  */


-- 

     Bo Thorsen                 |   Praestevejen 4
     Free software developer    |   5290 Marslev
     SuSE Labs                  |   Denmark



More information about the Gcc-patches mailing list