Exemple #1
0
CDirectiveIncbin::CDirectiveIncbin(ArgumentList& args)
{
	fileName = getFullPathName(args[0].text);

	if (fileExists(fileName) == false)
	{
		Logger::printError(Logger::FatalError,L"File %s not found",fileName);
		return;
	}

	int inputFileSize = fileSize(fileName);
	if (args.size() >= 2)
	{
		// load start address
		if (ConvertExpression(args[1].text,startAddress) == false)
		{
			Logger::printError(Logger::FatalError,L"Invalid start address %s",args[1].text);
			return;
		}

		if (startAddress >= inputFileSize)
		{
			Logger::printError(Logger::Error,L"Start address 0x%08X after end of file",startAddress);
			return;
		}

		if (args.size() >= 3)
		{
			// load size too
			if (ConvertExpression(args[2].text,loadSize) == false)
			{
				Logger::printError(Logger::FatalError,L"Invalid size %s",args[1].text);
				return;
			}

			if (startAddress+loadSize > inputFileSize)
			{
				Logger::printError(Logger::Warning,L"Loading beyond file end, truncating");
				loadSize =  inputFileSize-startAddress;
			}
		} else {
			loadSize =  inputFileSize-startAddress;
		}
	} else {
		startAddress = 0;
		loadSize = inputFileSize;
	}

	g_fileManager->advanceMemory(loadSize);
}
bool Preprocessor::EvaluateExpression( DefineTable& define_table, LexemList& directive )
{
    LexemList output;
    directive.pop_front();
    bool      success = ConvertExpression( directive, output );
    if( !success )
        return false;
    return EvaluateConvertedExpression( define_table, output ) != 0;
}
Exemple #3
0
CDirectiveHeaderSize::CDirectiveHeaderSize(ArgumentList& args)
{
	if (ConvertExpression(args[0].text,headerSize) == false)
	{
		Logger::printError(Logger::FatalError,L"Invalid header size %s",args[0].text);
	}

	updateFile();
}
Exemple #4
0
CDirectivePosition::CDirectivePosition(Type type, ArgumentList& Args)
	: type(type)
{
	if (ConvertExpression(Args[0].text,position) == false)
	{
		Logger::printError(Logger::FatalError,L"Invalid ram address %s",Args[0].text);
	}
	
	exec();
	Global.Section++;
}
Exemple #5
0
CDirectiveAlign::CDirectiveAlign(ArgumentList& args)
{
	if (args.size() >= 1)
	{
		if (ConvertExpression(args[0].text,alignment) == false)
		{
			Logger::printError(Logger::FatalError,L"Invalid alignment %s",args[0].text);
		}
		if (isPowerOfTwo(alignment) == false)
		{
			Logger::printError(Logger::Error,L"Invalid alignment %d",alignment);
		}
	} else {
		alignment = Arch->GetWordSize();
	}

	int num = computePadding();
}
Exemple #6
0
bool DirectiveRadix(ArgumentList& List, int flags)
{
	int rad;
	if (ConvertExpression(List[0].text,rad) == false)
	{
		Logger::printError(Logger::Error,L"Invalid expression %s",List[0].text.c_str());
		return false;
	}

	switch (rad)
	{
	case 2: case 8: case 10: case 16:
		Global.Radix = rad;
		break;
	default:
		Logger::printError(Logger::Error,L"Invalid radix %d",rad);
		return false;;
	}
	return true;
}
int Preprocessor::EvaluateConvertedExpression( DefineTable& define_table, LexemList& expr )
{
    std::vector<int> stack;

    while( expr.size() )
    {
        Lexem lexem = expr.front();
        expr.pop_front();

        if( IsIdentifier( lexem ) )
        {
            if( lexem.Type == Lexem::NUMBER )
                stack.push_back( atoi( lexem.Value.c_str() ) );
            else
            {
                LexemList ll;
                ll.push_back( lexem );
                ExpandDefine( ll.begin(), ll.end(), ll, define_table );
                LexemList out;
                bool      success = ConvertExpression( ll, out );
                if( !success )
                {
                    PrintErrorMessage( "Error while expanding macros." );
                    return 0;
                }
                stack.push_back( EvaluateConvertedExpression( define_table, out ) );
            }
        }
        else if( IsOperator( lexem ) )
        {
            if( lexem.Value == "!" )
            {
                if( !stack.size() )
                {
                    PrintErrorMessage( "Syntax error in #if: no argument for ! operator." );
                    return 0;
                }
                stack.back() = stack.back() != 0 ? 0 : 1;
            }
            else
            {
                if( stack.size() < 2 )
                {
                    PrintErrorMessage( "Syntax error in #if: not enough arguments for " + lexem.Value + " operator." );
                    return 0;
                }
                int rhs = stack.back();
                stack.pop_back();
                int lhs = stack.back();
                stack.pop_back();

                std::string op = lexem.Value;
                if( op == "*" )
                    stack.push_back( lhs *  rhs );
                if( op == "/" )
                    stack.push_back( lhs /  rhs );
                if( op == "%" )
                    stack.push_back( lhs %  rhs );
                if( op == "+" )
                    stack.push_back( lhs +  rhs );
                if( op == "-" )
                    stack.push_back( lhs -  rhs );
                if( op == "<" )
                    stack.push_back( lhs <  rhs );
                if( op == "<=" )
                    stack.push_back( lhs <= rhs );
                if( op == ">" )
                    stack.push_back( lhs >  rhs );
                if( op == ">=" )
                    stack.push_back( lhs >= rhs );
                if( op == "==" )
                    stack.push_back( lhs == rhs );
                if( op == "!=" )
                    stack.push_back( lhs != rhs );
                if( op == "&&" )
                    stack.push_back( ( lhs != 0 && rhs != 0 ) ? 1 : 0 );
                if( op == "||" )
                    stack.push_back( ( lhs != 0 || rhs != 0 ) ? 1 : 0 );
            }
        }
        else
        {
            PrintErrorMessage( "Internal error on lexem " + lexem.Value + "." );
            return 0;
        }
    }
    if( stack.size() == 1 )
        return stack.back();
    PrintErrorMessage( "Invalid #if expression." );
    return 0;
}
Exemple #8
0
bool Section::MakeData(ObjFactory &factory, AsmFile *fil)
{
    bool rv = true;
    int pc = 0;
    int pos = 0;
    unsigned char buf[1024];
    Fixup f;
    int n;
    ObjSection *sect = objectSection;
    if (sect)
    {
        sect->SetAlignment(align);
        instructionPos = 0;
        while ((n = GetNext(f, buf+pos, sizeof(buf) - pos)) != 0)
        {
            if (n > 0)
            {
                pos += n;
                if (pos == sizeof(buf))
                {
                    ObjMemory *mem = factory.MakeData(buf, pos);
                    sect->Add(mem);
                    pos = 0;
                }
                pc += n;
            }
            else
            {
                if (pos)
                {
                    ObjMemory *mem = factory.MakeData(buf, pos);
                    sect->Add(mem);
                    pos = 0;
                }
                ObjExpression *t;
                try
                {
                    t = ConvertExpression(f.GetExpr(), fil, factory);
                    SwapSectionIntoPlace(t);
                }
                catch (std::runtime_error *e)
                {
                    Errors::IncrementCount();
                    std::cout << "Error " << f.GetFileName().c_str() << "(" << f.GetErrorLine() << "):" << e->what() << std::endl;
                    delete e;
                    t = nullptr;
                    rv = false;
                }
                if (t && f.IsRel())
                {
                    ObjExpression *left = factory.MakeExpression(f.GetRelOffs());
                    t = factory.MakeExpression(ObjExpression::eSub, t, left);
                    left = factory.MakeExpression(ObjExpression::ePC);
                    t = factory.MakeExpression(ObjExpression::eSub, t, left);
                }
                if (t)
                {
                
                    ObjMemory *mem = factory.MakeFixup(t, f.GetSize());
                    if (mem)
                        sect->Add(mem);
                }
                pc += f.GetSize();
            }
        }
        if (pos)
        {
            ObjMemory *mem = factory.MakeData(buf, pos);
            sect->Add(mem);
        }
    }
    return rv;
}
Exemple #9
0
ObjExpression *Section::ConvertExpression(AsmExprNode *node, AsmFile *fil, ObjFactory &factory)
{
    ObjExpression *xleft = nullptr;
    ObjExpression *xright = nullptr;
    if (node->GetLeft())
        xleft = ConvertExpression(node->GetLeft(), fil, factory);
    if (node->GetRight())
        xright = ConvertExpression(node->GetRight(), fil, factory);
    switch (node->GetType())
    {
        case AsmExprNode::IVAL:
            return factory.MakeExpression(node->ival);
        case AsmExprNode::FVAL:
            throw new std::runtime_error("Floating point in relocatable expression not allowed");
        case AsmExprNode::PC:
            return factory.MakeExpression(ObjExpression::ePC);
        case AsmExprNode::SECTBASE:
            return factory.MakeExpression(objectSection);
        case AsmExprNode::BASED:
        {
            ObjExpression *left = factory.MakeExpression(node->GetSection()->GetObjectSection());
            ObjExpression *right = factory.MakeExpression(node->ival);
            return factory.MakeExpression(ObjExpression::eAdd, left, right);
        }
            break;
        case AsmExprNode::LABEL:
        {
            AsmExprNode *num = AsmExpr::GetEqu(node->label);
            if (num)
            {
                return ConvertExpression(num, fil, factory);
            }
            else
            {
                Label * label = fil->Lookup(node->label);
                if (label != nullptr)
                {
                    
                    ObjExpression *t;
                    if (label->IsExtern())
                    {
                        t = factory.MakeExpression(label->GetObjSymbol());
                    }
                    else
                    {
                        ObjExpression *left = factory.MakeExpression(label->GetObjectSection());
                        ObjExpression *right = ConvertExpression(label->GetOffset(), fil, factory);
                        t = factory.MakeExpression(ObjExpression::eAdd, left, right);
                    }
                    return t;
                }
                else
                {
                    ObjSection *s = fil->GetSectionByName(node->label);
                    if (s)
                    {
                        ObjExpression *left = factory.MakeExpression(s);
                        ObjExpression *right = factory.MakeExpression(16);
                        return factory.MakeExpression(ObjExpression::eDiv, left, right);
                    }
                    else
                    {
                        std::string name = node->label;
                        if (name.substr(0,3) == "..@" && isdigit(name[3]))
                        {
                            int i;
                            for ( i = 4; i < name.size() && isdigit(name[i]); i++);
                            if (name[i] == '.')
                            {
                                name = std::string("%") + name.substr(i+1);
                            }
                            else if (name[i] == '@')
                            {
                                name = std::string("%$") + name.substr(i+1);
                            }
                        }
                        throw new std::runtime_error(std::string("Label '") + name + "' does not exist.");
                    }
                }
            }
        }
        case AsmExprNode::ADD:
            return factory.MakeExpression(ObjExpression::eAdd, xleft, xright);
        case AsmExprNode::SUB:
            return factory.MakeExpression(ObjExpression::eSub, xleft, xright);
        case AsmExprNode::NEG:
            return factory.MakeExpression(ObjExpression::eNeg, xleft, xright);
        case AsmExprNode::CMPL:
            return factory.MakeExpression(ObjExpression::eCmpl, xleft, xright);
        case AsmExprNode::MUL:
            return factory.MakeExpression(ObjExpression::eMul, xleft, xright);
        case AsmExprNode::DIV:
            return factory.MakeExpression(ObjExpression::eDiv, xleft, xright);
        case AsmExprNode::NOT:
        case AsmExprNode::SDIV:
        case AsmExprNode::SMOD:
        case AsmExprNode::OR:
        case AsmExprNode::XOR:
        case AsmExprNode::AND:
        case AsmExprNode::GT:
        case AsmExprNode::LT:
        case AsmExprNode::GE:
        case AsmExprNode::LE:
        case AsmExprNode::EQ:
        case AsmExprNode::NE:
        case AsmExprNode::MOD:
        case AsmExprNode::LSHIFT:
        case AsmExprNode::RSHIFT:
        case AsmExprNode::LAND:
        case AsmExprNode::LOR:
        case AsmExprNode::REG:
            throw new std::runtime_error("Operator not allowed in address expression");
    }
    return nullptr;
}
Exemple #10
0
CDirectiveFile::CDirectiveFile(Type type, ArgumentList& args)
	: type(type)
{
	file = NULL;
	
	std::wstring originalName;
	std::wstring fileName;
	int virtualAddress;

	switch (type)
	{
	case Type::Open:
		fileName = getFullPathName(args[0].text);

		if (fileExists(fileName) == false)
		{
			Logger::printError(Logger::FatalError,L"File %s not found",fileName);
			return;
		}
		if (ConvertExpression(args[1].text,virtualAddress) == false)
		{
			Logger::printError(Logger::FatalError,L"Invalid ram address %s",args[1].text);
			return;
		}

		file = new GenericAssemblerFile(fileName,virtualAddress,false);
		break;
	case Type::Create:
		fileName = getFullPathName(args[0].text);

		if (ConvertExpression(args[1].text,virtualAddress) == false)
		{
			Logger::printError(Logger::FatalError,L"Invalid ram address %s",args[1].text);
			return;
		}

		file = new GenericAssemblerFile(fileName,virtualAddress,true);
		break;
	case Type::Copy:
		originalName = getFullPathName(args[0].text);
		fileName = getFullPathName(args[1].text);

		if (fileExists(originalName) == false)
		{
			Logger::printError(Logger::FatalError,L"File %s not found",originalName);
			return;
		}
		if (ConvertExpression(args[2].text,virtualAddress) == false)
		{
			Logger::printError(Logger::FatalError,L"Invalid ram address %s",args[2].text);
			return;
		}

		file = new GenericAssemblerFile(fileName,originalName,virtualAddress);
		break;
	case Type::Close:
		return;
	}

	g_fileManager->addFile(file);
	Global.Section++;
}