예제 #1
0
파일: peep.c 프로젝트: lronaldo/cpctelera
/*-----------------------------------------------------------------*/
static S4O_RET
termScanAtFunc (const lineNode *pl, int rIdx)
{
  sym_link *ftype;
  bool banked_reg = (rIdx == R0_IDX) || (rIdx == R1_IDX) || (rIdx == R2_IDX);

  if (!isFunc (pl))
    return S4O_CONTINUE;
  // let's assume calls to literally given locations use the default
  // most notably :  (*(void (*)()) 0) ();  see bug 1749275
  if (IS_VALOP (IC_LEFT (pl->ic)))
    return (options.model == MODEL_HUGE) && banked_reg ? S4O_ABORT : options.all_callee_saves ? S4O_CONTINUE : S4O_TERM;
  ftype = OP_SYM_TYPE(IC_LEFT(pl->ic));
  if (IS_FUNCPTR (ftype))
    ftype = ftype->next;
  if (IFFUNC_ISBANKEDCALL(ftype) && banked_reg)
    return S4O_ABORT;
  if (FUNC_ARGS (ftype) && getSize (FUNC_ARGS (ftype)->type) > 4)
    return S4O_ABORT;
  if (FUNC_CALLEESAVES(ftype))
    return S4O_CONTINUE;
  if (FUNC_ISNAKED(ftype))
    return S4O_CONTINUE;
  return S4O_TERM;
}
예제 #2
0
// SUBEXP
statment_type subexp::getStatmentType()
{
	build_in_func buildInFunc;
	char *pFuncName;
	parser parParser;
	int iFuncNameLen;

	for (int i = 0; exp[i]; i++)
	{
		if (exp[i] == '=') return Setter;
		else if (isChar(exp[i]))
		{
			iFuncNameLen = isFunc(exp, i);
			if (iFuncNameLen)
			{
				pFuncName = new char[iFuncNameLen];
				parParser.parseFuncName(exp, pFuncName, i);
				if (buildInFunc.chooseFunc(pFuncName) == buildInFunc.chooseFunc("show"))
				{
					delete pFuncName;
					return VoidFunc;
				}
				delete pFuncName;
			}
		}
	}

	return Equation;
}
tid_t create_vtbl_struct(ea_t vtbl_addr, ea_t vtbl_addr_end, char* vtbl_name, uval_t idx, unsigned int* vtbl_len)
{
	qstring struc_name = vtbl_name;
	tid_t id = add_struc(BADADDR, struc_name.c_str());
	if (id == BADADDR)
	{
		struc_name.clear();
		struc_name = askstr(HIST_IDENT, NULL, "Default name %s not correct. Enter other structure name: ", struc_name.c_str());
		id = add_struc(BADADDR, struc_name.c_str());
		set_struc_cmt(id, vtbl_name, true);
	}

	struc_t* new_struc = get_struc(id);
	if (!new_struc)
		return BADNODE;

	ea_t ea = vtbl_addr;
	int offset = 0;
	while (ea < vtbl_addr_end)
	{
		offset = ea - vtbl_addr;
		qstring method_name;
		ea_t method_ea = get_long(ea);

		if (method_ea == 0) break;
		if (!isEnabled(method_ea)) break;

		flags_t method_flags = getFlags(method_ea);
		char* struc_member_name = NULL;
		if (isFunc(method_flags))
		{
			method_name = get_short_name(method_ea);
			if (method_name.length() != 0)
				struc_member_name = (char*)method_name.c_str();
		}

		add_struc_member(new_struc, NULL, offset, dwrdflag(), NULL, 4);
		if (struc_member_name)
		{
			if (!set_member_name(new_struc, offset, struc_member_name))
			{
				//get_name(NULL, method_ea, method_name, sizeof(method_name));
				get_ea_name(&method_name, method_ea);
				set_member_name(new_struc, offset, struc_member_name);
			}
		}

		ea = ea + 4;
		flags_t ea_flags = getFlags(ea);
		if (has_any_name(ea_flags)) break;
	}

	return id;
}
예제 #4
0
int parser::parseFuncArgs(char *p, int &iStartParse, subexp *pSubExp, float *pArgs, int &iArgsNum, variable_scope &varScope)
{
	iStartParse++;
	int iSubIndex = floatToInt(parseDigit(p,iStartParse,true));
    // Implement unary minus here
	for (int i = 0; pSubExp[iSubIndex].exp[i]; i++)
	{
		// Parse digit
		if (isDigit(pSubExp[iSubIndex].exp[i]))
        {
			pArgs[iArgsNum] = parseDigit(pSubExp[iSubIndex].exp, i, true);
		}
		// Parse unary minus
        else if (pSubExp[iSubIndex].exp[i]=='-' && pSubExp[iSubIndex].exp[i+1] && isDigit(pSubExp[iSubIndex].exp[i+1]))
        {
            i++;
            pArgs[iArgsNum] = parseDigit(pSubExp[iSubIndex].exp, i, true, true);
        }
		// Parse next arg
		else if (pSubExp[iSubIndex].exp[i]==',')
		{
			iArgsNum += 1;
			continue;
		}
		// Parse build in func
        else if (isChar(pSubExp[iSubIndex].exp[i]) && isFunc(pSubExp[iSubIndex].exp, i))
        {
            pArgs[iArgsNum] = pSubExp[parseBuildInFunc(pSubExp[iSubIndex].exp, i, pSubExp, varScope, true)].result;
        }
		// Parse variable
		else if (isChar(pSubExp[iSubIndex].exp[i]))
		{
			pArgs[iArgsNum] = varScope.vScope[parseVariable(pSubExp[iSubIndex].exp, i, varScope, false)].getValue();
		}
		// Parse sub string
		else if (pSubExp[iSubIndex].exp[i]=='$')
		{
			pArgs[iArgsNum] = pSubExp[parseSubExp(pSubExp[iSubIndex].exp, i, pSubExp, varScope, true)].result;
		}
	}
	iArgsNum += 1;

	return iSubIndex;
}
예제 #5
0
파일: peep.c 프로젝트: Trewdbal/cpctelera
/*-----------------------------------------------------------------*/
static S4O_RET
scan4op (lineNode **pl, const char *pReg, const char *untilOp,
         lineNode **plCond)
{
  char *p;
  int len;
  bool isConditionalJump;
  int rIdx;
  S4O_RET ret;
  bool findPushPop;

  findPushPop = untilOp && (strcmp (untilOp, "push") == 0 || strcmp (untilOp, "pop") == 0);

  /* pReg points to e.g. "ar0"..."ar7" */
  len = strlen (pReg);

  /* get index into pReg table */
  for (rIdx = 0; rIdx < mcs51_nRegs; ++rIdx)
    if (strcmp (regs8051[rIdx].name, pReg + 1) == 0)
      break;

  /* sanity check */
  if (rIdx >= mcs51_nRegs)
    {
      DEADMOVEERROR();
      return S4O_ABORT;
    }

  for (; *pl; *pl = (*pl)->next)
    {
      if (!(*pl)->line || (*pl)->isDebug || (*pl)->isComment)
        continue;

      /* don't optimize across inline assembler,
         e.g. isLabel doesn't work there */
      if ((*pl)->isInline)
        return S4O_ABORT;

      if ((*pl)->visited)
        return S4O_VISITED;
      (*pl)->visited = TRUE;

      /* found untilOp? */
      if (untilOp && strncmp ((*pl)->line, untilOp, strlen (untilOp)) == 0)
        {
          p = (*pl)->line + strlen (untilOp);
          if (*p == '\t' && strncmp (p + 1, pReg, len) == 0)
            return S4O_FOUNDOPCODE;
          else
            {
              /* found untilOp but without our pReg */
              return S4O_ABORT;
            }
        }

      /* found pReg? */
      p = strchr ((*pl)->line, '\t');
      if (p)
        {
          /* skip '\t' */
          p++;

          /* when looking for push or pop and we find a direct access of sp: abort */
          if (findPushPop && strstr (p, "sp"))
            return S4O_ABORT;

          /* course search */
          if (strstr (p, pReg + 1))
            {
              /* ok, let's have a closer look */

              /* does opcode read from pReg? */
              if (bitVectBitValue (port->peep.getRegsRead ((*pl)), rIdx))
                return S4O_RD_OP;
              /* does opcode write to pReg? */
              if (bitVectBitValue (port->peep.getRegsWritten ((*pl)), rIdx))
                return S4O_WR_OP;

              /* we can get here, if the register name is
                 part of a variable name: ignore it */
            }
        }

      /* found label? */
      if ((*pl)->isLabel)
        {
          const char *start;
          char label[SDCC_NAME_MAX + 1];
          int len;

          if (!isLabelDefinition ((*pl)->line, &start, &len, FALSE))
            return S4O_ABORT;
          memcpy (label, start, len);
          label[len] = '\0';
          /* register passing this label */
          if (!setLabelRefPassedLabel (label))
            {
              DEADMOVEERROR();
              return S4O_ABORT;
            }
          continue;
        }

      /* branch or terminate? */
      isConditionalJump = FALSE;
      switch ((*pl)->line[0])
        {
          case 'a':
            if (strncmp ("acall", (*pl)->line, 5) == 0)
              {
                /* for comments see 'lcall' */
                ret = termScanAtFunc (*pl, rIdx);
                if (ret != S4O_CONTINUE)
                  return ret;
                break;
              }
            if (strncmp ("ajmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          case 'c':
            if (strncmp ("cjne", (*pl)->line, 4) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'd':
            if (strncmp ("djnz", (*pl)->line, 4) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'j':
            if (strncmp ("jmp", (*pl)->line, 3) == 0)
              /* "jmp @a+dptr": no chance to trace execution */
              return S4O_ABORT;
            if (strncmp ("jc",  (*pl)->line, 2) == 0 ||
                strncmp ("jnc", (*pl)->line, 3) == 0 ||
                strncmp ("jz",  (*pl)->line, 2) == 0 ||
                strncmp ("jnz", (*pl)->line, 3) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            if (strncmp ("jbc", (*pl)->line, 3) == 0 ||
                strncmp ("jb",  (*pl)->line, 2) == 0 ||
                strncmp ("jnb", (*pl)->line, 3) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'l':
            if (strncmp ("lcall", (*pl)->line, 5) == 0)
              {
                const char *p = (*pl)->line+5;
                while (*p == ' ' || *p == '\t')
                  p++;
                while (isdigit (*p))
                  p++;
                if (isdigit(p[-1]) && *p == '$') /* at least one digit */
                  {
                    /* this is a temp label for a pcall */
                    *pl = findLabel (*pl);
                    if (!*pl)
                      return S4O_ABORT;
                    break;
                  }

                ret = termScanAtFunc (*pl, rIdx);
                /* If it's a 'normal' 'caller save' function call, all
                   registers have been saved until the 'lcall'. The
                   'life range' of all registers end at the lcall,
                   and we can terminate our search.
                 * If the function is 'banked', the registers r0, r1 and r2
                   are used to tell the trampoline the destination. After
                   that their 'life range' ends just like the other registers.
                 * If it's a 'callee save' function call, registers are saved
                   by the callee. We've got no information, if the register
                   might live beyond the lcall. Therefore we've to continue
                   the search.
                */
                if (ret != S4O_CONTINUE)
                  return ret;
                break;
              }
            if (strncmp ("ljmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          case 'p':
            if (strncmp ("pop", (*pl)->line, 3) == 0 ||
                strncmp ("push", (*pl)->line, 4) == 0)
              return S4O_PUSHPOP;
            break;
          case 'r':
            if (strncmp ("reti", (*pl)->line, 4) == 0)
              return S4O_TERM;

            if (strncmp ("ret", (*pl)->line, 3) == 0)
              {
                /* pcall uses 'ret' */
                if (isFunc (*pl))
                  {
                    /* for comments see 'lcall' */
                    ret = termScanAtFunc (*pl, rIdx);
                    if (ret != S4O_CONTINUE)
                      return ret;
                    break;
                  }

                /* it's a normal function return */
                if (!((*pl)->ic) || (IS_SYMOP (IC_LEFT ((*pl)->ic)) &&
                    IS_FUNC (OP_SYM_TYPE(IC_LEFT ((*pl)->ic))) &&
                    FUNC_CALLEESAVES (OP_SYM_TYPE(IC_LEFT ((*pl)->ic)))))
                  return S4O_ABORT;
                else
                  return S4O_TERM;
              }
            break;
          case 's':
            if (strncmp ("sjmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          default:
            break;
        } /* switch ((*pl)->line[0]) */

      if (isConditionalJump)
        {
          *plCond = findLabel (*pl);
          if (!*plCond)
            return S4O_ABORT;
          return S4O_CONDJMP;
        }
    } /* for (; *pl; *pl = (*pl)->next) */
  return S4O_ABORT;
}
tid_t create_vtbl_struct(ea_t vtbl_addr, ea_t vtbl_addr_end, char* vtbl_name, uval_t idx, unsigned int* vtbl_len)
{


	qstring struc_name = vtbl_name;
	//struc_name.append(qstring("_vtbl_struct"));
	tid_t id = add_struc(BADADDR, struc_name.c_str());
	if (id == BADADDR)
	{
		struc_name.clear();
		struc_name = askstr(HIST_IDENT, NULL, "Default name %s not correct. Enter other structure name: ", struc_name.c_str());
		id = add_struc(BADADDR, struc_name.c_str());
		set_struc_cmt(id, vtbl_name, true);
	}

	struc_t* new_struc = get_struc(id);
	if (!new_struc)
		return BADNODE;

	ea_t ea = vtbl_addr;
	
	ea_t offset = 0;
	
	while (ea < vtbl_addr_end)
	{
		offset = ea - vtbl_addr;
		qstring method_name;
#ifndef __EA64__
		ea_t method_ea = get_long(ea); // get function ea
#else
		ea_t method_ea = get_64bit(ea);
#endif


		if (method_ea == 0) break;
		if (!isEnabled(method_ea)) break;

		flags_t method_flags = getFlags(method_ea);
		char* struc_member_name = NULL;
		if (isFunc(method_flags))
		{
			method_name = f_get_short_name(method_ea);
			// this line crash ida when compare qstring with null
			if (method_name.length() != 0) {
				struc_member_name = (char*)method_name.c_str();
			}

		}
#ifndef __EA64__
		add_struc_member(new_struc, NULL, offset, dwrdflag(), NULL, 4);
#else
		add_struc_member(new_struc, NULL, offset, qwrdflag(), NULL, sizeof(UINT64));
#endif

		if (struc_member_name)
		{
			if (!set_member_name(new_struc, offset, struc_member_name))
			{
				//get_name(NULL, method_ea, method_name, sizeof(method_name));
				f_get_ea_name(&method_name, method_ea);
				set_member_name(new_struc, offset, struc_member_name);
			}
		}
#ifndef __EA64__
		ea = ea + 4;
#else
		ea = ea + sizeof(UINT64);
#endif

		flags_t ea_flags = getFlags(ea);
		if (has_any_name(ea_flags)) break;
	}

	return id;
}
예제 #7
0
// RAW_MATERIALS
void raw_materials::getTokens(char *p, subexp *pSubExp, variable_scope &varScope )
{
    int iStartNum = -1, iEndNum = 0, iOperandsPos = 0, iOperationsPos = 0;
    char cSymbols[] = "*/+-", cDigits[] = "0123456789", cSpecialSymbols[] = ".$,";
    parser parParser;
	string_func stringFunc;
	statment_type statmentType = Equation;

    for (int i = 0; p[i]; i++) {

        // Parse digits block
        if (isDigit(p[i])) {
            fOperands[iOperandsPos] = parParser.parseDigit(p,i,true);
            iCountDigits++;
			iOperandsPos++;
        }
		// Parse digit with unary minus
        else if(i == 0 && p[i] == '-') {
            i++;
            fOperands[iOperandsPos] = parParser.parseDigit(p,i,true,true);
            iCountDigits++;
            iOperandsPos++;
        }
		// Parse sub expression
		else if (p[i] == '$') {
			fOperands[iOperandsPos] = pSubExp[parParser.parseSubExp(p, i, pSubExp, varScope, true)].result;
			iCountDigits++;
			iOperandsPos++;
		}
        // Parse symbols block
        else if (isInArray(p[i], cSymbols)) {

			// Validate that no dublicated symbols
			if (i > 0 && isInArray(p[i - 1], cSymbols)) throw SymbolDuplication;
            opOperations[iOperationsPos].symbol = p[i];
            opOperations[iOperationsPos].left_op = iOperationsPos;
            opOperations[iOperationsPos].right_op = iOperationsPos + 1;
            iOperationsPos++;
            iCountSymbols++;
        }
        // Parse build in function
		else if (isChar(p[i]) && isFunc(p,i)) {
			fOperands[iOperandsPos] = pSubExp[parParser.parseBuildInFunc(p, i, pSubExp, varScope, true)].result;
			iCountDigits++;
			iOperandsPos++;
		}
		// Parse variable 
		else if (isChar(p[i]))
		{
			// !Here we become aware, whether it variable set or variable use
			int iCurVarIndex = parParser.parseVariable(p, i, varScope);
			if (iOperandsPos == 0 && p[i] && p[i] == '=' && stringFunc.isSameStr(p, pSubExp[0].exp))
			{
				i++;
				statmentType = Setter;
				varScope.vScope[iCurVarIndex].setValue(pSubExp[parParser.parseSubExp(p, i, pSubExp, varScope, true)].result);
			}
			else if (varScope.vScope[iCurVarIndex].isInit())
			{
				// As after parse our "i" is higher than it previous was on 1.
				i--;
				fOperands[iOperandsPos] = varScope.vScope[iCurVarIndex].getValue();
				iCountDigits++;
				iOperandsPos++;
			}
			else
			{
				throw VariableInitError;
			}
				
		}
        else {
			throw SyntaxError;
        }
    }
    if (iCountDigits - iCountSymbols != 1 && statmentType == Equation) throw SyntaxError;
}