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 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 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 (op.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(op.arg2); 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. */ op.arg2 = (uint16_t)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(op.arg2); if (value >= 0) { /* Use the value zero now */ op.arg2 = 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", op.arg2); 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(op.arg2); 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. */ op.arg2 = (uint16_t)value; } else { DEBUG(stdout, "Failed to find jump label L%04x\n", op.arg2); 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 (op.op != oEND); /* Replace the original program data with the new program data */ poffReplaceProgData(poffHandle, poffProgHandle); }