------- 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