static void initPTable(void) { register int i; TRACE(stderr, "[intPTable]"); /* Skip over leading pcodes. NOTE: assumes executable begins after * the first oLABEL pcode */ do { insn_GetOpCode(myPoffHandle, &ptable[0]); insn_AddTmpOpCode(myPoffProgHandle, &ptable[0]); } while ((GETOP(&ptable[0]) != oLABEL) && (GETOP(&ptable[0]) != oEND)); /* Fill the pcode window and setup pointers to working section */ for (i = 0; i < WINDOW; i++) { insn_GetOpCode(myPoffHandle, &ptable[i]); } setupPointer(); }
static void putPCodeFromTable(void) { register int i; TRACE(stderr, "[putPCodeFromTable]"); /* Transfer all buffered P-Codes (except NOPs) to the optimized file */ do { if ((GETOP(&ptable[0]) != oNOP) && !(end_out)) { insn_AddTmpOpCode(myPoffProgHandle, &ptable[0]); end_out = (GETOP(&ptable[0]) == oEND); } /* Move all P-Codes down one slot */ for (i = 1; i < WINDOW; i++) { ptable[i-1] = ptable[i]; } /* Then fill the end slot with a new P-Code from the input file */ insn_GetOpCode(myPoffHandle, &ptable[WINDOW-1]); } while (GETOP(&ptable[0]) == oNOP); setupPointer(); }
static uint32_t regm_CheckSection1 (poffHandle_t hPoff, uint32_t dwOffset) { OPTYPE op; /* Seek to the beginning of the section. */ regm_ProgSeek(hPoff, dwOffset); /* Read the opcode at that position. */ (void)insn_GetOpCode(hPoff, &op); /* Is it a oJMP instruction? This happens when there are nested * functions. The entry point into the parent function is a jump * around the nested functions. */ if (GETOP(&op) == oJMP) { /* Yes, then the block really begins at the target of the jump */ return GETARG(&op); } else { /* No, then the block really begins right here */ return dwOffset; } }
static void pass1(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) { OPTYPE op; uint32_t pc; int opsize; int fileno = 0; /* Build label / line number reference table * * CASE 1: LABEL * Add label number + PC to table * discard * CASE 2: LINE * genereate a line number reference * discard * ELSE: * pass through with no additional action */ pc = 0; do { opsize = insn_GetOpCode(poffHandle, &op); if (GETOP(&op) == oLABEL) { poffAddToDefinedLabelTable(GETARG(&op), pc); } else if (GETOP(&op) == oINCLUDE) { fileno = GETARG(&op); } else if (GETOP(&op) == oLINE) { poffAddLineNumber(poffHandle, GETARG(&op), fileno, pc); } else { insn_AddTmpOpCode(poffProgHandle, &op); pc += opsize; } } while (GETOP(&op) != oEND); /* Replace the original program data with the new program data */ poffReplaceProgData(poffHandle, poffProgHandle); }
static void setupPointer(void) { register int pindex; TRACE(stderr, "[setupPointer]"); for (pindex = 0; pindex < WINDOW; pindex++) pptr[pindex] = (OPTYPE *) NULL; nops = 0; for (pindex = 0; pindex < WINDOW; pindex++) { switch (GETOP(&ptable[pindex])) { /* Terminate list when a break from sequential logic is * encountered */ case oRET : case oEND : case oJMP : case oLABEL : case oPCAL : return; /* Terminate list when a condition break from sequential logic is * encountered but include the conditional branch in the list */ case oJEQUZ : case oJNEQZ : case oJLTZ : case oJGTEZ : case oJGTZ : case oJLTEZ : pptr[nops] = &ptable[pindex]; nops++; return; /* Skip over NOPs and comment class pcodes */ case oNOP : case oLINE : break; /* Include all other pcodes in the optimization list and continue */ default : pptr[nops] = &ptable[pindex]; nops++; } } }
static void pass3(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) { OPTYPE op; uint32_t pc; uint32_t opsize; /* Read each opcode, generate relocation information and * replace label references with program section offsets. * * CASE 1: LAC * generate RODATA relocation entry * CASE 2: PCAL instructions * replace label with I-space offset, OR * generate a PROGRAM relocation entry * CASE 3: J* instructions * replace label with I-space offset * CASE 4: LDS*, STS*, and LAS* instructions * generate a STACK relocation (if imported?) * ELSE: * pass through with no additional action */ pc = 0; do { opsize = insn_GetOpCode(poffHandle, &op); switch (GETOP(&op)) { /* Load of an address in the rodata section */ case oLAC: /* We are referencing something from the rodata section. * No special action need be taken. */ break; /* Call to a procedure or function. */ case oPCAL: { /* Check if this is a defined label, i.e., a call to * procedure or function in the same file. */ int32_t value = poffGetPcForDefinedLabel(GETARG(&op)); if (value >= 0) { /* Yes... replace the label reference with * a text section offset. No relocation record * is needed in this case. The only relocation * may be performed is a subsequent program data * section offset. */ PUTARG(&op, value); } else { /* Check if this is a undefined label. This would * occur for a call to a procedure or a function that * is defined in some other unit file. */ value = poffGetSymIndexForUndefinedLabel(GETARG(&op)); if (value >= 0) { /* Use the value zero now */ PUTARG(&op, 0); /* And generate a symbol-based relocation */ (void)poffAddRelocation(poffHandle, RLT_PCAL, value, pc); } else { DEBUG(stdout, "Failed to find call label L%04x\n", GETARG(&op)); fatal(ePOFFCONFUSION); } } } break; /* Jumps to "nearby" addresses */ case oJMP: /* Unconditional */ case oJEQUZ: /* Unary comparisons with zero */ case oJNEQZ: case oJLTZ: case oJGTEZ: case oJGTZ: case oJLTEZ: case oJEQU: /* Binary comparisons */ case oJNEQ: case oJLT: case oJGTE: case oJGT: case oJLTE: { /* Check if this is a defined label. This must be the case * because there can be no jumps into a unit file. */ int32_t value = poffGetPcForDefinedLabel(GETARG(&op)); if (value >= 0) { /* Yes... replace the label reference with * a text section offset. No relocation record * is needed in this case. The only relocation * may be performed is a subsequent program data * sectioin offset. */ PUTARG(&op, value); } else { DEBUG(stdout, "Failed to find jump label L%04x\n", GETARG(&op)); fatal(ePOFFCONFUSION); } } break; /* References to stack via level offset */ case oLAS: /* Load stack address */ case oLASX: case oLDS: /* Load value */ case oLDSH: case oLDSB: case oLDSM: case oSTS: /* Store value */ case oSTSH: case oSTSB: case oSTSM: case oLDSX: case oLDSXH: /* Load value indexed */ case oLDSXB: case oLDSXM: case oSTSX: /* Store value indexed */ case oSTSXH: case oSTSXB: case oSTSXM: { #warning REVISIT } break; /* Otherwise, it is not an interesting opcode */ default: break; } /* Save the potentially modified opcode in the temporary * program data container. */ insn_AddTmpOpCode(poffProgHandle, &op); pc += opsize; } while (GETOP(&op) != oEND); /* Replace the original program data with the new program data */ poffReplaceProgData(poffHandle, poffProgHandle); }
int unaryOptimize(void) { register uint32_t temp; register int i; int nchanges = 0; TRACE(stderr, "[unaryOptimize]"); /* At least two pcodes are need to perform unary optimizations */ i = 0; while (i < nops-1) { /* Check for a constant value being pushed onto the stack */ if (GETOP(pptr[i]) == oPUSH) { switch (GETOP(pptr[i+1])) { /* Delete unary operators on constants */ case oNEG : PUTARG(pptr[i], -GETARG(pptr[i])); deletePcode(i+1); nchanges++; break; case oABS : if ((int32_t)GETARG(pptr[i]) < 0) PUTARG(pptr[i], -(int32_t)GETARG(pptr[i])); deletePcode(i+1); nchanges++; break; case oINC : PUTARG(pptr[i], GETARG(pptr[i]) + 1); deletePcode(i+1); nchanges++; break; case oDEC : PUTARG(pptr[i], GETARG(pptr[i]) - 1); deletePcode(i+1); nchanges++; break; case oNOT : PUTARG(pptr[i], ~GETARG(pptr[i])); PUTARG(pptr[i], ~(GETARG(pptr[i]))); deletePcode(i+1); nchanges++; break; /* Simplify binary operations on constants */ case oADD : if (GETARG(pptr[i]) == 0) { deletePcodePair(i, (i+1)); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i+1], oINC); deletePcode(i); nchanges++; } /* end else if */ else if (GETARG(pptr[i]) == ARGONES) { PUTOP(pptr[i+1], oDEC); deletePcode(i); nchanges++; } /* end else if */ else i++; break; case oSUB : if (GETARG(pptr[i]) == 0) { deletePcodePair(i, (i+1)); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i+1], oDEC); deletePcode(i); nchanges++; } /* end else if */ else if (GETARG(pptr[i]) == ARGONES) { PUTOP(pptr[i+1], oINC); deletePcode(i); nchanges++; } /* end else if */ else i++; break; case oMUL : case oDIV : temp = 0; switch (GETARG(pptr[i])) { case 1 : deletePcodePair(i, (i+1)); nchanges++; break; case 16384 : temp++; case 8192 : temp++; case 4096 : temp++; case 2048 : temp++; case 1024 : temp++; case 512 : temp++; case 256 : temp++; case 128 : temp++; case 64 : temp++; case 32 : temp++; case 16 : temp++; case 8 : temp++; case 4 : temp++; case 2 : temp++; PUTARG(pptr[i], temp); if (GETOP(pptr[i+1]) == oMUL) PUTOP(pptr[i+1], oSLL); else PUTOP(pptr[i+1], oSRA); nchanges++; i++; break; default : i++; break; } /* end switch */ break; case oSLL : case oSRL : case oSRA : case oOR : if (GETARG(pptr[i]) == 0) { deletePcodePair(i, (i+1)); nchanges++; } /* end if */ else i++; break; case oAND : if (GETARG(pptr[i]) == ARGONES) { deletePcodePair(i, (i+1)); nchanges++; } /* end if */ else i++; break; /* Delete comparisons of constants to zero */ case oEQUZ : if (GETARG(pptr[i]) == 0) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcode(i+1); nchanges++; break; case oNEQZ : if (GETARG(pptr[i]) != 0) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcode(i+1); nchanges++; break; case oLTZ : if ((int32_t)GETARG(pptr[i]) < 0) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcode(i+1); nchanges++; break; case oGTEZ : if ((int32_t)GETARG(pptr[i]) >= 0) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcode(i+1); nchanges++; break; case oGTZ : if (GETARG(pptr[i]) > 0) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcode(i+1); nchanges++; break; case oLTEZ : if (GETARG(pptr[i]) <= 0) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcode(i+1); nchanges++; break; /* Simplify comparisons with certain constants */ case oEQU : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+1],oEQUZ); deletePcode(i); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i], oDEC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oEQUZ); nchanges++; } /* end else if */ else if ((int32_t)GETARG(pptr[i]) == -1) { PUTOP(pptr[i], oINC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oEQUZ); nchanges++; } /* end else if */ else i++; break; case oNEQ : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+1], oNEQZ); deletePcode(i); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i], oDEC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oNEQZ); nchanges++; } /* end else if */ else if ((int32_t)GETARG(pptr[i]) == -1) { PUTOP(pptr[i], oINC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oNEQZ); nchanges++; } /* end else if */ else i++; break; case oLT : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+1], oLTZ); deletePcode(i); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i], oDEC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oLTZ); nchanges++; } /* end else if */ else if ((int32_t)GETARG(pptr[i]) == -1) { PUTOP(pptr[i], oINC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oLTZ); nchanges++; } /* end else if */ else i++; break; case oGTE : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+1], oGTEZ); deletePcode(i); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i], oDEC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oGTEZ); nchanges++; } /* end else if */ else if ((int32_t)GETARG(pptr[i]) == -1) { PUTOP(pptr[i], oINC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oGTEZ); nchanges++; } /* end else if */ else i++; break; case oGT : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+1], oGTZ); deletePcode(i); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i], oDEC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oGTZ); nchanges++; } /* end else if */ else if ((int32_t)GETARG(pptr[i]) == -1) { PUTOP(pptr[i], oINC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oGTZ); nchanges++; } /* end else if */ else i++; break; case oLTE : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+1], oLTEZ); deletePcode(i); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i], oDEC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oLTEZ); nchanges++; } /* end else if */ else if ((int32_t)GETARG(pptr[i]) == -1) { PUTOP(pptr[i], oINC); PUTARG(pptr[i], 0); PUTOP(pptr[i+1], oLTEZ); nchanges++; } /* end else if */ else i++; break; /* Simplify or delete condition branches on constants */ case oJEQUZ : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+1], oJMP); deletePcode(i); } /* end if */ else deletePcodePair(i, (i+1)); nchanges++; break; case oJNEQZ : if (GETARG(pptr[i]) != 0) { PUTOP(pptr[i+1], oJMP); deletePcode(i); } /* end if */ else deletePcodePair(i, (i+1)); nchanges++; break; case oJLTZ : if ((int32_t)GETARG(pptr[i]) < 0) { PUTOP(pptr[i+1], oJMP); deletePcode(i); } /* end if */ else deletePcodePair(i, (i+1)); nchanges++; break; case oJGTEZ : if ((int32_t)GETARG(pptr[i]) >= 0) { PUTOP(pptr[i+1], oJMP); deletePcode(i); } /* end if */ else deletePcodePair(i, (i+1)); nchanges++; break; case oJGTZ : if (GETARG(pptr[i]) > 0) { PUTOP(pptr[i+1], oJMP); deletePcode(i); } /* end if */ else deletePcodePair(i, (i+1)); nchanges++; break; case oJLTEZ : if (GETARG(pptr[i]) <= 0) { PUTOP(pptr[i+1], oJMP); deletePcode(i); } /* end if */ else deletePcodePair(i, (i+1)); nchanges++; break; default : i++; break; } /* end switch */ } /* end if */ /* Delete multiple modifications of DSEG pointer */ else if (GETOP(pptr[i]) == oINDS) { if (GETOP(pptr[i+1]) == oINDS) { PUTARG(pptr[i], GETARG(pptr[i] + GETARG(pptr[i+1]))); deletePcode(i+1); } /* end if */ else i++; } /* end else if */ else i++; } /* end while */ return (nchanges); } /* end unaryOptimize */
int binaryOptimize(void) { register int i; int nchanges = 0; TRACE(stderr, "[binaryOptimize]"); /* At least two pcodes are needed to perform the following binary */ /* operator optimizations */ i = 0; while (i < nops-2) { if (GETOP(pptr[i]) == oPUSH) { if (GETOP(pptr[i+1]) == oPUSH) { switch (GETOP(pptr[i+2])) { case oADD : PUTARG(pptr[i], GETARG(pptr[i]) + GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oSUB : PUTARG(pptr[i], GETARG(pptr[i]) - GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oMUL : PUTARG(pptr[i], GETARG(pptr[i]) * GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oDIV : PUTARG(pptr[i], GETARG(pptr[i]) / (int32_t)GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oMOD : PUTARG(pptr[i], GETARG(pptr[i]) % GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oSLL : PUTARG(pptr[i], GETARG(pptr[i]) << GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oSRL : PUTARG(pptr[i], GETARG(pptr[i]) >> GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oSRA : PUTARG(pptr[i], (int32_t)GETARG(pptr[i]) >> GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oOR : PUTARG(pptr[i], GETARG(pptr[i]) | GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oAND : PUTARG(pptr[i], GETARG(pptr[i]) & GETARG(pptr[i+1])); deletePcodePair((i+1), (i+2)); nchanges++; break; case oEQU : if (GETARG(pptr[i]) == GETARG(pptr[i+1])) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcodePair((i+1), (i+2)); nchanges++; break; case oNEQ : if (GETARG(pptr[i]) != GETARG(pptr[i+1])) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcodePair((i+1), (i+2)); nchanges++; break; case oLT : if ((int32_t)GETARG(pptr[i]) < (int32_t)GETARG(pptr[i+1])) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcodePair((i+1), (i+2)); nchanges++; break; case oGTE : if ((int32_t)GETARG(pptr[i]) >= (int32_t)GETARG(pptr[i+1])) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcodePair((i+1), (i+2)); nchanges++; break; case oGT : if ((int32_t)GETARG(pptr[i]) > (int32_t)GETARG(pptr[i+1])) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcodePair((i+1), (i+2)); nchanges++; break; case oLTE : if ((int32_t)GETARG(pptr[i]) <= (int32_t)GETARG(pptr[i+1])) PUTARG(pptr[i], -1); else PUTARG(pptr[i], 0); deletePcodePair((i+1), (i+2)); nchanges++; break; default : i++; break; } /* end switch */ } /* end if */ /* A single (constant) pcode is sufficient to perform the */ /* following binary operator optimizations */ else if ((GETOP(pptr[i+1]) == oLDSH) || (GETOP(pptr[i+1]) == oLDSB) || (GETOP(pptr[i+1]) == oLAS) || (GETOP(pptr[i+1]) == oLAC)) { switch (GETOP(pptr[i+2])) { case oADD : if (GETARG(pptr[i]) == 0) { deletePcodePair(i, (i+2)); nchanges++; } /* end if */ else if (GETARG(pptr[i]) == 1) { PUTOP(pptr[i+2], oINC); deletePcode(i); nchanges++; } /* end else if */ else if (GETARG(pptr[i]) == ARGONES) { PUTOP(pptr[i+2], oDEC); deletePcode(i); nchanges++; } /* end else if */ else i++; break; case oSUB : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i], oNEG); deletePcode(i); nchanges++; } /* end if */ else i++; break; case oMUL : { int32_t stmp32 = 0; switch (GETARG(pptr[i])) { case 1 : deletePcodePair(i, (i+2)); nchanges++; break; case 16384 : stmp32++; case 8192 : stmp32++; case 4096 : stmp32++; case 2048 : stmp32++; case 1024 : stmp32++; case 512 : stmp32++; case 256 : stmp32++; case 128 : stmp32++; case 64 : stmp32++; case 32 : stmp32++; case 16 : stmp32++; case 8 : stmp32++; case 4 : stmp32++; case 2 : stmp32++; PUTOP(pptr[i], GETOP(pptr[i+1])); PUTARG(pptr[i], GETARG(pptr[i+1])); PUTOP(pptr[i+1], oPUSH); PUTARG(pptr[i+1], stmp32); PUTOP(pptr[i+2], oSLL); nchanges++; i++; break; default : i++; break; } } break; case oOR : if (GETARG(pptr[i]) == 0) { deletePcodePair(i, (i+2)); nchanges++; } /* end if */ else i++; break; case oAND : if (GETARG(pptr[i]) == ARGONES) { deletePcodePair(i, (i+2)); nchanges++; } /* end if */ else i++; break; case oEQU : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+2], oEQUZ); deletePcode(i); nchanges++; } /* end if */ else i++; break; case oNEQ : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+2], oNEQZ); deletePcode(i); nchanges++; } /* end if */ else i++; break; case oLT : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+2], oGTEZ); deletePcode(i); nchanges++; } /* end if */ else i++; break; case oGTE : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+2], oLTZ); deletePcode(i); nchanges++; } /* end if */ else i++; break; case oGT : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+2], oLTEZ); deletePcode(i); nchanges++; } /* end if */ else i++; break; case oLTE : if (GETARG(pptr[i]) == 0) { PUTOP(pptr[i+2], oGTZ); deletePcode(i); nchanges++; } /* end if */ else i++; break; default : i++; break; } /* end switch */ } /* end else if */ else i++; } /* end if */ /* Misc improvements on binary operators */ else if (GETOP(pptr[i]) == oNEG)
uint32_t regm_ReadNodePCodes(struct procdata_s *pNode, poffHandle_t hPoff, uint32_t dwStartOffset, uint32_t dwEndOffset, uint8_t cTerminalOpcode) { uint32_t dwOffset = dwStartOffset; long nAlloc = INITIAL_PCODE_ALLOC; long nPCodes; uint8_t bTerminatorFound; dbg("Reading Node: %08lx %08lx %02x\n", dwStartOffset, dwEndOffset, cTerminalOpcode); /* Allocate an inital buffer to hold the instructions */ pNode->pPCode = (OPTYPE*) malloc(INITIAL_PCODE_ALLOC*sizeof(struct procinsn_s*)); if (!pNode->pPCode) { fatal(eNOMEMORY); } /* Seek to the beginning of the data */ regm_ProgSeek(hPoff, dwStartOffset); /* Read all of the instructions in the main program section */ nPCodes = 0; bTerminatorFound = 0; do { /* Make sure that there is space for another pcode */ if (nPCodes > nAlloc) { /* If not, then reallocate the array */ nAlloc += PCODE_RELLALLOC; pNode->pPCode = (OPTYPE*) realloc(pNode->pPCode, nAlloc*sizeof(OPTYPE)); } /* Ready the pcode ito the array */ dwOffset += insn_GetOpCode(hPoff, &pNode->pPCode[nPCodes]); /* Check for a terminating pcode */ if ((GETOP(&pNode->pPCode[nPCodes]) == cTerminalOpcode) || (GETOP(&pNode->pPCode[nPCodes]) == oEND)) { bTerminatorFound++; } /* Increment the count of pcodes read */ nPCodes++; } while (!bTerminatorFound && (dwOffset < dwEndOffset)); dbg(" %08lx %08lx %02x\n", dwStartOffset, dwOffset, GETOP(&pNode->pPCode[nPCodes-1])); /* Save the number of pcodes that we found */ pNode->nPCodes = nPCodes; /* Check for the correct terminator */ if (GETOP(&pNode->pPCode[nPCodes-1]) != cTerminalOpcode) { fatal(ePOFFCONFUSION); } /* Return any unused space in the allocation */ pNode->pPCode = (OPTYPE*) realloc(pNode->pPCode, nPCodes*sizeof(OPTYPE)); /* Return the actual end offset */ return dwOffset; }