linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Re: patch for problem with va-ppc.h included with egcs and gcc-2.95.2
@ 1999-11-30  6:00 Jason Kim
  1999-11-30 10:58 ` Franz Sirl
  0 siblings, 1 reply; 15+ messages in thread
From: Jason Kim @ 1999-11-30  6:00 UTC (permalink / raw)
  To: Franz.Sirl-kernel, linuxppc-dev, gcc-patches


Agreed, ssh2 code isn't necessarily the cleanest in the world, but then again
the varargs situation in PPC world is a bit peculiar.


typedef struct A {
  char foo;
  char *bar;
} B[1], C[1];

typedef C D;


void tst(D d1)
{
  D d2;
  d1 = d2; // this is legal
  // d2 = d1; // this is not
}

declaring arrays of fixed size seems a bit strange for a type which will be used
by user code, since it makes d1 and d2 be different types sometimes. Not to
mention, having struct _va_list_tag  AS va_list seem to fix the problems neatly.

Is there a technical reason for keeping va_list as an array of 1 element? 
(instead of just a single element??)

-jason.


Franz.Sirl-kernel@lauterbach.com wrote:
> Am Mon, 29 Nov 1999 schrieb Jason Kim:
> >There is a problem with va-ppc.h distributed with recent versions ofgcc (2.95
> >and onwards) as well as the older egcs 1.1 releases.
> >
> >va-ppc.h typedefs va_list as an array of 1 element of struct
> >_va_list_tag but this causes problems when va_lists (or pointers to
> >them!) are passed as arguments to functions:
> >
> >e.g.
> >
> >void foo(va_list va1)
> >{
> >va_list va2;
> >va1 = va2;
> >}
> 
> The source is wrong, this code is simply non-portable. Use __va_copy(va1, va2)
> or some memcpy trickery to fix the source.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread
* patch for problem with va-ppc.h included with egcs and gcc-2.95.2
@ 1999-11-29 21:03 Jason Kim
  1999-11-29 22:45 ` Franz Sirl
  0 siblings, 1 reply; 15+ messages in thread
From: Jason Kim @ 1999-11-29 21:03 UTC (permalink / raw)
  To: gcc-patches, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 116 bytes --]

There is no ChangeLog here. The original files in GCC (2.95.2) had no
changelog (!)

jason kim.
jwk2@eecs.lehigh.edu

[-- Attachment #2: letter1 --]
[-- Type: text/plain, Size: 1093 bytes --]



There is a problem with va-ppc.h distributed with recent versions of
gcc (2.95 and onwards) as well as the older egcs 1.1 releases.

va-ppc.h typedefs va_list as an array of 1 element of struct
_va_list_tag but this causes problems when va_lists (or pointers to
them!) are passed as arguments to functions:

e.g.

void foo(va_list va1)
{
  va_list va2;
  va1 = va2;
}

will cause the compilation to fail with incompatible pointer types under
PowerPC linux systems (including LinuxPPC 1999 Q3)

Included with this message are two patches, one for
/usr/lib/gcc-lib/ppc-redhat-linux/egcs-2.91.66/include/va-ppc.h

and a similar patch for gcc/ginclude/va-ppc.h in gcc-2.95.2 (generic)

This patch is needed to compile and run programs that use vararg stuff
extensively such as ssh-2.0.13 on PowerPC based linux systems.

I have tested my patch in a 1999 Q3 version of LinuxPPC and seems to work
fine. (i.e. ssh2 compiled, and ran, and works with no probs)

p.s. gcc-2.95.2 and the latest binutils seems to disagree on what the proper
target name is for linking... more on this as it develops..


[-- Attachment #3: va-ppc.h.patch.linuxppc1999.q3 --]
[-- Type: text/plain, Size: 5944 bytes --]

*** va-ppc.h	1999/11/29 13:33:07	1.1
--- va-ppc.h	1999/11/29 13:39:12
***************
*** 12,18 ****
  
  /* Solaris decided to rename overflow_arg_area to input_arg_area,
     so handle it via a macro.  */
! #define __va_overflow(AP) (AP)->overflow_arg_area
  
  /* Note that the names in this structure are in the user's namespace, but
     that the V.4 abi explicitly states that these names should be used.  */
--- 12,18 ----
  
  /* Solaris decided to rename overflow_arg_area to input_arg_area,
     so handle it via a macro.  */
! #define __va_overflow(AP) (AP).overflow_arg_area
  
  /* Note that the names in this structure are in the user's namespace, but
     that the V.4 abi explicitly states that these names should be used.  */
*************** typedef struct __va_list_tag {
*** 26,37 ****
    char *overflow_arg_area;	/* location on stack that holds the next
  				   overflow argument */
    char *reg_save_area;		/* where r3:r10 and f1:f8, if saved are stored */
! } __va_list[1], __gnuc_va_list[1];
  
  #else /* _SYS_VA_LIST */
  
  typedef __va_list __gnuc_va_list;
! #define __va_overflow(AP) (AP)->input_arg_area
  
  #endif /* not _SYS_VA_LIST */
  #endif /* not __GNUC_VA_LIST */
--- 26,37 ----
    char *overflow_arg_area;	/* location on stack that holds the next
  				   overflow argument */
    char *reg_save_area;		/* where r3:r10 and f1:f8, if saved are stored */
! } __va_list, __gnuc_va_list;
  
  #else /* _SYS_VA_LIST */
  
  typedef __va_list __gnuc_va_list;
! #define __va_overflow(AP) (AP).input_arg_area
  
  #endif /* not _SYS_VA_LIST */
  #endif /* not __GNUC_VA_LIST */
*************** typedef struct {
*** 53,63 ****
     a warning about increasing the alignment requirement.  */
  #define __VA_FP_REGSAVE(AP,TYPE)					\
    ((TYPE *) (void *) (&(((__va_regsave_t *)				\
! 			 (AP)->reg_save_area)->__fp_save[(int)(AP)->fpr])))
  
  #define __VA_GP_REGSAVE(AP,TYPE)					\
    ((TYPE *) (void *) (&(((__va_regsave_t *)				\
! 			 (AP)->reg_save_area)->__gp_save[(int)(AP)->gpr])))
  
  /* Common code for va_start for both varargs and stdarg.  This depends
     on the format of rs6000_args in rs6000.h.  The fields used are:
--- 53,63 ----
     a warning about increasing the alignment requirement.  */
  #define __VA_FP_REGSAVE(AP,TYPE)					\
    ((TYPE *) (void *) (&(((__va_regsave_t *)				\
! 			 (AP).reg_save_area)->__fp_save[(int)(AP).fpr])))
  
  #define __VA_GP_REGSAVE(AP,TYPE)					\
    ((TYPE *) (void *) (&(((__va_regsave_t *)				\
! 			 (AP).reg_save_area)->__gp_save[(int)(AP).gpr])))
  
  /* Common code for va_start for both varargs and stdarg.  This depends
     on the format of rs6000_args in rs6000.h.  The fields used are:
*************** typedef struct {
*** 78,86 ****
  __extension__ ({							\
     register int __words = __va_words - FAKE;				\
  									\
!    (AP)->gpr = (__words < 8) ? __words : 8;				\
!    (AP)->fpr = __va_fregno - 33;					\
!    (AP)->reg_save_area = ((char *) __builtin_args_info (8));		\
     __va_overflow(AP) = ((char *)__builtin_saveregs ()			\
  			+ (((__words >= 8) ? __words - 8 : 0)		\
  			   * sizeof (long)));				\
--- 78,86 ----
  __extension__ ({							\
     register int __words = __va_words - FAKE;				\
  									\
!    (AP).gpr = (__words < 8) ? __words : 8;				\
!    (AP).fpr = __va_fregno - 33;					\
!    (AP).reg_save_area = ((char *) __builtin_args_info (8));		\
     __va_overflow(AP) = ((char *)__builtin_saveregs ()			\
  			+ (((__words >= 8) ? __words - 8 : 0)		\
  			   * sizeof (long)));				\
*************** __extension__ ({							\
*** 118,151 ****
  __extension__ (*({							\
    register TYPE *__ptr;							\
  									\
!   if (__va_float_p (TYPE) && (AP)->fpr < 8)				\
      {									\
        __ptr = __VA_FP_REGSAVE (AP, TYPE);				\
!       (AP)->fpr++;							\
      }									\
  									\
!   else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8)			\
      {									\
        __ptr = * __VA_GP_REGSAVE (AP, TYPE *);				\
!       (AP)->gpr++;							\
      }									\
  									\
    else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)		\
! 	   && (AP)->gpr + __va_size(TYPE) <= 8				\
  	   && (!__va_longlong_p(TYPE)					\
! 	       || (AP)->gpr + __va_size(TYPE) <= 8))			\
      {									\
!       if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0)		\
! 	(AP)->gpr++;							\
  									\
        __ptr = __VA_GP_REGSAVE (AP, TYPE);				\
!       (AP)->gpr += __va_size (TYPE);					\
      }									\
  									\
    else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)		\
! 	   && (AP)->gpr < 8)						\
      {									\
!       (AP)->gpr = 8;							\
        __ptr = (TYPE *) (void *) (__va_overflow(AP));			\
        __va_overflow(AP) += __va_size (TYPE) * sizeof (long);		\
      }									\
--- 118,151 ----
  __extension__ (*({							\
    register TYPE *__ptr;							\
  									\
!   if (__va_float_p (TYPE) && (AP).fpr < 8)				\
      {									\
        __ptr = __VA_FP_REGSAVE (AP, TYPE);				\
!       (AP).fpr++;							\
      }									\
  									\
!   else if (__va_aggregate_p (TYPE) && (AP).gpr < 8)			\
      {									\
        __ptr = * __VA_GP_REGSAVE (AP, TYPE *);				\
!       (AP).gpr++;							\
      }									\
  									\
    else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)		\
! 	   && (AP).gpr + __va_size(TYPE) <= 8				\
  	   && (!__va_longlong_p(TYPE)					\
! 	       || (AP).gpr + __va_size(TYPE) <= 8))			\
      {									\
!       if (__va_longlong_p(TYPE) && ((AP).gpr & 1) != 0)		\
! 	(AP).gpr++;							\
  									\
        __ptr = __VA_GP_REGSAVE (AP, TYPE);				\
!       (AP).gpr += __va_size (TYPE);					\
      }									\
  									\
    else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)		\
! 	   && (AP).gpr < 8)						\
      {									\
!       (AP).gpr = 8;							\
        __ptr = (TYPE *) (void *) (__va_overflow(AP));			\
        __va_overflow(AP) += __va_size (TYPE) * sizeof (long);		\
      }									\

[-- Attachment #4: va-ppc.h.patch.gcc-2.95.2 --]
[-- Type: text/plain, Size: 6437 bytes --]

*** va-ppc.h	Mon Aug  9 01:55:16 1999
--- va-ppc.fixed.h	Mon Nov 29 15:43:17 1999
***************
*** 12,18 ****
  
  /* Solaris decided to rename overflow_arg_area to input_arg_area,
     so handle it via a macro.  */
! #define __va_overflow(AP) (AP)->overflow_arg_area
  
  /* Note that the names in this structure are in the user's namespace, but
     that the V.4 abi explicitly states that these names should be used.  */
--- 12,18 ----
  
  /* Solaris decided to rename overflow_arg_area to input_arg_area,
     so handle it via a macro.  */
! #define __va_overflow(AP) (AP).overflow_arg_area
  
  /* Note that the names in this structure are in the user's namespace, but
     that the V.4 abi explicitly states that these names should be used.  */
*************** typedef struct __va_list_tag {
*** 26,37 ****
    char *overflow_arg_area;	/* location on stack that holds the next
  				   overflow argument */
    char *reg_save_area;		/* where r3:r10 and f1:f8, if saved are stored */
! } __va_list[1], __gnuc_va_list[1];
  
  #else /* _SYS_VA_LIST */
  
  typedef __va_list __gnuc_va_list;
! #define __va_overflow(AP) (AP)->input_arg_area
  
  #endif /* not _SYS_VA_LIST */
  #endif /* not __GNUC_VA_LIST */
--- 26,37 ----
    char *overflow_arg_area;	/* location on stack that holds the next
  				   overflow argument */
    char *reg_save_area;		/* where r3:r10 and f1:f8, if saved are stored */
! } __va_list, __gnuc_va_list;
  
  #else /* _SYS_VA_LIST */
  
  typedef __va_list __gnuc_va_list;
! #define __va_overflow(AP) (AP).input_arg_area
  
  #endif /* not _SYS_VA_LIST */
  #endif /* not __GNUC_VA_LIST */
*************** typedef struct {
*** 53,63 ****
     a warning about increasing the alignment requirement.  */
  #define __VA_FP_REGSAVE(AP,OFS,TYPE)					\
    ((TYPE *) (void *) (&(((__va_regsave_t *)				\
! 			 (AP)->reg_save_area)->__fp_save[OFS])))
  
  #define __VA_GP_REGSAVE(AP,OFS,TYPE)					\
    ((TYPE *) (void *) (&(((__va_regsave_t *)				\
! 			 (AP)->reg_save_area)->__gp_save[OFS])))
  
  /* Common code for va_start for both varargs and stdarg.  We allow all
     the work to be done by __builtin_saveregs.  It returns a pointer to
--- 53,63 ----
     a warning about increasing the alignment requirement.  */
  #define __VA_FP_REGSAVE(AP,OFS,TYPE)					\
    ((TYPE *) (void *) (&(((__va_regsave_t *)				\
! 			 (AP).reg_save_area)->__fp_save[OFS])))
  
  #define __VA_GP_REGSAVE(AP,OFS,TYPE)					\
    ((TYPE *) (void *) (&(((__va_regsave_t *)				\
! 			 (AP).reg_save_area)->__gp_save[OFS])))
  
  /* Common code for va_start for both varargs and stdarg.  We allow all
     the work to be done by __builtin_saveregs.  It returns a pointer to
*************** __extension__ (*({							   \
*** 110,120 ****
  									   \
    if (__va_float_p (TYPE) && sizeof (TYPE) < 16)			   \
      {									   \
!       unsigned char __fpr = (AP)->fpr;					   \
        if (__fpr < 8)							   \
  	{								   \
  	  __ptr = __VA_FP_REGSAVE (AP, __fpr, TYPE);			   \
! 	  (AP)->fpr = __fpr + 1;					   \
  	}								   \
        else if (sizeof (TYPE) == 8)					   \
  	{								   \
--- 110,120 ----
  									   \
    if (__va_float_p (TYPE) && sizeof (TYPE) < 16)			   \
      {									   \
!       unsigned char __fpr = (AP).fpr;					   \
        if (__fpr < 8)							   \
  	{								   \
  	  __ptr = __VA_FP_REGSAVE (AP, __fpr, TYPE);			   \
! 	  (AP).fpr = __fpr + 1;					   \
  	}								   \
        else if (sizeof (TYPE) == 8)					   \
  	{								   \
*************** __extension__ (*({							   \
*** 132,142 ****
    /* Aggregates and long doubles are passed by reference.  */		   \
    else if (__va_aggregate_p (TYPE) || __va_float_p (TYPE))		   \
      {									   \
!       unsigned char __gpr = (AP)->gpr;					   \
        if (__gpr < 8)							   \
  	{								   \
  	  __ptr = * __VA_GP_REGSAVE (AP, __gpr, TYPE *);		   \
! 	  (AP)->gpr = __gpr + 1;					   \
  	}								   \
        else								   \
  	{								   \
--- 132,142 ----
    /* Aggregates and long doubles are passed by reference.  */		   \
    else if (__va_aggregate_p (TYPE) || __va_float_p (TYPE))		   \
      {									   \
!       unsigned char __gpr = (AP).gpr;					   \
        if (__gpr < 8)							   \
  	{								   \
  	  __ptr = * __VA_GP_REGSAVE (AP, __gpr, TYPE *);		   \
! 	  (AP).gpr = __gpr + 1;					   \
  	}								   \
        else								   \
  	{								   \
*************** __extension__ (*({							   \
*** 152,179 ****
        /* longlong is aligned.  */					   \
        if (sizeof (TYPE) == 8)						   \
  	{								   \
! 	  unsigned char __gpr = (AP)->gpr;				   \
  	  if (__gpr < 7)						   \
  	    {								   \
  	      __gpr += __gpr & 1;					   \
  	      __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE);		   \
! 	      (AP)->gpr = __gpr + 2;					   \
  	    }								   \
  	  else								   \
  	    {								   \
  	      unsigned long __addr = (unsigned long) (__va_overflow (AP)); \
  	      __ptr = (TYPE *)((__addr + 7) & -8);			   \
! 	      (AP)->gpr = 8;						   \
  	      __va_overflow (AP) = (char *)(__ptr + 1);			   \
  	    }								   \
  	}								   \
        else if (sizeof (TYPE) == 4)					   \
  	{								   \
! 	  unsigned char __gpr = (AP)->gpr;				   \
  	  if (__gpr < 8)						   \
  	    {								   \
  	      __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE);		   \
! 	      (AP)->gpr = __gpr + 1;					   \
  	    }								   \
  	  else								   \
  	    {								   \
--- 152,179 ----
        /* longlong is aligned.  */					   \
        if (sizeof (TYPE) == 8)						   \
  	{								   \
! 	  unsigned char __gpr = (AP).gpr;				   \
  	  if (__gpr < 7)						   \
  	    {								   \
  	      __gpr += __gpr & 1;					   \
  	      __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE);		   \
! 	      (AP).gpr = __gpr + 2;					   \
  	    }								   \
  	  else								   \
  	    {								   \
  	      unsigned long __addr = (unsigned long) (__va_overflow (AP)); \
  	      __ptr = (TYPE *)((__addr + 7) & -8);			   \
! 	      (AP).gpr = 8;						   \
  	      __va_overflow (AP) = (char *)(__ptr + 1);			   \
  	    }								   \
  	}								   \
        else if (sizeof (TYPE) == 4)					   \
  	{								   \
! 	  unsigned char __gpr = (AP).gpr;				   \
  	  if (__gpr < 8)						   \
  	    {								   \
  	      __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE);		   \
! 	      (AP).gpr = __gpr + 1;					   \
  	    }								   \
  	  else								   \
  	    {								   \

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~1999-12-02 16:15 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
1999-11-30  6:00 patch for problem with va-ppc.h included with egcs and gcc-2.95.2 Jason Kim
1999-11-30 10:58 ` Franz Sirl
1999-11-30 18:05   ` Jason Kim
1999-11-30 23:28   ` Jason Kim
1999-12-01 15:33     ` Franz Sirl
1999-12-01 19:18       ` Jason Kim
1999-12-01 19:41         ` Kevin Hendricks
1999-12-02  5:20           ` Jason Kim
1999-12-02  7:15             ` Richard Henderson
1999-12-02  7:27             ` Kevin Buettner
1999-12-02 16:15               ` Jason Kim
1999-12-01 19:43         ` David A. Gatwood
1999-12-02  2:04           ` Jason Kim
  -- strict thread matches above, loose matches on Subject: below --
1999-11-29 21:03 Jason Kim
1999-11-29 22:45 ` Franz Sirl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).