Ejemplo n.º 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();
}
Ejemplo n.º 2
0
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;
    }
}
Ejemplo n.º 3
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();
}
Ejemplo n.º 4
0
Archivo: pfopt.c Proyecto: hechan/NuttX
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);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
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;
}