Example #1
0
//*****************************************************************************
// This method will walk the byte codes of an IL method looking for tokens.
// For each token found, it will check to see if it has been moved, and if
// so, apply the new token value in its place.
//*****************************************************************************
HRESULT CeeFileGenWriter::MapTokensForMethod(
    CeeGenTokenMapper *pMapper,
    BYTE        *pCode,
    LPCWSTR     szMethodName)
{
    mdToken     tkTo;
    DWORD       PC;

    COR_ILMETHOD_DECODER method((COR_ILMETHOD*) pCode);

    // If compressed IL is being emitted, this routine will have no idea how to walk the tokens,
    // so don't do it
    if (m_dwMacroDefinitionSize != 0)
        return S_OK;

    pCode = const_cast<BYTE*>(method.Code);

    PC = 0;
    while (PC < method.GetCodeSize())
    {
        DWORD   Len;
        DWORD   i;
        OPCODE  instr;

        instr = DecodeOpcode(&pCode[PC], &Len);

        if (instr == CEE_COUNT)
        {
            _ASSERTE(0 && "Instruction decoding error\n");
            return E_FAIL;
        }


        PC += Len;

        switch (OpcodeInfo[instr].Type)
        {
            DWORD tk;

            default:
            {
                _ASSERTE(0 && "Unknown instruction\n");
                return E_FAIL;
            }

            case InlineNone:
            break;

            case ShortInlineI:
            case ShortInlineVar:
            case ShortInlineBrTarget:
            PC++;
            break;

            case InlineVar:
            PC += 2;
            break;

            case InlineI:
            case ShortInlineR:
            case InlineBrTarget:
            case InlineRVA:
            PC += 4;
            break;

            case InlineI8:
            case InlineR:
            PC += 8;
            break;

            case InlinePhi:
                {
                    DWORD cases = pCode[PC];
                    PC += 2 * cases + 1;
                    break;
                }

            case InlineSwitch:
            {
                DWORD cases = pCode[PC] + (pCode[PC+1] << 8) + (pCode[PC+2] << 16) + (pCode[PC+3] << 24);

                PC += 4;
                for (i = 0; i < cases; i++)
                {
                    PC += 4;
                }

                // skip bottom of loop which prints szString
                continue;
            }

            case InlineTok:
            case InlineSig:
            case InlineMethod:
            case InlineField:
            case InlineType:
            case InlineString:
            {
                tk = GET_UNALIGNED_VAL32(&pCode[PC]);

                if (pMapper->HasTokenMoved(tk, tkTo))
                {
                    SET_UNALIGNED_VAL32(&pCode[PC], tkTo);
                }

                PC += 4;
                break;
            }
        }
    }

    return S_OK;
}
Example #2
0
void Peeper(uchar *ip, uchar *ip_end)
{
	OpcodeInfo opi[4];
	uchar *start_ip = ip;
	int n;
	int op_count = 0;
	
	for (n=0;n<4;n++)
	{
		if (ip > ip_end)
			break;

		ip = DecodeOpcode(&opi[n], ip);
		op_count++;
	}

	if (op_count != 4)
		return;


	// Double optimizer

	while(1)
	{
/*
	ld r0,r14	
	ld r1,r15	
	ld r14,r0	
	ld r15,r1	
*/
		// All are ldr
		
		if (opi[0].op != _LDR)
			break;
		if (opi[1].op != _LDR)
			break;
		if (opi[2].op != _LDR)
			break;
		if (opi[3].op != _LDR)
			break;

		// check r0's
		if (opi[0].rd != opi[2].rs)
			break;

		// check r1's
		if (opi[1].rd != opi[3].rs)
			break;

		// check r14's
		if (opi[0].rs != opi[2].rd)
			break;

		// check r15's
		if (opi[1].rs != opi[3].rd)
			break;

		*start_ip++ = 0;
		*start_ip++ = 0;
		*start_ip++ = 0;

		*start_ip++ = 0;
		*start_ip++ = 0;
		*start_ip++ = 0;

		*start_ip++ = 0;
		*start_ip++ = 0;
		*start_ip++ = 0;

		*start_ip++ = 0;
		*start_ip++ = 0;
		*start_ip++ = 0;
		return;
	}
	
	
	// Register to register switches
	
	while(1)
	{
/*
		ld r0,r1	
		ld r1,r0	
*/
		// All are ldr

		if (opi[0].op != _LDR)
			break;
		if (opi[1].op != _LDR)
			break;

		// check r0's
		if (opi[0].rd != opi[1].rs)
			break;

		// check r1's
		if (opi[1].rd != opi[0].rs)
			break;

		*start_ip++ = 0;
		*start_ip++ = 0;
		*start_ip++ = 0;

		*start_ip++ = 0;
		*start_ip++ = 0;
		*start_ip++ = 0;
		return;
	}
	
	
	//memset(start_ip, 0, start_ip - ip);
}
Example #3
0
void RebuildFunc(SYMBOL *sym)
{
	OpcodeInfo thisOp;
	SYMBOL *ref;

	uchar *ip, *ip_end, *ip_last;
	
	int real_ip;
	char str[256];

	if (!sym)
		return;

	RebuildEmit("\n//****************************************\n");
	RebuildEmit("// Function: %s\n", sym->Name);
	RebuildEmit("//****************************************\n\n");

#if 0 //OLD
	if (strcmp(sym->Name, Code_EntryPoint) == 0)
	{
		RebuildEmit(".global %s\n", sym->Name);
		RebuildEmit(".func %s\n", sym->Name);
	}
	else
	{
		RebuildEmit(".func %s_%d\n", sym->Name, sym->LocalScope);
	}
#else //New

	if (strcmp(sym->Name, Code_EntryPoint) == 0)
	{
		RebuildEmit(".global %s\n", sym->Name);
		RebuildEmit(".func %s, %d, %s\n", sym->Name, sym->Params, RebuildRetType(sym->RetType) );
	}
	else
	{
		RebuildEmit(".func %s_%d, %d, %s\n", sym->Name, sym->LocalScope, sym->Params, RebuildRetType(sym->RetType));
	}

#endif

	ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP);
	ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value);
	real_ip	= sym->Value;

	while(1)
	{
		ip_last = ip;
		
		if (ip > ip_end)
			break;

		// Print labels
		
		ref = (SYMBOL *) ArrayGet(&CodeLabelArray, real_ip);

		if (ref)
		{
			if (ref->LabelType == label_Local)
				RebuildEmit("%s_%d:\n", ref->Name, ref->LocalScope);
		}

		RebuildEmitStabs(real_ip);
	
//		Peeper(ip, ip_end);

		if (ArgSkipElim == 0)
			if (ArrayGet(&CodeTouchArray, real_ip) == 0)
				RebuildEmit("// ");

		CaseRef = 0;

		ip = DecodeOpcode(&thisOp, ip);
		DecodeAsmString(&thisOp, str, 1);
		RebuildEmit("\t%s", str);

//		DecodeAsmString(&thisOp, str, 0);			// Sanity testing
//		CodeSanityChecker(thisOp.rip, str);

		if (ArgDebugRebuild)
		{
			int len = 4 + strlen(str);		
			str[0] = 0;
			
			while(len < 40)
			{
				RebuildEmit(" ", str);
				len++;
			}
			
			RebuildEmit("; 0x%x - ", real_ip);
			
			DisassembleFromSource(real_ip, str);
			RebuildEmit("%s", str);
		}

		RebuildEmit("\n");

		// Check for case statement, which need case data after them
		
		if (CaseRef)
		{
			RebuildEmit(".data\n");
			Rebuild_Data(CaseRef);
			RebuildEmit(".code\n");
		}

		real_ip += (ip - ip_last);	
	}
}
Example #4
0
void CActiveReader::RunL()
	{
	// the read has completed - for the moment we are not really interested at the moment

	if (iAuto)
		{
		switch (iReadState)
			{
			case EReadHeader:
				iReaderOutputConsole->Printf(_L("Header byte recvd\n"));
				iReadState = (DecodeHeader() == KHCIUARTCommandHeader ? EReadOpcode : EReadConnectionHandleFlags);
				break;
			case EReadOpcode:
				{
				iReaderOutputConsole->Printf(_L("Opcode bytes recvd\n"));
				TInt opcode = DecodeOpcode();
				if (opcode == 0)
					//NoOpCommand has no more parameters
					{
					iReadComplete = ETrue;
					iReadState = EReadHeader; // start again
					}
				else
					{
					iReadState = EReadCommandLength;
					}
				}
				break;
			case EReadCommandLength:
				iReaderOutputConsole->Printf(_L("Length byte recvd\n"));
				iReadState = EReadCommandRemainder;
				break;
			case EReadDataLength:
				iReaderOutputConsole->Printf(_L("Length byte recvd\n"));
				iReadState = EReadDataRemainder;
				break;
			case EReadConnectionHandleFlags:
				iReaderOutputConsole->Printf(_L("ConnectionHandle bytes recvd\n"));
				iReadState = EReadDataLength;
				break;
			case EReadCommandRemainder:
			case EReadDataRemainder:
				iReaderOutputConsole->Printf(_L("Remainder bytes recvd\n"));
				iReadComplete = ETrue;
				iReadState = EReadHeader; // start again
				break;

			default:
				__DEBUGGER();
			}
		
		if (iReadComplete)
			{
			iReaderOutputConsole->Printf(_L("Decoding...\n"));

			if (DecodeHeader() == KHCIUARTCommandHeader)
				{
				iReaderOutputConsole->Printf(_L("Decode: Command\n"));
				iEmulator.CommandReceived(iOpcodeBuf, iRemainderBuf);
				}
			else
				{
				iReaderOutputConsole->Printf(_L("Decode: ACL Data\n"));
				iEmulator.ACLDataReceived(iConnectionHandleFlagsBuf, iRemainderBuf);
				}
			iReadComplete = EFalse;
			}
				

		}

	// queue another one
	DoRead();
	}
Example #5
0
void RebuildCppFunc(SYMBOL *sym, int isproto)
{
	OpcodeInfo thisOp;
	SYMBOL *ref;

	uchar *ip, *ip_end, *ip_last;

	int real_ip;
//	char str[256];

	if (!sym)
		return;

	// Say no returns yet

	ReturnCount = 0;

	// Enumerate this functions labels, unless we're generating a proto

	if (isproto	== 0)
		EnumerateFunctionLabels(sym);

	ThisFunctionRegs = FunctionRegUsage(sym);
	ThisFunctionRetType = sym->RetType;

	if (ThisFunctionRegs == -1)
		return;

	RebuildCppProlog(sym, isproto);

	// if we're generating a proto return

	if (isproto)
		return;

	ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP);
	ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value);
	real_ip	= sym->Value;

	while(1)
	{
		ip_last = ip;

		if (ip > ip_end)
			break;

		// Print labels

		ref = (SYMBOL *) ArrayGet(&CodeLabelArray, real_ip);

		if (ref)
		{
			if (ref->LabelType == label_Local)
			{
#ifdef Cpp_DEBUG
				RebuildEmit("// %s_%d:\n", ref->Name, ref->LocalScope);
#endif
				RebuildEmit("label_%d:;\n", ref->LabelEnum);
			}
		}

		if (ArrayGet(&CodeTouchArray, real_ip) == 0)
			RebuildEmit("// ");

		CaseRef = 0;

		ip = DecodeOpcode(&thisOp, ip);

		ThisFunctionExit = 0;

		if (ip > ip_end)
			ThisFunctionExit = 1;

		RebuildCppInst(&thisOp);

//		DecodeAsmString(&thisOp, str);
//		RebuildEmit("\t%s", str);

#ifdef CPP_DEBUG
		{
			int len = 4 + strlen(str);
			str[0] = 0;

			while(len < 40)
			{
				RebuildEmit(" ", str);
				len++;
			}

			DisassembleFromSource(real_ip, str);
			RebuildEmit(";%s", str);
		}
#endif

//		RebuildEmit("\n");

		// Check for case statement, which need case data after them

/*		if (CaseRef)
		{
			RebuildEmit(".data\n");
			Rebuild_Data(CaseRef);
			RebuildEmit(".code\n");
		}
*/
		real_ip += (ip - ip_last);
	}

	RebuildCppEpilog(sym);
}
Example #6
0
int FunctionRegAnalyse(SYMBOL *sym, FuncProp *fp)
{
	OpcodeInfo thisOp;
	uchar *ip, *ip_end;
	int params,n;

	fp->src_reg = 0;
	fp->dst_reg = 0;
	fp->assign_reg = 0;
	fp->uninit_reg = 0;
	
	// Make sure we have a valid symbol
	
	if (!sym)
		return -1;

	// Make sure the symbol is a function

	if (sym->Type != SECT_code)
		return -1;

	// Get the start and end of the function in the code array

	ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP);
	ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value);

	// Set up the parameter regs
	
	params = sym->Params;
	
	for (n=0;n<params;n++)
	{
		fp->assign_reg |=  REGBIT(REG_i0 + n);
	}
	
	// Scan the function

#ifdef AFDEBUG
	printf("\n");
#endif

	while(1)
	{		
		if (ip > ip_end)
			break;

#ifdef AFDEBUG
		{
			char buf[2560];
			buf[0] = 0;
			DisassembleFromSource(ip - CodeMemArray.array, buf);
			printf("%s\n", buf);
		}
#endif
	
		ip = DecodeOpcode(&thisOp, ip);

		// Ignor push and pop
		
		if (thisOp.op == _PUSH)
			continue;

		if (thisOp.op == _POP)
			continue;

		//-----------------------------------------
		// Deal with syscalls
		// for some strange reason rd is the syscallId which will
		// tag unused registers as used for void functions
		//-----------------------------------------

		if(thisOp.op == _SYSCALL)
		{
			FunctionReg_Syscall(&thisOp, fp);
		}

		// Check for a dest reg		
		else if (thisOp.flags & fetch_d)
		{
			if (thisOp.rd < 32)
			{
				// Since this is a dst regs we say its initialized
				fp->assign_reg |=  REGBIT(thisOp.rd);
	
				// Say this reg was used as a dst reg
				fp->dst_reg |= REGBIT(thisOp.rd);
			}
		}

		// Check for a source reg
		
		if (thisOp.flags & fetch_s)
		{
			if (thisOp.rs < 32)
			{
				// check if this reg was assigned previously, if it was'nt it is uninitialized before use
			
				int is_assigned = fp->assign_reg & REGBIT(thisOp.rs);
			
				if (!is_assigned)
					fp->uninit_reg |= REGBIT(thisOp.rs);
			
				fp->src_reg |= REGBIT(thisOp.rs);
			}
		}

		//-----------------------------------------
		//		Deal with immediate calls
		//-----------------------------------------
		
		// Add the call parameters to the used list

		if (thisOp.op == _CALLI)
		{

			FunctionReg_Calli(&thisOp, fp);
		}

		//-----------------------------------------
		//		Deal with register calls
		//-----------------------------------------
		
		// Add the call parameters to the used list

		if (thisOp.op == _CALL)
		{
			FunctionReg_CallReg(&thisOp, fp);
		}
	}


#ifdef AFDEBUG

	printf("\n");

	printf("                  rrrrrrrrrrrrrrrriiiiddddddddfrsz\n");
	printf("                  fedcba9876543210321076543210rtpr\n");

	printf("src_reg = %s\n", Bin32(fp->src_reg));
	printf("dst_reg = %s\n", Bin32(fp->dst_reg));
	printf("assign_reg    = %s\n", Bin32(fp->assign_reg));
	printf("uninit_reg      = %s\n", Bin32(fp->uninit_reg));

	if (fp->uninit_reg)
		printf("");

#endif

	// Make sure zr is never uninitialized
	
	fp->uninit_reg &= ~REGBIT(REG_zero);

	// Make a composit of which reg's were used

	fp->reg_used = fp->src_reg | fp->dst_reg;

	return fp->reg_used;
}