コード例 #1
0
ファイル: Disassembler.cpp プロジェクト: bjackson/LC3Tools
bool Disassembler::DisassembleData(LocationVector &LocationStack, istream &InputStream, uint64 &Address)
{
	bool fRetVal = true;
	unsigned int TempChar;
	Data *pData;
	while(InputStream.good() && Address < EndAddress)
	{
		//Get a byte of data from the stream.
		TempChar = InputStream.get();
		if(TempChar == -1)	//EOF
			break;

		//Add the byte to the sequence
		if((*TheProg.Segments.rbegin())->Sequence.empty())
		{
			//Create a new byte element.
			pData = new Data(LocationStack, DATA1, Addressability, new IntegerNumber(LocationStack, TempChar));
			(*TheProg.Segments.rbegin())->Sequence.push_back(pData);
			pData->Address = Address;
		}
		else
		{
			//Add the byte to an existing array.
			pData = reinterpret_cast<Data *>(*(*TheProg.Segments.rbegin())->Sequence.rbegin());
			pData->vData.push_back(new IntegerNumber(LocationStack, TempChar));
			pData->Length++;
			pData->Size++;
		}

		Address++;
		LocationStack.rbegin()->second++;
	}
	return fRetVal;
}
コード例 #2
0
ファイル: Disassembler.cpp プロジェクト: bjackson/LC3Tools
bool Disassembler::Disassemble(LocationVector &LocationStack, istream &InputStream, SymbolList &Symbols)
{
	bool fRetVal = true;
	unsigned int i, TempChar;
	JMT::ByteData ByteData;

	if(fRunOnce)
		throw "Disassembler called twice on the same program!";
	fRunOnce = true;

	//First read starting address.
	for(i = 0; i < sizeof(uint64); i++)
	{
		TempChar = InputStream.get();
		if(TempChar == -1)	//EOF
			break;
		//The address in the file is always little endian
#ifdef BIG_ENDIAN_BUILD
		ByteData.Bytes[sizeof(uint64) - i - 1] = TempChar;
#else
		ByteData.Bytes[i] = TempChar;
#endif
		LocationStack.rbegin()->second++;
	}
	if(i < sizeof(uint64))
	{
		CallBack(Fatal, "Unexpected end of file.", LocationStack);
		return false;
	}
	StartAddress = ByteData.UI64;

	//Then read ending address
	for(i = 0; i < sizeof(uint64); i++)
	{
		TempChar = InputStream.get();
		if(TempChar == -1)	//EOF
			break;
		//The address in the file is always little endian
#ifdef BIG_ENDIAN_BUILD
		ByteData.Bytes[sizeof(uint64) - i - 1] = TempChar;
#else
		ByteData.Bytes[i] = TempChar;
#endif
		LocationStack.rbegin()->second++;
	}
	if(i < sizeof(uint64))
	{
		CallBack(Fatal, "Unexpected end of file.", LocationStack);
		return false;
	}
	EndAddress = StartAddress + ByteData.UI64;

	//Check addresses
	if(EndAddress < StartAddress)
	{
		CallBack(Fatal, "Program end address is less than start address.", LocationStack);
		return false;
	}

	//Create program origin
	TheProg.fDynamicAddress = false;
	TheProg.Address = StartAddress;

	//Create program segment
	TheProg.Segments.push_back(new Segment(LocationStack, Addressability, 0));

	//Add the pre-existing symbols
	for(SymbolList::iterator SymbolIter = Symbols.begin(); SymbolIter != Symbols.end(); SymbolIter++)
		DisassembleSymbol(SymbolIter->first, SymbolIter->second, SymbolIter->third);

	//Try to disassemble instructions. Instructions have highest priority.
	uint64 Address = StartAddress;
	if(ToLower(TheProg.sFileName.Ext) == "obj")
	{
		if(!DisassembleInstructions(LocationStack, InputStream, Address))
			return false;
	}
	else	//"bin"
	{
		if(!DisassembleData(LocationStack, InputStream, Address))
			return false;
	}

	if(Address < EndAddress)
	{
		CallBack(Error, "Unexpected end of file.", LocationStack);
		return false;
	}

	//Create labels
	list<Element *>::iterator ElemIter = (*TheProg.Segments.begin())->Sequence.begin();
	for(LabelMap::iterator LabelIter = Labels.begin(); LabelIter != Labels.end(); LabelIter++)
	{
		//Find the element this label points to
		while(ElemIter != (*TheProg.Segments.begin())->Sequence.end() && (*ElemIter)->Address < LabelIter->first)
			ElemIter++;

		if(ElemIter == (*TheProg.Segments.begin())->Sequence.end())
		{
			ElemIter--;
			if((*ElemIter)->Address + (*ElemIter)->Size != LabelIter->first)
				throw "Disassembler: Ran out of elements while adding labels!";
			//Label points to end of program
			ElemIter++;
		}
		else if((*ElemIter)->Address != LabelIter->first)
			throw "Disassembler: Label points to inside an instruction!";

		//Add the label to the sequence
		Label *pLabel = new Label(LocationStack, LabelIter->second->sSymbol, *TheProg.Segments.begin());
		(*TheProg.Segments.begin())->Sequence.insert(ElemIter, pLabel);
		LabelIter->second->pLabel = pLabel;
		if(ElemIter != (*TheProg.Segments.begin())->Sequence.end())
		{
			if(!TheProg.TheSymbolTable.ResolveSymbol((*ElemIter)->LocationStack, LabelIter->second->sSymbol, CallBack, SymLabel))
				throw "ResolveSymbol in Disassembler failed!";
			pLabel->pElement = *ElemIter;
		}
		else
			if(!TheProg.TheSymbolTable.ResolveSymbol((*(*TheProg.Segments.begin())->Sequence.rbegin())->LocationStack, LabelIter->second->sSymbol, CallBack, SymLabel))
				throw "ResolveSymbol in Disassembler failed!";
	}

	return fRetVal;
}