------- Comment #14 from dick_guertin at yahoo dot com  2006-01-19 04:00 -------
Good news, I think I found the problem.  Bad news, I can't think of any
solution.  Please read my comments at the end of this information:

typedef struct nkw
   {
      char tok[16];                /* TOKEN, BLANK PADDED */
      short tokl;                  /* TOKEN LENGTH */
      unsigned char flg1;          /* FIELD FLAGS */
#define NKWFP1   0x80              /* PARM1 */
#define NKWFP2   0x40              /* PARM2 */
#define NKWFMAT  0x20              /* MATCH ROUTINE */
#define NKWFRTN  0x10              /* PROCESSING ROUTINE */

      unsigned char flg2;          /* MISC FLAGS */
#define NKWFPUSH 0x80              /* PUSH */
#define NKWFEND  0x40              /* LAST KEYWORD ENTRY IN LIST */

      unsigned char flg3;          /* MATCH SPECS,SPECIAL ACTIONS */
#define NKWFABBV 0x80              /* ABBREVIATE  (3 CHAR MIN) */
#define NKWFAB1  0x40              /* ABBREVIATE  (1 CHAR MIN) */
#define NKWFSET  0x20              /* SAVE KEYWORD IN CP */
#define NKWFNOBK 0x10              /* DO NOT BLANK */

#define NKWFCRTN 0x04              /* rtn is in C */
#define NKWFINIT 0x02              /* Convert string to EBCDIC */

      unsigned char flg4;          /* INTEGER MATCH SPECS */
      unsigned char flg5;
      unsigned char flg6;

      long parm1;                  /* MATCH PARM 1 */
      long parm2;                  /* MATCH PARM 2 */
      void (*mat)();
      long (*rtn)(NSCNCB *,
                  REG,
                  REG);
      unsigned char stuffing[24];
   } NKW;

struct sckw {
  unsigned char stuff[32];
  void (*nkwmat)();
  void (*nkwrtn)();
  unsigned char more_stuff[24];
};

======================================

static struct sckw CDEFPRT = {
0xE2,0xC5,0xE3,0x40,0x40,0x40,0x40,0x40,    /* SET */
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0,3,48,0,
128,0,0,0,
0, 0, 0, 0,
0, 0, 0, 0,
MTOKEN, CDEFSET };
static struct sckw sckw1 = {
0xE2,0xC8,0xD6,0xE6,0x40,0x40,0x40,0x40,    /* SHOW */
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0,4,48,0,
128,0,0,0,
0, 0, 0, 0,
0, 0, 0, 0,
MTOKEN, CDEFSHOW };
static struct sckw sckw2 = {
0xC4,0xE4,0xD4,0xD7,0x40,0x40,0x40,0x40,    /* DUMP */
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0,4,48,0,
128,0,0,0,
0, 0, 0, 0,
0, 0, 0, 0,
MTOKEN, CDEFDUMP };
/* - - - - - - - - - - */
static struct sckw sckw268 = {
0xD6,0xD3,0xC4,0xE6,0xE8,0xD3,0x40,0x40,    /* OLDWYL */
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0,6,48,64,
32,0,0,0,
0, 0, 0, 0,
0, 0, 0, 0,
MTOKEN, XCTL };

======================================

As you can see from the numbering of these items, there are 269 of them, all
layed out in sequence within the C-source.  It is possible to start with any
entry, and scanning is then supposed to go until the last is encountered,
signified by the '64' in the '0,6,48,64' line.  That is 0x40 in flg2.  The
scan.c code for rlookup looks something like this:

======================================

   NKW *rlookup(NSCNCB *scancb,
                NKW keyword_table[],
                long stack_ptr[],
                long *routine_result)
      {
         if (keyword_table)
            {
               NKW *kwp = keyword_table;
               long match_result;
               REG r[2];

               while (kwp)
                  {

                     if (kwp->flg3 & NKWFINIT)    /* Convert to EBCDIC */
                        {
                           memset(kwp->tok + ntohs(kwp->tokl),
                                  ' ',
                                  sizeof kwp->tok - ntohs(kwp->tokl));

                           ascii_to_ebcdic(kwp->tok, sizeof kwp->tok);

                           kwp->flg3 &= ~NKWFINIT;
                        }

                     if (kwp->flg2 & NKWFPUSH)
                        {

                           if (kwp->flg3 & NKWFCRTN)
                              {
                                 long saved_regs[2];

                                 r[0].as_long = R0;
                                 r[1].as_long = R1;

                                 saved_regs[0] = R2;
                                 saved_regs[1] = R3;

                                 R2 = (long) scancb;

                                 R3 = (long) stack_ptr;

                                 R15 = (*(kwp->rtn))(scancb, r[0], r[1]);

                                 R2 = saved_regs[0];
                                 R3 = saved_regs[1];
                              }

                            else
                              {
                                 struct sckw *sckwp = (struct sckw *) kwp;
                                 long saved_regs[2];

                                 saved_regs[0] = R2;
                                 saved_regs[1] = R3;

                                 R2 = (long) scancb;

                                 R3 = (long) stack_ptr;

                                 (*(sckwp->nkwrtn))();

                                 R2 = saved_regs[0];
                                 R3 = saved_regs[1];
                              }

                           /* If match found and processed, we're done */

                           if (R0 == 0)
                              {
                                 *routine_result = R15;

                                 return kwp;
                              }
                        }

                     match_result = call_match(scancb, kwp, &r[0], &r[1],
stack_ptr);

                     if (match_result < 0)   /* Error */
                        {
                           *routine_result = match_result;

                           return kwp;
                        }

                     if (match_result == 0)  /* Call processing routine */
                        {
                           *routine_result = callrtn(scancb, r[0], r[1], kwp,
stack_ptr);

                           return kwp;
                        }

                     if (kwp->flg2 & NKWFEND)
                        kwp = (NKW *) NULL;

                     else
                        kwp += 1;
                  }
            }

         /* If we get here, there was no match... */

         return((NKW *) NULL);
      }

======================================

The keyword_table parm passed to rlookup is the 1st in the series of sckw
objects to be scanned, and then "kwp += 1;" advances to the next.  But the
kwp->flg2 & NKWFEND test is supposed to stop the loop on the last object.

What I've discovered is that the -O2 option causes these sckw static objects to
be placed randomly in memory, NOT in the order they are declared.  In all
previous instances of the gcc compiler, input order was preserved for static
objects.  This is the 'problem'.  With -O2 in gcc 3.4.4, order is not
preserved.  So the scan falls off the end when the ending sckw is misplaced.

My question is this:  Is there some option that can be used with -O2 that will
preserve the input-order of static and/or global objects?  It would be handy if
global objects were also kept in order, such as:

long r1;
long r2;
long r3;
etc.

Alternatively, is there some way I can force the input-order of sckw objects?

By the way, I placed a 'break' at the if-test for flg2, but it never sprung. 
Another 'break' at the increment statement {kwp += 1;} was sprung.  That's how
I found these sckw objects were in random order.  'gdb' has problems with -O2
and -g combined.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25791

Reply via email to