🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Robert R. Henry Tue, 17 Nov 1992 20:06
sparc va_arg botches some structure passing
#1422
Author: Robert R. Henry
Date: Tue, 17 Nov 1992 20:06
92 lines
2596 bytes
The following program contains a varargs routine,
which is given a 32 bit structure by value in one
of the varargs slots.

It is compiled by BOTH gcc2.3.1 and gcc2.2.2, host=sparc, target=sparc.

When the resulting code is executed it bus errors at the line marked ``HERE''.
Examining the faulting instruction shows that it is executing
	ld [%o1], %o0
with o1 containing 113.  The value 113 is what the va_arg
should ultimately deliver; there's one too many indirections going on.

This situation happens even if the structure actual parameter
is the first actual parameter after the 'op' parameter (so
its unlikely to be a register window alignment problem, altho
one never knows).

#include <stdio.h>
#include <stdarg.h>

typedef int TERA_Boolean;

typedef enum _FullEmptyControl{
	FE_NORMAL = 0	 
	,FE_FUTURE = 2	 
	,FE_SYNC = 3	 
} FullEmptyControl;

typedef struct _OperationAccessControl{
	int    :27  ;	 
	TERA_Boolean fwd_disable   :1  ;	 
	FullEmptyControl fe_control   :2  ;	 
	TERA_Boolean trap1_disable   :1  ;	 
	TERA_Boolean trap0_disable   :1  ;	 
} OperationAccessControl;  

typedef long long int int64;

void encode(int64 *r_result, int op, ...)
{
  static int v[] = {
    0,
    1, 1, 2,
    3, 2, -1
  };
  int64 result;
  int shift_amt = 64;
  int iarg;
  int shift = 0;
  int pass_op;
  unsigned int uarg;
  int type;
  int optype;
  int save_low_offset;
  va_list ap;
  va_start(ap,  op);

  for (iarg = 0; v[iarg] >= 0; iarg++){
    switch(v[iarg]){
    case 0:	/* begin */
      printf("begin\n");
      break;
    case 1:	/* reg */
      uarg = va_arg(ap, unsigned int);
      printf("reg %d\n", uarg);
      break;
    case 2:	/* lit */
      printf("lit\n");
      break;
    case 3:	/* UnsOpAC */
      {
	union {
	  OperationAccessControl ac;
	  int prt;
	} ac_ctrl;
	OperationAccessControl acl;
/* BUS ERROR HERE */
	acl = va_arg(ap, OperationAccessControl);
	printf("oac %d\n", ac_ctrl.prt);
	break;
      }
    default:
      break;
    }
  }
}

main()
{
  int64 x;
  encode(&x, 0, 17, 18, 113, 117);
}
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads