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; }
CDirectiveHeaderSize::CDirectiveHeaderSize(ArgumentList& args) { if (ConvertExpression(args[0].text,headerSize) == false) { Logger::printError(Logger::FatalError,L"Invalid header size %s",args[0].text); } updateFile(); }
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++; }
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(); }
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; }
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; }
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; }
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++; }