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; }
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; }