Example #1
0
        private MethodBody BuildMethodBody( ModuleInfo moduleInfo, Method method )
        {
            Debug.Assert( this.Debugger.DebugHost.CpuHook != null );
            uint[] codes = this.Debugger.DebugHost.CpuHook.GetMethodBody( method );

            uint instrAddress = method.Address;
            List<Instruction> instrs = new List<Instruction>( ( int )method.Length / 4 );
            for( int n = 0; n < codes.Length; n++ )
            {
                Instruction instr = new Instruction( instrAddress, codes[ n ] );
                instrs.Add( instr );
                instrAddress += 4;
            }
            MethodBody methodBody = new MethodBody( moduleInfo, method.Address, ( uint )method.Length, instrs.ToArray() );
            if( method.Type == MethodType.Bios )
            {
                if( method.Function.MethodName != null )
                    methodBody.Name = method.Function.MethodName;
                else
                    methodBody.Name = method.Function.ModuleName + "::" + method.Function.NID.ToString( "X8" );
                methodBody.Function = method.Function;
            }
            else
            {
                if( method.Name != null )
                    methodBody.Name = method.Name;
            }

            return methodBody;
        }
Example #2
0
 private void AddMemoryReference( List<MemoryReference> memRefs, Instruction instruction, uint target, bool isRead )
 {
     //Debug.WriteLine( string.Format( "adding memory reference at {0:X8} ({1}) to {2:X8} for {3}", instruction.Address, instruction, target, isRead ? "read" : "write" ) );
     foreach( MemoryReference memRef in memRefs )
     {
         if( memRef.Address == target )
         {
             memRef.References.Add( instruction );
             if( isRead == true )
                 memRef.Reads++;
             else
                 memRef.Writes++;
             instruction.Reference = memRef;
             return;
         }
     }
     MemoryReference newMemRef = new MemoryReference();
     newMemRef.Address = target;
     newMemRef.References.Add( instruction );
     if( isRead == true )
         newMemRef.Reads++;
     else
         newMemRef.Writes++;
     instruction.Reference = newMemRef;
     memRefs.Add( newMemRef );
 }
Example #3
0
 private void AddLabelReference( List<Label> labels, Instruction instruction, uint target )
 {
     foreach( Label label in labels )
     {
         if( label.Address == target )
         {
             label.References.Add( instruction );
             instruction.Reference = label;
             return;
         }
     }
     Label newLabel = new Label();
     newLabel.Name = string.Format( "loc_{0:X8}", target );
     newLabel.Address = target;
     newLabel.References.Add( instruction );
     instruction.Reference = newLabel;
     labels.Add( newLabel );
 }
Example #4
0
 private void AddCodeReference( List<CodeReference> codeRefs, Instruction instruction, uint target )
 {
     if( target == 0 )
         return;
     foreach( CodeReference codeRef in codeRefs )
     {
         if( codeRef.Address == target )
         {
             codeRef.References.Add( instruction );
             instruction.Reference = codeRef;
             return;
         }
     }
     CodeReference newCodeRef = new CodeReference();
     newCodeRef.Address = target;
     newCodeRef.References.Add( instruction );
     instruction.Reference = newCodeRef;
     codeRefs.Add( newCodeRef );
 }
Example #5
0
        public void Populate( Instruction[] instructions )
        {
            this.Instructions = instructions;

            // - determine locals (loop for first addiu $sp, $sp, [size]
            // - find all labels (branch targets)

            bool foundSpMod = false;
            List<Label> labels = new List<Label>();
            List<CodeReference> codeRefs = new List<CodeReference>();
            List<MemoryReference> memRefs = new List<MemoryReference>();
            uint[] currentRegisters = new uint[ 32 ];
            uint validRegisters = 0;
            bool inDelay = false;
            foreach( Instruction instruction in instructions )
            {
                //lui $n, NNN
                //addiu $n, $n, NNN

                //lui $n, NNN
                //ori $n, $n, NNN

                //lui $n, NNN
                //l* $m, NNN($n)

                //lui $n, NNN
                //s* $m, NNN($n)

                bool wasInDelay = inDelay;
                inDelay = false;
                if( instruction.Opcode != null )
                {
                    if( instruction.IsBranch == true )
                    {
                        uint target = 0;
                        foreach( Operand op in instruction.Operands )
                        {
                            if( op.Type == OperandType.BranchTarget )
                            {
                                target = ( uint )( ( int )instruction.Address + 4 + op.Immediate );
                                break;
                            }
                        }
                        if( target > 0 )
                            this.AddLabelReference( labels, instruction, target );
                        inDelay = true;
                    }
                    else if( instruction.IsJump == true )
                    {
                        uint target = 0;
                        foreach( Operand op in instruction.Operands )
                        {
                            if( op.Type == OperandType.JumpTarget )
                            {
                                target = ( uint )op.Immediate;
                                break;
                            }
                        }
                        if( ( target >= this.Address ) && ( target < ( this.Address + this.Length ) ) )
                            this.AddLabelReference( labels, instruction, target );
                        else
                            this.AddCodeReference( codeRefs, instruction, target );
                        inDelay = true;
                    }
                    else if( instruction.IsLoad == true )
                    {
                        int reg1 = instruction.Operands[ 1 ].Register.Ordinal;
                        if( ( validRegisters & ( 1 << reg1 ) ) > 0 )
                        {
                            uint target = currentRegisters[ reg1 ];
                            target = ( uint )( ( int )target + instruction.Operands[ 1 ].Immediate );
                            this.AddMemoryReference( memRefs, instruction, target, true );
                        }
                    }
                    else if( instruction.IsStore == true )
                    {
                        int reg1 = instruction.Operands[ 1 ].Register.Ordinal;
                        if( ( validRegisters & ( 1 << reg1 ) ) > 0 )
                        {
                            uint target = currentRegisters[ reg1 ];
                            target = ( uint )( ( int )target + instruction.Operands[ 1 ].Immediate );
                            this.AddMemoryReference( memRefs, instruction, target, false );
                        }
                    }
                    if( ( foundSpMod == false ) && ( instruction.Opcode.InstructionEntry.Name == "addiu" ) )
                    {
                        foundSpMod = true;
                        int adjustment = instruction.Operands[ 2 ].Immediate / 4;
                        this.LocalsSize = -adjustment;
                    }
                    else
                    {
                        uint flags = instruction.Opcode.InstructionEntry.Flags;
                        if( instruction.Opcode.InstructionEntry.Name == "lui" )
                        {
                            int reg = instruction.Operands[ 0 ].Register.Ordinal;
                            validRegisters |= ( uint )( 1 << reg );
                            currentRegisters[ reg ] = ( uint )instruction.Operands[ 1 ].Immediate << 16;
                        }
                        else if( ( flags & InstructionTables.OUT_RT ) > 0 )
                        {
                            if( instruction.Opcode.InstructionEntry.Name == "addiu" )
                            {
                                int reg1 = instruction.Operands[ 1 ].Register.Ordinal;
                                if( ( validRegisters & ( 1 << reg1 ) ) > 0 )
                                {
                                    int reg2 = instruction.Operands[ 0 ].Register.Ordinal;
                                    validRegisters |= ( uint )( 1 << reg2 );
                                    currentRegisters[ reg2 ] = ( uint )( ( int )currentRegisters[ reg1 ] + instruction.Operands[ 2 ].Immediate );
                                }
                            }
                            else if( instruction.Opcode.InstructionEntry.Name == "ori" )
                            {
                                int reg1 = instruction.Operands[ 1 ].Register.Ordinal;
                                if( ( validRegisters & ( 1 << reg1 ) ) > 0 )
                                {
                                    int reg2 = instruction.Operands[ 0 ].Register.Ordinal;
                                    validRegisters |= ( uint )( 1 << reg2 );
                                    currentRegisters[ reg2 ] = currentRegisters[ reg1 ] | ( uint )instruction.Operands[ 2 ].Immediate;
                                }
                            }
                            else
                            {
                                // Changed - no longer valid
                                int reg = instruction.Operands[ 0 ].Register.Ordinal;
                                validRegisters &= ~( uint )( 1 << reg );
                            }
                        }
                    }
                }
                if( wasInDelay == true )
                    validRegisters = 0;
            }

            // Sort all
            this.SortAndSet( labels, codeRefs, memRefs );

            // Add labels to instructions
            foreach( Label label in this.Labels )
            {
                foreach( Instruction instruction in this.Instructions )
                {
                    if( label.Address == instruction.Address )
                    {
                        instruction.Label = label;
                        break;
                    }
                }
            }

            this.TotalLines = ( uint )( this.Instructions.Length + this.Labels.Length );
        }
Example #6
0
        public MethodBody( ModuleInfo moduleInfo, uint address, uint length, Instruction[] instructions )
        {
            this.Module = moduleInfo;
            this.Name = string.Format( "sub_{0:X8}", address );
            this.TotalLines = length / 4;

            this.Address = address;
            this.Length = length;

            this.IncomingReferences = new List<ExternalReference>();
            this.OutgoingReferences = new List<ExternalReference>();

            if( instructions != null )
                this.Populate( instructions );
        }