diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianInstructionLib/Arm/Library/ArmLibrary.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianInstructionLib/Arm/Library/ArmLibrary.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +using System; +using System.Collections.Generic; +using System.Text; +using SymbianUtils.Tracer; +using SymbianUtils.PluginManager; +using SymbianStructuresLib.Arm; +using SymbianStructuresLib.Arm.Disassembler; +using SymbianStructuresLib.Arm.Instructions; +using SymbianInstructionLib.Arm.Instructions.Arm; +using SymbianInstructionLib.Arm.Instructions.Thumb; +using SymbianInstructionLib.Arm.Instructions.Common; +using System.Reflection; + +namespace SymbianInstructionLib.Arm.Library +{ + public class ArmLibrary + { + #region Constructors + public ArmLibrary() + { + } + + static ArmLibrary() + { + // Load all the ARM instructions + Comparison armInstructionComparer = delegate( ArmInstruction aLeft, ArmInstruction aRight ) + { + // We sort in reverse order, hence right compared to left + return aRight.SortOrder.CompareTo( aLeft.SortOrder ); + }; + iArmInstructions = new PluginManager(); + iArmInstructions.LoadFromCallingAssembly(); + iArmInstructions.Sort( armInstructionComparer ); + + // Load all the THUMB instructions + Comparison thumbInstructionComparer = delegate( ThumbInstruction aLeft, ThumbInstruction aRight ) + { + // We sort in reverse order, hence right compared to left + return aRight.SortOrder.CompareTo( aLeft.SortOrder ); + }; + iThumbInstructions = new PluginManager(); + iThumbInstructions.LoadFromCallingAssembly(); + iThumbInstructions.Sort( thumbInstructionComparer ); + + // Load disassembler if present + iDisassembler = new PluginManager(); + iDisassembler.Load( null ); + } + #endregion + + #region API + public IArmInstruction[] ConvertToInstructions( TArmInstructionSet aInstructionSet, uint[] aRawInstructions, uint aStartingAddress ) + { + IArmInstruction[] ret = null; + // + switch ( aInstructionSet ) + { + case TArmInstructionSet.EARM: + ret = ConvertToArm( aRawInstructions, aStartingAddress ); + break; + case TArmInstructionSet.ETHUMB: + ret = ConvertToThumb( aRawInstructions, aStartingAddress ); + break; + default: + throw new NotSupportedException(); + } + // + return ret; + } + #endregion + + #region Properties + #endregion + + #region Internal methods + private void Disassemble( ArmBaseInstruction aInstruction ) + { + if ( iDisassembler.Count > 0 ) + { + IArmDisassembler disassembler = iDisassembler[ 0 ]; + string disassembly = disassembler.Disassemble( aInstruction ); + aInstruction.AIDisassembly = disassembly; + } + } + + private IArmInstruction[] ConvertToArm( uint[] aRawInstructions, uint aStartingAddress ) + { + // TODO: optimise this + List ret = new List(); + // + uint address = aStartingAddress; + for ( int i = 0; i < aRawInstructions.Length; i++, address += 4 ) + { + uint raw = aRawInstructions[ i ]; + foreach ( ArmInstruction inst in iArmInstructions ) + { + if ( inst.Matches( raw ) ) + { + Type type = inst.GetType(); + ConstructorInfo ctor = type.GetConstructor( new Type[] { } ); + ArmInstruction copy = (ArmInstruction) ctor.Invoke( new object[] { } ); + copy.AIAddress = address; + copy.AIRawValue = raw; + ret.Add( copy ); + Disassemble( copy ); + break; + } + } + } + // + return ret.ToArray(); + } + + private IArmInstruction[] ConvertToThumb( uint[] aRawInstructions, uint aStartingAddress ) + { + // TODO: optimise this + List ret = new List(); + // + uint address = aStartingAddress; + for ( int i = 0; i < aRawInstructions.Length; i++, address += 2 ) + { + uint raw = aRawInstructions[ i ]; + foreach ( ThumbInstruction inst in iThumbInstructions ) + { + if ( inst.Matches( raw ) ) + { + Type type = inst.GetType(); + ConstructorInfo ctor = type.GetConstructor( new Type[] { } ); + ThumbInstruction copy = (ThumbInstruction) ctor.Invoke( new object[] { } ); + copy.AIAddress = address; + copy.AIRawValue = raw; + ret.Add( copy ); + Disassemble( copy ); + break; + } + } + } + // + return ret.ToArray(); + } + #endregion + + #region Data members + private static readonly PluginManager iArmInstructions; + private static readonly PluginManager iThumbInstructions; + private static readonly PluginManager iDisassembler; + #endregion + } +}