예제 #1
0
bool Architecture::FormatOperand(
    Document      const& rDoc,
    Address       const& rAddr,
    Instruction   const& rInsn,
    Operand       const& rOprd,
    u8                   OperandNo,
    PrintData          & rPrintData) const
{
    rPrintData.MarkOffset();

    auto const& rBinStrm = rDoc.GetBinaryStream();

    if (rOprd.GetType() == O_NONE)
        return true;

    u32 OprdType = rOprd.GetType();
    auto const* pCpuInfo = GetCpuInformation();
    std::string MemBegChar = "[";
    std::string MemEndChar = "]";

    if (OprdType & O_MEM)
        rPrintData.AppendOperator("[");

    if (OprdType & O_REL || OprdType & O_ABS)
    {
        Address DstAddr;

        if (rInsn.GetOperandReference(rDoc, 0, rAddr, DstAddr))
        {
            auto Lbl = rDoc.GetLabelFromAddress(DstAddr);
            if (Lbl.GetType() != Label::Unknown)
                rPrintData.AppendLabel(Lbl.GetLabel());
            else
                rPrintData.AppendAddress(rAddr);
        }
        else
            rPrintData.AppendImmediate(rOprd.GetValue(), rAddr.GetOffsetSize());
    }
    else if (OprdType & O_DISP || OprdType & O_IMM)
    {
        if (rOprd.GetType() & O_NO_REF)
        {
            rPrintData.AppendImmediate(rOprd.GetValue(), rAddr.GetOffsetSize());
            return true;
        }

        Address OprdAddr = rDoc.MakeAddress(rOprd.GetSegValue(), rOprd.GetValue());
        auto Lbl = rDoc.GetLabelFromAddress(OprdAddr);
        if (Lbl.GetType() != Label::Unknown)
            rPrintData.AppendLabel(Lbl.GetLabel());
        else
            rPrintData.AppendAddress(OprdAddr);
    }

    else if (OprdType & O_REG)
    {
        if (pCpuInfo == nullptr)
            return false;
        auto pRegName = pCpuInfo->ConvertIdentifierToName(rOprd.GetReg());
        if (pRegName == nullptr)
            return false;
        rPrintData.AppendRegister(pRegName);
    }

    if (OprdType & O_MEM)
        rPrintData.AppendOperator("]");

    return true;
}
예제 #2
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operand* ConstantFolder::LoadFromInitializer(Initializer* initializer, const Type* loadType, 
											 __int64 offset) {
	DebugValidator::IsFalse(initializer->IsInitializerList());
	bool isNull = false;
	bool isZero = false;
	
	// We may be loading from string constant.
	if(auto stringConst = initializer->Value()->As<StringConstant>()) {
		return LoadFromString(stringConst, loadType, offset);
	}

	// Exclude initializers that have an incompatible conversion.
	if(initializer->Conversion() == InitConv_PointerToInt) {
		if(initializer->Value()->IsNullConstant()) {
			isZero = true;
		}
		else {
			// Definitely not a constant operand.
			return nullptr;
		}
	}
	else if((initializer->Conversion() == InitConv_PointerToPointer) ||
			(initializer->Conversion() == InitConv_IntToPointer)) {
		if(initializer->Value()->IsNullConstant() || MatchInt(0)(initializer->Value())) {
			isNull = true;
		}
		else {
			// Definitely not a constant operand.
			return nullptr;
		}
	}

	// It's undefined behavior if we try to load from a null pointer.
	if(isNull) {
        return GetNullptr(loadType);
    }
	else if(isZero) {
        return GetZeroInt(loadType);
    }

	// Obtain the value from the initializer. If the offset is not 0, or the
	// types don't match, we must extract the value.
	// Not that we give up if we are requested to extract a value that is larger
	// than the one in the initializer, or if the offset is too large.
	Operand* value = initializer->Value();
	auto valueType = value->GetType();

	if((offset == 0) && (loadType == initializer->Value()->GetType())) {
		return initializer->Value();
	}
	else if((offset > TypeInfo::GetSize(valueType, target_)) ||
		    (TypeInfo::GetSize(loadType, target_) > 
			 TypeInfo::GetSize(valueType, target_))) {
		// This is undefined behavior, because we want to read something that is 
		// in memory located after the operand, and there are no constraints
		// on the way global variables are laid out int memory.
		return GetUndefined(loadType);
	}
	
    return ExtractFromOperand(value, loadType, offset);
}