Пример #1
0
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();
}
Пример #2
0
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();
}
Пример #3
0
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);
}
Пример #4
0
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);
}