From bc572f27be84beff821dc03945051ad678554be6 Mon Sep 17 00:00:00 2001 From: woojin Date: Fri, 19 Sep 2014 21:14:42 +0900 Subject: [PATCH] SOURCE LINK: support DWARF4 import and modify eclipse cdt edc plugin to support DWARF4 Change-Id: Ia855410047276871358b9157525c6bb41405fcae Signed-off-by: woojin --- org.eclipse.cdt.debug.edc/.classpath | 14 + org.eclipse.cdt.debug.edc/.project | 28 + .../.settings/org.eclipse.jdt.core.prefs | 8 + org.eclipse.cdt.debug.edc/META-INF/MANIFEST.MF | 28 + org.eclipse.cdt.debug.edc/build.properties | 11 + ...g.eclipse.cdt.debug.core_7.1.0.201109151620.jar | Bin 0 -> 515782 bytes ....debug.edc.tcf.extension_2.0.0.201109151658.jar | Bin 0 -> 60400 bytes .../lib/org.eclipse.cdt.dsf_2.2.0.201109151620.jar | Bin .../org.eclipse.cdt.launch_7.0.0.201109151620.jar | Bin 0 -> 224614 bytes ...rg.eclipse.cdt.scripting_1.0.0.201109151658.jar | Bin 0 -> 579714 bytes .../org.eclipse.tm.tcf.core_0.4.1.201109151255.jar | Bin 0 -> 489956 bytes org.eclipse.cdt.debug.edc/lib/truezip-6.jar | Bin 0 -> 486450 bytes .../cdt/debug/edc/IAddressExpressionEvaluator.java | 54 + .../org/eclipse/cdt/debug/edc/IEDCConstants.java | 20 + .../org/eclipse/cdt/debug/edc/IJumpToAddress.java | 47 + .../org/eclipse/cdt/debug/edc/IStreamBuffer.java | 116 + .../eclipse/cdt/debug/edc/ITCFAgentLauncher.java | 80 + .../cdt/debug/edc/ITCFConnectionListener.java | 35 + .../eclipse/cdt/debug/edc/ITCFServiceManager.java | 57 + .../org/eclipse/cdt/debug/edc/JumpToAddress.java | 141 + .../src/org/eclipse/cdt/debug/edc/MemoryUtils.java | 710 ++++ .../org/eclipse/cdt/debug/edc/MessageLogger.java | 221 ++ .../acpm/AbstractFormattedValuesRequestCache.java | 36 + .../edc/acpm/AbstractRegisterRequestCache.java | 33 + .../edc/acpm/AvailableFormatsRequestCache.java | 33 + .../eclipse/cdt/debug/edc/acpm/BaseRangeCache.java | 113 + .../cdt/debug/edc/acpm/BaseRequestCache.java | 112 + .../acpm/FormatedExpressionValueRequestCache.java | 30 + .../debug/edc/acpm/GetRegistersRequestCache.java | 24 + .../eclipse/cdt/debug/edc/acpm/ICacheEntry.java | 52 + .../cdt/debug/edc/acpm/MemoryRangeCache.java | 71 + .../debug/edc/acpm/RegisterGroupsRequestCache.java | 26 + .../edc/acpm/RegistersByNameRequestCache.java | 63 + .../edc/disassembler/AbstractDisassembler.java | 106 + .../debug/edc/disassembler/AssemblyFormatter.java | 176 + .../disassembler/CodeBufferUnderflowException.java | 28 + .../edc/disassembler/DisassembledInstruction.java | 95 + .../cdt/debug/edc/disassembler/EDCInstruction.java | 145 + .../disassembler/EDCInstructionFunctionInfo.java | 80 + .../edc/disassembler/EDCMixedInstruction.java | 69 + .../edc/disassembler/IDisassembledInstruction.java | 35 + .../cdt/debug/edc/disassembler/IDisassembler.java | 108 + .../formatter/AbstractCompositeFormatProvider.java | 189 ++ .../edc/formatter/AbstractStringFormatter.java | 116 + .../edc/formatter/AbstractVariableConverter.java | 66 + .../debug/edc/formatter/DefaultArrayFormatter.java | 104 + .../edc/formatter/DefaultCStringFormatter.java | 89 + .../edc/formatter/DefaultCompositeFormatter.java | 173 + .../debug/edc/formatter/EDCFormatterMessages.java | 25 + .../edc/formatter/EDCFormatterMessages.properties | 11 + .../cdt/debug/edc/formatter/FormatUtils.java | 486 +++ .../debug/edc/formatter/ITypeContentProvider.java | 43 + .../edc/formatter/IVariableFormatProvider.java | 39 + .../edc/formatter/IVariableValueConverter.java | 51 + .../debug/edc/internal/ByteBufferStreamBuffer.java | 67 + .../cdt/debug/edc/internal/EDCApplication.java | 50 + .../internal/EDCDebugPreferenceInitializer.java | 30 + .../cdt/debug/edc/internal/EDCDebugger.java | 249 ++ .../eclipse/cdt/debug/edc/internal/EDCTrace.java | 128 + .../edc/internal/ExecutablesSourceContainer.java | 61 + .../cdt/debug/edc/internal/FileStreamBuffer.java | 73 + .../org/eclipse/cdt/debug/edc/internal/HostOS.java | 72 + .../cdt/debug/edc/internal/IMemoryAccess.java | 51 + .../cdt/debug/edc/internal/MemoryStreamBuffer.java | 61 + .../cdt/debug/edc/internal/NumberFormatUtils.java | 221 ++ .../eclipse/cdt/debug/edc/internal/PathUtils.java | 273 ++ .../cdt/debug/edc/internal/PersistentCache.java | 213 ++ .../cdt/debug/edc/internal/StreamBufferBase.java | 251 ++ .../cdt/debug/edc/internal/TCFServiceManager.java | 618 ++++ .../cdt/debug/edc/internal/WaitForResult.java | 101 + .../cdt/debug/edc/internal/ZipFileUtils.java | 347 ++ .../internal/eval/ast/engine/ASTEvalMessages.java | 84 + .../eval/ast/engine/ASTEvalMessages.properties | 55 + .../eval/ast/engine/ASTEvaluationEngine.java | 171 + .../eval/ast/engine/ASTInstructionCompiler.java | 522 +++ .../engine/instructions/ArrayDimensionType.java | 64 + .../ast/engine/instructions/ArraySubscript.java | 227 ++ .../engine/instructions/BinaryLogicalOperator.java | 165 + .../ast/engine/instructions/BinaryOperator.java | 201 ++ .../engine/instructions/CompoundInstruction.java | 47 + .../eval/ast/engine/instructions/EvaluateID.java | 149 + .../ast/engine/instructions/FieldReference.java | 176 + .../eval/ast/engine/instructions/GetValue.java | 174 + .../engine/instructions/IArrayDimensionType.java | 26 + .../engine/instructions/IInvalidExpression.java | 25 + .../eval/ast/engine/instructions/Instruction.java | 521 +++ .../engine/instructions/InstructionSequence.java | 259 ++ .../eval/ast/engine/instructions/Interpreter.java | 161 + .../eval/ast/engine/instructions/NoOp.java | 39 + .../eval/ast/engine/instructions/OperandValue.java | 409 +++ .../ast/engine/instructions/OperatorAddrOf.java | 70 + .../ast/engine/instructions/OperatorBinaryAnd.java | 135 + .../ast/engine/instructions/OperatorBinaryOr.java | 135 + .../ast/engine/instructions/OperatorBinaryXor.java | 135 + .../engine/instructions/OperatorBitwiseNot.java | 138 + .../eval/ast/engine/instructions/OperatorCast.java | 125 + .../ast/engine/instructions/OperatorCastValue.java | 75 + .../ast/engine/instructions/OperatorDivide.java | 149 + .../ast/engine/instructions/OperatorEquals.java | 155 + .../engine/instructions/OperatorGreaterEqual.java | 155 + .../engine/instructions/OperatorGreaterThan.java | 153 + .../engine/instructions/OperatorIndirection.java | 115 + .../ast/engine/instructions/OperatorLessEqual.java | 154 + .../ast/engine/instructions/OperatorLessThan.java | 130 + .../engine/instructions/OperatorLogicalAnd.java | 154 + .../engine/instructions/OperatorLogicalNot.java | 126 + .../ast/engine/instructions/OperatorLogicalOr.java | 156 + .../ast/engine/instructions/OperatorMinus.java | 206 ++ .../ast/engine/instructions/OperatorModulo.java | 149 + .../ast/engine/instructions/OperatorMultiply.java | 136 + .../ast/engine/instructions/OperatorNotEquals.java | 155 + .../eval/ast/engine/instructions/OperatorPlus.java | 223 ++ .../ast/engine/instructions/OperatorShiftLeft.java | 118 + .../engine/instructions/OperatorShiftRight.java | 136 + .../engine/instructions/OperatorUnaryMinus.java | 138 + .../ast/engine/instructions/OperatorUnaryPlus.java | 137 + .../eval/ast/engine/instructions/PushBoolean.java | 50 + .../eval/ast/engine/instructions/PushChar.java | 170 + .../eval/ast/engine/instructions/PushDouble.java | 79 + .../eval/ast/engine/instructions/PushFloat.java | 63 + .../engine/instructions/PushLongOrBigInteger.java | 347 ++ .../eval/ast/engine/instructions/PushString.java | 67 + .../ast/engine/instructions/SimpleInstruction.java | 32 + .../engine/instructions/UnaryLogicalOperator.java | 166 + .../ast/engine/instructions/UnaryOperator.java | 172 + .../ast/engine/instructions/VariableWithValue.java | 108 + .../internal/formatter/FormatExtensionManager.java | 203 ++ .../internal/formatter/IVariableFormatManager.java | 30 + .../formatter/IVariableFormatProviderChooser.java | 27 + .../debug/edc/internal/launch/CSourceLookup.java | 166 + .../internal/launch/ServicesLaunchSequence.java | 192 ++ .../edc/internal/launch/ShutdownSequence.java | 180 + .../debug/edc/internal/launch/SnapshotLaunch.java | 14 + .../internal/launch/SnapshotLaunchDelegate.java | 149 + .../dsf/BreakpointAttributeTranslator.java | 459 +++ .../edc/internal/services/dsf/Breakpoints.java | 1207 +++++++ .../internal/services/dsf/EDCServicesMessages.java | 41 + .../services/dsf/EDCServicesMessages.properties | 18 + .../edc/internal/services/dsf/Expressions.java | 1428 ++++++++ .../cdt/debug/edc/internal/services/dsf/INoop.java | 36 + .../edc/internal/services/dsf/LineEntryMapper.java | 144 + .../debug/edc/internal/services/dsf/Memory.java | 471 +++ .../edc/internal/services/dsf/MemoryCache.java | 836 +++++ .../debug/edc/internal/services/dsf/Modules.java | 1188 +++++++ .../cdt/debug/edc/internal/services/dsf/Noop.java | 64 + .../debug/edc/internal/services/dsf/Processes.java | 303 ++ .../edc/internal/services/dsf/RunControl.java | 2761 ++++++++++++++++ .../debug/edc/internal/services/dsf/Signals.java | 24 + .../debug/edc/internal/services/dsf/Snapshots.java | 50 + .../debug/edc/internal/services/dsf/Symbols.java | 307 ++ .../cdt/debug/edc/internal/snapshot/Album.java | 1325 ++++++++ .../internal/snapshot/AlbumSourceContainer.java | 45 + .../snapshot/AlbumSourceContainerType.java | 28 + .../snapshot/ISnapshotAlbumEventListener.java | 25 + .../cdt/debug/edc/internal/snapshot/Snapshot.java | 305 ++ .../internal/snapshot/SnapshotLaunchSequence.java | 68 + .../debug/edc/internal/snapshot/SnapshotUtils.java | 649 ++++ .../debug/edc/internal/symbols/ArrayBoundType.java | 69 + .../cdt/debug/edc/internal/symbols/ArrayType.java | 78 + .../debug/edc/internal/symbols/CPPBasicType.java | 112 + .../cdt/debug/edc/internal/symbols/ClassType.java | 22 + .../edc/internal/symbols/CompileUnitScope.java | 96 + .../debug/edc/internal/symbols/CompositeType.java | 399 +++ .../cdt/debug/edc/internal/symbols/ConstType.java | 34 + .../internal/symbols/EDCSourceFilesProvider.java | 40 + .../debug/edc/internal/symbols/Enumeration.java | 59 + .../cdt/debug/edc/internal/symbols/Enumerator.java | 38 + .../cdt/debug/edc/internal/symbols/FieldType.java | 82 + .../internal/symbols/FileLineEntryProvider.java | 737 +++++ .../debug/edc/internal/symbols/FunctionScope.java | 197 ++ .../cdt/debug/edc/internal/symbols/IAggregate.java | 14 + .../edc/internal/symbols/IArrayBoundType.java | 36 + .../cdt/debug/edc/internal/symbols/IArrayType.java | 36 + .../cdt/debug/edc/internal/symbols/IBasicType.java | 50 + .../debug/edc/internal/symbols/ICPPBasicType.java | 38 + .../debug/edc/internal/symbols/ICompositeType.java | 117 + .../cdt/debug/edc/internal/symbols/IConstType.java | 21 + .../debug/edc/internal/symbols/IEnumeration.java | 31 + .../cdt/debug/edc/internal/symbols/IField.java | 39 + .../internal/symbols/IForwardTypeReference.java | 29 + .../debug/edc/internal/symbols/IInheritance.java | 57 + .../edc/internal/symbols/ILexicalBlockScope.java | 32 + .../edc/internal/symbols/IMayBeQualifedType.java | 31 + .../debug/edc/internal/symbols/IPointerType.java | 20 + .../debug/edc/internal/symbols/IQualifierType.java | 23 + .../debug/edc/internal/symbols/IReferenceType.java | 17 + .../edc/internal/symbols/IRuntimeSection.java | 34 + .../cdt/debug/edc/internal/symbols/ISection.java | 71 + .../edc/internal/symbols/ISubroutineType.java | 20 + .../debug/edc/internal/symbols/ITemplateParam.java | 17 + .../cdt/debug/edc/internal/symbols/ITypedef.java | 28 + .../edc/internal/symbols/InheritanceType.java | 49 + .../internal/symbols/InvalidVariableLocation.java | 93 + .../edc/internal/symbols/LexicalBlockScope.java | 44 + .../cdt/debug/edc/internal/symbols/LineEntry.java | 83 + .../edc/internal/symbols/MayBeQualifiedType.java | 52 + .../internal/symbols/MemoryVariableLocation.java | 217 ++ .../internal/symbols/ModuleLineEntryProvider.java | 434 +++ .../debug/edc/internal/symbols/PointerType.java | 28 + .../debug/edc/internal/symbols/ReferenceType.java | 22 + .../symbols/RegisterOffsetVariableLocation.java | 89 + .../internal/symbols/RegisterVariableLocation.java | 103 + .../debug/edc/internal/symbols/RuntimeSection.java | 79 + .../cdt/debug/edc/internal/symbols/Scope.java | 340 ++ .../cdt/debug/edc/internal/symbols/Section.java | 74 + .../cdt/debug/edc/internal/symbols/StructType.java | 23 + .../debug/edc/internal/symbols/SubroutineType.java | 28 + .../cdt/debug/edc/internal/symbols/Symbol.java | 56 + .../edc/internal/symbols/SymbolsMessages.java | 42 + .../internal/symbols/SymbolsMessages.properties | 23 + .../edc/internal/symbols/TemplateParamType.java | 72 + .../cdt/debug/edc/internal/symbols/Type.java | 89 + .../debug/edc/internal/symbols/TypedefType.java | 35 + .../cdt/debug/edc/internal/symbols/UnionType.java | 23 + .../internal/symbols/ValueVariableLocation.java | 81 + .../cdt/debug/edc/internal/symbols/Variable.java | 120 + .../debug/edc/internal/symbols/VolatileType.java | 33 + .../internal/symbols/dwarf/DwarfCompileUnit.java | 291 ++ .../edc/internal/symbols/dwarf/DwarfConstants.java | 636 ++++ .../symbols/dwarf/DwarfDebugInfoProvider.java | 1459 +++++++++ .../dwarf/DwarfDebugInfoProviderFactory.java | 56 + .../internal/symbols/dwarf/DwarfFileHelper.java | 176 + .../symbols/dwarf/DwarfFrameRegisterProvider.java | 950 ++++++ .../symbols/dwarf/DwarfFrameRegisters.java | 191 ++ .../internal/symbols/dwarf/DwarfFunctionScope.java | 54 + .../internal/symbols/dwarf/DwarfInfoReader.java | 3451 ++++++++++++++++++++ .../edc/internal/symbols/dwarf/DwarfMessages.java | 107 + .../symbols/dwarf/DwarfMessages.properties | 58 + .../internal/symbols/dwarf/DwarfModuleScope.java | 268 ++ .../edc/internal/symbols/dwarf/DwarfVariable.java | 27 + .../internal/symbols/dwarf/EDCSymbolReader.java | 175 + .../edc/internal/symbols/dwarf/LocationEntry.java | 58 + .../internal/symbols/dwarf/LocationExpression.java | 323 ++ .../edc/internal/symbols/dwarf/LocationList.java | 101 + .../edc/internal/symbols/dwarf/RangeList.java | 132 + .../symbols/elf/BufferedRandomReadAccessFile.java | 388 +++ .../internal/symbols/elf/ERandomAccessFile.java | 150 + .../cdt/debug/edc/internal/symbols/elf/Elf.java | 1231 +++++++ .../symbols/elf/IRandomReadAccessFile.java | 110 + .../cdt/debug/edc/internal/symbols/elf/README.txt | 6 + .../files/BaseExecutableSymbolicsReader.java | 205 ++ .../symbols/files/DebugInfoProviderFactory.java | 71 + .../files/ElfExecutableSymbolicsReader.java | 159 + .../files/ElfExecutableSymbolicsReaderFactory.java | 98 + .../internal/symbols/files/ExecutableSection.java | 81 + .../files/ExecutableSymbolicsReaderFactory.java | 132 + .../edc/internal/symbols/files/FileStatistics.java | 64 + .../edc/internal/symbols/files/ISectionMapper.java | 48 + .../files/PEFileExecutableSymbolicsReader.java | 276 ++ .../PEFileExecutableSymbolicsReaderFactory.java | 56 + .../edc/internal/symbols/files/SectionInfo.java | 66 + .../edc/internal/symbols/files/SectionMapper.java | 189 ++ .../edc/internal/symbols/files/UnmanglerEABI.java | 1824 +++++++++++ .../edc/internal/symbols/files/UnmanglerWin32.java | 83 + .../internal/symbols/files/UnmanglerWin32EABI.java | 29 + .../symbols/files/UnmanglingException.java | 42 + .../edc/launch/AbstractFinalLaunchSequence.java | 943 ++++++ .../cdt/debug/edc/launch/AgentSettings.java | 90 + .../cdt/debug/edc/launch/ChooseProcessItem.java | 24 + .../cdt/debug/edc/launch/DebugServicesFactory.java | 154 + .../eclipse/cdt/debug/edc/launch/EDCLaunch.java | 775 +++++ .../cdt/debug/edc/launch/EDCLaunchDelegate.java | 361 ++ .../cdt/debug/edc/launch/ICacheManager.java | 103 + .../launch/IEDCLaunchConfigurationConstants.java | 34 + .../cdt/debug/edc/launch/LaunchMessages.java | 46 + .../cdt/debug/edc/launch/LaunchMessages.properties | 22 + .../eclipse/cdt/debug/edc/launch/LaunchUtils.java | 176 + .../cdt/debug/edc/services/AbstractEDCService.java | 224 ++ .../edc/services/AbstractTargetEnvironment.java | 80 + .../eclipse/cdt/debug/edc/services/DMContext.java | 146 + .../cdt/debug/edc/services/Disassembly.java | 569 ++++ .../cdt/debug/edc/services/EDCServicesTracker.java | 242 ++ .../debug/edc/services/IDSFServiceUsingTCF.java | 32 + .../cdt/debug/edc/services/IEDCDMContext.java | 49 + .../cdt/debug/edc/services/IEDCExecutionDMC.java | 33 + .../cdt/debug/edc/services/IEDCExpression.java | 75 + .../cdt/debug/edc/services/IEDCExpressions.java | 22 + .../eclipse/cdt/debug/edc/services/IEDCMemory.java | 39 + .../debug/edc/services/IEDCModuleDMContext.java | 42 + .../cdt/debug/edc/services/IEDCModules.java | 29 + .../cdt/debug/edc/services/IEDCService.java | 20 + .../cdt/debug/edc/services/IEDCSymbols.java | 84 + .../debug/edc/services/IFrameRegisterProvider.java | 35 + .../cdt/debug/edc/services/IFrameRegisters.java | 42 + .../eclipse/cdt/debug/edc/services/ISnapshots.java | 17 + .../cdt/debug/edc/services/ITargetEnvironment.java | 201 ++ .../eclipse/cdt/debug/edc/services/Messages.java | 21 + .../eclipse/cdt/debug/edc/services/Registers.java | 1237 +++++++ .../org/eclipse/cdt/debug/edc/services/Stack.java | 1639 ++++++++++ .../cdt/debug/edc/services/messages.properties | 4 + .../org/eclipse/cdt/debug/edc/snapshot/IAlbum.java | 87 + .../debug/edc/snapshot/ISnapshotContributor.java | 44 + .../cdt/debug/edc/symbols/ICompileUnitScope.java | 57 + .../cdt/debug/edc/symbols/IDebugInfoProvider.java | 108 + .../edc/symbols/IDebugInfoProviderFactory.java | 37 + .../cdt/debug/edc/symbols/IEDCSymbolReader.java | 46 + .../eclipse/cdt/debug/edc/symbols/IEnumerator.java | 32 + .../cdt/debug/edc/symbols/IExecutableSection.java | 35 + .../edc/symbols/IExecutableSymbolicsReader.java | 115 + .../symbols/IExecutableSymbolicsReaderFactory.java | 60 + .../cdt/debug/edc/symbols/IFunctionScope.java | 79 + .../edc/symbols/IInvalidVariableLocation.java | 34 + .../eclipse/cdt/debug/edc/symbols/ILineEntry.java | 61 + .../cdt/debug/edc/symbols/ILineEntryProvider.java | 137 + .../cdt/debug/edc/symbols/ILocationProvider.java | 57 + .../debug/edc/symbols/IMemoryVariableLocation.java | 23 + .../edc/symbols/IModuleLineEntryProvider.java | 43 + .../cdt/debug/edc/symbols/IModuleScope.java | 94 + .../eclipse/cdt/debug/edc/symbols/IRangeList.java | 99 + .../symbols/IRegisterOffsetVariableLocation.java | 28 + .../edc/symbols/IRegisterVariableLocation.java | 35 + .../org/eclipse/cdt/debug/edc/symbols/IScope.java | 97 + .../org/eclipse/cdt/debug/edc/symbols/ISymbol.java | 41 + .../debug/edc/symbols/ISymbolReaderFactory.java | 30 + .../org/eclipse/cdt/debug/edc/symbols/IType.java | 66 + .../eclipse/cdt/debug/edc/symbols/IUnmangler.java | 62 + .../debug/edc/symbols/IValueVariableLocation.java | 19 + .../eclipse/cdt/debug/edc/symbols/IVariable.java | 83 + .../cdt/debug/edc/symbols/IVariableLocation.java | 74 + .../cdt/debug/edc/symbols/SymbolsMessages.java | 32 + .../debug/edc/symbols/SymbolsMessages.properties | 16 + .../eclipse/cdt/debug/edc/symbols/TypeEngine.java | 554 ++++ .../eclipse/cdt/debug/edc/symbols/TypeUtils.java | 307 ++ .../debug/edc/symbols/VariableLocationFactory.java | 89 + org.tizen.dynamicanalyzer/.classpath | 3 - org.tizen.dynamicanalyzer/META-INF/MANIFEST.MF | 7 +- .../org.eclipse.cdt.core_5.3.1.201109151620.jar | Bin 4524396 -> 0 bytes ...rg.eclipse.cdt.debug.edc_2.0.0.201109151658.jar | Bin 1643561 -> 0 bytes 328 files changed, 57664 insertions(+), 7 deletions(-) create mode 100644 org.eclipse.cdt.debug.edc/.classpath create mode 100644 org.eclipse.cdt.debug.edc/.project create mode 100644 org.eclipse.cdt.debug.edc/.settings/org.eclipse.jdt.core.prefs create mode 100644 org.eclipse.cdt.debug.edc/META-INF/MANIFEST.MF create mode 100644 org.eclipse.cdt.debug.edc/build.properties create mode 100644 org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.debug.core_7.1.0.201109151620.jar create mode 100644 org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.debug.edc.tcf.extension_2.0.0.201109151658.jar rename {org.tizen.dynamicanalyzer => org.eclipse.cdt.debug.edc}/lib/org.eclipse.cdt.dsf_2.2.0.201109151620.jar (100%) create mode 100644 org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.launch_7.0.0.201109151620.jar create mode 100644 org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.scripting_1.0.0.201109151658.jar create mode 100644 org.eclipse.cdt.debug.edc/lib/org.eclipse.tm.tcf.core_0.4.1.201109151255.jar create mode 100644 org.eclipse.cdt.debug.edc/lib/truezip-6.jar create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IAddressExpressionEvaluator.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IEDCConstants.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IJumpToAddress.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IStreamBuffer.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFAgentLauncher.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFConnectionListener.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFServiceManager.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/JumpToAddress.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/MemoryUtils.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/MessageLogger.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AbstractFormattedValuesRequestCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AbstractRegisterRequestCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AvailableFormatsRequestCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/BaseRangeCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/BaseRequestCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/FormatedExpressionValueRequestCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/GetRegistersRequestCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/ICacheEntry.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/MemoryRangeCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/RegisterGroupsRequestCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/RegistersByNameRequestCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/AbstractDisassembler.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/AssemblyFormatter.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/CodeBufferUnderflowException.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/DisassembledInstruction.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCInstruction.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCInstructionFunctionInfo.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCMixedInstruction.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/IDisassembledInstruction.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/IDisassembler.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractCompositeFormatProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractStringFormatter.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractVariableConverter.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultArrayFormatter.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultCStringFormatter.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultCompositeFormatter.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/EDCFormatterMessages.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/EDCFormatterMessages.properties create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/FormatUtils.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/ITypeContentProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/IVariableFormatProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/IVariableValueConverter.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ByteBufferStreamBuffer.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCApplication.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCDebugPreferenceInitializer.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCDebugger.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCTrace.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ExecutablesSourceContainer.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/FileStreamBuffer.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/HostOS.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/IMemoryAccess.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/MemoryStreamBuffer.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/NumberFormatUtils.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/PathUtils.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/PersistentCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/StreamBufferBase.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/TCFServiceManager.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/WaitForResult.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ZipFileUtils.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvalMessages.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvalMessages.properties create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvaluationEngine.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTInstructionCompiler.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/ArrayDimensionType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/ArraySubscript.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/BinaryLogicalOperator.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/BinaryOperator.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/CompoundInstruction.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/EvaluateID.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/FieldReference.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/GetValue.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/IArrayDimensionType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/IInvalidExpression.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/Instruction.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/InstructionSequence.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/Interpreter.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/NoOp.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperandValue.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorAddrOf.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryAnd.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryOr.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryXor.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBitwiseNot.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorCast.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorCastValue.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorDivide.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorEquals.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorGreaterEqual.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorGreaterThan.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorIndirection.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLessEqual.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLessThan.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalAnd.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalNot.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalOr.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorMinus.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorModulo.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorMultiply.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorNotEquals.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorPlus.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorShiftLeft.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorShiftRight.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorUnaryMinus.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorUnaryPlus.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushBoolean.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushChar.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushDouble.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushFloat.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushLongOrBigInteger.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushString.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/SimpleInstruction.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/UnaryLogicalOperator.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/UnaryOperator.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/VariableWithValue.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/FormatExtensionManager.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/IVariableFormatManager.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/IVariableFormatProviderChooser.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/CSourceLookup.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/ServicesLaunchSequence.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/ShutdownSequence.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/SnapshotLaunch.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/SnapshotLaunchDelegate.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/BreakpointAttributeTranslator.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Breakpoints.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/EDCServicesMessages.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/EDCServicesMessages.properties create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Expressions.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/INoop.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/LineEntryMapper.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Memory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/MemoryCache.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Modules.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Noop.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Processes.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/RunControl.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Signals.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Snapshots.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Symbols.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/Album.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/AlbumSourceContainer.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/AlbumSourceContainerType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/ISnapshotAlbumEventListener.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/Snapshot.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/SnapshotLaunchSequence.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/SnapshotUtils.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ArrayBoundType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ArrayType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CPPBasicType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ClassType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CompileUnitScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CompositeType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ConstType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/EDCSourceFilesProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Enumeration.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Enumerator.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FieldType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FileLineEntryProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FunctionScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IAggregate.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IArrayBoundType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IArrayType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IBasicType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ICPPBasicType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ICompositeType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IConstType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IEnumeration.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IField.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IForwardTypeReference.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IInheritance.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ILexicalBlockScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IMayBeQualifedType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IPointerType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IQualifierType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IReferenceType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IRuntimeSection.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ISection.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ISubroutineType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ITemplateParam.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ITypedef.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/InheritanceType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/InvalidVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/LexicalBlockScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/LineEntry.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/MayBeQualifiedType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/MemoryVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ModuleLineEntryProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/PointerType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ReferenceType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RegisterOffsetVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RegisterVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RuntimeSection.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Scope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Section.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/StructType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SubroutineType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Symbol.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SymbolsMessages.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SymbolsMessages.properties create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/TemplateParamType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Type.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/TypedefType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/UnionType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ValueVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Variable.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/VolatileType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfCompileUnit.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfConstants.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfDebugInfoProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfDebugInfoProviderFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFileHelper.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFrameRegisterProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFrameRegisters.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFunctionScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfInfoReader.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfMessages.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfMessages.properties create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfModuleScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfVariable.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/EDCSymbolReader.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationEntry.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationExpression.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationList.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/RangeList.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/BufferedRandomReadAccessFile.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/ERandomAccessFile.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/Elf.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/IRandomReadAccessFile.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/README.txt create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/BaseExecutableSymbolicsReader.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/DebugInfoProviderFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ElfExecutableSymbolicsReader.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ElfExecutableSymbolicsReaderFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ExecutableSection.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ExecutableSymbolicsReaderFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/FileStatistics.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ISectionMapper.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/PEFileExecutableSymbolicsReader.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/PEFileExecutableSymbolicsReaderFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/SectionInfo.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/SectionMapper.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/UnmanglerEABI.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/UnmanglerWin32.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/UnmanglerWin32EABI.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/UnmanglingException.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/AbstractFinalLaunchSequence.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/AgentSettings.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/ChooseProcessItem.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/DebugServicesFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/EDCLaunch.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/EDCLaunchDelegate.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/ICacheManager.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/IEDCLaunchConfigurationConstants.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/LaunchMessages.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/LaunchMessages.properties create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/launch/LaunchUtils.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/AbstractEDCService.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/AbstractTargetEnvironment.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/DMContext.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/Disassembly.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/EDCServicesTracker.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IDSFServiceUsingTCF.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCDMContext.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCExecutionDMC.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCExpression.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCExpressions.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCMemory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCModuleDMContext.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCModules.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCService.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IEDCSymbols.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IFrameRegisterProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/IFrameRegisters.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/ISnapshots.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/ITargetEnvironment.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/Messages.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/Registers.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/Stack.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/services/messages.properties create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/snapshot/IAlbum.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/snapshot/ISnapshotContributor.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/ICompileUnitScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IDebugInfoProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IDebugInfoProviderFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IEDCSymbolReader.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IEnumerator.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IExecutableSection.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IExecutableSymbolicsReader.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IExecutableSymbolicsReaderFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IFunctionScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IInvalidVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/ILineEntry.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/ILineEntryProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/ILocationProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IMemoryVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IModuleLineEntryProvider.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IModuleScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IRangeList.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IRegisterOffsetVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IRegisterVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IScope.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/ISymbol.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/ISymbolReaderFactory.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IType.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IUnmangler.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IValueVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IVariable.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/IVariableLocation.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/SymbolsMessages.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/SymbolsMessages.properties create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/TypeEngine.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/TypeUtils.java create mode 100644 org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/symbols/VariableLocationFactory.java delete mode 100644 org.tizen.dynamicanalyzer/lib/org.eclipse.cdt.core_5.3.1.201109151620.jar delete mode 100644 org.tizen.dynamicanalyzer/lib/org.eclipse.cdt.debug.edc_2.0.0.201109151658.jar diff --git a/org.eclipse.cdt.debug.edc/.classpath b/org.eclipse.cdt.debug.edc/.classpath new file mode 100644 index 0000000..16f53cb --- /dev/null +++ b/org.eclipse.cdt.debug.edc/.classpath @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/org.eclipse.cdt.debug.edc/.project b/org.eclipse.cdt.debug.edc/.project new file mode 100644 index 0000000..3f52031 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/.project @@ -0,0 +1,28 @@ + + + org.eclipse.cdt.debug.edc + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.eclipse.cdt.debug.edc/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.cdt.debug.edc/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..dc7828d --- /dev/null +++ b/org.eclipse.cdt.debug.edc/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Fri Sep 19 19:14:41 KST 2014 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/org.eclipse.cdt.debug.edc/META-INF/MANIFEST.MF b/org.eclipse.cdt.debug.edc/META-INF/MANIFEST.MF new file mode 100644 index 0000000..8007ddc --- /dev/null +++ b/org.eclipse.cdt.debug.edc/META-INF/MANIFEST.MF @@ -0,0 +1,28 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Edc +Bundle-SymbolicName: org.eclipse.cdt.debug.edc +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Require-Bundle: org.eclipse.core.jobs;bundle-version="3.5.100", + org.eclipse.equinox.common;bundle-version="3.6.0", + org.eclipse.core.resources;bundle-version="3.7.100", + org.eclipse.equinox.preferences;bundle-version="3.4.1", + org.eclipse.osgi;bundle-version="3.7.1", + org.eclipse.debug.core;bundle-version="3.7.0", + org.eclipse.core.runtime;bundle-version="3.7.0", + org.apache.commons.codec;bundle-version="1.3.0", + org.eclipse.core.variables;bundle-version="3.2.500", + org.eclipse.cdt.core;bundle-version="5.3.2" +Export-Package: org.eclipse.cdt.debug.edc.internal.symbols, + org.eclipse.cdt.debug.edc.internal.symbols.dwarf, + org.eclipse.cdt.debug.edc.internal.symbols.files, + org.eclipse.cdt.debug.edc.symbols +Bundle-ClassPath: ., + lib/org.eclipse.cdt.debug.core_7.1.0.201109151620.jar, + lib/org.eclipse.cdt.debug.edc.tcf.extension_2.0.0.201109151658.jar, + lib/org.eclipse.cdt.dsf_2.2.0.201109151620.jar, + lib/org.eclipse.cdt.launch_7.0.0.201109151620.jar, + lib/org.eclipse.cdt.scripting_1.0.0.201109151658.jar, + lib/org.eclipse.tm.tcf.core_0.4.1.201109151255.jar, + lib/truezip-6.jar diff --git a/org.eclipse.cdt.debug.edc/build.properties b/org.eclipse.cdt.debug.edc/build.properties new file mode 100644 index 0000000..c34e114 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/build.properties @@ -0,0 +1,11 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + lib/org.eclipse.cdt.debug.core_7.1.0.201109151620.jar,\ + lib/org.eclipse.cdt.debug.edc.tcf.extension_2.0.0.201109151658.jar,\ + lib/org.eclipse.cdt.dsf_2.2.0.201109151620.jar,\ + lib/org.eclipse.cdt.launch_7.0.0.201109151620.jar,\ + lib/org.eclipse.cdt.scripting_1.0.0.201109151658.jar,\ + lib/org.eclipse.tm.tcf.core_0.4.1.201109151255.jar,\ + lib/truezip-6.jar diff --git a/org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.debug.core_7.1.0.201109151620.jar b/org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.debug.core_7.1.0.201109151620.jar new file mode 100644 index 0000000000000000000000000000000000000000..1d61b19accd062760c77d165f13df8d9256d237a GIT binary patch literal 515782 zcmV)JK)b(CO9KQH00;mG0MThLKL7v#000000000002BZO08K?yK`lv6MlVf4PDw^Z zQ&cWZM*hkG0Ij`QlcMa>HhR7y)_+*B;`t7C_&%*5h^{Z*111p!We^4T!477Sc^-cK z)|$Gi8!WNcK}T1WLvl}X9OZRN$^M=Q&{IQq}OfFHAe{sSu`GqC<2l_Gl@y~z!Yxe*A`+q)v_|rq*`QR^~x_-~gBlmv{zJ1_-7QcV& z?Mch1@WPkRUBBl+iLW2Ey}-)bys*NrQm@~0{WNg<@V`H%`eTzIKd#&42RH+O*$RMx z1$f;vWRt{M@i(s-zUJIr%m2BvPFJ~lW@&yBdr_eow|$l0d%t0Ny)R$C=jS_qSk-k? ze)Bay!q~KeU*B|Fm%jJ?DB9%iK#VvHwa9#b%k_Ku-er2ZmgiQe2kpHtvtG`arU$ou za(6y@2l3k*ek9lL$>PepEvFXz-{x;S^Q_3s|MS29{_V55J@9?ybuO;oV})_n{s>?G z)3dnFt?c&?7Off{hr$*eYbOZXa4hC^w0BkLN0~&x?}(SYC_Dv8PmU+r>hqH|3KhZ^?%*R{LPMB z%}k(m?I)ELnK#q$f0EmFH?8buXg*$jwL1Uj)v~?5f@X&6U3K73Wyc3rQ|AAAf8n41 zz_06GSmujOLlez#t$%UaRm1%AA9VOt2VRxH4^O}TGs+)@)f69sxi`D}Aq4#AKmPfT z4(1jydOqzRUrTThqOU~zX{K|e&>Jwb>d90ff;iN zfc1iy3Vye@w#NEup4I<-NX}KweaIr{L#7$li?qLJ^hG7VNWH0|Uj(;hrlzdV28?%- zBL%1~$4Qxm;fjgJ3cl&r7wM?uWR`QC@Wb^lLxL4`y;YX(DPSTBtaf@MAvq6K(wyeL z75u)zU!Q<}`|SfSa8{mQ7c>9yqQrln?0Uw{FSX}1=ks2zw^rOuTPA}V@lZcA+3PZT znc`oTxM$3)c%}>6x~x27DWr%9Y2X3H*=-}t9uxd3H2G-tV07;4jK5KD{-+VX5mg^=?KE?ba8)Ru~eP68L5b+uMp>p0)>a^qzRx zj9TVc1s+GX=akvY!JiK;jj>^qi2<-_4I(Vxh;-<=PF}Enkv}Gyeus^pr1cJRvshG< zsW3x{19V(nsu(&+QWP+y06iw@lUkqB(u z-N|irt4>Zc%pbY&U#A#grUD3D`A8-lLXM0Oa z1Tr7{7@r})6pzEi3tpz3xMKC2F)ePJ?&Uq#RVg$tva;SMg1w8rb^~o+8vG(Zw{Yoq zi&GpRjPdxkyKOk~h8=&N#*Np%%|S2m&lV#G3mD%z8`E8As@eI}#{Pbr_bvn##JYBW z)+du(lEAOdXNpv6A^PA4H>KTzRvpV{IV~<5#9?lyUly=Gjtv0PuP1qURiTY(oW|~Ce2Ob2sRcGhzr6^EL(q2;WN*IZz^Rp(1e|$Ic8d0wn30N*wBc&IWXovmj{dArrQ+&|X_@)1 zS8wX<7uEXfgOK7Wn-u%jZL2mu1H50s;CxBL^l`+tesMd0Dv@46nH{Y`4fjy}q8e_O zrH;?qC$-Rs2L=7+E>C|dt5>vk1)DeX=nTv`)h%?gE{>{i1Zy7N%yu=&hg`@S%aL=A zi80>(-g$ME-C`}ea&-|XQhV|X*$w_(5di9OP1Cz#SyV8!ef{DS1c<$Q6hIG{O0 z&nqxA%d~b_nV6_@#Lg^Vx-*ke@rBv)qPqydj{aU-_o}ZKQETmG)PDiJGF56DY+`jK zA2lr?F>Ajyv1qk~gXDWK{#E8D=l;`y;{rVU*^^{v#aCrzO22%w#O}`V9kbKi5?d#M~<2umZ>F(;~W4QAKbHGY(@-wO4~h} zkf1OZc8%5^N=&cmXHM$yUSX9M7kx+FFYN=Cm#xffB{B;5rS`p`dr0QGUYF}Jc{?LF zmGC;B1KS5+T6L35wdG0oit?lZ#0g0p31apS!ua>G{sJ0%h3zL`eL$j?U*g0pwq<3L z(ilk`HtJZt`*uFwweLG>e*up-%|C=6r=e)-ya?AW&Zd60bRtoonk)~cBV5;4C}U_t z0FhjEIs!o)c?f{(XMflBsqATVsDLDDC+92c8qV7*z;{&SCl z>3XJm=R}qnKjly%$5>l|Rnr-3uzzmRcauHu6?q^7egg=hU*fV^l67cghBp<7&7;Qa z?O=#jUWOK0u-8@V6_j6^x#|fgW=or}%3!f`3M53>`q^lR|4EI0a}qr zK@A#PlZ)MXL7YeWFz>;ewHJB0JK)7EtJQYO>nPlAk*n`yoX*lNi@ubo1 zYziyNZ|Zcw8s~V%Az&Va4xEJ3+_o4^aOO#Y6VIvhtM^o7SFnTMao1KrQ64Y^zQ}W= za72rWq5~`zc{?J;@$;~7-qkt$1fd5&hvsY|`V>a{9W`eu*RZ3`Sb8w{;O_mR2~J+& z#%1y9`}arI)`FkofgoyKS^47b055j?DOeesCj(rc7WZvUuOod)8}&d~MKh{Rn;#hk zHbG}eplL}Xh*<6(v|YbU@XwGb85!3W9(W{o)J*bgB zyT3mVQhv{@EY50$xPZ;nEYO5*4=|=N zgT&O2m+PH=3jb?y;h|toWC0q-xAS$V6hKl4h~D5FG3i?5K~(!GYkPCVK7P635v#d5 z36*EwGHv}MC-P}*pe{!`|RMK zCy)*X>WBpD~EInHi2oyIfW|HZU>E>Bz!Aio@4`R#vJNPen=;(xV z3W(+ikIxtq&Fp1EHJGwq=xhDK7*>zry8&t^y8-HVRoo*uUVsN=1J zxqg~&9^BBsM{?falJQEfxs5*?GJn@;K1q`XMG$3e5kg{BEw~&3o__9T$<;E;WIa98vi5bc!#h?VV=qXi zTC~GT-esct!J%oQgW&Jf(Hi<=wU4o94u^5lodHc!l-#UcQIEWgJ_URZGTYPBQH?th z{yn?R9V|!*5BH_{iURqQ>eN_A%TK}K8|?lD3$Ic{FqDI)qR6^7w_ckbVFmza`0_#J z_^vA6yr!!%G_E^HDwA7kyjNr`YtdTA1B-m+R;T*7*LDWj*VDQiip@aC_&FoCD2WAV7))Aj|^57v|8rsaaO4FijbQUi< z@?g$(6%4i7f5Aik_{(+3*FPrx7I!{dZPpsGI)|WWZuC~bLR6$PYVp*be)D7Bf}bDT z?Dhn`;-fu)5Ie%Nlta0Ip)KY(x<5H$)a>&%$y39nOfqrm$m-YB5M> zoOyDT2WGlY;wOyr;rtE7m(KW_nz91vP$hLbMH-ZZODnE`%6^b&^S;8bL7)Ed1&7nI zopsH$%#cOH1JGm{noH-zjOLeoNj(m`m8EkCT4ITw$;GVOa{D+_4|8lnVB~{A>@N|! z&&lM^SfUS^6OLX+b_y4SAzji0Z=80TT1r!5<09Ih*6_vA>m8;5RrE>T)7-h;gJ;%p z>{g@!YI`_+zj(b{^^O-SOT^McVCD#s9G0$Y56`Bn%=FLF*x&B6& zZaVnaTx(Y__#U6$S$O)5qp^#Nb^OZues{Nr9I||VvC~vf zXIt{Ta4TSr)jXOLGh;Rmc}PW^+!%pg~AiUtmn@1|&z zyW_lRT)H}X{`z`=`_GE%(=d-u8d`SX7F?Z|78IkgLHWq2Y}AK`v5vD)8$kVV$(9T8 zT)NQCFCb;JoGxh+nUt3YkLCN2hEF~k*61cni4@f3tUHO&W-ldxODgc#K;GxnEPiuo zeiBp%19_cc5Iitl#8yB|C_VP-^`bIQ>+bu_->d5fl`7!L%Z0yE31Gfoc*}5lS{|DY z=lJ45hxB)j@1U$))ATm9mEBgKR7wJHh=mm1a<{0zSK!}F=_fC7U`km!G{Lp1V)#Tn zapgjiJ1PYi9P5u}ar{g$yyZ`ZN4#|1nVKi-#fB}l3G3xz=fUxja>wS0@q3(A#v~De z3xb)C=dQjCvAP6I8C(;|I4Af$-Sr0Fdu3Vmq^Y}vAneV`B&$^-Wld=l_*xth2mR`X z4sjHPi&|fnXhBW177v#sV6V2*);*`~Q=yuJdzILq<1#3Dvq8uyX_?V9I`L$I9EIyK zAgkwtaD$s-PMD$G1q$Xe`tgj*w6QOdBdGICWNR(1LIP_=;E*4bj>9hrLZhV1t3Yf zt!Vxk^n82i6Q|}^*Y0;D!%<2R#Rht!bG500?u_K?*#x=FAJlQ*WL#cneK_Ny5-qt; zd^b!$)zm^^I%5w!t(`Ubses=nywMwzrUF0LK~u)&7?xCUUThBJ%BvR-SdShQ+K;9n z#64`;QidY1E#mo9Ra$;4`Sa%j!`}pj7ly<|LCWy9Ax%kXw*&+cy+Unq{>NaxR~~}y zQ@u1ZhdnI?i$=@!&aDhI$+fXK{wp2qD{1n!U+xm@a+xiig9PmfO72u7pxJI6gy*e3 z9jRwOg-tWh8A`yS^1(Qmwo)q^sjVbhC)6b+%gZJm8#{ZjYK24Re8v!KZIP`mLb_kT zE4khodiiKtu*XW1Q5g<90r(=Yg|-ZFt}+jmvx_yct&iv8q>UzN{2rL?Cujvmn_>k? z!qS2^-Gfk1_zZ{haPEB{3mzJz^pg4<1SFn?(XzOjZ_uEIH<{^L=TwCki?SQ*>U|UyN8Bmv8K7jA9WeDO zn3;U|M<(Zuw;uWaVcl)jmgAVD1cXx}7x5$_)gS z9E+QOE!qm>=p*cVeUg_lqB}K23xXsXEOHN4wzsocR2^GyYejo2Oow5LF8)=7wMw61%!Hn^Vz(<|#3R!(s0S~^A7q-r)bMZkid zh72@NY7@^u=VA4M2`;$#_3%k9RzLc$OP+f?tud77R?NrKjhL*1CE>;XKUdu1t14CRpHm#CR!^nvA0XJ~6Z0QZMH4F0utaoCg6#l1vEfQ25prK%Shh|)gE zxmG-en*2HDe%BLDS;10DdF~w@-2rTh!XjmY?t^Ui;1Iv;oHwZYX#;&nnVs_#Te?B2 zP5=-J4X!@hY{S~j@d2j$R}CnARtN)OI$_@VMQ4`MkzdS@)Mhe))IDhD)6ZH+)8n%E z;TGYq6qr42U{k zcnukw+`@;*%)VDZ~dIHTav*~50aVR4)iMn<`d(lk9)Z}g+xx{ z`vS9b+(@?#hEFPt61RVp@A_$#h5!eL#bpTQ91FQ!rJaOU+Ux8wS}xhqcIjsf!Hu)w z5W<9sHBULp37Um<&cH-A7YVqGJ$|&V{K?I*vRi9~;f-|JA1Ny{r?CsVED2e=D3Sup z@}mcc@ppSz3<=yuouO@9lu>X2W93{%6v^tg5C!3DtB-=(PrK(ap) zE%g_L0?4ZsrjOJ)r>v8Ibzcu2@->S{NbD|4=t?1;DAa?aOw#ryh z6HL!FXoif9C4Fj3nOU}#S&?DUkym(Ha4R+IhAK$Hyfv3@YJd=skb6nplC>R_N7jAN z`2SvN@Lq2Asd>apyPcr}IT=%Ha{$gqe^U_Zp-WD)O)#=%@+HS{&m70I?zAN; zgfa?{hU!V-?k`;JrziVCNpDO1vYzje@tbMOKl7J*wEiV)eJHu?-7sO&u)-rtAn;QiR1AC*Jv-O|Sc#ZlRv_5yZu7 z-UHFga67S=$_ShOa~Ho3`qjbww3&O3E2xxoNdvl1b=$5zyB_CtiD5GNn8L5G**eLH z2k;r|v*v*CtNVg^j8NR$@GtRr`bw`>+9d$jkv zk%slBlK)u(+ndRrH(_`65N#`*HYu}PajayL=8;Dp+{FWJ?eY(=Vqh(EeJP6&sj+0& zP8oiVLGm7>1l&K5O_B^%vt3VC^5Spy@N1m4MQU`RKtafZb0;c2YNyl_Xtx~4;k!Aw zx8V*3_N;miFvLZ)DrPc=2x(WXb6{o@weg@^{oy=S)*&8js$gJ_4JkQPs+2cNR3530 zC;%wT4jCopsZNoEbt`nf5#fS5k(HWY9c(ODGOWsxD+ZT|j6XCu&_Wxt_#@& zGDH|%y+-tzCLq~1x2p$|c;BY``y=v^oddPRrU%%A3ep0$lR8q+OC-)mHY&Qq;lu*t ztOOgwsW@kcUOm?|(r|M=?eI~qRgcyXZ;7SMi=3l((;D@yGW70QaSC=a*G$`1&!-Ee z36k$;gfOube=M({zpdA+Rk)dhel#Zp6Nm@aoHNJwd3NzOL0RF#i~ySl4ewV5-Pf*E zA7P9B8Z<XfdGiu}epRCulDib!T6wtcagtdVN!KAlng!NH_s)60HV`nUbTI(j;by z{j_IEv$6A~gnekFoqh)P*t*-OGh`{hhwso1v`{lTGF=zS&zKc{cXYO80Tr+LC|NHeflh zVP%uJRLece=*#vnsbaZ$$`kv{1Q<*{B{ZoMinY3eW*fI;Z*FYiteH#h?5SRIXy%kR zS>M~cHjshMVJi4$Hw|Ijh}KSS9yUb#(?GsDA!p9A36H84Ry!uFfQ1 z%sQA7sxt!5g}K^tPFpYZ(Oo5n3hC!V+Je!w6@D9~3dKmC;5 zj~msk;+~DQzu#sGgc-Oh78h1hiK9Hi;d}4Fa5q#vmvJ^S!O7&Xrx)-7Q4xnKn~5+1 z#&RS-v!;K|>|7_cDI_baya9$WePZZ|#;^J0ga84!(l)Hykba$=AH?MY$>P^L5(c*J z3a5PPOoQOwMY&o*wk6q+`+zgH51N2)C?)eDC1LZ`$=91jXb^~6wQRw3=SIN;X|%)n z4aK4#UzEGc%tzKOn@J`^RvQLeGD2;J+&Dk*%Za_}tD@|;L^!r3;DSH$D9KH)AaWh- zF9M-LqW4F+fv-iWw{-43hJ5#;()JkB8DOmPEL=e&0nwBxpm38sb>83 z*IrrYl0Wg;fuCokU{Ci+(BOcDL#t4F5HG*?fqV%f48%7RE1+@*N9T?02d5Gi4P!bJ zC0|y@vetiT=sBE;aFHpk?Tv=9PypkOEoKtiG@r+Q_Gf+fKN}tXmgLC_&+rm$U@4n( zxNaj7=OL$VmVPsbA_6eVCq zbJMuqIv0I!fN*p)X6A#!es`LF_nG=*4;sBExaho^7eTiaFctNVo)EL>S$eWP;&5Q! zT4vaebMcw4(W>klcoNM+WLB&njR$;Vn*ACjt!x&XpyW3vvqH7S$R^%zT%)~y^Y;5=EJ+Ax`&lfn zF)FRk7T5_Gna&l$eK0=O<8J@nG;S~@HoHL561i&7IWfKP6Qy1NfU4$8wi_2l63gfi z-z#!nDpNB=0(|T4eSf+uw>2v80luQFKk3Vkf7FY=7UbQS-~(%_U^Ysv1w3+nyVz&} zcrtgg)LnMXSbW#h1Pj-qR|R-|fS)hkD=?S#oV8e;TN+pffNGu8tYuY-^z(eQMfr&? zuei&zy#b?gJnn5>2V6OZX~njw13z7*LRAFNe`N*Up5o35s18<~L7Q(>NQtnLs*n4# zHnq}C@Kki?Q~u#|;Gy4Fq|EbbM@A*LruOD#v7lIIzNNQ~@dxGTFZ``LO_Z#q=m|MQ za*U6y$*nVkI+;wTGVvfj`GPq66ZnN(VmcA3$?2#}pruPvke?BL0R3rY+wicaVK+NY zPf@X$lpveQ7VBkmbaM&C5gz|f+(2BvG>hAN$YFl)6G&QX{$6K`Okj{y*slR5K0Rt& z-}lS|eBr8DQ<3RTWOMBSCFYZ~w1-PjK-~u^0{6NzeN?O6;>`CiuOhmTQ9HWI@)%8U ztC66~X|Y#l^aIx+{K_kOx!bURi+WZLk{+ox=lrZ{EZc$If~J*n_eW({-xY`_*+5$Z zS}&LOqk)Z>yRpWO9Y!hpbIX(5{S&^%U@Z z!`OFuHd`l?YJ9y!1KMPli9%abO(zL>e4DMC#5-t$rl*@?yzs z542zStheOI(1PGzz?tY8zgj6KI=K*)SgQ~}iF7m#^zn5SzjB2K-S6$%Tc7ge0+wB~ zspi1JSvrR*z}BNX0t_teP@ry$PzPkUV)c{?c3g&l=w9D1k8YVib=~Hd>kj+rhrF+W zNxV86b!Y_3ODoP>$RyTlVXQa)(y{dwo!{-8b_V8xy|Yqg*6_Z!S|b|}R1uwd^hU6+ zBmAyWH&siA#*1mtFF7&mOyxLte1ukw(WMo?(E$5%*X!xh-xBs&+?mb75i$E}-OrAM ztoe~VtrwMhFOUMFQj_2jsL0YBCt5-}9213DVMa5?N9&sEipdm!)-97W67(1ZPwX*#tY1QKMpOH{S>-$H9kwV(a^v1N zaeoX%-m~otxCC`XESAv9U((2GhqhfX*1|p-Z~bc*zrJ`clzyHHE!FJG)0&4Nol*}D zveQx?Q?3O|JT^B0W1Rq_pP+~Z2d zTvG=k6*iDC!uDdd#qpEUJlaR^D&)XwS3lhS((&c`%N3elo%A6~3QG;e%C#DGr4R6Q zl8IAzP8^!E`@H)oz85jvyR3VXU4o(qUm(7??OQop`DKFNf{X8+w_a-Vd*yfJ+{x)I2S{U9?6)+>a|p9;5PR`Q3;fGPV#D%*R!jmc z#`a-R+0Bv5avVGG_-VQNjNU#vufILS4==KRjm@r{-3%^b-I1o8S)}b@C%AhTL*`?z zT>H2w;Od#j_tp+O;;;dCOT*d2sd(5)@m|Su8M2D8bNAl&LZjqEJ*a zpbdIRXJ?Szy0`_Hb4{s|vFPA8D81;fZ-?a*%^X)3gLJjUGDA30A#~W2FVEYnmrLHR zjy?a;dUn9UrDLyPXG?r7O@NTP6o_KOcsuvP2lDsBC+)os?fa8X2#YY(_uQ0&!xJP_ zH}+K`TNx!BU@ldDcAOjJR#c7Ev?IGRW-gG(3!-|CH~P?BYjzdmy(3f!UuM=w_X?G(eVSs-K-~K&YWqk z12S)RG~X>-ufs zOpo}YYgazwL6Vj_yG*Fk%X99+1DD;>AVv{TODSSa#p|H9w<~Lr$OqjXi9>Fg#=#;0 zaD$y7iz87_0vc{Vi4Wuis#hDXeNZ31&fQ0K^Y7c!6nSVLnnwc3)2=GOhSD?Pg4o~_ zzJ5;*92~;TK`qTEV5a){JYF9Gg^_pq(G*r&WULP8Q?~Dg*0)}5!)qwr8ik#>DQMt@ zZl<7CTi-c-efU9+f_=W8k7^U`;3>}$;}Pe;0WStX~{ z_FQla|^qZi0ALsNrQ=`?$G!rk3QFwvQiK#Q_T^ zWmw$s0K2bu7u%atHFqq-`TQ(lBTW0J^sSd0aTHzU-#dXO=p)C{l~HZBR)igK#4&)Z zKmt3AG`R)OeBNGie+0m877QuUc6ZtwL)SLJq{;Qqr9v+HgeVme0W zmLV#}Dlg6^n;g3bn$vw5?Jv}dq2a>yVFJTT$2w1_h)Cw#Y?2%U6d=t9dD_nxclOt6 zp(ndc^wUBSr>ZCeL3YK&!BwXoPPKk% zp^`IJ>{eB>k|&ed=y>@rl;|&EuikK5)Z+V8n8{6IR2a1g2&OY#>9{GB=PyA22ycFv zmA+}k8KRb5KwHF1Ks2-}Y1U_8Eg16Tsiv-PojCic!V~4HW{@S*QHv?J+p()$^>@n! zetrtczZX^Y7yE$c3R@lUhFRkxa9*>@g09b-!jGSGLqA<`{we+1W2V(4wcNuT!*CKO z4|4=O5gBdz$@chslmpE&tsPV@I#}&Wc_w5hZqwE$Ew)mkhQ$IpJk^}>?W(ZX)Ng-E zCF73EtwgUB+|Vz)jd0teCWPIjdd6na_^+jdNbR(TkHNB~n@j1OW ze4oVm-~=1;E+?ELFqedN#iHZ_1r6$`ipTUpHTli8F0bW@H@al6_;kL{+hcIV@w&C! zr6$jz@+4+dynm{S`J>6}FxI9jvzXwgWDd{j9V=d{N~PxM#iqfhBBS5bA=DW;YbWzu zUfRrzEg+)6Pkvs7xcVe``kw5Rw(KT3R0emz4rf=s;-{^=pB%ZxxvZ8ECma<~j z#m?<2x3SAGkSZU-dsgb4qeawiL~k{5_H`C)pk>UPi|rFZ*1K)0`?a>EhdB*tJD*z3 z7Bng_tF}pZHn$(&&-s^11v0udL&{#7BHiw6z1J71D-H-iZ|q$T&V@yJ&a&;k-Rvia z2O5MwH2rHYc&S*)?)LzL^^Jn^&Q%3493x|ZMOp|Vt$^l%$o(Ufr>i1}2jf+f%4bo{ z7CL6*kW)pybS)g>6%i~Sv}a#&@h=_zzX_HhOb70Si?mVJ_>P-f`r;y8GL)%+=Ls^H z_u`&AKU;hEssstyV&Rz=T1k{-fe{l8&5X6UDA+3Y59@HRCFrL6qeNt)!TYQj&Kx%cm67$}(;txr2`bMnu;7-rUNYT_$>tSk9T z9J8PBF_ZX?zX(kh*>QeZAaJHeWJ@3O(G>t6N|22sXHW-rmF{ct5Zt2JQEFqkRDC)&*PWYmE{`s*~A zn-bm~FDr^a?vw^2g6ni}%C!7o6?=5PXA8$lXpY4E!) z+`Npe$sxAD87G~5P4?@BOt6~`pZ$3^!hVYB<&2VTs{#;z-~%Mwb-Yx=tB#vJAD+EY z{qNm<0vKS`QAZ?UtIDM{P0UR`O3wOI%JA-V`W_mmeuQtu$!_n6LUC}d(hwQwfjfKe zTa^Bo)gh<74n~O+mQyus$1^xvT1~fFJ$-%r3(o%v^83Pv=MAvt!uf=hm04***wc4H(62|0sjuZE#<%S|8xGG$1xdv-;#7 zt$LF-*#a`;8sJRk0dO~fU%&IlnxdR>ZrsjTkYjW1tnMn)gste#KUs@ma~aU7Tag7RKeS0nDxfRJ;#BrQBO zs&3Jg-o_S)|MvC8-^XYYv5XoDIBe4($IQrL2{sFIaRZ#5bL&6N!YB1Olwh^U1cX7~ zK`UKc?bSrYF9`!-a{TD6qdj~l@v5A%TSMxPV9ISKnt@hkc{BCb5r#6mmAVjC6;#EL zS1H>^nlz6jW z^6ilX@dP`L=Lh$MZ~Di`Od3|*MJo^~lx~#=NwnTDf<6~Uc2ju?YD$rojs8I5R$d<$nhRQX92Z-WKko@g%%l_@+auzw>Cl%N?EZccL?^&W zDSGEQI9n^cdD>7~D{Hnf?*0w@4rdi#K`soNYCebfysp8;MLty!Iw92&9H>uMiG8`t zzBdl8FP7^~ab8}uikAwsI4`E^4x)vT{_QOSdrQ&XiY@N&Tq`gGjABKUim;ZQX%QTU}BW9qi6(mAinX~zeM+=TdlBl&sDjotceT=!@B!f6dG zXQ&MVaTGJqePQ*9B2!sq)*cncM z@LuriuT-YHsv4>!^|^x;tE;=Clh(yFij`2QLIhp)c~)BoUgU50j3d)5E^i%w|BM6DTxh>Akt zj@a>dP!-P~{a>7wc>nXStn@+8iNn0|K*y~?*RvZRbh6R|lg#yEkR^%hH${0C zru9EgY*p2#5BQ&dK}M@^yl~>ytiP045d9KgQC>DPdeEsLWGPUB@FJRw(qHce7J!J3TRh4y>aut0Q z{O4w~4mDTpx=b@bL0k(X_?dWJwj8gjXVy$N>B~yL9P!AS{WL(?v%;_)tYoTTo(_u{ z+HzZOv3zQ?t*AO313c|~*mrcpiEQ9$46 z_8Bt|TbyAHr>(V(yS6j!aNlQM_vQ5(eAtvxNg+@i6oWJnMBC3HK3=DZY3>q3SmXCe z@-Cj!)RrB470Ak2Q#u|U#-8LQR-T8cKXnP%%g{A6>c>Y)W=`^srOf?#H=M=c=iB%B z;=djVxz8LcR;@C;eapY!wBaiF*YAz4pW_Our*bInU>IU!Vn1MR*+yhR{d^%le@6AP z_BhL;CI`tZ$;0?%+o`a;T?nVXo&3w+xt>aWwXj|}`bFDa3bop*R5a2oQ;JY*922T^ zPhR}{wd1B2>()!_-`cnd$M4!!%P`tn9+uKAy$PMpbwkcKmD3&#m&n$ z-?Z$jWIEtBh#vYbLTT3KSX0<~OU-H0FlSFo-e;+Q`|p=S{VH@(IK_EJ9gZyG+S_5p zbm4v(`L)*kY*a?C6q~wNJLCRZ=^qlARVpfORd07#eB>|5UhuJYCRhjUPJr_19^rPC z#aHAbSatAGWv?4NrM0K9-xws?gmF(g6u<9IT1L2+(oKIxE}xhD(V)t;mAY2xzT4HC zIs0N-|A0_CtV4%hg{n|qi@j=cap07wQ};is)~^HiZl>e65g8Q(+tNAH8YWLW)hqG~ z8?S+$>Q)xf-6zQYWtyxP;820Tjnyk?x&qRh7xyRjyvxq3#p!bK=Tb6jTvQ2rVqNv^ z0{vNoKkqpyd45=3f9ERkChp&}QGt3Q8B_=&o!Ref)uWBMip0K-^6^uMY5j82-XUu} zHm&Nid0Dh@U2^vFd86Nu*uqxJ6M`tD;YeW(0<68W6KzoN&YM1>&>9(7<)k)W=B}*d zWrdV$-fzv;A4uQD#7-uSCv=Ow`NI#+@aDE}%f7C9RQeuWH`uj@z!-t>~mH3(HsS}pYNz_c2bADs7mq8zIbnlG#&Eu9UZ zFXFh(x(6`%%Q{`Ryapcc$2uzPD78w&n6j^n#fe(LBCs;-Dv*2OPN(#)Lz8#bkWIii znoM2~X?}@XXQ3T77Jed+PlXuM=SB#9AC#{V-0r(67ReH1-6cR+o17zbcQdNyWBMDz0P3f$Go}dg~*H0b9;Ko+$Q$kT+FCQyx)_|ZUK>$mYAMI zp_~WqW(B)B-?@pmHN8ZBR|&|d2n&%iVh|BFlf>d&k%zhg=5vqF%sYM9r+a#MMIwL1 zH8-I0r|g!bFu<)11mAOQP7(9oj^-D8+X9a&%ZEhLyURw$QT{M&g`l>qNHLN#p@&{` zb`L|gyZn5JAFrk4RZZgI_5QlPaX6G*V7Zrr6tawXo6WV$0i5B?ewEyLbe}EGn;HE< z4`i@Hi!O7h&NuZX6=H1$;%kD$(g%coOy1C88dkwX6eBVzk{a#u7?8Y8L)&y#uTj{d z&dJY_;*?vYzz1;KA(prE$SSfh6MURkn{mF|3dK6RZlF}b6;%Q6v9DJ>97-+x#wX}j;eDU@aJK0 zCJxHa0sj}Rc+D?;&O5CywU<^m+dbipIgK~Wkmpx!Mjzc=61!gRaK+t1kHYBJv%N-7 zb$P{C^(q@iTGl)T=@-i}pZ1<(?1WH8}hLp+{x%I2W%&NkVne?gDPn zWdgT6W-%~(#u8{@9b`@Y8vBo5s_n4$5_H=*0kkpzHNIp{u;A+X}vg|U*yZlfL6((G74J5 z;2G)#&Bnen!TK@${jEsVcV6=xAqR`u@H4KYePfhm%d&3Swr!)U%eJe_wzbN3ciFbp zW!vsDyKLL$t9|Z$=f1n&xci*_-Wp@BKXc@lkzYncM$S1SGL%eDbUMJlM6TKIL|pzJ z{YF7|FTsE>5Eh{bd@SR}k{6a!IXTg9pclTvS^R2?WI*KEgC^DJnKg9M|GihI8HC7t zb4*Zr&h+qAuEDvN|zOO2#Xm$rAU0ppNS@I=OaembO_iXq`kSWA3+^bY zE&Oe!8RNE;4Ob9~QMoy1Ah8#!H+DA#neB<4wq4H(A2>Q+74{#e{i2N_@?`aQ`^NfG zP-XSEGK-FHY?46BZdbj{lU0|x2wbis7qW-bIj0me7`Q#l%Y_0ipLaOf>JI&HZ<1$K z>!vd0cANwoh81VRT~@Qq10?uv>pgfz&-0mf)JXQy;kp{R>OqTls9gnW*8*(g%3f#h zfq?%boeCHhx9_Q2Y8t`mO|kR=xnk6Rw>#a-+br#PO}RZ#Ud`xG8xXU)>#iCVPM5zI zma20Vugv|^c(Xb2?AZF7!jn?g<}5r;ldQiY+?VDN*B7bPjDC(hb+@(Pn}NQi*Yxfx zLFMbT6a0#d8E>&)Y?Q%h0+>&&L43Z*@+*&xESh#O{cUd@5c$R>HRmhR1NTUPCArMYm36lUeeGYQ_5Y)_1spGcFig!hAfx??4# zv1X{bVuPh0n~Ko_)4RDEHu2jZOXsk+%EWQImlVSa?kq?NgFI`@(4iL3nURhH^3;>; zFnaO$YGJDBZv@84bCM zVn;}(K+PAIuIeQLvB684UA7pBY-)6@-c5?ty47k5%K{t|^sr<#4kh33$GzUrH1R^8 zW2hHS2wYHPm%jlf=dr>r0&YlT1_CcK2viFYO@`7TJC{R?@DRTvW&BVBYdw6#uX8xo zWtf%FJh*dtQwxN@kIe5eVasG==ilrMUQq(pSfFLt_@>`j(BwGLANi$EzfMv4hIj&l zc0t33bU(1<1OHgT(7KAfR>Bq3nc&hRAE93RJD2~5HI6US=q$}zixZ@-@&^ftt7yK>Bb7}WZ zt77fR9t0YRV@dYmJ6&=($!U&;5h9{{vK}%-W@0E?6ebdS?GZsmJ$?HnsBNe6h*-h| zPZ^J?TbHD2KdjnfXuZSJ=C|6Jp&2@NSPP#Ukzy400(N7Angx^c z=$~=2TYE5gF|1lp(J;O%vlcT^#(|5SY2ich8CyCmjzI}rbE$CasVuMYJKWS(lR@7L zmJ7~F4X`twVA)n|lJFWvKZ=%ReL_(v8|!s03cLl!u@|8C%Rw&;X3JgI*d9In^dA}` zu2lI`wQEe*q~Mr>aMOFuS{v0-?Z|@dQ~5?}NxMj+;+$<55R7Bz1# zU&`(GCOa(PdJ*#X4-k+X+9pExwXYaO6rD$jTX)S>K!%3#JEA%38e27MOsKQdjO7qz zt~vv&X%oBRBrr~}H%sAF*)MrJVLPPncx!C;ko5k(RK9NaPWmVLfT9W-LFwr~DhV5|YqRq+d>X!-qoNpoxT>N9I zkKdWubbatsIz^2~=IX0^EYwV#Bsj_!9btGCf*)mTUmL?*m&%(GqGrO;wIKQoq043O zh>Q;zyc0&aWeX<(7Grb|BV4!dF}}kwHcio1@QP-E0~vQVSR5TWDTvA9zIrpX=G0Yj zL$I!;;ZO`@^RyMb`pJ0ew3ksdJRB``=U3CJ7l2~U0b3qL?w0Nz<7iO4mX7kJfdGxO zrOa=zYuc%DMK`ywX%zOoN6XB5a^V|FVYsFBGEeO zxm!}W+A%BsURaT141X4X^)GM+50or*HiI1*ZHtXys=_TA6U^(8SD)cX|l zZb)VZSDfU&iZx;lqO{FdLGBM?d99##<$)%!z{0h=-wv!~CGeVGB*B7c#^?{+RbRMl z;*N;)<PcnC`;h@%6rE6rKuOME=zETn~^L0dsR2_xo<15vq+Jig#sbPFs+X z{muTxwebw~ccRx8^;aVZjqXTsTYg9YvIjGo2DNpgEV zviGcTzh|*1mY?Vz$CBUnDjwjgpc1J2n|X_AdGt}{4GZ!R!*b@JZ8S_9I`QdoHRES$ zlLE5Z?SUfb#ZnSx?J^?=2eCG^@(ugltfnh z4z5AfWJYZub40C_PB$o5%BiB%fx zE~<@Z6#mPSDy`2?#~Tu{gW3#k*L_OoUZ~R^W$n@oDZ%=$%73&M z6CZsQvT)jZ{>^OE5_qFVmU3mPW_E&*V>Zvb&9wO%<0j#QfIKnr@mVAS(7{6r79$Xe z(bsB$iJ%5)-n)yzNk?dY^CfQ zuu4w6-QT6SV%Z_2WnR_s-e3I*ydlv|jl?4H{&!dgk!qEqz#il}) zA~GXANX^90TS$f9E}534IdA|FwK*@%9lJ$sClSDqej^uK0~(_iI^zi4I+kUa=5y;c zoPZNsN;N((!OqqS%xqcZ)HXtGXjIIbrtC32%E6h?%zhb-2T{|rgHct@qw(DSpxM$6yhpy;Gx7{x zJfhQbzv!HI=cKILnNCJjLEfnwTLY5C9@uw+d@KQ%@4D`%&$?Oj3t52xQiD-qqS@I3 za(?!RnYD_a19(SFM__9jH17rY0EN5najzn&6&4J}6J`)xW7IGs1&1hT#pnl>cjE9B zuhZ8uhj|^~2MpRvTWMg64V&dqjtVP%)>qT38ZPs5A7IYci6EdaD_kc|t#IYxO5e+F z;)EHF+>r$l`^uw@i;v23B&&;&rDjkuC3)?o1vF~SS$u-6&^GtTDZ_L-<;@jTN zaEgec9L11eSCS3YO?p}K!rnyNC8jX+2`3ugCWyf_I5UM5zK9rpHFL@Td}9pCzU|XQ z1bpP@FsZgcRn;D;n$jtuWg{!v&o_spg~LDvhPr&NKSTQ(Rdfh2QL_ap(C>t{$M;^rLKV;2x$agEZBv$4RzNYJWhF>yY#2Oqtyq zR{r)L&j#uh`+}3r|G7aI*>= z*#;+wDyLUSqhd49b7eP1`ZS$;43`|jRtt6z_a(2hX0IQ#*sR!wR~Ra4LyC%WI6?kw zX}92ng`PC%gs|j#@|R)Z>&FW_@3>XY3pJu1rXp;B(V=}je{i{H*O+sDC{KN%z?SWWXWw|ac=FX+<#ck+9hrgy{X2y!`G5@T4{=kV z_s)T;a3AaFH1ZT!lAlsV>J-snymxZ*7h!q#7*~(Tn-pa^pFa*k8)XBY2brh^Vh5RdX^usy3sKFv7u z=4lZy{t%y!Rh^Sc5rtsEB<5H%9ba2*=TE1j01)gG+mO+>|F|}CwaqTb`fkJZ(6TlC zJYO90*7WxLK(@xekeWz4k#9|lO39Ns%rVO~>=Q^w7%p^4<6dSWM~`CIsBJv>!iy00 zUeb_+mx@X2H+vzl!=Lmrg!)l8rDO!9uRy7dCn*CYc!V6F0vD&g> z`%w8w%(^Z~2kfR-P&PJlm{+ngyqu?H(KRA3q#U{0(A$wA(=bI6l}A>_3Od0Kr*m;V zKdH1!_EWazVzKJ+gxfjX_GY(2YjY7+otRgi2AJ~goYV&U{ek32Ey}@!VpM=JYr)T+ z9*@0(AqL)kSD5$sEw1CEu#R<@lkTWJ{|f6Q(y$JtGrVQ*gjXjs1WS~LEW0@%6(Dd= zgX|KpM!17s%dM~aA84MJq<8wY%LOSvHx{(}4QNI}Ny^|&K_AD6b@^08`lY*ChM$)< z@bl?u!R{R<8@$YV;d7TEIpVFpd&7jgL;p#S(MX~{AKy!M^ z!QL{n6JFEImQby3NePF0ULsmf19pye{{|Jja8X~VP4)m8H1iNgI7fbKaHDp}KEEHU z55&wsR-{|ElpWTsML(euWdKs#d`-Xqp?nrKS=+bai~N{IW?NkpZc=9Pxb^lhZ{`acBTX`s(Ui|8LRyR@Qyb zUutwL;Pc6|5p`BdJ=LB=q^|;og2fSFyk^iO?2Vvx;OqhJQLT3_4O3T}QMzrxDR?_s zx$tspa`Q;V(()eKIF_dQpt!n?h>aWGbBkpirRnza{Uq@CIM&@Eg$=YsMF?`bdJ|W( z``-eNv9``DsP9xK-X`2`;acPNj2X}ATe#4Zqu|GtRKH!G>w-_j?OFx{lpJh}QoY{n z+eM;*okIayYZo}pKccU$^Iphg(oZvYe?IufFiQRieJ$FtoFkIhDKL)lUC7@})mw~M;-X7DY z2Q(VJ+zp0%2;OzIGjev^#QqK5$%5Rq#c?7SRX2~pQ4bs|MZ~vlUrLqlj*AaDzh#aamNNN;+3m~cfn(s`n`OA!%9INTiIjdE%eRtWg1CzP<#jXNWRfOxvvtJAG@3N7!>>ha z@t3&(Uz;!oZ8v$&n8=}E;)m4Zqfu@Y5LhN-e!oEtDcsD6>Oi3>UcKk7WVl)-GGHU` zb54bKVTYs#3es!ZTj=7XXm@iF7sqe5?z4q=D5MQ-9Af7K>xHODH>U=T$FpY5)&raf zq`{?RJ;pk%9Ex0{2#jp%wS%fR3ON-*y$)K5*gd~we?aTL9b@|1B(*X3P);}%LbNF; z&!>~D;x|ddc0U!N8pog#7Uo66^^jE2JQ@O35njF^c3Cl9n2VWlctQ@tt}pL9epW2a zK0`IW!=&z`J%^Fs`k_=)rcuAXFE~nwRe^6;5lnMxJP^MBjqBGTbi4NeJ7tbiTL&WE z*n4||>GsT;L=W7riJNs_%j3P^=f0u-KDTmp00USX`L~WvsJDPJl}gk7W7SlCAyup$ zfUK7Ej(N%LHk7+#R;#riD+YneW^X;3y&2mz>UPGZeLWi`OnM{~uKq1~j5>BTsU5uM zJAC-UL?ggdc-YLYv*rfF>@I#{u|0EnF!rH)NeK`9_&GXB;{)G8-}*;ZEZk~SIYD-> zn{Mr3ZR9G0SB$I^q+YX{U^dK)#4_Un{Yklma<{-!}G>1fy3O zB>M@Tt zVfqGK6C3$G+eOoJ=p_zu{;O|C*6o^kr}RwKBCE}*OTp+ah1{L=jB3*Kvw@vv;skX& zdgQvW((_(1<`%mXD}&y>sPQxfr7t&`$^{v?Egfl--`;JNnSwVJv>Z~tBY6RrUjWh) zT|9^Ou|et+=+ z!ch7yHJpv1wARDRr5&>CIZcC=ggVRvgljfsV`tvYMHK1-s*fWWI6=!)(L`XzH=@J+ zsj{JBO@AMpIUWCEf9cpefpaI)0@;nBGjnL7^y4ZEznzAY!fsZFxazO8ZQm@9%(-?C zVmh$;zE@4Or>tI}P{X6Ag!M2A(ojQJwH$Z)D?S!ho>%mHd2EE30JF#Zb0cnwKK9=|eN2DNld_D7N-q&&IgwQ8hYN4iFViNsA zIY*O0WhA^Fjni0jjQ=Tb-Shjt8&&E+rdr+4$!uP`V%2Tc+gQ=y3k<}X`FAQ+nFu&$ ze94_3IK7;fYIHTASjs0qu|?iWTCbXhtXg0oEg$ouyVaGONuVBoK`!@=dGqCYob0Bz zH~-S0+@W7PxP>D-`EDfmbgd7E5V#uZQ6&`Rd4dxRnGG?f?b|FgYZb${C)tv>jK}c3 zi(IhSbTLmS!zvO-HY|IPAHg$=&#Y$jgsr(lt$(*YOUGH=YPT+liI z*Y}9Hp9=&PAa5Sjn>eXv8!T!#-%RY8VX^am!7SP!Zmw$l>Nj|!y4mzTA3poo;Vr{M zqDih!F*?tKaD1vRy$>G1?!?Q+>wJTcjb)a2AI3nOcYLUph8Q4p#JBAK!IJFm zQ9F974(RBEC~M%N-@TrKg`J%|$$YeH+e)u|^}7I*;$$A3rPj(bE7$fsaD)j5H6K1! zBEH8egH64jJb4un!LHJY77Ot#8AdwP4jAK$$ToELb~`=GzYN8dWww;8Z^_!0sX?hE zM#GycAhbT;a*MRRr3dzGQ_O}NdhG2BbKJyNt{65_4(W}-XA>-ShuXeZ)L$m_n<*>op3E_G8wa+U*zCAL+1{)Q7gid&|1mAvpY12CEeNcn> zOP3}xUdGE(&^1f3fZL+M6`v>7s9$v}s9o?JZb0whT+Q_+8)O^QH*}iiOrJF<)=gZi zETg0>uPa{lQWzdDwRg;Jd|-V0CoM(y=~N{=A_!T*`&WjKBCiKq>kZrrK;3fDq}>7o zCrs87^>#8}0%=5vGxFfq8+==G(2&g{mJQQKDZkda*D1I(YfRaX2Pk=B(0bA)MYwu_TB zb_ON)G88K2HsaZqqX5jE>!EHm8VkQhm)e%3~tAOKtVSjem2RFBRp!>VRKtLEt-B|L2SqU-?-A)+|pR1!V#C!q^kCM?V z%l(y_ihXaNWI8x*buDy5R32o(QcJqG-O<;y$2rsvWpz%CG~GSlVt-cO#?Z2O2R>NG zlpP5`11I?-SC<*wCgrR5hSkJj>FrI#Jz}_uO5JQ@^g5K&(SUfX3wU_Gyvz zgY{{m92kGtm7cr8j{Yp@whmOz+FR*awP~QKnyx;tq?qp9VQzTQs!^1?#}vojBQ}*Z>!RP%8AYOxNAuPy6;L6#AZUk0aY;Gm%oG#$Zf6B=c2` zOzZSIux^nd{eTv!YbL#Gb!4#-CIi7_9;sX(y4KynSyCo^y$$|=ccJEi3(1kEV+bN? zjn%EBPg$494X~s;Qt9ydTs!otsMJ29PN$g~O`Gj>CM{ebsKS6~;n}^x{oJAp5i!G; zsw=AbD3FHvtAhy937s{T+TC`qkROcQg?EPeF4d*WattI=}(rwj;w5O@9LkDH(n)BQJs&CuU}~z^qh>8YGhy@TUIt->$M*;uc0!F z$6)KD0sFRhw`uP<&RyI04C-u`^u6>WJ-Y7#h}~;`;9a&xjbKeNmP?8mtQpU6C zG3{9av6#A85>=Vj)hbIKer61>ZlhpRxr|o06z{y%m0vfM2DGscH?{Y=LM=2vJF@~F zv{6k6occ5Nf_^N4xRgNzB2bFwWAiy?)zWqawaXcuX@gB1NbE58e{;qzkHzUa zcc>W*DqcN9^oH^>eJp8CN^0r4LiMzrV(};!BAU&@%YJ8FI*Kd9D#y0iz)$k?2K$wm zw$syERw0hoLf*#L92q1DJn~a3wLUja3KIuqKpq41@heY)9I4)U-8>S z!Ns_sj^#&`z#*)WLb@6WVCVCN#qpipv9*qFTTR`V+SopvGOXvQElJ88E?F19_)F2j zm|d8@!X;*z>367aONK7}UOj+sXQBO)J3XPF-n}0^46e?XR25foe@Co2Qd)7LjuFts znVkUFNp;esX^5k|R=^q$o(AQ?F%(EykG}=jH;5J&pO%9&I6P#we}_>Kw=Q$k@RG^cS8& z^h_M(dhpv=cS^L@Q7x)gWgSrt?5*>;_3$sgmo@4Z_N7tLR5nI@2W+_~;s6xc!cug7(GYaM)3rea(rvbhn@! zta-k0#pPs%Gm!8?OLi6J##ve(gQ00pNvTT>)lDzIH~A613?g7@e6E_ zTpz^>`2IDolst?KX~s*R<>I1t3UW|<{=E_|GOZvcq+ViMt!L9V)iCz)zLED#iFfD2 zmFD;oZKNP#Rzq_$wDSzj*CO`ZeGtvK-iF{SI;qqCRb?l=&9=uu$%3PVdwF8H2CKlp zyeVNl`bLl)n{UZBs|rD*wAe1MtlqKvfe^*R<>4HEF>)09FSqZdmHXAmGl4GcF>%Cq zQRes~+?r)w`Oos~xhz8h>ZHWcMmIZOK1(WsVp*~QpM{AOo=@*-1yd@4K^?yj@YiD zb;D^)5eAOR(V24RJV%vp^dUGrPy3*E^&anv%_F$r-=4bTEhdvw+iH|F!LY1tZp1Wl4fX})~f>rHB;!cj4UxEpJpDMG@3f&)9knPf> zmofb*cT7YwhK1}H&v3W`gEltYyJrilLkU6|66?-BD}c^L{C*1z3s^goP0DTFd75UA zeA3Q+oalxnPxD-Zm_G`jJW!ca8pq?>DPA)|1g+-h&F#=U_?4QmrFe`V<6IJSZ9sdk zdOke~In&gXNy%&s=XYDn&O91RBwGN&)JdnnSH}1-5!Us+gE7EV_}GGC@> zC2-Z`u(>gqXHd`XITzCX6mS|`OyrE&7?7OFYP9Wt4}J6Yt%D# z^hLX_$=?*fb9HgtGJr%7i?M0}(#kt4Ci(^VE~{*#D}ixH=>k-FyBMOJbXCQ5 zFaTqzfg6tj2%K+G$(~o3J>#}^OVp(IH;J%yAe~CwtqepeImycIWE0=|;bSu1)+d>7lC=4 z5^Yt0buV6$c@yf?8#4ksUiwNNpP6d0|5>%!A}t|yGGWyo6c$g&2{4Gvy+F;FqPUkM z`4ldA(D+tQ$g{AHcbaiD@W&@S(!DrF=&S*VFv62%=VD8OdSXiOqtL(Im*UTH)xoG1HLg>S&0RwQgHwU>b1Kn+XiQB%b}lYycECAGua-G3=%FVX5rE6zM3J`&CI1jF}{i@c-VqxwlC#J zZ+5yUdmr}@$TyPr8{`n_emRQU)B>~B2auw3GrL_%?f^K-BE;PM;jqy$b}0ZT@&YFt$0m8>q!f~p2pR=HCtVIaS57@6Yg=sNOfvGmJv^4mdwo} z%a6$qXsB7qh%BS{!k96?cvCz`q&=C#tYafk4!a;cMNBcX8-ta)%{x-yO{C8J+ooB) zvbC=_qV#(XBg{(}+hmkL`}6Pz>>mkMYS|gJgls@S<{f{PV1@p9aM?c(EBj}Hm7qTjj&i%En8 zxB?n#(G+57gr@D)l+iG&4ONWM!)u$zq(Pt>ci4UFZ=A2aFQm^~M!6p{HlE(j;gKwQ z-2$Jmb+G};MDFTzX>Twgrik50Kd6Ag+cOGjFtSL4fu#r`1r1|SxS(8sNe;DAu#`ST zvKRR#D<_T&QSKeyuya`0&;q7YiDv?E;}2|7#I0#)^Ldh{4{z3SP8+xS5%z4=K81D* zNC)l%eSS?4;}g)JY@O+cYMHYp6cjOtg%cQ==0EcASD@45C+sX(V?Bptd z!`3giy8WV4M*G#BVM0zxwN=mtpw=~ySjGIso3(39_*{ZQ4VQE3ir|x7tM)gKVwC9-z)#C!yE^hX_oL&V1${<)2_7tMiIXwZ)V2F zdVl;gk*!O%rlfTWVmL{}B@dhtG2E@BRP|52VlPt--8z=OM~fJOcgNR?JP*xzTG)U?lpGc*w!jNW^hPZ)71q z*ggs&g9P;U{r8O_IYVeSuZBD6e0YM}uy3w(Gmyg=KF>-^o zw%*>^p|(FXCg4i#-4$7~Gr}^4-RIE{R`5$SW=S&UYIxoiTjMmKtL^WNLZDm$(HD0q z&PTVrrT!`!g9Fh(+e-q~n_+thc(l~lnj{tPvZtFq`jX2=`?R^3g@(UZH2!9*XY9N> zcSDle$uYXhg42E6<=*e^##Ghq;AOr;AMXhW3eR&kM}S{I96*MP7?UN*bQmWrb|;)& z`}X=-CRY?}(x|J>ji8He)8ryCwkJm`W3ZBH;Pk%Dpe^P1eCK}EtjdPC^Z3dKhxd`{ zNkqaySzQ+*Aa8j;?iXM*lI=P_Z6;|*bklZ7^Udab(FMKEHE6yiX)-5~HYo3uUL^A@ zec^XQ10ixJY)frLmiuMv^ooNSyUX1hq(_y>TaxylqNy2NDNk_1aL~=plUXlAfX+YpLmx(6ethbSC$EM ziR+?z;y&0Btg9cp4b}R5)!nFcS5$m^1`~YvtT&!fSz8Zu4)05nF@+4^xz~Uf}cC+#uF`qG5tSO-*|?RoHLM# zl5v1|jS;4j48(O{uuHkuFcvvANatOYmqwNC(>UOJ?YeKS9x5vh5VS}uD`croc$T)I zew4)d7-^G)Fq$T@yx%&Yd8?}I8l$;b`_G4(NYW1Vs@^j&oZS>1oHG8h{+V;AC&NVW zd-j|3QK)&f&BpoMmHzbjSemFxo;RcP_mdYYQ+Dn~p=m5p8ET*C*5uypZ@g#yc1H2y z#kL=(zA~=rcUz=kmr}>MzZhQ~z-e9QaN!#|b6^`+nA9k6!N4!xt_|BVtC@}8PUst` zyzfAe@8`h+YkYQVbyO6^JkQ~DIej?`c9mdW_)U^&ccn-ep7Dg`=x4}Uzh0DL@1a8(K9ovL>Mp1 zAccA6aR1hf<2l(-7*$SA(0j)+Bpp_l!lshjq3GEKB!n#z;ibql0w?71Zczpgho{!y zsefUEnaFuJWrzE^!+$EaJYa0^pBqt7?{9j1F}qld7fK2u+fMSVh)3q|c_a$ghjH1u)Qh3ODojM?jF3WWFvB~ixN#+GuzFim3r1KshR$BND znM9cVCr>NPAeB9*epU#yE7Q~X@i4RRlW-@h1fj=1UbNG{e-HR*qZxkj-8`tMffm`j zMgUy==;YQ>AQsNyX(O7_sTlko@HC*2$uo!_S#uPE?X@Eqa*a{7Rn?X4lD9b=IZHu5 zDsO#jrL{(g)w)(!cIVJgaxz;sD)ajyDWfXW_ostxpTN3SLk5}F;U?ckWUq7DJLI@E zz0!nEExq)HR^7^I>g)Gful7Q@nF0S?W4#UXraq|(f=gFDtTNs8Gmnm%lfI4A1X=2191SINJkqZa`x2=zaNuS{2;xz};YY@4V(%TuY>9AwwQLlVe_o~(f z0?0UB=I`#@zEf?x#@8HX?Pjapkjv<|`>VhF-wWNh%-V$=DlwvX)=^YVh^nU^kG7)W ztyh=A1_51+a(n~?rCE6i$JlHr#S68m3`~zZYJnbmTNTEhaD~ zw%$^=et<)aqBA_rqlZJu5Rv@YOr&^KBO^ngn9NoF>A%p^2~@DJ=K<-V(JluOangLPk>dNr)^MLVG64t zR789qLTV`P3DA)Q{vvJ z{s>-wl;PE5#7`{AEV3s<`{59EvgAlzmh8OfjUT<08z$cMPSCXGj%N!WNc&0N9uz>m znX^1lMe-g3MATJc3ugA;jF}A8LxOHIf{$b4g8gtuLZXbs#cC;3q+)*{hUxd;XoT=h zCFUv$o2Iy{ri!p76>v`T8eyXL9)$qWTz}&rmt~^P@U?E{E3-u3s^eLsvO@ovd~kL# z&OB^3q=fbcA|!~FUfV<%MO#%dLen63Z%vTs*?Mf7n;8{V*mY9v?jUN5=B3`|y#*f+ zkm+L%#s?&}Ptjd{*e^=b;@(HC8674a_O2B)KO`r8!i&}r}$5PHhI1+=)jh#b@*>`hz? zUAT&=_7yHZ*u)Ns>#20D-L$$Y&4x0bo31r;%+Kb%MpnPw{dQK~s9Lr)QDetLyVivh zb4kpO?7V694pm?8$ax!w5UZ2D<^2duGlbn+r&PF#|Mk|C9#gwZV1>dHy=Gf2Z*}$9 z;XlP~ajlX!t&O%faF|ae%=P7asGYB<`79nV2%pf3>b2|W96y6EJ%C>g+a}2h1uF~N zpYb#f1m>A0Td`hcgCB;PwM)ZsYkHp1n@z=C5O<=eogvSOQGz}7%)ysBYDxQ1X+2|8 zE}On;dF@UoL<>ds;-H-n&JAMuFvV3ABQv!4Mh?Gx_K-!cOG(amS1C>1g466^D&!_A zFiYI%LEqBha3do4HWI)16l>|6stgWA0n$>*nHaJsWU;;*yj&R&D9Dp!cbgL(dvu^l?@r*fmS`__UNo&BzU zHpJ!Z4rMDJzqCi9gY1;v$C@U!v76N|u(rpdw^lc?PayR z@@3iG1mU-8ByRNhr8qn_4MjX&)UR?M%LM7njXe&JjuEcjT}vIx-PkNS=*vEDTrwT3 zHGYQ7E5Yf(F|PC;MEu;M!EC7BP1K(va!cba+zRM_H#G-oZZPM5C8@jL+j*l8hp zj&e}K0|7x`{GU6mNyGnsEHw20xzhsuta$+m^~a&nAbT#vIE#KxY<}o#(k6SV?r9rPL}_6y)IoGU}TKl8PdBCk-lvuW29yiA7g68-?`xO z+lC40+Tr12@7#Cj%3TR#TJVLY$y978W=aCrWOmh<^|{qMg3^fr%5~kx0{z#|l52}X zm(~Q>GUG#^Ga);rK`Hksh=O>k?|0Z*RY|7^C=z*AB1(ncEax2EDTdLtOuzX@W`2?u zA08!Fp5Pp>M72rAF?;GUe9c_rU{{F|v!MAElKl1efEIt_VVJ#35-AktQ3G^HwA=pK zI&U$^Nr0;8ISo7wdV0g)OtnfOuJrqx6-iSN24f3+OaG)jci)K0H3z$XrsK;8SZm8S8 zhAJ10R=*OW1qk|*2fY46K_9`6-MN5)fYd&<^uH8z;!hJL@&7$hb`AhL69*>?6GxNb zaTpL{B%sYUdFJYaAe9i3MPY?{&qK&taP3SPs6-8&!?P0tucoRt1(L=@o-xAa<;1wd zu`>T65C>RA{JBYj2};n?WX1A+=`oAN+Yz)g&5dGg^bTHyqHz)q`;{s8oGtY z`pS1qk2EcTaPmY{BIkwur*aepc;{vqi2wl{YFJU zF($2cDMd%)2epT3k4{EmhKr4LNPcioXq;rce*m1gM3aD)SmXfw4~_-H^X9&O_R0C* z`W^oh$6%j#Kke!-4d~Bp;Qq7Ce~S6H+9Lg_?Z0vpfA0I!75+os|K0Z=?f>Bi{+1ND z|0Bx3^d^56=npse2Z8^$K>vU;GPd|zl9B&wIFnCL{nx(r&ocfSpf&(w6YIYvDb2r@ z^glqI-0l9_LH}7?(tm*ru(2_)HU3+|68|;i-yc2wzXSN`eq1aZEdaI#e~;RK0dDAE zVqj$lu&{M9Fmn1tcl=vaQ2n*!jsRx|BNJ-?z{=U~Z{bq@HLi)9iIKCDfuXg@-xK#= zz#3aP8aO(d*ce*7|1D|%XS4mJ)x_cN&KTMMIQW0U{cX>}^lxJRmpc4CX8&gc{_isX zedA#MHzogn*0q0^n*Ud&`*-pGU$u|n-zCVw$kf8t*u>#)>GmJ1{=Zm~B!xvJl^qO> zOq6U5>>SMjP7FrYpLUe^O;);30LgoHu)IR=4%AmTe3QlviAOWg?~r(VVAhniKjDj3 zZRq0)&m-vTw{5b#0D{uwRQ5hk);fURMwT8Bo>BA^p?n_0IUkFq-xUKq0^2Se#}?V8GP(y(=Eab38BeAb95o_!s=2cqKpX22Q_Kaah(xS_A8?o z?5$h9T0oNs*Q-afdeg_rMBluO!9ZmRo!&lpup#HXz+wzP42TdBR$TBQ^s;SR+(O~( z(0ud+jF=*_3;BKZ4Zjf64rPQgX#M3Thc#gacy*KRou_kuujQIEmOQ^7R`roo9d6ZM z@+ec0Zf2G3sV^Ow%rv!}t&P-m1y?Gvr%RP6B4Ha3wg%+}(~b$x3hx%(5XIUd8>BW! zNby)0Y4uK2DTdzpfOt4}?cH2*ikz{~I0~`z5A`P4ny*CqA-#YLdXjaJ%jV8k7sVT0 z{*pCW0Xk{K{<88`tP{!>L`q+xoQ zkb*wu#OwJcw|WJ6{i%dC67xom($F=(!g-!J%+!8)(2Q4xr_OBPlsxG*r{c_v&sUUNaJDQokEp=<8SKPd z_>LXSC#E$l@Zn0yrgAV*6pd_t!ht2;&%BA{5Wz9Xmowpm+iMsCXmnN#cI9CTE@mEp zW2S%_sJ`Xx-Tuex()vQ#kMd6@EdG)S;eV}5{}J~6!H3X4*MC`ni;1!5AMxOSkQ4a_ zIRZ!`W%(370_}dDYaGoO?C%00t(Rc&lBi&}i6uviXNW>viAyehQra9h$J6ek<;EuXuV$!{jOe70_I( zB>tNyNeobu^M5KQg6$sQd}604oQ*AzhexfANXSy@_&g#hUgCvs5CSTKjAw5VA&cNA zZyI(cyjomdJG)iV98&UqH*0*YX{&all?o#GxZTLhwH}EubxekzkBfY1tW=Jj%63&u zRdP^zoedAXYWD+$E=n|$mD1X$J?|u>qyfx!pVviS1_I-RF7p&4ft2O-G}J?s145ib z0D*dd-#^C~k(-DtZ(?KT=q_dsvNiip!6WOTRsl9U4fP2qJb;;~(bCdBM7iAx8Dgl_ z?UR!G=7`*o5`Z=<791QO5YSu3(NozQ%jzr!9{0Eu}&R2RmYY!TPuepl$BzXjMzQnTnv8pt2z3 z%t_Mq(F~1ujl^!a1VRo*EeeSBGrvk+Vx@feWfWiVM#~ZoOxa3;=xdN}lMuUEo= z8!S{&w-oWZ>i{)iUTYhiH&N6Tj|ouV2Xup-hG%TV)M9KN8>FRkMw7s8b{~@lZ^!XM^A4X27sf?9n2;xWe|7xemZfvzdckNenUiFS!k-9Q#TD( z|6UXK=5vAdnoaAF>;li^kFt7AHa~nyh)1cwnY6w&{ZcAX6&HBCn08kY@$=kxCOalZ z8{(V@xi7kVKxYta%LV(lhx_ax0g!44`2DkiNZd&7KQXupfbc<2|I;Tpi^B3HcV>Z4nhH}DJy?4-NGas+rZV>>(#Y92fL&-=)tI}h5-DPyM z)VB4pD8^A>tD9>rG9lr(%p*=~(ToCPg6vQ|8`m#_^pK@MCCE+z{jnN&SmZnLh8&B|!EI0}?6<1DeGO zBt=87zYTQ+u~P1yOhC}JYgO^+CaO>YKJf-}{Ck*`2kZdQg}TjfJipzbq$Wut>59w% zR#qn^@J)iDiXf-C+X8XsU+Wxjn^BwZ?08L)-jXRmOw~|KssBNgv8EwMh3#$6)W%&c zGB(zsu{v1#T`cczH`SAGmOi-=^cc^4VDSjv+*4jpR3i(J14)dX6^VODXc-){;qyM! zcNC4_MMR+j0%iYYphTW87YhS~8u;H6Th+zM-UNWv|Cu@;-SZPh514sf<`IS?2g z92}4>gcKYc{OVQ$l5f-#2ux7<<}H#gL@gb24tG_rpY_QXDWWZGHe1htw@dgUi$h-?4P1^4bv^|nvuyk@`&^B5HoN*K(-_^6O4R+J%`ryEp55%oSd0s#Qy7^C zhSHY}RIZoqQ-dm?3*6DPsH0?RkoP|$^Yh`5&pwF5S;vHVnb@aTJ(S?^55V_?5>PWV33?m&F1I1t4mLsZB7k{ z>Uij&GJ7+_Vi{v$VYP$btK+H@Q;(Z2V+5pFGvvEWSRes6#16^!D@uSx& zU;HNS_!qEKa|HrK5!bKS-@s95L8ast!#bbY_`SzubkuqWm_%ZF%w)lQUEkFilL3M4)9Y6Wr7*W3v zSq;NYbl%KjEwO}`LCbR9u#yMAg;P4kBOW=SL}nj?F@c8)7r~04b)4kPH+FpM&1Z6t z^j8&K<8fAKW*0R@?uujj8KBPiYZZPYYyZDsrGEs8&jZwy{beSa+3auK3o!o!B#s_$ z!9hWy#cuBSTHkgpkOd)vzY>5f_yHxA#t}GRF%A|KZ)camt7Sk_cTeZBh@1H@yjbi>| zAm%&Tx&Nn+UzNIz`KYz!Hr;P%tPViqYzyk5w#M5$*nTBtvrRF~kGd~lP!JC2^LOd; z&)&_;by!$Po}~A2fjMY0YwM?syJIC=AKEkgFGR;*Rg<`z#orQL6g24r9(53# zG^XW-Xrl+$1YFEShighBvkfdEe@guUqdw)LTEZ=~t{|93^|G7pS#bXVn`A77=vZ|} zA-o9jEybgEZ{+gz)+6C%WwloM@R(#>*qNT1inq1X;Hiujsr&WoX_r2coO~HxxEo(S z7LFMDsq^5?`kkG@t-;+vtHVy`{booL65(6t-M$YLVV{W1e$a>}t>h$pRHpWXBlSlA zxOZpRmI5_RbZq3F-$h3$sl=PD5)hr_T1ODRiEuO+{DjqKEvbwM#~1 zwWSeh=vTgsIyIfVClA8C#!U3P9Izxz<3r^q9zw5f-5W!Hmi~%!f1=W>ke@Bu{#T|6 zTYWtmBq#W*)T1hEFR8&Yxp@lBcV!G4h98|csC#)U0lPT3u!|D1b)N^g-$_B9JI1Vz zrS;#yI0<^;ddXvR9c>(T~3$5Ls^N*}5)DA1ffP zeF8h%nUrviNR;w*zGj4a1_hIk#o!EOPh@7O#9p7QLI)cH$WIXby_zEz4XS~s8X!e4G7*?0}?<%;Cw~;^sCa(K03)N$Bq+bfNy$Ue#k^PV*Qe^DPP;|78>>a0_$`m z!;t+XC>DwWNoWlp<&CekZ8sDEk&w?Bh=im1V0oO{n6heXQEs{RWu@R{H>-fqjiL_k zfvqfW7H}_VuGKnu%~HM+S-@k^W396;&1PlD3I0)^)Q^u@V5By(EPTl!;+>k@t3^TzMw;#bJ zr^eqcJyDC!?qf@lE8}A%2(5nEjA0cDD0&#f%R&$GV?(45M9=Z2RU(Bxe{B0cN-QAx z*K4I00{;460^{GLSAw>aOdS7`KR)7j8F2VHml5w(bCB#PZYCpqy>P04jEuF69E$!W zkyP%o%!D8qh_-a<-f(NZgsLFbk#0QRruSVQ1~HHlEO9riUGYX}%A)g%wU46)wtER3 zh)C1z9Xdkw{D@ohB+n)vc}_|ob*hsE1ViFV4wI|CQ-WN!yayaB6xc-r2@svK&~c3w zUpGLducM@@j|OC$xK{dqL8kppdQl5AX+V546UQqa5dTL}co?hBD62TvtYfVPR>So> zHQmwTDi|-Zg)26_sDxA|d0OwNdNqHXj--8olLL0owo9omVkQlhk)yB{tzc^Vu*6{9 z)sl@}Xo6*=No*iW|LSu+MxX1k*P69HZ7F8|M75~a`SQNwa6>hY6zDZ871Q%DmJik7 zar%luXjP18946c`5Wsrqcx(5f6x6j1^GpPE@a%)Varqy^GNNIS1;{2X`C~G}VG#^4i>3GpPg5Q#P^!t{& zi;cGvn}Y@-nR96AXmhD@F^~M`R!1pz10JQ&XYM>AZl%slUP=`0hVZ?|Sk3i~0!zx` zh$7u3BNIn0$8q7Df!aqefxvnhAT`RhnepbaLEP5G=07ZhA7B#EADbPv2nX;WGBO~` z2&yn3Q+c#&YX_(CuybK*zP+FlSLl-GrBy!;3P8y;sAUuur=;5gmZ2j@Rp4F1)TTZq zJ{A`(OCMvhAZEa5>qQ^2P>9u6{lRM{XQ|)`CS*y7!|v_a>#0!s>Dj!efGj5d7Vs7y4__S~)2yHNSnzLiQsW8>JhcJVK2lE3-KMQpUNHM@use;G-9 zWRnc62x{PYg^OmPpIL@53xfA;w0MZ$YeU89oN|y z8}0e%emm_8-88Hv&Cy~o7O`gS+S`v<34C1XC@Ej<$<+7+m#`7>`1hB1>aY(iK42Lj z?z(^->3Wd@X&#!05{mr+n`IKs*e9?SH?>ppLtuvA<>2v2ksDnD^MfU^vo^Cg_g*1hbsD$1wiwMKod-Xk|-z+cr!;dzr}iRPdoZB)6tP2y5!t0 zh2H>SG9|X!<|P8WiWD{tc(>RS%Lg;TOz4-6;~Eup4=X&mI4Vf+8O$y`)Od!CGdGd| z9ZX+qJi@?VZx&R3rfe9scw(8|DL4X775W;gB|UpGf|w{1L3J3f)=yKhZFfL_#3wre@i&#k zeGQWi;|X5}F5e05+y|k=8XWX}PzeX--!jk3k7HO*(mg6OhdIM-%C=|ye<22~_}af_ zq3oTOH24yoSEP|1YP`XZ?{yKC&p9*ie+JZ}d94wN+*pAUF18nQ9#=K^rya=;cXb&b zlztgPmogzAvwJ24YEHT9!2KJWh8M=GqM}A#l5|yC=o;bovH8D@cop0q^ex%(?tPQK zQ3RQQ<5Fo&sr=b)aX25&bFW&VM&O&tgL>kYwD?fbv2$9y(l1R%dsb$zQKbWsK&PB{A@qnGVdOnR>13W4o>XS#&k3ci|F_|ps=1w`^HoQ>0#CNc1oefs_vf z@p(s}00jwAl?ubuKk^cw{4{M+fWos;;P=n<$;}gxCcsqu2ROS@nn1y+pUq<_lT5?< zajy~ZL!>o{O-o#oMzP@Wp&@z%)4)4BX95PdMv^daD;uny)s=eDS+e<-*wmY_6|LGr za!~bT26ed#BTMJ4bVC+4SHL^giOcfnYnA+W;Xym3UVRTHBvpK|F#|9_ha3g-B9N1@ zz3Gky#~4hNFp(s(5LRLV-y;}k2!Yq$oQnIe;@{i@{w&X~8o(75#J6u^=`tz<=*+{n zcd4AJz*dXfPZP@4%JhtAD6p}@+Fe9aB|{0V3aA0(FB*Rd2?mFwCA8M$d_YR&b7WSx z8$XCLYQ{4NT{u_)cTY8Z)gf$IrCZJA9n5o`PU%^iv}M` z*8uYSU&?tk#cJ#Dr zmBstRB%C*VkSa^g(6Suc0QG5y2inEj>b+!lXY%xzTqAXO#y4WK)*o}ff5h)!a>yb8 zrZ~XxL!^Y9RNFu7af($`pP}Q$XCx;VMTCsizj-ms`vc!7h=j%fY7)-uw>`4~fj5EQ zKYPT#XyE(}lE~TFnq5)HpYaf=)%9Bnxp*=KDRc*GKHN4w9`D92IRft zd5(sQD17@8clh+0?6bLbc+<^RnYE*lU{noEL&C~iQ{trkW$53tn|Nu9)7!O}YJa^W$^!vCA2EM_(_^e}{wG5tUs3EELw7UYlHn zf&Xzc*ZL#5{(~)rk8T>jFC>rZ5@m^6e+~(JNH|aPJGYh>rmLa~{0^>rS{PjNyb0@F zRZC7^Ufu)y|FrsD`Ibam=4u}czFAD=p63zZo12frN&fW=+bKQC{-nP*NaN1hBptx~ zyn%9})la;nwG2)MtU3#0ztijQ@PmdscS%0g1^{+U|Zx<=?p-d;DOlXND6rmwn6yj6nxa6=nQ3Gc zC~Y)?8RC{^Z_5T{Tl3Q z*t?9Y#)zOJ5W+43^zn@Z@5w>q>h-kW%|-uvR{g82gU17ji-{0|<3eB_%YQPw&$At~mF z*KRydM5IDZ$G-UU!8w6jp#2Q33T5ko2c5`StSb0e8lT>-IY*Z890HJHSb-gajfKvh zg>EYL8&br`_`m$`LFDF;0xJ7Iy*m_A;3i=FW;?l%thfsP!+5cjI?a+#pmXZ7e+=gIDbtq2

a7?t48i6udQy@BqIe=xsr;qI?=VPgiA^wQ#_hdeVJ@Uppp^TKg4uO9ftqayNyS zgnatu6z7}Nrj7HdI9-z{d(b3657!qjX*5K3d9-lJb$`71LkqjP89~^&A&Z`Gpcz%j z0_`~_*d#bSueJjP>x;kT(n&u#eHQ&MRs5`y_E}3F58EF)FIg9=2^nd!#tU@WYEB+H ze@wuzTD4@^QYKuFk+i?{l)iRK8lTEubc)^uX;DnnV_-t0F0MM-+x#b4y3M_Mr#xNz zy$ce7fKew3I{i3tZKS<o zD^s&n6G)OaO?i_Sz#eQW8`%jr#d^@y5!Qv|d7Qg>!`k~<aJ~syincIzsF}mRNN+ zJs^BufIH7V$CMM;3O`c>ev)3BkY_d4I-K#!?%m>4Xe`%p4VB*6_9>ASQW|%m{rjHO zxOG!oFq+`lYOEO@>|Gd(JY)w=~@*E1OMY@$?CC* zqXjVWcSVW+(WD3;?Vv3z6#26dTn&7PkvxF&~tMyPBu}9*vES7;0-)S|%&+QE0@{8wMiQ8Z=@-i=f{T zi>jbzD;pZFd1gqrjVHNBZzFy$W<2=An}uTp5WG2payskaBw+EFQUi; zSP4DgE@>1qiW&xJ33z>j=H~Gl3V5$P{D0)>%Xl4vj?M&k4AegWlLVSV)bEABy3q}e zY4f!J~p<6}uh^Y(?)Fx)*;4#IE{){uwpXsfl zOQGVj^ciZvf~*Pwz1`!7I8x-Q_~=VQhJ!*>a?t+Nvy1)|90)83-g?Jz8LwAxiI6WvK80lB#NW9w8c5Z7#NKJTcSbmtIGRPh`=g*bA1}+TLgrQE@U}ZY_X_=$)$zR6&9sUcTS&-D&gM{`o1W(8bOGn;^ zklBpgdS%BBS>R5E1ex0&!Bba^wsb$ceE-f10B4BbB~}Dj2JN*`;pTz$f*ScJ(*Rm` zV@L@hQC$?!#^wJ=oM=Bq;%`my(Ml42AKsy=fnu0CG zdBVuS(DIl%e~uFL>i7c50NfB8A{HvSoKU*(Ul?rDY_V^abc$es9|@$_09t6VPh#3(&i~?A>{-n6;W2 zge(BP%N^_3WqBw$WIl=n+RgCpQQ-4Zhf=Hv;6oPeU!+K%>wo%1+bmL1XW{#?ijqPO zJ|hiZ%nTX4^FaFV3iy9;jtiRkpEMA#ylHGf3+0*rhz@`9%;roRX@7QaOWMLpa(C6s zN5dDrwL^o!@+(Zgqk|*0iQPEZHYuV%6SIG71R3u`L5HY;2d@Q?9*#*uE!99-tQtz-NvGw^ zXHU-I%S@`x zC5WoE)tWfZGp#%4Ro!1b{lN(h-0NdB{kT-b#{}vu65z$3E0#5qNf};vVMGkH|D)C2 zI$6s8-wU6cJIke+T<0wGV=pPP$`HrwxH70gF3oj}zd@9-#WFT*^Fq@_JCB+Mtep?E z^8|GT)e4iOw2lq6!>sB;OWsqCs!(^g1wH5T+OFh@0NC`gA0gqDA_WnS!w;bGLcc9a z?xYUz6na#|9ny*wJItJHpr6+O@QIG7BKSZ*@8mn`Wj`;s<-P=zOrN^eQ*QqJ8g>>> zuVm7{JwMaO7l8Om>)anQN&xXwej^FC$#K3`R*p@>>5OF*VP68!;K~Qn;^K#-c@lDx zT0wuqkni~#;22+hkYt3;x>z6rZ$H4xlPV0a(sA+f4Kme;JH{(-qw9gGH%BOqe1%3u zgYguHPWkj+EB4JH)I|kyMefMoQ{My+&v54HE4Dz?2}bBD+AHwD%=cK-)8;zlOAO_p zsxyJg(aPQP5xPorHwSE9D}z)n>SbhUQPjo-c7OjPgz*cuSC`D-tCGqh!@+oqVhG=U zn(Q-1E!|P^=E~k|qjU3s&tfq@(p4j6rNC1@PbvDoQvV#oR}Om~b{n*%TK8iQgT~C$ zNhcyFhMc?&9jweF;VsH?Fw2TG(R^^RNYo|J_$?1m$j-G&5dr>svzh{mEB^~$a7aiTUFP;AUJP~L=pa23JXfG5tSU#&O z_sZ1)h>$&i2pRo_2U3+R%D&G;NUCCUux{l*WLIxrJDy;I2QUB%6L+_{>-W>;&xWAh z0OXAfhxk{ROOirxlporpFGruKAirV>F0-e+)d)HiS8sd z)Ve%cmb1XfC-n>v;my}V11^ze%A?BsO$Ix&cMg>2J$6mWe5v5Jq3so9Cd7P=nTPyS z+JfppJQzEI#)G5Oi+FH1Asnrf%WD^i2a)sPwGoH5iZfc~sq zwKO+UcR8tFwAca_?YAU9Rxucmpe4d(Vd1ns34&Ht*9U`}dj&KX{8Kc%C@h{ah%%u3 zG5GZ-mCmUJ6c+yU)Bo4PBLDA&h321y#YWK>cvf-36&QIj!$<~}Tx0yH&l^*2H5-@fcB0!uJUwqvP%!1hKf4TKBW5%c~$1GY)8 zNwBoH7VD{;v&wCC^7sYu@ENF+O=QD*=HoQ~W{Uu*Cq+T*BuC?V%TC}$Uev*^(k&HC z(T(h6|1_{27L^c!iTM_Y2;ce!1GVL4P|AEyA zI|2Tn{xN*KRlCbBG(O4C{-;=%QCcrIgod6cT0FUIE7LE*AaG&SmC_yLE#W2r(La7n zghyJtsTD7V^o+4n;8`~Mt9~p+6M7ML$~*4-Cj^gQBUU2fVXT5hs=0YByekhS&mWtg zKCdEoKJ(nmuZiQ@F=1sdQ@9Ui@{JekT;@#291bT(b((T~P*+df~ETRA6ROEB3{ep5!K*7wbhi>dy<( zUi9vJP%JBm8^4lJvYYvIu#d|XWTV5S;!JHtN}P8l&NNtw3snJM1TlP%E~>BITg zSUqZ~Lh6a%9J0^?-x(ECUjvHHy%A|qDc0Md5PXRB3dUvYpwq)eA6j=zUu#3$z+eAW zV)S^M-| zP7&<}`Y#+1e}#@qN|j)0C9W2Ayq_4LX3=(q2}TRl;-9RLt6RyP{m7l=jsG^g3vZo{ zKWCggsbSv3aLzM5|=XGg?vpTm1kr#2N?V=;mn{FsU@ItkgjVYGUI*>~~FzQ|4| zUj)2S4?5^xu(BAx8@TlXOe2r8z03q;M7!1!9^OO?YUaS2>C@j6qj9=+pINcn&!-_O z$ky2lfiL5((Q3loO ztZ#aIvUCjHk;_Kz`_rR&Gh~H0>2KPa;S(X~V`fEHd$Lk>k`!bTEW#ACZImt2`i$7UlaT0}MPaLSG16_a6WHEXqjP9;8LT zP7=eXLDxzj@JxDNiZFh{eB6Ap=IKINI3rhrO@V!UUtd~Qx3eodK^%$aBJ*UD)pq}& zTDF?$PojM%*yhgob)=83UguxivzMP^j#_JG%IGX+y*`E^C7)liK&V1|G$##^1B1+b1=mRTC?cY|{_8J6+AV z?G~sv>z*>^#wUimWgX~T(l`U2<&{yM^|)(LILB>yP zwE?tDh&2Ka8hJ0~9E4`ce8giae^L;`E5SCs`KG-RE>eq`_sUQQPo41_!2A^n>mR$(-m+Tber^33oqgUt`Kfa#K-Ha}OFn91*C zl*cZH`AG0u2~jhPXy65!IY7APZo#78GZ{<}FR`ZzSSM^J{$WJ7nyU`KAMhRNx$(EK z>>qRAE;Qtu(DhHV6IDWioXz(9`q)BL!u6o$P6z=(3oFsPJIL6t z^JY(m-h5N5?nzVQl0dkJz=eQrh)@?7?~8$0>nngu)_V_kt_6Kg6!*4~K3Qt8?;QX= z+(ES1B<~yt>@x6wF9s?aSps__f7hLY1VZ1h;h3lv3bM`)vZ#2igxrkSq{O118FBF` zsMtgOEHa~t@_n65bP8V-73c>QrR5pqfiL8+z&LR1I_;>cIQ@E*{zQPBZ;T)b_(wnx z_K?&2LSUl@H};1b(Jbolw86Q+YH|;PWuC(ghy0g?7Axx@<`) z+n)~}6Uqb1Nrf;p(evz;#dq9$0w=UP=~fKAGhEA!5_nBI(Jy^l?)Xu3KKfoUi1`>F z9wG3e!McTo0;vHcN4(Y|{`E{f)Tz`!j%Fs#Vs^Hs7G^GvAn1)M_De-&D?L(#WkYqD z7+TO}3L`6R5{2VH9YFq`L*c<%a)`MvCCw5Yt2STEwh4Qn{4#BrFd2V+InwO7b4Dn` z;Fdjn5KQ1QUNKBWLXCt)sm-?n{g@CKTO#h5xQBvKYJ4*CE|yu2U$Z5O(r6gFJ1YvJ z2t%+&AIQbxzjY{lF?k+lfWmXP)3crJt3@w1rLWIt_{xp-7t?5P?8JjX;=+ zi5YZ{{f{knm2PN5bzOSII;{9{_?hTqdqls)M=5YHx0?cpKFXV>g65x^r6=Ego_a^9 zF%r|$|KR1FaanG4=fTL;>itB`Tlf%O|D{=@hF~<*dAVbV$I}7GI~Dx?*M+P-0rbIZ z=0bhW=qO^ZKVVxmg?He5(q&RcKu8>+j~H5kP$p{65|Ca(o=gG`7P+}0}&wZzYp99DA~4zo+iy2>rcV6~ zWSMC5aO!0}N@ix4d#3(?Ti@dWq)z#$k1w5_$QX6v_6C={c{>8vKpY^(Ed`1+D>s%>G!^f?hXaC2C>W zrF_n$AQek%k@D=R`bWbl!3%P*7Mf2O2 z-l5V0t!kJ_bmr2%BHN@2i%$D-?IH4egM$z8_u_t*pEw5>$PEVOGNG)W5t@EoSy>fC z%o3vPW8hQwNI=I7Zjmx#Dmi;&7w8WYO5v=$)8zgNS&mJ_kAMnc*XAeE(uKik!6>o3 z23()uT20)@^)*0_7SL;YmnIjl47ffU_9F|ccO#nl8a|*9!(6{q?Fr-nzfcI%*X(50 ztQJ!__WA1CP1qBz;heL?@YF;bT-nl7$wQnd!k0Lgo0*g&5TsUSNYiJLx3p^Of_gr&_Ev@l#bXRUj4DcJ0)(yg$!-Cj z`mWejD!eUw4P(;NR93wO^3Hb-KW;yUb<*W~Z(E^k6X?C} zH}~R=T{WFCCn7PHrSc4=Daz?x(>wJ-J#z@3v(8d2=3b&VBYi~GVY-Wb3zIjmy#>BcO&wrl&{p8s*Qz5~b>D#mTdx+R| z>#vkE=p*&3Kll;C1o3U=&Ni$E`8kd%X;$1JS>$^uC%uNZw+M^pO<74{&)59n-IF<0 zLVrtNLsxI+_*$b7_cyfIru@g6CrG|3bUn3e2o$L8Byi7^Nk9q@;v6#Blmv?KlwGqh zV+>L~Orn3vHBpMe8V-y%5&tg%S426XlSEu`1mqKWEVv_i0B>!2 zZE^N5cE>M?LMWh-wgqciGah$dq%IFE%@ zaFlT?-dC#iaTiA85XvS`v6LAgZO>G3(Y1m?Kq1kM&RjkxwZ_EtrAHF8^SVXb2TVW1 z`mCwsUrBxz+Dhzw)o8w9S!`}0BLf%V0OyN!*7%fcpqajrr||#fW~jABz1Wy22W7ypLDSHe@bAPO7ShV+n}jZN9! zaLtNEUfM?5fK;dtdhCMYV+uMgq|y1uY0S>uW!L>vSVJ(Os1I|s3eWd&H^$Kd%()Sc zwbk_SLdpE8h?F zqJi6)=1W$UNO&tS@>PypCwxx7E_lfNzTzclLko1R_HM)(TwHLphi>lv)|tx1`Nnh` zE8|ZUI-fqlqtW|?x~;dWFv1}thXi>{*ak+$n99cB`lR0Rc_Ac|CU0R)sWsRwH$Cai zQO>e+wsnMXE787-%xa{NN3gZDo6Jn-{pdPU~;r=0pzaL?h_u$TesnSMh>Fldb;^(7lZ?hJhaCnHam+y&v8;Yn2ua9od zM&@*OUu(1cBt@iPxdUH)r%NJImnvoC(^2I-8~U(ht;b3mshZhH3pzsltvi-s2Brb{ z)Fg4u1fHmLgi36NtuNGJ^L`1JPiqh8x~A7n8QR;7WZ+3Zzn>_>*?X@3GLiaF_Lm`L z=^HMV+5r?{60L?vk#0&trQ@B~622|Eqs;>THe(G!a*!qL&eRa*Ak>8K8t zJ>Z_ltHl>t-2t<;T}JP#=Tal@eqU{|T|dh$1$*I5gl1hBaX25$SCL4)hg2y6V10^> zG+hV0qHWRpZ=EH~89AZ_UOifj8BjLWr(+Zv+lvu$OxR`ujfQ4pC)j6&f~BMLzDm&; zbsN>vVbM4%E4NB4(CHy1PkQWqCtbZm+#M(0=d3LCJi{t}{JdtBwX)l3?!9IBEvwrj zuobY*h^I}PtNg9QxD2v=h*QyhVT;N2a~9uYsy+$YAb$8HNviprHhHxSeOo2FOnj_~ z=Bw{OBe~aTdcID?-S&FYk0|}La1qU*HLTQ?TFn`HuOQu`J*(Yme&`$Ae{K7S7qbV1pb3uObCz1)XD(>{>pOxs3dn!a zkbj|?OD&{F0n5H@z~RjbE6x0o%Gtr=2YyYdDgrMxv~u0(+_vIOgG#8Un8wvs^LGJC zQpu<)w-O$Mi&bvPnCASO&$(8^?Hb{XOk!F^)aVK-qPuw6*?C>^P4+R$iv{lWgC60G zfoFI#FCK~8!ai2rqNu?Qn2(I5mu|N=Etscr(bs4(S#pzzt(_kltLr)3c*3VA#V{pv zc9iiWxl?M#`Qfj^V>0ASbBO?yK_ra8F_W6G*kxt^b_7&Shw{#eK~9oFW_CV!CnRQ>3_^7i1!|S9&<+_eP7V}I;#wQ zof{ZUD5(R*x?P;3Yso4p!vL<21lk$CDn5o4_Jap$e@``iS4>U1BO@m}cA!*-Z?+~e zhRuu@<4R3P8fbnvkK&NFF|{{R+ruP+0xXoZA04r2YdAME66j zFUUvLN^^}g3vE^#19jD*$-fdJ+A3yOpFK{VWgBb4&D;=Jya2`1S>(}Ob$A61jvYt zZb5v#$b+W@17jknc1>`c(xj%Ew{W4ctvdc;(gvVjXq(}m)%&k^$DpxI71;PNc`9dN zG5O zLzA*xc7;d{0#b(6VK?@S=Y-Re%d(JBq1E*M8YL&~y7SZW;q0o93+yzx)VZ|g=n{56 zQ(K+(CBS^w8 zwE~J$yjF2HO3c7@Bzrrjzp8EZu;0tal@qy)O|mOFXj_QDaTGkiV@~%tfO7B=NV`}* zZc8u6Hw~QggsxtCG9i6`=1NVscEt5dREzs4b9~LScR3G(1N~lRzIK?a4U6@9qefn- zDOQ~p@r)l%|6(a!D5%T5=FVD$}TH6_0{bekF@VHRE;c|Cl0rnK8IAr$qD15-d zi-5Z%+wigDrfD_&STtB{pA!5@XC;G)(N@Lb9$`O$pL+7-*V^PNd?W83QV>^Zr@;J! zoW+vxy=Z&Zhl&!_G(6ry$z{FZ&q-;flSkuel{RIzZe{ipZ50Xn1~Y2a{Rw8{?ZP!D z*&jmhR@cR3+BHyOg)Kz*k3BiHYYGrm1c_xTjZq~n98oHpZTpjWXa@8|sA~Hx5-or8 zXUva1V(Fs>Z4&q>@EjeMl~=y2h+Lr1ZrEYoN19ymFQFF7^aJ08<9~zvUZ#ZhW6+c< z)D6wvE^#gbTC2I%nr@V0|AH5Psr53&{^ku{nB9g~M#tWy-O@KQT96kLAd?x&3WN=& zabuX2W=>$Xz{8z+L-&Ms>%`C?f{a8h2 zdPn$@(_r~CYKk>{NNl~F2TMqfe09GO49YNC|J^SNk@q8?6G)yDFU2-S_@&y;ENE2| z>zS3@B|t1v^J}8P_H7~w$NbfUDJ@1Ws!~EouB#Lhb$2W{3ho;P)xAT+;6bOb0dL`- zY-8saPW2mw492i^$wqsNzeb7w~Hu?hV z7GQ~Ij_~ruWb+4ssoJdoU0oJ= zieW(4U|{wV32ULXLwtdfoSY3~K}4~6KpPJaH%NP-iREJSu1y~UW4KZOSyldrJX4RH znP~(4+v^}nLka^rlpYJQuAx$gW}3arWMWtpHdqSUXG zU(d$E^3;#czUI>KcJL%UV_h&DX-X4jGsq1a2*z%>uYt+ag=Z_tcGUN&IE1>-NczMn zw!kTh)F6AtPh~F9lly4Q+jif#Br_Ov(B5gRwKrycMAZE2lYXl`NtEGn&pzz(c<0@! zGJJW|L^b~bbH05q8Hc+|(Ty;;?gO8tN#vMrf8^7;-B0sYTE9GuszeYhXK0L=+_H_% z9#E-RkKI0)(!yW{Uv-$;IC3#2qp60983b6pG2C^j$sQ@#WJH&geWGdUi|FIt{%)6B;b;)K8fZd$Yy}2GP?w^~A|xm-|<)2EKtz2J|IXScpKXP7B#Keq)SFpfrAfu?G z9l=_#GwIHo_S&}ET~5!oXrSq!bE2D)aQy83wz#`-2;WGL0G{%j)D=PtWbx*y=Cc2c zj=*u68~<57(>8~Li+OG=NVL?!WU7R{NJ8=ffjDJY9LJ)gARzi&lV0p`qIc(Z}*`}R|Fag-Y8Ny=;F%fFfHJ4JQfn= zSQC(pJaW~@&jx*mpBNfFs4MuJ&?WVRi5>@ ztf5a1NjxXRy~S{DN+CQRd26~(ZoXcrBasKN+aXFv!RcbmL5V-U#41`8VcC+M=SIZ5 z2y@o1SQi@8QZAY^Y!_)3`79#)dU7qYK|;U4jof~EO(^Va&~>g&v?lq1nZNATR|{M& z4U&>~8(%8?5A9F*q>u34V0%i8om5hPL`hvD%}dm)h&{H$Mo6W zg|)-qgRgo>pKp;{`8Ll;t`(W2=W~!+N=3)F4QquwT%Pg=u~~BZ8dUK`**V&=(k4$( zoOtiI$4ZKuq)&>H9f{N%a#I>B)MW;^C`uj;t2UEyK74NKXA&wjt;X z3-$Zjk)cwh;unp)_k$F1A_v|`@#)uJ~NZ9Y5><6#h}+2i}1MQ=OtE~%8(oiB3Lpp z`o9zvL>N8Eph_4@U8%#K7uwU7d}qaCpbNeE0vy2d^x>GMW>N&byg1OB1VR>#U;`fp z{oYb=O{CX@&Z$GIhJUWa01^b;sc3D1qYa2rDm#6pp`wXXomI_=t5Lh6z3 z?gr`Z?gmNe?rxEmM!HkFyOC~?2I=k)K|+cD1G?YF`z^12^PkygXJ>SF=03l3pZmmh zuIp2k>%AP)8U@ngoR1zoeAKmA>#?NW(tXOgg4_s5LM$m$G~end6v_k434zqKnc%ql ziS{o*Ha|Z^@}4I4fOW+->$mPfLXK;<)gu-~C{hd76p9mNOOvEUjHW^PP=8j23Syi{ z>|2HBBpVH>e>9PqV-3G2w}#Bj?z*dviH42FqBW~Gy89I`aCuB*nw$m#(Aa{w;H5)% zfYKm~`9Y@ci_8X6OuzDIQxWEiyZHC6+U)v44l&|I0XwnR7t8M$sltY#Lp63fr@4nhQ-;5^eL25?Mrih2r3d^ev4<`_Dqg(;+vHFr3)qD_ zmnR{<`bI*i%jBQ*1;hGOEb4Whw*1y%y`x_YM zKf)t$cy!;Pk(rjl#k}^zMj`OsNC?qEgoMN;Z1_0BvhGJ;H6+vZBNZdS0XsqdI_iL? zFcY^Gm1yq_)2RzJE796s0URRv3bGQ+hTRW&jYlhT2q zYv*|LS(aB(;O={B03C;}qX$6pvZ!7%4vohqa8wu~s=!YYyniwt6O!^hRRK(*1{*Ih z7(hTWf3zAJ2U^klQ7iKQj@$h~0QDa=%0J#0eak$c@&04zvlHhNrpT4B_WVHy<(^}& zq}9}Ej@6@Bot|44Nv~5c1xT@&d(;qTW-{xSP`D|X-)-A4AK$$qZSA`(GPX^tdKd2r zDdIK%a|dqudyzvtkpGzglcG2}<(>`)o5FARkJknKj*H}eDfaQ#<+s2Me;)j2a}PLs zfc3do!+GkXr@u;2ZM*&vYBE6%xEC3>X$V?Mt=8W4!2NBgsV6vfgUC#X`&EJeYP$?+8 zYB{F^&9Dvp{re;FTW0u6yYt7B8YVw4GtURlEh&I)|Di^6&d$rmuM0Y;j;GsCOyuc% z5eellZ$i1zeb)fGMfn1mj*9d$G$3cSdhjG8XV6mnIhT*VVqgjBCn#8-PrAB78cPF z-4#-Z$*BYHCud>E4bdee$|*@6@Kv#K!5b?PM`4}46Fukaj_H3B5^kDt=9^xyBf@v< z{3*QxTROfOP_~WQ{B{4@ajS(6OTiycLzQt&XQaK^7aRf)EUsB3Z^0HmiE1}bJQ7Pn z%nK!fOU_ld<2uK?ZFaflvKw_Ntl2!-M&{*nN1;Qe?4&j{51%$lk@8Ub`k|Raumc+X z>#z?Xbpy*j%x`RiiBOGI>)5>Ijj&SG46ldYiBC!xLXB`5#w9AF%D*@vqO@kbw1{Q3 zx_ux4QS|Z~NQq|(@{hG04YYY`!nTzb33Ru=CynB9jxWi~;Ly>GT>L}q! zx6(A$Q4&QCCj^3E1ZD(#fScvRz7M^l>ibpisukE9nn(rcm^4QvR_q#aWvE_h)!bm0 zJd8fxe?A$h1Kx92n)IzDJG0uA(Mkob8yBJb%p;f3#nfC$y|SA1A#71fFeAWvar z%YoV%n2eRAKbn@d`k7%F!*q(x7gzRPn$}NpcaYXnij+c2yAYnadyW;38kVv&aVH1U zA;nX%_;aVKB^E1S9Pepj*bbXc$urO@RceyJ^nSBJ)NnJqW&Ju(tMGaUD4eC@$D+%C zna3+-9aztULGCQINV?L&HWawDSi3n`mSNp+oZXiu9*$viC0sIz3l=3D7n~ zkG>qgHLm$)-OzyHi<-|x`kZkcO zx4Sh7?H-&eLvDsFw9~=h&SS(@wf)fJqJRaTlfTBN8%6w$2XhN3e3k%n zmSQLA#Is;)V#5D6{T}dTQ~2b|6t#M zUm#`=kus$qc&x?D=}^3b>EX7_BD2~cJpbDg_<0ax`RfELJyvA42o~&;Y^m%s&RpBg z({VsF@sdOQ$V-pwPuaZL>;>En?gyx^CbX=A7-u_a_mIFqXt3X$7NN|*M&lgZ5faR# zzYnvD{*3dv$^Z7DnW*?(C> zHs)f)t$%n=QvO7diM&r13XDY7d97g!6!N z+J)#GbC`0nlFnMgdS>jrhi=$pmqiRO*yzIidFPhIn*L_3kge#%u)0nR{&2Y+)<6^ zPR$(e{k4HzRF38Ouix*tLdqXNhks_QIZ?yF5dfg~&bN>7(mOc)@`GV5z?LMi1PRG&+<3)uGF%;Wg3?WJ^Ie<-FV10wS~RO)?2{+(r2%v zEr@%a2obkmG|PcSv&m4_nc14x|M=5MtMY3&PKhEr6HaXOcv=TOc5laGp9_Ch*7VKp z?q_Xw2pUq(2}WwA^!*jaDaGa3WSCin3=4SWsUBHcf**L_7`!+Jr-tLNu2Z@Voz-_Mp zF;cUIAw|odagX6zdrzGp$~*jYRSJs`RT>1aM@V)9bPojy#55GAh#i*Rri@q;RKv9} zt*zNt3K(&^LQ5!ahV82)^Qyo!Oog3<``QX&gFd^hLErkYXn057sl*{lP*qr3U?djN z`aJ2pM_~wF|LsR%v1K-qaob=XEbrd_2ObSPRaK1~V7$2o{{BCuj(-C8{>Y$##TOVq zp!k)jyO!gkF9a_?0)WSA$)g=e$qVtZg*&q@KJh5C?&TSC|Dj zuV+$F7A<~rDteRlJ36w=tz2EjR)7ROcY=kn))~K3%5A4(aYdHANwHZm#lgYhvIm~_ z=7uk);_S_Pjc8+sBP|RDPML8`&(s$9?`5ljE#gednxum>t-7D+eF8cfx$NY~3s{J2 z!BCW3J$)S)Vym6nKtkGM9%gkP#`oDA6z);YHH~F8PA6$ z-X{w>;$oG}_(RWoMd!cN?j@ARl-hU#e8Z=k(#j*nO>wLPOSkyy=U$e@no$`~Dz+Ho zK-KY}cQ@9&;HFv>nzG?W&+$apDB@VQDGL4`sHeYN&weQ@C%SxFn8PMcFZm8pMeWsX z`+;8h$O4pf9B;g+7x$ZY^IyFpXR;wzJ+=cgT+hrz*g7c;NMDgEb|{&NrRm&8BWd;p z*ihK|bU&nT7jrDN_fS5kM=i+*{2RafR{lr!7XBx7qVO<*>X<;csMxzmayD=MGC~L> zQJId_2O|=rJO@|gG7V-;deFJ+h@pFNrd2g#II>*~KLI~Yum$X%7NWA$>QbpCS3y;j zg}w%=miSO{x}Mf~K#Q=_#@zQ$pFsb>8nuFGO8}m69r*iqfBLOq)q{-Uf7l@MqYO~trYEmlm0t)J*8{`{ zjjRVIh)hUKOp0p-Cg$ip#ZhhYILW2i51hrr2h@;HN zd02KQhuMTrZ;0#Y^KI!I`xC|_ERj(MFg&zM#TeZ_x8v`2sF(|+iVm5oVNLQ7n^v5$ zqp+oOeM|=_xEPqPHaR<lPYnNvN7dXtKfg+>M)sR-MUJ^Hv=p(KsPJyb&U1~kB z*6z|tbwwWi^l1jfN`}ihUf@9ElEWnFlaGrU7BM8-wzau|PaaGuZBeLup!j-%&DSV2 zTCa!sALStS^ZQEK@=?e7t;$Kk(aOQp(opuHdb0m{L4UTK#Py~{L*?a9;0S$u$>7+7 zg5co^pPj9kGR{*YIU5TcTa5mo&(X8~><{gRZdBM<*p!>Djhp@iTVFDhF>JeHL@$1C z%s_&a9NSHXIdNzNdYlxBBU3!lY`wupCH-rlue)HCPK)BGSH69^TyCJA+p*Ud>t5wu zpJCH#bY=2tXz09@IQ9noavGbJt+;x{q)ON`C5oZhiqBG8b#7 zo$GB`2RNEk2Ts;rFAhFn4CpX=_P-XvrbY>w+v~+79$Na?CK{_~ps!t-X`d{wsQY{n zUglgoo=Z{{t(qX8;3Ak#y7~h>g1R;ad-9jk%v0$5ya@>-qV|5Hw(n7s|JI7(kFDAt zrY=$0SDfI3U-q4QLTD}bw7af=oWC1l8X`g=m(kD$>`I4ME1D6TxM7GyS108J?$p=o zjaSS%sp*cdQxe1L{-vAq^E%Et_ol1Uiy7-DF0lJx-=-G$&u&C?)Z;_HSuD~KpEg&H z7JT#<)M4sj_1FK5o*48_Z)Jx-j+X<4s+LARXZmSuiVBU04q?FHg6`KUBKk}J#D&vD zVmbpGS+wv@hx9gT&Pny$bKy8+NQG*X z^filn^2knG(B25W`|O!t+Ht+2n_#ZQoMwW2Na zuWbvWA!(ow1q1dk>I8Aj7?Rmd?&xc7V5|JO=F9zFFNl@LCFvYTN*KksDl527i&Z40 z34kdWht;Z^&3jVP*MO;vYhdf?V#@2n%YFXhLHQ0pq^PaO3^&sI6osl=U}!y8(3bv9 z%|;xyHhh9q97*q~VMZ@|IP5{1pCeBqbuujAo46qbU1nPh$OQBdxs8@L7W9IWj*2(C z$9uC<%@WuB* zJRLH@b}H=&!W}<#d26wUXNI-VB}E_I@9}aivNDI2a4}citWR_yW860NLeYSt5KUa7 zKo!%S67l9>^%ZB$;L)n{TH6x?xTnM|jsXdcCj7~Ej=U1GW0{p zrw@p(@}2}b#sj1h99C({*t#Q;1k^8-!W8C2;oCm3WW>`L?S(@xp2Os{jCxpw$xS;l zqs2~X23s@@zSf0Mlk7y9;Sqt?=ToJQ`_6L^vP;A2cg4F@$SIzXVzG~$=h}~;`xZWx zoEScfR`=}W$;ksBX{*^M=KEau>!WWi|8H65Coj-HtGlqjs_D5OuXN6d&_h0LzZVw3 z)$Jt3V!`^cL}5aS1(S!Ku$KHoT)RD`y!cGIYC^hyyBQG)N&`;UNuP z>Zp~_4B9oX1+FchkSMJ+ETC+*LuB6o$JSx-0vuRc$pXX{w?~(`4-C!-aUWDvIvqQ% zf%M&m$ITn}3Y#0~LJ6OaS<&znq8uFN_dBbB3s&Sy)za z)|Z#v`EVI%SjTB#QewoUZT%XbaHiMBt#Y*p%YbTwz$IC&31K?=lhIqJ5B;pCIfuR5 z^PEo>+9-U-H>Z$%ze!Pp$@&Ffts4Yn8n!WaV|NPWK66D^!(Al~am}Z=i}ffal5+Vl zaflW^@5R~UqgRbnlFKk6rdojF8`nRs6wU1Hw?;Chpw^k8makz?705u5DN8swDOl{JPjL}vw08->5yQh*A1 zY5^_>tuw!Qvz}3QT4W@Lu^TGT91j(z1u%K)OLReAI5Ow3>>5&O+*!5fx}$cn@O9yY z>+`}zv8xK#1($D%Rn1~6IGOf+{=v>s;(k9tkAJl9_FGli4~m0-b~jDcQ=y==@EV;PaD2RuiE1I#NyKenn0^KIU}|YVRhc*@-50O zsIJFyLRFvdWxZEi>icRX%K?2RU_@+c96=Vv5yp_S_(=?>GDV#|k=E#?bgzjo8v2bK zo`8f5t;_CVgTgBej>rfoXsBQ)36M@1=cen^(S&G^+ZEzNYup-G`?Q9;# zaQOM@K5#gTLkr0`e6v*pgPna6Zj*RMgy-R6&QVZr6 zZV0u~d`O(LFX})bbr{=aTuJ`R{cri^>q?cNtE+f3FU?0hw%BG{yTpTRgA_ZizZrf1 zZae|8eilW?9gc+R6~DAKh+LYwUS7!{67E-cA}Hr!O^xQqh}_4Bi6oNnBq%0v^1wJ< zKS`CqSW>Bb;&T-1q?A`V25A%Sq&}d<7#1Hwsyfprg3L zX2!eV*;H8U3`Uz3JRIW{v)FZJFB_m~%v{$}+Kg3FNhRgXl2~rw?n<6ag)&?i!3i zUDxN#cI7B&3_~-5JC``&ko>-jG zG#NwBNwroiq9vOsLX&o^E=834pj4*GpOa*#nCErA9X_%h<}6K9K|miFiI@x`YRaOa zkuGXYWlwAK&M2bFYrhPw3$e4T_r$G-*CM4_vBB&Jvut-Rj%g)F4+doZ8be$=BT(xN zeLHT|_n~u)z@h5PuvPmuTe$2WBPR5ufNwyrAAHp7e`_fH6Zv(IiTPn+|H%0tTbKp& zRvNM>o^OM7keg4(LBXI~$lX2+!%9j>#aYx|TD-b^!V{A)3A*=+iC}1`H@!dI)!oY# z+$M-ffF(9B!mqzj6|Dog7V&g5SQ$TsT^mY8Wac@H@-z7_l_h?5JhAEv3j6-l_eZwRwmMg+5Npu!^kt}Q-C(e|XNFGHz->tw-nZLi_m$-uz3F4W}kPd$p zo{EjJs>dK#uQ{d{UeiKw3o=o370IRRrRvVS6I04=X4_KHjg91md&&>r zy?p7MBH{s!>8r9UK#T}JmVbUu8Xs$DczkICjn@{4=#GOkydiz^n(>(XUe6b*(eE|w z=6Ivhrq2Hm$JP~0yF~L0>0(w0J#11o8>z)1rux9oYShv4PV|u1%$PdCN~-w{T$)9qhOgR zdl@$Iqov4ebmlwFKQP@>FfS^AMxl7rD8Gd#`rB^Gf26B_s`X?eq_5BuM7BotX~`)&%shzwx-Ya4#P}C z)bx2R%GofopgP4PTAxr#CY;Ry%K@X?NtJov`=P zHePj$M=ajPn-(%&odM;&hOBK)F;J?+VQsnUi6{mSiwP5V@tJe%i5R!z3u2uw zvR5@ks&up{@b7fcWE5#dspl4)zFG@2=r*}oD3)Cl3LxvU3UCUDX3XG)dW90V&yQ=u zq*#W-ppbrb@~!BmTcM}8YuHm{@M*1!+pKRJ&z(>e!Ke^`uGXf$ zqX%<8zr-f60Yr4jiq6UPD_iO6%*q$PIuO4=Jhv!Lqdy=Z4am#68i|Z?KI8NM z_;%Gmy?mS87(S=s_=1f}`YcLy(4n%a^GopyyYVq5&oJJT9?W$6AsZ!jBX%?F6#a1h zwCs_JHk$>DMH$x}*Zk~HZr>nO?oLE(W_rpP;6$uolG098#vG#*Xx^5;#f%$kgPyJk zm|9tsh|Tn&p|c3g$K1+^)SXQk@~hw+*V}%WlIftq$Wj8o#+OI)1qR^7`7br#J^ohM z&d%CS+{(!M=VgfaL%a8739S&9pAWiL(-{PGa7Y?{kFgj<*!!{0hI{E&DFkF^t0lV5 zHrC^l=EbK&V?<}n-%;F6zu?5@OiH~KJfpvndX>{>nAv?BS@Fd$$Wgs~V7S2`GyE0y zmCcxd+DkQ}s7*>WPGc>F6l&dbQSRq#`XQ_Yz@SSc5KV_2R=51Lz&Upmreg(yz64X( z$?S#9NzcXtp^%C9D6I7~rXMB;pIjl+f>kWh>xWn&y?b&{13WU+qi*^OOCI+|5wW(j z)OB$9bF0`t9B39kfWLONdI_zj3#72kXTU8VYvX6I2~%>KY@&$*7Z$X8RbL7p7*T~U8T~#bYlxftKWDk)F7_|<>j{OXyPXNB9K24m*C2(0BQoy>eDUB&=~X5=hEs0 zGQg-P7BT_{et%}Zm>V^7RD{P5>YYKA&I7=HkN zy`OfGwsrazRvR3(z*akNV3mP}VcA6_PyjYxRFF3g z&=(*erz8WG{yXI=JiOG=YbQI#yHfQ2*P}m9(F;8K1Q{=T#XUvu4-Vc3 z0$wmJ;F}f-@aZFT!#Ad5umRtWM=oj;jJxS)`D4=zyuo>6ivIQA)A9G6F}_Hi##8!lBxF6|LGtACvbjX6E{D!lrj z9wr*6uHsisaduUf%+##)YnOqKt>Z0SJIyU&#qgE9G0Wb9r!8lBM-rG(WBnr z0G97PUvN8=KM!b)yGJeZi=Hp+V(RdhmouCn)`t#RXd6_aJ8VfnU+*g*ABqYs<;g%D z1;HdAecG@;#Amr4L{{2GDWjk>?Q>ktRh5JXOTF^J%)$fh)!PB_DAme^T*zN8 zg$C}53l-gzq<8U2HNPPZeMa?XleeuHLddSv6qJ-tOmvrJNk4U^2@jH1vG(0u8jxG)oRZ@;&)jnS|i13dR zV*A0$A;TUOR|D$%DOfk{{waoYNzTe|6yDgqfzF)3v*3;QTQbeg^;Fwv1IXYwv74`sI_p{yes0Eq^@aTi^3$AgWRQ-Wn{&7KKqb#k* z<$&q~&Y%O0R-mMU;1_;h`Yv4QvX>l;`dw2QR_{U@Cs1q*s_7g;SQy!zVG-eq67EgVG( zdKGkfE>?2|2*rO7Yh&L?%X4P$+$(sUYaVCiT+@5}eCbrWmvl9Kr{XxtDV~54$8D0e z1lAdYGJJljUN@0D!d#?xhNF4$*eqZjdS-Gj%omCY$I95FTh`=p8Ihm1V6hDOj&>60g?)w+F#fYN^*%;NZ5J3h?dCKHvr@#Qs6}dH4ZT&tV9a{=#Cfz#BGeI=cUs9!FV1SayDPDM&r2qz`{8`QR7^NOzwN4KtIZcnisK3#ROOF(_4Ubcw{)G%;YS*x7lP&=bxzwpVZ|1cwAOgI7u4^%Sy@{;1Kd_z8`8H$5Bhs1dgNQCDx#(kzPJFl%;xjq#0XCZe7BTbxA!-EUMen zn%5JBQ|$$TQ%PZLrTTWk()+A9RQm3QuFPzP#De)Rr9I~-=~b5p13_H9eQeZJLOdrc zWqIn^R||{N?#7Kb*LbzJrjSm#=nYGS{;7vQJ8r(t@&KUY(~`7uwot!V%~1I`pdNA9f{s9D?uc*0SHjO zduG0i-|zY$;FbLW1`?2=4!;9s08)I#n*c6B=Lh`&Y(YHSJ$=aLqmRNb8bHL<;y(-^ z2}GVEr@Z7HYqZUDmIK2p)uI&0T*)FcnSfW2Afo?j^RV|C?GIVHz_mrs`ygF@Kt}{w za@}7YOlLiy(Qo<5l;>qwR9f4#sY)ete371-d#Uo2dE9jOjExhU(O8Oxnwvgn#}-_# zC`}|J04%_-+bq>x}7B$(p1--Oxd8vk6r{)u!9g<-cMXetW%oK^I@qq zxY#x*19<#{M@{exEzG}UN&l+5PzuytSeaZ~8@lHDU(@3MS`i=>;$`{&Oo{nr1t$Vs zTBbt*dgvm%-YK9CdN!|3|5^cvqkF+e0?+$+ zF2Dx-8^2Hi`~>~~)AjGaJiO<6nK~;iw+|t@!~OuA0Kd&D)VRZ2ikf#!Zfp+)bHUDt zf3j|X>+(J3m`*Sq-u!%!+Fn!HkDs{(BoUq9aa7aYLO0i!?&uy^2m3`Vvap=aoz;5L1Ly85-#SY2Px*SCeO zTSF1J!N`y0M?RUIA+|G(wMK`v)ACRfb;0H`76FfY^{5lD{+dC4Ok))c^$qV8!T)Hi z05RD2i+jS-QWgizJ}jl};|d5MJ~}dy7Px}}%v4vLDfbDY9wDTUKTD_7$uQmhqAY%w z-wIW!eo1f_e6H&_X$P@CVlR`i8j?z_l26W9e6atJ**n`gastawqBL2Dw80I9)ig_D zmvCRyxhf16?Y7!a=swdC7jK7j!rfXhvf$BRbsRL=fAS&#tFV;lcek7+aY6T9aat~z zCj>$hGZZ0ik?tQA+{O>}_jF~bkH*Dc^p8Iw*oykrHa|&){wx%&M4l}HZ^h@XsEtsc z>!D_#e#<{fWrK`J{@3!2ug&aajQDK}U)xCpy_PUjFl~Ho_Zs1Ca>4QL!5T)2x@JmZ zI>dyYkRPgFNqhelc)^e2_y9m13fRI-;sFEn4a4 z#TR6cnVHw!dK026*{mzzkV6Vk9p&{KN?}CPMZdjGf&ofIL@f}sh5fFpH zUa~&(UztJZeJkJYnx6O+_KpF&S1sh^0gTC@Zc2OvG-}tQM*YR;`zMb0e+rU+`Wa$g z)@0Yg|J~1m=sJj^#c0|Ky1NsvT;Vl-NZ@?JP({ZW0;=FZntXilv8oxMj{!PK-0+wG zqfbHq;A5bIZxBpy{^?_0!-Nd?ap-a8&foO0zenc3S>)(!60vT)c_ZrI9;BQ9)}orA zVI-RZ_G%FH-qO=^WTxDP)_IvH0Cc(GnS zyi=5Y7(i*D1E4riD8Pabj{zi1-(clQ1$zA(VkA(qhq#Q{s|8j7w8u5@_wRR(4)~|P z@K7oKRm3YyeoO|Kns9>~_>gC0z4o?BDo6KR@5d)4#+0UOy;SO{!N9=U?_+8yMapVpQ?XZRtH5 zZba+hCJE#-Ar6?|tS)Mo-7icyKAd_;JEc#c!Pfh^6!--baGwa8_W2m<&I<@<7;;{C z<)W5yg1j8Ewt3n5TE&q?kp`RgYxLAi?P;S7Pml<*LEupGK&2w*%l0>e&y{~dWw1*Owk$MHc6A=>wb!^B6 z!bdbjnWRU{s8;SH<2BxC+-bUTwxZ&JejR&#`&jJa4XtzY& zXGU8mJUlbUPpoVy>6nnycPvXaCABG?H|qvexr_3(l}zo zKRXu+E@E*vcD*NQ_u(76YlZVk<2<|=%7yJR`G$CeX=%U!vKZg22Wms5s12 zC`yq4?pfkT`mnW`R^eiF_Lv`9&AqP0{r2=*W??uE$Se=><=WIWlh;RcOYEj^iv)_CsaFW_}o@??x;n6N%ghOb4gEd=BF zP$2|f7rTcRZ~@wS zBMqR^gH`=Z(5YwhNaXydq1JJOU361rj%eUex$@o1ciItsWnZs1a$D8weoO-JL}c#E zS50MeNYX^BAm(0dg=o{56mp-;e(u}we%Bu-u0^E`?Jj*Y`b8yo0cMV z(;SobzIPjvg=|+L-w_PvCv5|)^sA)QKc@CAbk>d?m7>M3(>>>t!C7QQ{2&UQhtcfA ztn)c4Ex#MH1frRAA4iRuV|?OzJGlG%wq{sX`w{3ZIpB{)#NWzP|Ix^dptk}p z-w5BqcaXwoBEPE#FgOs~1x$<&>9EJ}O!L^?_TUMa zjyG9{l09{UV*5eXNw^%bK9N_#=Y@e5WEBpY)>@h(F_#N|7?tS*4%EV+tX0c0|1Sh( zB1%P-g$?`Tc~q5`aC+6zPM&lXcFV18THd~22`1aCD{`SAV}<$ z-+wV;AhHAxmyDJecU74pcGNQzh$f9qitZ=JW{-?QVEZnZ7cCW#y|X8;XxI=5_pvuF z!qPi0x*lg%ru8#wT(?#ni%3J;O0o+rqf&g>n9|@5#~=k;*d2XGZuX`xsQ0$?OvE(P z=Sox159CQ5Mi(icRX*)D;!R@78;YG469ZIeiow5WAM!fech0OgAQ}5=G=bt-IdXf` zy1}yGI${f z#O>by2fu-?4NynzC!YUDHI=GpX+9x`&Ruty#9U&D*7S`*ds^AJs!ozOs2EZK9oEMO z%Xb&edcu5IEIH|Y$LoRHZY7%x^2;ea5+2qtOUsaasD=w3*%9`S4YF3Pcb8`dlv7zWS$vC(7H2 z0D;v&>9Tp078c*7cdOY12?V^b)MWUn9YHQs^;B*+OAf*r#65}H-MB8V10^e`;E3zy z39JXFGde9l=GmwQvab77d`l}A{K#vVe+TY7S9t{?Gh;3pf82{4FlVjm{~4lXbXTI4 z*V12Bz}OOuXsQ>vp-`*fa}AP7pIM)2{dr4lfNq>uT0HetxO9wR4a18IgEs}AowTbXM&S#U^gIH>-+e}-RP|8<_0=(QEi$(Yr zqQFGw>z?T`Mqc=^*Ofk0sgT|1zB;)7@Y;fsS-6F?~t#XQ@6OlS&<)lYE( zeV}G2#Elt+U<3$C2x68~;7vi?5?WUX2lSM8T_7y@s`%3$$ZO&HiNs+8`u4_0srDn> zjIFmPr~9l=lFJ=Zj7QDBb~3dZky|x+Q#qppk|Ep)p0XRJxsh-qS|b+bG!<*f8(Awxidq$SPTI=!W`)B5a*pV| z25BN7JolB4RcF7@cXl4}@;<4+b-dd-Poy*oZON1;j5E)Z&bLie&wE-ZQzYBeYjt=> zEsZjtH17C*{EG{=tbP)?PLGhdznTf@R=HV5C^P6_ean*o4a(w)ZPT%o(aCL4ct&cc zMZRXK>$JD90Z3YV0W24=t{a71RJ37UVb3>xV$M5>D}{T%f=%aZBz{xcDND(Tm69)3 zG#VRFsyV@M<{3A7CLP>et=i5VyaoS8vR=ac=`$;%4NDV0h%L-v#P5E4fl#+KF(0_P z3_NP6)+EdXdL20wC1fdHl4oDx9KakgT%YT`C!RJYxk}lG+Idp_EJA~(Gy9kpo*6%OBe|RW#;-lcn1%Pgf z`RKF$-#RXTgiauUMOatgn~bS& zU**1K+#HAR%{<8=rA8)n(gMXhg{7~Twa`L+a%>Y7UsQt|H{`3`_$nPHFNlRV7RrPr z8q?e|J|dzjenF$brHG25+Se2YZYE-kPFE3a*dHbDFzP1On`EVrD}B_auc=kN*;eS| ze94`iFc8f`b48uL8I7z-5%{g)nt7A*wF`YT@71{*pG=K4-Q<@%z##j;l{pQ^)rgnG zmu(|t7V7tH)PSr(pCAO77IbNSNcI+~_w=C^JO*?lHk-5ABj%b(u~DCQL&V4wC4Cv? zo(tTTPZirEw5XRi>NPLxf! zgU%%f+%h zRDQwh;`F=j!s;xqC_U+Dgm@uWAiY$tYusD~hikP1MZlB-<_x({+%uch%3Qi&m@d5x zct-i}072G-_gw!lSgipH?+UJMC7$kQh zTj6EaBAIdC|0_Aair(=E*(?ci9NlO=rS1ndE0ZoV-U;a2x{vy{;N$t&PsKN7E8}}i z`$KL9oK`s)x;WU20kZ^)KWatbg5Nzun$UK(kGd=Pi+H$&e~J)X|$@vEZjmClkUpO8=pvHG=~VuY}`D#PqouPQ~c=pQ!Q z>?+V>FI#MBY2bWcS+O9B$mO9*#ys&`Ou(y{i#41nV8^XrX4gR=7l79lP`z{iuzP_R z_j1OKCT~GZ?4F49?JGam?Wb7}Lp!}#_54iWdAESSe{XBN_$7-7{!QOB@?PH*KA_jq zWKKZR`%C>3h01ol;V4w7pm^jUVdrp0p;GLoU@fqh`t48Iko6EV&MI^n*Y8e;j!!)9 zB~IJeQ|L@YPV{le06r!PLE*?-(?)x{vHZNEyaHsB%%=mG&j`FZ9>s{C=Kx~o>y6H=D*6l2n!))|h-n=#w>8E&}->~d|7$MwM^XKu~JXG4cEqnhLs z-HM84*%2}MPHfKQG+Otf1@UU{aGp^`ztk~2iz}iL-0>TIuFL6%^Q@D+_3FFAnxx?u zm}iUrRoOV#GWIIU< zw+}mG?W5gPMvR0Ty-Lsn4R3vjwdO!c7Xo0Kiu7oj%J_@c{|8%sm}37uTfQfa2~quV z(;8~%J6O^6esWS`AtZX-=I7k8{X5hK2?RheHn54yFbzP$FV$=;)LwF5RMxt=S9#0u z5%iYYeIHjW3j%KGG8MimBq9a^6O%h-MU~++f6nb4cD&-d3<)}41@;BiKRy>@9VCjC zwH67hTTQ24sgAobY=IQqLj@p`2IL6FKHi%o5Y;*Qw1YlC&n3CYoGu;+G5|*{JXfJ% zsW1nK6(8nHH3&RN*gI!j z-1DZnfn4rvx`06lX4s=mzN7tQAG&m3 z6*F9Kg5HlWZXb;~zv%UUcG`c~BUb6T^@IvCx3xnJ(s&#y$4(Cqy4-k0Pq}s6m$BJQ z=J!sfQ8H3VguSo*da*exak`e1Na?G^zd!vhKXGI)V6#R(PPq9kb$xyP`%%m5yX)`U z%TKJ<$xsFX#si#2n6eX>jGYRfVsvuWoQRIDIUt22y8wG>`yqV97wB;pJt00;8Udde zEJIc+mkLrRFYxeyBX={WP`47#QTEC(w`_e(0Lf`vrR*NgqLl`X9czh^`G+x=ka+P= zR+GCT6ISUvUq@D34aGD~aH5LdxlwcaK8527kdA0VI6lRv_hqy7(1r`-7kIIIA_NC2 zOH2q5DZiy$S^7r{iNDWI#2i3vlOXio!%8!X0|e zlpHg`RdgEtDBaO59^uca(T15#7q0LvV(7C7ofy9R;3RY8eL+R1JMJ zX@#3p-~$E<>kI|e6%s_TafM6;;|`rn#96dRvk}XjEsWQ6o z^_xz@qm@hm1Ve)GH6(|BoI_>q$D|}N&*xE!YAyk520%hV&5y11gh+WtEJAH1x*rC! z<0fK<7fk$0*V8%PMY>3#iaz%u_mB~_Ls|A+rA4;rf4^J4BoI^zkTto%Z6($0TbcL! zX!QA|-weYgXGamnHO*=);P%&EkkPbmW@|zRa+Iy}2KAYw99`E;K9-_`4+~XeCxJI1gJX1!!W9Fm>Q_V(1N7>H= zMvs75BC(*yek#{ko9)ouK(_=S zf~cE4gN6@jY^%+?s81Ymz>s!nGm}-UiB^CC2(l^^1_MyvZ8opi3u5u2E2OX$Wz>rD zkY}*9?bG<)W`vo0%%pYV%eP+^JzjTB+hiS73YUD_Ir1^NLYXvF44fCGevO)eAGF!d zi_1HW$1qO~iZw9@z6k;7+@9#BUZmW8l(OJ#s9~HgJ^Kn9R7ItUqR~MldqQ& zuy-5XE!pEOvA%tYiMf+&|1(Ot^}kKOa@B6X-Xu;w^HWsgP>bUtrE`D6rq2+siX_8+ zdWwhd85vvqmoXTv)n&FW!t@b>x^+2z&*yA8Ddj|SJPIh>uYB3fAxdA1;l9%;iT@3| z!4E|U!freP)l?n*5Y8wJP`I(fPqECNj6V|^LQ?7MfO^PeeC`x2MnJZb0o`=}{g(R& zOy?i=0?Gb3yMjjuAY}93GHSbjWz^NyW_wgOY+o=fqttLb1I;d83*k&Nt~{{$vy0Sb zJ4Q<1nJ$gCEWM=(V8RJeFFs1k{OHnVT9BGtc|m5u_OXEr*jr~ywdc(J5?*sDa-Gu7 z&9Xu`J$GcZsZIeBz_TS0b)r7yL7)&L>Uo(ZC>MxD4rcW~IxwG=)G7qY9V&z-q_TEl zh2RClpDt1SVx`hOuNch$838;;`R_*f2Ue;-oyN@F%-O{ZjPO>Vfq|kV;D+$h#cOS4!3fLd%--FEX z^-)v&0~qknzyWY^RdZ1D`V+BX7CQ=VfcLhSTdD57*RXpp6oS>=Q$tgX2%5#=pe}Kz zli5o1fSTZbT&Up9j}eJ69F|k2(_8b@+XtFAJrnZE6uI~FSBz*jW)>yqka6~#yflI~ z85Db(4%i51@ijCbc%Zb_XxBJ>UdIzR>!Ko!-a&?e)m6=h8)syrw}f2cSssar zV6Tu-h8)Q~ih;LxjP7k}GxR?|J)n_`V!9 z21xUuK@VV_13&bIh`wG&sHY5kL+a{k?{&zz)?_BTxV1j}rJQtw@A{W3Gj zd>2cx)pMyipX;}uQ+Mb7;zZ~(^4i#1KPoQ#eiyN=5R7#L$vPiI5c;uNuawG9<_#BU z?p3rTOf_e`(hrF%mh$};shP+Lx@L}u z--3m@f-pE(45}TJ&~*Cq!ruv@`+O&TY1GW0n7sJWRu_c)guA4z5=Z5FEhK{R9ULg? zw9qt?+HBmLm@hLljddVjYgOWDE)f7sbnD_hVA9b-{VLaZo2MoCJ;pz|VIVX+nIv*| zUca1hbjKUI)x5I?k<`=5!SCI74j)HUwuCSfJWp0o0V1oSsUVXM`6y(+1Xlq$xEx)H zpy)90XoL^~{qG}yia$K|aS|Q3x2@J74Uf>b-@kF{vzs2q7VA6jq?M6%Dy0RHH8UDw z;m@&Ge|RzuMqGe5)bmG~PSy%mmXxN*M>g4zFWwu}GcGtqFe5KNBUC>q;yNHs0Pbyr!mu!3ia7SqrWbz)S^1a^`6fl8Ba&0EngK zsAFCmf~_@}etgmavIX>`=ldVvIDek+ho051?e@RyzDAFN8U4{B0k0CJ*nnG!7RR_JU0c~6kz!M=vtIC~FFUxM7`n5i>ts-S~xt-j1wfdR1VQdX~ zZKNGFSn|43+D3uOijj~c1nGU``rzG|xFk(zV)^VX!y%tm@n|OxHegXx^a~VXJ{nyV zR&U5urR{{DaO$!zW>f|{4Vy3^2wt^&yRfy6AGrU3ke*-K_Dcs@;PI;Q_cAgtV*(f> z{O_e1kc|3+wBQp{Ghs1b-+(XB%u&=!0;#l?++<(6yMwdLEf$7jox+BgVf}}}dZqXl z;>f_x*_2&P^^)t`^&d|=*v|0=G7n#fz9{fzrSdA~WD99)8t2C0GqEhO{qS9HqJvTf zFKk*$0O@0>^iMYd@^>8jx+%`_I?)_!?EQ_kF`lj;qa0ayfMy$bF?R-hmmjy9TFqoc zPAD_c-`k3$NxIC$dDSAneiIV9`6>>jFuu33nz}bzpzyJrEPAdYQ=x%M;r_l)Cdg^YaT z;$3XC+;Hd6oDlgA6PSIZLCc@EgNknyCPqE{41nD30%2`4LPQ7F2M@4J5*ob&29PTf zKN_=s^Sb%_>HVXvp~Md^3NmoHO3^!e`Due>tve-@p?^_XU1ybFygdHYBo1s*`_mV^rie zr>Gx{u8L!q+*HBFr1UNt3^&LaL0Lg8ZrEyz#P5vh1;_O zYmWlMcK;jbfRr(lF=roPvt_mOmTD6GvMZ9C)j2DFv@2vh>83Axce8?bSg^rP{=S_? z!8TFmb7KAEY66`hoNS}zh7-u#s+_l!U$n4j1h{2JrNq7l;A)+Mgp80SEs&@C5!kcV z__N5MUIQEJC6=U|PqlY!MY1Lr!AeKaoF?Ci#v+-av2%v z+h^RLo-Vem)#DXO&|15cURsplwBpv7_Xpa+9r8Jj23{lAEgD>UeE4h`S5$$wkKQ_~ z<)*IWkjZ)ImUh)6)znV=iCuq7!jzK4=`>Uf?$C|kx|vTj2{-K9R>mO4fnal5`t)++ z{1g&DCXqzRB-=byExtgYWXB2{V<*bj0Pdf!-N}vvjEm3(Lk`)Q;*3f6f%c(9ydNBE zdWk$GA}I#6sC{LI2=>)!2-UjQ5Hqz}wAYC&nM}Wy*erj3!K6II!K{^_6Nm>OOm2zj^jA+V1z4=p|4Nj z3AwfVse?4ZL0v{php;Hs_~pygi*G+6m5jt^C$By}->zGGQ`~b79i!i49NbO?*z`p)IIzUJj~=JVjOU~l7-_?XQTdEz9&*64AfE!iXY-7YL6U@$ zW+OGYvI7g~ypO#5z#FjQ$n+Wv`tJvQ{(GJDTbJ1{Y>c?AnH^{`98@^E{_)tE2|K@L zj0}?0ve28bsK-K3w56n3o<`M1Sdi6EMp2pj!)2)mt!t`4L=GKrV;*BFgY@O!pZF3Q zc2qZeB%)sS=YKykyf{0PyRd(Cb9F`3;U%EXTf&;lTEbfBD6?8Cq5;qYhyYYpqk!6> zE;u^X>x4LydW{4j!oFQ1*BOCwZ7Z7^k>Wg>&Zju%M@^w?4 zYa4D=V#ov;^y}*G z2Q2+f<^cB{L7hCm*0~e^q`kqz=okl6M`RBCXWgO5P1@dC-r84MSK6>zu-ai-VcIBF z&&;0#ogp$AaVJuHsgeg7HMKrg>zTYWX&iA5-lQI6O7==#V0@n3B7YA#L#?*>aj5eC5{l7V=zv?0k3lLm6&RNnuve4s>>cci~+` zSi{q**U>LbZR@Mxq7QiLMrVah;G&4Q-9OJ7nD}(p3FW*Q`E(rH@_ys=+aiyg;O^2r z3?Yd!#t6I*kO*i4ybeJECLa^6y04n8a<5VWs9MM~Fqjb+fES??z*1m2@FGMvTnQszJ=hj+%_JT+}z zrb#6YGVF8q4Ns)%iH(QGcV`Z%GS(g}XqCy+5ch1w(L5fhu z3thQgRDRrFY|UsU_-;e@{mIV{Xbv6obYXzhzR{x@o&YN9km8i@#2b12I>Z^OR=U80 z&J1M91cCN_6k{Yn!c@&HUYf>i6Hvija+JH&F*8%lp7Xs3p)-5j3}JE2t2PDAx*R%VLBarMy;KiV-ik*{tskxUJ!hO?6+vkAcwpuy)U z0DQNIO9a6M5c!%ouo+~T^GELt#s5p&Jx~Vzr)&RmUBB2D_8`TP(D#9rPY5FQ0+_9g zg=JwN^OM49&!M}@xCrpvHM))yN((-N$Jm;5)hhX%)29=s7K8QIAltFQhUCOulEIO@ ztWmL&#!dR9YSE*B9mcbexh*B-$I3WA_no%v^mC)FV%R5CAl&;m>+F{`FLVrP`>ddN zn?H~W-hTCJrIAZ36U?ZM(>KV&;^Giy5at(tef<5Z?yi;PO(%}I4Bl=1X)7`58HYcj zj>fcf%2*F3yz~#alFE>8Iyr_@INlG<{I_Rtti2!ukw5Bw(*J7{g7(YYoWYLwS1iOY zmG`F>y_&$@_YJ^xN9l6wbmH({yAO-^*_ZrSEv(f>m!!j3ab25Aj zZP%wuCOkSXJAj{ph}k zN*iXczpZTQVtbvG5Bg%`2*XcSjj#|h;@F_vbk@k9ctyfx+CxRN7p%W#^OZCoXEvuQmLZnblREa@ z_tHCT4y4U`dr0hZ6`Nes2o-n8eqj24A*7Yhtm`lqrwB1 z)b&X)qv*n^+KbX2=SA|T6+04CCir01wITYZ#$M$ce?>#MxoO{7_AS)bjxh%K)~3%S z00rF->T-NNikc3vayUf#o`3hzD6p!6O>3pRNPCGd>t=wd71Uv}B;~>tNRS07XK@lz zFsiL%(lijyH$9N@T%fc?z_=e-^|(3J;uPG*T|xE<3EjHeDmZ->q8fH>ngvhIy`N|_HXI0iSnWlH7m=Q^ve6`4^`9 zUcQ_i80_Ln$sd<^2H+`_%&#_^b0dg>JM=)&f{sKJOGTT$fA4Tr9WCx5@h&!mWAzKWi0ddJ`McxP@Q{O@xC4e+3Cfjp7VPHy$7cO zEs}wwl9`|q9D|<-mVe2aH9fJt^7ABTw)3=U#VV> z06}f~lOT;i+p4bp!=Vu{R!|Edb-eW^b!BwDCxW&AAZ%1Ux#~F{(;T0-G`%{8#LPw< ze9~8rDnUc-rY}0_a+PXc0PWAUSXSlODug&ZnbjE0VGC9Ch;|vS){VB;oOSJ`=80&p z!kGcnYfWXC7`b^Lqc-e5@{*o?5!KI9gclAFJ$n0u&t4R-VM+Mx;cQ{%^G(!&EcEz( z_V3MoMgLqy{yz}{RZl@1lF(z(@z9g`A@|{g- z<>`lQf0N6iU-`3Dr9>}Ll zuCpqVFdPm=T@l4s3^X!hqxm^<|6X_N`r9dz5aA4Rk9lcdHm6THo9L!8&yk_)gppCA zy8QZTV?{b;6s*1t)xK8mgrm{!R>(kEf2>LgL;eqRgs`ixuWA|{;Fw9|z5(Nq%URvI zRxb?_;fLQz+ff%5mp%tD)><*{&(NL)xp}3x_#SL-Y|65Xw)motgpB%RHkYTR`*XeH zP=MNDf<8jSJBkU<$AzsmtDdixDxyGQL<(i3#ojOZP%^8kY+`wKKZ4gki}Y1DOos*; z!wSyX_L^?E+#d87ngt&#Z8-L5Ag8<7%&GW0J>Eh9m0orb2Wy7Ksgqcl$ed$lL*hEr znsE$j#Nc!L?Ci06G!B(YH3hmFMIC0*BkP^^n+F$dLqL-P?}gq!dWeNUukjy?VreDN zOx_B#d0}h|qH4DQ{bc6+mkCPd1IIX4MtRkjEA>z3+sZ1?xNplPKas0pAsGlzrAyAn zn|7H~tSO$ZpdL#`u)vjaN3H+_%{@=eza8u?oFWC7oI&#;G%^g(dProCt|VjV^Hp1@ z(U&4w*wR%Nxg5Br?$QwGCJe(YYG0xaa1LR55e-W{4~(mdpiJ7$r7Sk4F^Mb@qc@Q@ zr!G`8Sc+wuqli+ua%`?Fq=!ani?E3(cP`?HFG3z6!Nyid*IPNZ0ZagL?AmYGQb5aF z)o<%i4YP5Psoy&lj_e9NU)>f?Ao_}c9Nc-kaa1O+d-xpjj;=hK|CH^xZ~vZeDDP@Y z?*&(qI_EUqCwu@lW%}KyazS|H+aESQhVcx|raSFj{ee3gOX!){vi67mea-s5p~U)HDL3y5&F| z1>pgZQ@jh3rpyYnaAetqg`U5sW9P20R-t}MUm%`9w=Pf&EHIr~-^gK-XTnx{O!lD9nesl$l>n;p`3?KJ`i%Vgc%8sHOeyp>qNB3y)}_d+XC>fL*6 zn$QZ`2pRRzVGjrZ%l5^xTaelMA9eHJn~(kKs{Wb~{<@(G)D}RyMWCg_u%_CAMD9f0 zMpdbXN%|nTL>f{Ubs6zVHPX(B-mE6wXBD5CW9ALl15sD<&`d6p^F^vwI*EPEM@H~R zpWR>GuG0j#l_AJY@4kO?tr-Y|AGUx+xA)nXlTQ|=1ijHCY~w<$w7d1GsOU7}P)&1j zS#7fS;-!+&J0hAf>bZ^&lU7~tIG$~PppA37tEM^F8EmO$+SHRHl>T5!&RS%vt6N_X zokv_Vm*Th6#~yK`xafzN(V?RF+WNvVB(Fk#Llv!bGM*%41hqI_{8jeTpUBy>%f8D) z`h;vhXjfgP2gu#?0e1xugm75CN^Ex2%{oSY0!Fg0wdEEzqH^1!V0PEp7ECia<+k05 zzm`cFCN50OoxnpIMEAKpD=3yB-;$)cZGQ$5=CmWsjCYFk>?jS+e$w%U5d~5vbG%<_ z`5P)Rf!LIi;)RtZRKp}<1=SHDmzAb@6(NdG>JP{Mu9nw>#5e+aCzacPe$lBeb<{zD zWu05y(r%S!e!Z}x^%^X3f~4rZEp(b2Em4u)U1RNCky(U|A3UthbgYX*MzEH6mo?&A zy%_xp$4fqqB+jiK$mjM7o+s7prvT=tP4F3;PmZ_mi;jnO5Whn*p&-0sa){;Nfl;O?ud>Fv0zmPIXbHgxDI$hOdRdWY~;S!Yv zT#x%qxhuXwkcH)rqKM>^x!zcw%^kk72P3Gs@{hz0J}fVy?zu3-oOf45>~V8NFuCQ9pjhkOahSvXCmitu~BgcX}YX}6h%KY zoH8wKb^5d&qCz}H25`)mZW@hdy}kXwj+vJDqBI21MEfRv&dN|gc3^<*`BP9@fakDi zyE$o2I2C|Q4?Gv#Z}R{)$x^+k6CF#d?1mJC|Ivr7;Q)TZdy^klexP#~5BmJ~eERp` z8-JT-{5p7{vGOP&-uY0&pMn24CMcMpaC82v2h!t)!6&CQbor zQB7qeQD5~SrbaJf5jD0FBt5>qiQHS#jgtD@!CP>E1#kZK66cSg5Y+b{^S&~#uVPZ7W-I-nQX?Esla zR|m)cf(--@jK#i5g63QWMaLALP~viC=q#0Uw;>_&+_o6Ml%rC!L&H^( zZvaac#G?yD9XLq9l1a^Bg_-B?YgFVUXMe`l;AwJ}S5^_}_FrX0qXLua*LbD*m-T|U z#WUZ#+GU22>?5(Ym4qn__5+YFj!uI?1gQC}WM%ihi&1;_v!iFcSMMyF=M3zH}Bg{QO^Yw zKIDPm^I`1GXm~qRRlBS%IVsbXI5sr;ToXTXVi-lK<2%QoadzHG>hH?bPRV&JlG7xs zmEpd{Pp@{$Q2Lov~qT%5)1u)t=vso$ktp8N9RKQiUeMW69Z-xl2U^w~(rpSA$xePT!gx zHl|%U4u377d5M+An6ejH>!!>b*nJ{NU{WCtbJT+ckB21E@^H_{N{9Ui%qm1QRk27UF_r>! zLHyegX~&kXGb#_f6OLjZ-rI*{JH&{zVFTpk&W|2-0nj)8IobY8RV41|YGx0fM*Rwk zNs3i6P@vVOgzgLpBpX4YS|?U<0)A0w;Y#>fhx0I#_~FBh}KBqr_+&x*ru?Tr5!L%FHhOp|pXFvppOZaNZwg(qTz8Tg7XU7jP#QkVC!LzT5 zvs9!5Dad?O)1aTunLL#vwa+OI+^pyk&broeWohB8=JT|AgTN3)AH^UCe_C4P|87yg zUF+_>EYa%PC?ijoW}#luOCPT>QdJ<9BwplDs-rD08+VlfzJeVw;QT4r@hFD+Nx?mN zx<~Exd-b!pJ-99bqX0mE{55&AQxvub-I31{5`}U?8Bm3SWXp-KpoG>Yp~6M&V`?I! zARdAZwp;hXvT{1Kdyo7-C zTlY`O81!+|7%!=gU7pKwWjfw05s9zc+LqpJNq%ltBx0=@C(w{lrYGpvpsp^wpI+z3 zG)g|UDLzrf{SnLahZ@f*W((yuwUpNF-Z5mtJ+*I$dZW|2LQ-K;)#N7b6+C*6FAsDF z9?z`k>$%ucVSL9nj-!=>2Y7y-q(B}RZqD?m*?zBy^%vO0FYn4!2A2|e8MURQKk6@$ zf!<>)jWnN_v7k|V;69rRCfn7d$LAXx4hMtkZtV7tq&5spp3;|LKh5Lcjc#7U1?Zl^ zT)~7k3wUh!mAF>glR0+IR-O&`l(5${@MtK)jL__=OXuy1ytKd^7Z%ddlo~J0@QUX{ zWiPTdkg_A{AJ{V8*akEN5kFN|JMH~(7@b_xVV1tU_NuhaDlK$;nyrZ~7te?7943Ba z*J`m)o8b0tTWE!9ZseIQy`7&UCidQV;UUSFsNnI5$>PYny@~6H4wodm-r*7^>ZpUS zRx+}p8AD{o@Xs7C7NxR-F|!oBA}m9*v12 zzjc(sx@LA}npUos4sNc$)3E+d5oY3Ez2)1N0kb^a@IBm>MML- z@6vt{E6Nt9FT$Gzw3&gIKspFGfVpEH!x}00@8d<}L}#z)L5TMDDIm2SZ&Lp7?4``? zPc=qKi(*}xl$OS;x`@-V$@33`lQQD7$R|&%TU_*uwk(%lHy{1%!jd9W!b4B?Z>zZa z6ymkNFz}hI9s>i!R0{5$&U-=p+6s9^Wa^U#dSGyb`|r8lKTtFOfx>*)3i&rqC;E>I zqJFw}+PZn1MM)Q$<>O)r8a$Sc(-(cd#t=HELOG0+1wF79yesufg3eH=u4h{Uhm8+} zE+5&bk=3oYK6zC}aEstoOnggxGr1w4TQ061BD?2|qrNRqS5_U#p*{7SVK3ypEj3JE zc|c8FQ$fqq<3sWO!trUetHTA%983U0=azRor{KNU6%5tT zh>-)Rnc?ILQFBHHIi8;`3hMT`YR*|5gK zvk|qM&Es}qr)T#YW!NKpFez-oa%JZwwD|Otc;s1u8!6`DFHjsQFDdT^_~$v+9kwcm zKWD-puAV*MFdYJ|ufKr|nfa(8f3rdTZ}^zBy^E`}o5^4Jm;X>>p;0IF=O*spxZEEp zClz@hQ9V;u8JCDxJGOq{&s``$Lbo`v3v)2asMZbZ0X zp^=Jap44W2er4;Wsb-7;K+iQ}Thg}%s8TZ*STcf8^oluHqYFO_%1RTu@3-?}6mSjT zPaUpOd}rumMGD7Mw=oOfx0-pRu)YkTCYa-8c}~^`fsYloJy}?8f%l6nHoj>~F$wg{ zU>ErB@#y!mhriXHU?iQ}ABydEZ(Bjw9jwq%yKz{Z0SEjm*n^;+j_#28Ao}b$3i_m{*lMPa8i^_p!2~HxKZG>nn)BK7!-JDCr^>!QcoAR@ zf9EjNw`=^>A>7^%i;b5L0V}xkiUI=USb#^J>-W-Hm0z1(zv9;4Zb7@h?seIq0w}_9 zmAcD9JcIi45fBohhA5wBfTxGu(E6qTCd8%>Gn0F_o{+NuX|0r|30t?!Q!b_+&XC~K z=WnWdUcjf9t;&saTdcP@Zn9TBqZyAtjhC`yXx!$jSwpyH;|+=`EosB#eff0t#OGnF zi&hRHz1_dQO9Z&PrQ@)nrxgM3G9(nv8eX~W_s3Rb@m1@~e^zdI0rJLw&hGz`cKzp0 zdr~Zzq8K!x?%lpZIyVp^e65C~5d<&N0mP(CCo8kn`xk8Wt0l-t!>mIs4(3Z=NoEKG z;3=NGbNTco45s(>MnH16&g+=5 z`>wWMi?v65a*uG)%isELj^oev-VP&BOqM*+^7^!>=5kX=*BY4#hI+Ztivn}Ioguo8 zVoVh731!nA8#&hTEp^veA4D(>IAvnnfx-L)dU}pW-Q@Qg9e;+P|J2yC`=jCIUs9)| z*WkE{?rMVewGmq!4aO&klSo8nK9TbeE^|V?1}7Yjd(`{(2R3)%0ao>mwUn`a-5P)xt&F{1yTjfuy0f?^VKSf*WBS@4sErNDEM?su33X=(^hj2#12lhb19 zr2J*H{RSX+~wWe9JW7MA=pB`(!T38irqYd2`&bD?zPS??jYKY zjljYpP?3m*x=!S%<43t^`69BIij5i-c8&9*e^OUeSh%cSQ28PD8YrP=kSc1NFUr8f z#JPemIF^?*D^a>_gKwj#T++qxj^Pbe@M-iV##i{#%XRNycJ>BW1E)j@2PkK434^sJ z4L!cMEzVQ~28;xK&}1Z|||#b3K+~cXD=1;y$}>TC+G6KSk-s9?90;3Alr0 zh6tDJ&^gbUasJxV6(ilJ+*i9U-M1cAYvFos^h?3sg$r>HyaE{dsPp~i1*idVwgQ)t ze_Vhn@`@lPMn9PRNRkgL^_ow+E!R5}XvkwzEd_*lJsFzaRI6=y4n799Z*`Kayk#FT z$0YMMLLIJk*lIQ38h#LW)Xm^X)IHD)lgN%=Vyqi@ZkH=;?1shaDDwJLi*2%YZGe%B!A3 zu?Io^?Cp2|sW@cSAGW@?g)iQ5Fl(}XUv(^VQhUzZ$JYld8Euka^2Q`RXUFa=B zYtbsEo>A_*3pM>~yDqj#+`6x(1Bt|`linp2qUr^k9VjKdVnk2(S0S!zEjJMl@MAh1 zMJf<`sL8aUdoW^>Ib27!4S+ijI6P};h6eDSbkYBV!s;(Q63{{uXdL;Uos#%JcV$5{ z$%?w&xrAC=T=bUhejQ;n0a^oSGWoF7G}A$I)hkwQ1I~;dMJSg7JRHRx9TgK~DF=805^^6x2MnMu`;>E5mp~*o2V$J^Y<7 zv_A?;Is2u&um+ktxg5T~R2H@k;}CVi_@K2?lFTY7BK%4v-hw={mpWVug%@u`FD=!} zSW-2=P|a2$yE$O<{5-xI;j5#{Nk?zm)4|@R=)w-KihJjF5fUE!0gtvJH8-wXizjos z#cHqS8`nO)%H*Sh)@kRi@#?$Ro3T2#=e<`hn5QzJ15O?hH`4krA)kCl{#grrjH)0?jUB>vmEuKFJ`hJ}sc}4KT zHnLyd)R(JHS$OyL6(Ti9D%u7|p3Jau6@Ih%NQ;LtMJhcGW;||u%JKIHVX9O_SKQ8> zgi*-0FFykZWSV7+l6Ol%C>WDZsH*H=5zF3Szhk76QK2qT69a%WN{EWzMAND^yZhaZ z-maIYJG*eGsYMLK{*X~KS99K0gRF7!Xzc#I+0CC-+TUmpqTfE4CG7r0eK~Rk23nX0 z<)c0VJ$z913Q#{2p+JS7-L9wRLFO?7J+6chij3@M{7vH`izbBVB)$&tsU{W`96_H6 z9hW$|sLN579&tlXUrO_fh*ZFb+CFJ$(EZG8Iz)AV@fN8df+R6NVAOxwb%KNLmGQ)m z_88l_`scB+_X#NMDAg#=$eBxP*T*hBH=!|C>HgVFqCfq{Xl?x85Y4`QTB{L(!+8ot z&&o^Nq0ugtfimjw-$A>lGqzD@e0%y@rp9?80%~T$q3(&7c&h< zQw6fM=jAeUE$R%=R&WpXBFZc1nJzbkdgX*PhG~^pP?Zm;dXcb5bFeWDsDavj{c)4h zRG5)_Y9Ii@J2unJ#d@-jwmF(F&U|Jud4B{uHm}$&#FUJ0&@JG;I>x(O+8;MFe1eyL zN)2BrVdF)xmpkWwW$9zxal>W2Y z`A$G7u|)YfX(}4;R&($#LG3#q)H86+cmDst?7y0(AcU5qnX{{v*&hW^!7u6f%&Ga> zPg6SWXx*x)-cDa^TBU5MlorOi4Z67T*OOf_xzmF{tD)eIf`S;@m!K8EIUD~G8;66z za+V>)3gkI{Mnl3KsiQ=eU}L?Xg#e;J`%%-#Hg^Nz@)`cK2wG>iv>a~5^E@Rs6f=9J zoWeA<#xLTQrX`S9L+r(CMsX6KvtQuKc4A^2pV-Fa036@#rkbRFW|SnB2$SSxFeWY} z@S>AxSVtnt`?*iUW-)e4O<&xkB*7fpOhBTPhbTKgWoW5yF-6@+fV+d?&oX1Q7!(OZ zh@-|-iRT(-IOruYG5!K}rl{+FXpBFd-ExlZIep^0$b3>vR817$Gb+B(|##ByPxY5FKf!hlK*ax)(i2RL^G!frcZO!tx> z9^mXak5f_!48(cy=)L!Q*)fi9Y4&a zx&Ha@OP}c6>G6+ZB1BmgFmVcrw*3VH!j8R@1y!_mYA?%1%P;_Yc{pWd2uw&*lwTYd zt#W)#olc(WR^1!Ad_I?z7{*Vp*N1;unB#(-MK6H41pC?T{t3YQOkb^qBl&a%+T=_* zF$59Xl!?{ba_%~#Mo%(z=^^$uR(%-j1_hJHadp4f;1+$LV|R40vj0;XFLqP`l+N`Q z1u&9>bX`{#@pxy$IA|6vs}a!S#XlCh(xk7A+c)X2*LWR2@ugj7B&%K$kemN`b#2af z`s4Nl0m7ugbnICSIczzAQ-^(fmA(-qXm~_}3ngt#x6A^wz3w*+d<}5W*0d5GeQ=@)xSTOI8UAc+Xx> zV;K;%Cu&F37A!l%1PkAiv^Zm;EsWFoPU6?$X9%HwfbYTP%u)Onkh~l~VOeW=ny6~1 zQnEltr|(@#hlQ(qck=-3i{3K*1P1xnKN?W}SGB&HgN22y+23pZSb5N91Zb{b?1W)L zN@_0egj~H!0d-x9B zCzsuu@=3kYqyof9Z^h%N4Pz;$069l!RI>_ zs=SLq8D~=un@^eYm!YJRFsApURO@gEqu5bi>irhTNf}v(_b_=C5Au zNmvPUG`JUVi3pd~8u#eSF*{kOg_!QHS2P~OUFLPCmvH8WzX5DLYkTf;H1zOlX8Xc~ zKI$~%q*i_$(bZ^Pw9G=-(4Ahb>aZ-DYN&*kA-39Mi=>lQ!(%Ot$C*3qQ5Ay}PjWRb z*bz-?K5u36<3Bb%EtHMHnME-frR>vG7Aah}o+wCfv)}{BQJbmo+^-nFR502@T_Y!ngn=qogATDL;!rS939vG-g~)P9Lm4P6wdE$*o^X&ZQ}Yh)#l)}?bx?j* z*M2hZ&q_1Ivf~fBDbP)Z<~Z~8`_)f1 z8Ff7b;h~=vS*wUmah8P{6om&@FJ&jJ2sh55g-^>lbU6_=(V!h&x~jA3)4N%=&G3&e zQQV5n>^A97)X_^83dd(NCD7F!a_Pq)%w}+H;1Sn6?<=>Wmj7`$I~i3{q&_TDQ-~j9 zWBt^+>?8KM>&!TVTg{@_7=LYy6>e6|dSkM_D(i=p7@=HO;Cth(A>YE6hKm3^@p_;O@#2x`!Z^D) zyO6u`@OpE4KBt?d=4mr0Wp1KdM!@{sJ&89sd@ zo8|*-Hfd*TLduHpXB4O9arbNPt%U{$bt}>EG0ngZ`YKH5&i9`TQ)d;Sp}u*3e<~aA z3PYuxC>BE5FNJ|98=pX#Efs$&qTO_y=!gdZBD;N(dWEB^Mb7eC!23i_;^Zy&?nR{{ zqY!u2%RXoCD`cddFC0ULlyaY`9Wc)mYy)745+izb*}opc7*|jQ$ZslE%aa@0p>~DIPVbvMbTR~y6 zZ;7+U=}hc{wc26YABUZXs_l|rnAsHtYkS)(_23Q9i82u7m*mxcm!^!9h{So{%U)O& zhHpEDhns1?R(P`xFOV{)arclc@k)kcf!UMb9t9cx)_ITyQLO$S(=Yv4VQ}3g-o6k& zrjjkv3eoHy3>ceW2i0|gJ=M=$Z;Lo~`exSRb4`C;^1`4XTKa_H!k z^{pgG%_$o**hDf2G3YIi(lg%Di!hbq)^QCdI~2WuHyEnu%95}mBHuSD8<$3KA)q+1 z(&pdX?Z>6Ko5~GIlNXeGoY9_bUinF>~N$#MF7@Zu^-^@1F2TyL(9fy%=9I>J9Z`J`CBlA5lUFDB#O9^nGv+7`!9@sG)vu{PwFs z@;8LUuV8E!^T$e6#22-NNF}r@h@e*2olc$)Fp5D>kd~&0(RggD<88YwPQm(|3WM?bzptw5QGINa6UzTpR|^&5AoXP(x(!|66_6@_w!NK-4S;A!U@w~lH( z2Lh9eL6p~3#yJ=?7)vw7N_D1j3n9^3ZXeS=HR7DkB@WiC2& zy5vJFdgzQ6eR^EWY&b@v`+C^N#VTf*rWOVnB)jOhk*K4R@S{7iIAYFdQ%ZQ}uAn4E%Pw+~wAT|lE*X0}g`OrUt6IDcS z2bt$_DA@0HA4SzHoy`FMQvCdbE)sM263G*uhkVu(R*)1vXbUny8WXcON^E^q&l3Wb zia-oa&yvYoxn)Lv`7nhc06|1VaK>U-1DCF1U2iC&jHPD+?+zf=tl}zycWch0j^3!Q0S`Eq_D`rNK+IpEyF`2%N=@ebo^WOv zoljRYNdo6xQoxu91PM`Xj?(Kf9|hFKhvMt1C2H>j$Ow3k`pEAUU#b95>;ch;nu!5i z0e>&P{z{7T>Gd&LI4)~=G2fHifFN>DO`OE4S`iw7@AlobuL$em^?NC zzfqDxA;dsnRORip2M;r48Rm=^#W$dgl$H^SNVsyy=E{>_%VjzhDAWHuX#G80#~<@% zaK}X2-qqo6hWOjQD#R#gUp2H9q)|Xl6R=1E38H*sd^Q4v@}#8@Lm~i46exlu3jSpX ztM}E?dl?SebOV?%)0>O~Sn>>IwH8d;DK*s!4b?ixeI7eKpW;2O*5(&%bZjVM98+^K z<>pEV_?Y^>Jy-%KkQ^Ev#1-^@wAqOYkU2X-*N7z{0)%uy6Nw^cghNI1dpH*GgbF@j zT*p_?=f7hde(yH=mE`_y^)e~8QwFpR9d>V9>NcZ}>j#_DiU<9|OAQwX8WqXsIJr=C zDBeycEpl}0fuf*TU0ZQY=+fVOi-O|;IKA?WBao7X7`pIEc`9t{rL7tk9%1D2t2zxu z89wI0YiId1)p0lqY5s*;N;hmXaWjkj^T3T>&5aG?>=gZp%Z~0H?y4!jiG>9VdHLEl z9A104T%t=$n*_4q$^?Ms3OUQ+-OZJEL6CaEwa%8z3j4jFdKomeVDKkMns!aTy$T?c z>@tkJ%U<|5LK9R!%3>kdCzaH*_mk*_8P8X&2l!S!x?hEKJt7F@?ZQHhOcWfu$m>s8M+w8b+_TF>Oz4N;>d!9MxFL()6Z+ zntZADs(MNKQqlWy;TGaKTmzW4MjtqcVy>lb{Y$Wv)7eT-RP~V1S=yIOQu(-MjWYB_{?B^KxWu%p-hY8`92#g)9bi*FwAvKReYJ)t(rUn(45P$_T#-minl*9VvhA%}N=K zmtm@I5Tsz zHF^3M#CV1jNzxB78p`6O17Ea#zu{z*a4|oFj-M3g2A+jO$v}o5w7JYZYLLWEb*1t zhs0wZ(8E`D%GrSTNZ(T5#<<5W;zVeF-;82ue^X1!Fi2{BRVeur;AVl)#=-yD<+J{6 zmoN0+hOe}p*`CqD<-gwY<$Hpc(l=U=O$@?--Q-TjxWUVnuZRW|K5+&X$mdTN6!EzO`4M?M zX7DI@(2ni}X%51J^4|{2)}7mr(mTysFoi4b-XMMEdC}Q8(UmA-i>)-7Nc7hbaFu@6 z;06Plyb@MWHhwbN@FAMABfc4LOT{6JqY63wxXn?k=svrtp#~1cP=b=aCHS2yhl}LC zjtBklo@+mqqd%(fo$H(@J%Rs|DzTw3GBO! zAeUrYwGhy}LSI8H?B#KKza`MJgW3S_rG@$+2%O6Islve5g!`MgxWRu~Qm(zTv%V$P6#{gdN29cg{>MOq#8 zmP~}QN_x<3$R+D6lHqrKSh4;hGLa2af92#^Xo#d%g5#Wtpv3?YBMp7?bd_r5Wsu+R6BuAU;PVf-7 ze-M%BBb>pmXm(G;^T`)5!GUYFiHaC#fhP9f7Go7?r|XU+JhnOeu!fVmd4>KeX1;I3 zu^7Xn9h&;8Sb!xl*mW`}s^su=GbgQwiS0MXnT7iEg(!aJo`Hob{tbX}NHy2rKA%=o z0DB__?o@3E;{lTzViD?CMQ;oCOXT<_c9!b?5ldFHF)geDeTUkMJtIVl%UAm9Ef zTJt7Or*9x_JL622vAO9Xd@#Q%+gUYOQ3^d#R8cP&SV|#g*p=#-y7lL5MiS+^(EhXG zIQrXJrSyO6=>O^9e~1l}F#hG~W|cqs4NP8;k`PzgW=+&;V9h4$fRY|dX++YcCd=UK z-Fatj%BVH025zZqJ&QR}qe8wuzWuD5ELumXH2ntK1}EOF45yxzoag7)HH0rNJcgqx zZOXSsaw0p>LN5{Iyzj|7tFMRfTYIrTOqN$>0?0e#u!h?|U(k0%Ci=$^9EOS!Rl z!g(dsO5o5Vs$(v|L-&R}hpiYl-fV0~Y!&cM6G%VbIhCB{H(2Lfyja)@P3_y7ubB@d z=2R}B?I^-zJmJNUo`4mFiy4oSRoEhy!T7l~d<}`L@$|_HhhD%Z0zYeWb{t~9CQ4yY>MO@adtvDoXVvz(=InFW7sn6%5w7&Y{wE~dlS48XNG+i`|?}C z1`B%sAErjzm(GIrSi!{K-I*R*~&A z(B;MogS?@)obBptb0-uU#AmQc^u=dY@wiRFo2q!=RfHvwOWydQf$%9~rQ}0r<;&>( zr8l;*2nUXSQ4qN&1hA&;%BXFI8+Tx)5|RniSIPzYxL-mFX9<>#$!f;%2}O5XVM9eM zZ4|j>Tvlq}uKRSc^DX7dz}?N|;@}wU=zRm;Ib-e1Cx>UFpS-`zTTxx6B?v)XiuOZ}u77BjA6R$wdF#0ROl7z9jKa`QOmrHdXcY&5Ns=KRnf_ z+rqbFi16hRBLh=6?Gj5iGRaJ`B5O(AztI1A)Md@Pt}I}(GWOQUyfq!~gSgmXpWrwkJVfC$#W98stopsK8T@#qMo~?mmb+kwrgg^l(=>6Hs;ze5q?DqSXLvhWB472p2pxP5$ zfy(!-paa4^o53G}_Gt!sowvfz$W_iJ=&&eFC=TrRx5&fv@j1jUg1&)0t`A5Dr!Tyw zwldSeD^Mh3=x?rf{^( zqh4iG^Rfygv2%o4*2#!RBu7;-WF>@=EvTV?3h*0MnM!4xmxGox8xlp7IIV23@iiHv>?+(X$|h2}h$$W@k$@!LBOHDWDjX$3>QWFBYn8u7d%` zqsm3+q>H07Cd)yU?AaT|?za4v8>QBtGOGB2IK}7+Ya1=YIV^bycFW`qZkd+fliNk?8g6xL zI$5BLFN6JjCMET`igTkQ1H${V!qBY|_|+1$=tB$gJj3uWT1^Eg(-_8Yj(byT2SOCT zXWVi2#Hp<3%KCwls}}Y71watl^0jup;i|MLEl*(wVY^waSJf+>o}?%|ZyokO{q>Kk^q1QfH9fph51##U&l$5epu`0Ihk|f~;E4oh!9|21 zktKiy`9Z2VB*?}9rtIhaJ3iYs%}bvA)SGjj%5@!tqKH+2kq_wAO%E-b59MlT&pvq> zE5u`D!Q*^<&)1W$->#T{+;#onjgotR+EyjX9Np@qm=^)jN!}~$r@QSq{)!RfHfu~~ zxXVMPwfO`MGR?j%2tsGraHKLCI~Z*N2fYoXqQ^>v3}4?nG5-m71Kos61IQ z90lPbL`PX&k)g)uBOt>$zkON8ENLZ~Au5A#vf8kePmf4h9rqL%Kt-F+dQt$DS)WxP z!cr=r6Je>^dMd49QnF}rkRo-soV-Ni4?QrhcJeSA{;iNs;2XdgWf;zW$QLaj93R^J z1L>eZo?$SV)68|(W?1hvFf&7p@qngAyRv#F@?A5(!rhl-ABIK71iQ733Dc5l>Fm8{ zsZLj$0QO|4!2Ij3)oc{?xSGg4KV~8S@!aXzgT4FYPF)6N-k1^Hc%Xa0SdJ(6Sve0P zRJAF#{>APa0P57TT0~BMg3QBsRY*d6sg#vv+tt4$)w^tIwGsk*-^WN{>HN;hTb2*=3PX*htFYh#3u7!DUOkijZPM~TV32GB7 z=$Qd>--&{{n3#XvarwwW$M+OWT?{vkOXt&xqD+FHK!=5el>XZk^MK*CQdHr*O_AJ0 zc~ki!`k5Kl(E^_&e9D-wAE&V3Vft$+6pI)GbJ-x6wRp*~En*^VJ3?E*hknSI z9Gzq$<-RAGj5}(|A}jS&>e{h_oXn6cQ3Mp2TM65V6Jo}bq${;5*Ty*u4$-m{Q&T07 zm;N*#Jfdf7stp!HLXfZ)+3g?(Yp--yiRx`rfeCq#Z{xschH~|IEzZD_%h{2b6BmaG z#tAA&-OYTGOpjTE5D8oybqPu<0Gsyu`!D)1bfH8?Q`gr-Hxm`%+Oh%)_51wY%q zED3iHj@*LY^Zm$Qir3V!`S?o1T`r0*mHxsVGI`sQQ9ZO@Jg(&^P*swu!!!G{W$|Oj?>7;O}#p_Uc zp;rq2q7T)~fM}aPk8Z>80|!^QjUtnS;16ce4&+Ie4g?`6rb+~5RR_9b5Q_%WxT_3L zTZ*5cO2JjTgxrN@tItTZ$Rh99pP5Lz7d;`~1bd!Y#?pphlX#^kgwSnZh+G`ljY(V5 zyy+|ZTg8q)3Hn@0(&?sQa<`9TeMCWOL)9Ud2Ji3Z_)Foh%E-3 z{VXB|-f3Yy9oM?Z10C10$WiC9BL?qo;fVHqo1he$W@)@$0eT29G#Hwtig~*rVF&

a(p&$#jL!&?owFAvVapmkf03maIoJ9%jnwZKfkD5O*=Td5XciBVxi?6)N zuK=Lq*_2mY2>z5_JF2SrAa~<~Z=t|5`xjAUW46wkbFxJs<-=tqlFU5*uBHb8$9DS8 z>mQ7#OIv-0(wSGAHF(o?YFnPT;v=^jsrlGw;fqzD4u^iDfF$3(M3x5yAYy_Ewi5vCrLrMG)T(z_0$1B{C4{V~tPWjt!8`Q84*?XJj6 z@5B^iac#*~VAi&I3CRfTEcPBbk;*!HXG#}RdY`Fd?eg1SGAYIyu)FW+%QwT{H@AM~ z87im#QmRU5bJ11{@vIb2x*h(Fu=ut1SF57m$(iZoW|;}G{G$%yeym5ggDh5FUjs$$ zRfs^LU-=N1j05J}0fj}fwnPRC8WDRfx9a^B6-kLJu3-;yo|X~>&qTLH1Dj3?W?GG8 z@%w=*0WL~#SP8N8tC2m|_`OJZxf~#g)X?&!eIS!)E>}Y-NW4md`hq;}%iSaK@XNxQ z$Z|vu2;srJsbw4zSI@|+OWcaXi6OHNBEcfNS!q;|g$LTktc5&fdgh_Ly$Jv^#wYnb zNr&T?AJW1rMbihr*pP3uYByyj=J%F!v)+>mr;_^hfNu9pY~ud<6Mh_ym~0T6J3IK~ zso!}U+9kxtVku;EkSU>#ekt(i3~4-6IV9V#K)qj8O035fPn?0wpr3;LV}RM9X3Fy< zJN(6iK@{0XV1b_%F;CUsMw-P0wRLEjYkX$gwwh=8KNXprnH{b_+4p7m3(LD%WO zlI3S3C{%ko4Q3q{`_N zt8|Y1{Osy8Matz~Ue&$7KO2yUcHx|Ar~&npd5Z0k1r^@VNF_@^913^|z_&wE%rQff zl}D%~Lz}KGg9>k8#B7dRn{Yc=`X$>8rrdcx%Dd1%YW*IWz5T?b#%Z3e|6&)Ly_;xT zWu<4l*M5G>J=UKTI2B5rc-xS@dpHI-6Z8p8`?7T7cGdQqNM8jouN73=JmE&Zy;LWLSR*> zHo-nSFzu^Sw`VT)Zu+!m_PoQ=A5VfnY3&91&oqx|*?5ccmuzUlRW;lISIc^(t%UKGSVVK26Z z98*Co|%nPw9B19u>dQSDq!#o??5pEp5G0qMN1Rj?i3jO`uuG>Sp?H}f-;aFq8B(c!$N`T54yLz_pi z?E<`Hn~3qG)n{GzH4~U4g2{sEK}g&WBHFS?6rnz8|Mwz4ye3UqkO_G1556{Y3mAM78=fLHRDqMx#+m6-eytZ=WJvb|i!sQgWK^!b)^K-Gx*JWmNoNhH8 z<(cVD=22r^)V&KU)M=Hj>FU;a#U`JtVOIEQ7x#;w@Pm)zaQk!)?s$y89p=Q!Q-x8- zik@2?+s@cu+-a1*!ILvnK%nExGF#B#$%U{)l`4Wwm7*LQ_mL_~e9Nu|-Y8*-qbqxM zMuSenEJZ5qOF;>3&z#1n#jeUTASLS=XGn!}q$_r~uE%RoQ^X_c1IlP-$x(5fqtJw; z91st9Gb&H!-47&zz#GZ%$2{?JUN5zc)dCfxxmb@7IPqcSk(_MJTJ-4^GA1Qae*QMhb-h;+X|seT#p{2_G4J4r|I*qrJx0PzH9 zk@GxIGN^t!$iuo1|Hp`Wq<8Q{=XExm2$i%*WfXE`^3U$a^JvU1O5Kf)T==tmH>|MQSud=nxi`c< zsX<)8rxd#eq;Gy54h0^inh`KlEp#MRlr(I=zNYS5vR!8xYfr(~JU=nxhGqt?^Tj~) zO&shhyZ~WL#eW!<$Pzy$a-Bt6YbXaBQ#u?@sN}|bS(g=cyVlN4`x&vc|6&@g+MauK z{pie@M18@S*Tgog25++^(PzKY>#B*-6YO01(S@m3T zul+r2?o*RQ(Gc;i5L~c=xst)u@jev1qwhQI3=OXwFPo!8(m<+pI;P4xg@$8=m|JSi z0q}IzM>^I^nXbMm6@BG`v4t@l?im&vo9rG&L?EFF6kc%JezcO$F5=r~7O;;ZO?0F% zktk_YEs{YnBBc?Jg5Gq}W~tz*2BV7Su;&MWq`Rvl7w&R>=HIMgxl;w?tIsw#D(L6= zzRxYR_k^B(;N#*3a&P_J2pzf{fZ2}>BHTbgiS(`>eBiWu}W z8(B2W%|%&&zb{|r6F%cLb+*J@iR>{(+2in$iAhwLVsyYLUJbwCbA?~ZoCp%rSYR92=aU16+klUVHC{0KmLfl2gi5J;4{c;l4SZl`;daqduC z5!FjE_GDgrHtITl>~K1+!2E4Mn{zrfS@78bD|H>*c)G@y1-S}*Od(A4I~@j`s&M0p zw<3F|vQvZQT|Kxru0D+=`fmE_Hs|OGadB}jXPmWp*d;Ac9pmh26|2G(*&$WjtaHI2 z$vN{)VhHJ26csGMM~2Cpx8_S(i?FVUs@y~3K2Y>P;|rR}TK7k7?LV z+bG~f-q=9z542S&0RZuTlarYq{)BQAE(muh(bD%zR}l$_}U zQ(E3Dn$m(wnts3^CXIo4Gl zmQ5%mLHpBHbAcZ=#2J&t1Dp7JSu~&xf)u(DN*u)mKHxxr1&X{@mzk*1a2(0(toDKP z8HCI(h27k^8&i#MIYRXMD*|>)o)`?k+!kL-q&UCFuTLDJ`23hXb1#a2UX@3>x;#KMo{5Rde( z^T<%cWji-1oZ%-d*z8%DB?7(|WyIV(LvSsP77L`Sl{&OAikugF_00yf7fzew z%9^VgxU^dusZI*$SF<-<^>TEh-JQ`Ge-F&3E(y~B*pfe4n{tz!3$C@pX||mtxqrag z&x+@ogy?^(gE#7+p`byA;7O4NFGF%Q!)_g8sQb;j?e~O3ERH2%@b=5^kKvr;18*8B z%9k&kpDe)temD5vPgDQ(rr$*NQ=;S(+g?;vWra`@;v4ugs=x8;eO*Z4%z&=|8$2N! ziBuw5Z*`b2KVN0~gFFH}&*7BOX4doj>jzL>Kgdpm+}tCRgU==KhaZx~rXK|nOgbm&3l zm}gAGL{QN2=cyFD4425r=gji&L1X^`u=@{jgFi%`oSY2IK0%Q7{~Hfktzu)f#(?;d ztLHF-u%UiNvZ1AgNNl{Js?J?Y&%iK1al5iaCMBAf6k7kgr!l+9$wACuDol9J>Bojs z*}RF_kpy26UV4_NjfsM%J6Y~PzwxbOTu&LwljjEG8U#@p$n3O znWVrrSKaXp9b?pXWiq^_74$@vzT9D72!qPhgXSqP)#a>Y4Q{)6jv5bf6lq!{J*r?4 zb5nqbDeC;bffG^kcRay$nq<^#4d{g?9oZtNXN?raU`uHE=pX)e2i!kf9{?)*^r zD?tajg}K)kcOKnpRU}tNBBQ8!KwuT)lBFMKj&MosLU~o%B@gylti_h^=gt*DQA*AN zK=bWFP^}pN-F#G?4fiWZ#5pi2UFv%=1D6%(GuaExM0q8=>UvZIo1#}M#vqqsr#bX; z(i(oWj)f{^HIc%o8t#Tg}m{dFd( zyHaaCNKdB}dS|Ck7CTKv9g{0u&7mPhP%DkaacLBn9}8Q~llddzOBjjz{Fa@)q1 zgrBanLbY|3F$b1QeO>_Uo&E1|i2X5tcnL7<>7?LeoN}=#pEWbXm%Hql~QcZ)MR<|!{+WJeJ z3B<wOw9Ohv^ArMa#3 zqQpe?i6zI&pNAYUaSqDIpX&hxh`-B1|KVEs|NoebtUomxQC9ZgXtzW%P zbN$~o?LQnNZR_Ji zoU?MX0i3yM@~cTmhStJVVXD2w0NpI21`n5^kspw$gNj%(i!@WD^;(%wrbb^y$L+YN za>${XP_6#hbBJui&QMI`ls0bq$v{Lh_6S5r{eOcs!4@Y z0^A68@5ODhOi@u4x;L`~?)1H(x^XgL8eV&V39L!apQwsxtB)?80Q8luI*!;GJe5a_{8L=ut| zB@S(8B`U%%Vls}FI1a)d!IK`D4S{fQ-ZQ}EP2V0MA;7=calq|P-yKNeU@R@?n^z6^ z7V^?$!c}A1q1D9+)}(ue6JjR8m-yYFq50M~cg3!$>sN*utq!$~MN9v30CVnLjs6e? zW8}OTCs1p7H1@p^|FD*V)*aVaO@Sd%u33ia9?PAWB($0OOJv3m{5P-|hs*%gK=PZp zyIXco*_`5xBr8!_Mz545**^Ft&pw;Phk|>SXjIWTMmYu^;@uT#Z@WLd!;u zG@J2TC+004>dgx(w>1*g2-K8;hdcoG$%ANOLdBl+5)wy>$fUG$J%jYz@t$&FgIMo+ z49t#!Lwl`TvyC~&+ym>B=%aT$vu=TA5sSMWlvA$-;!q5zpktNT77G;aTp_w19hgI+V%Am z!oj$};Gvz-WJi)#;-Iu_M`av;6qg~8(bA*Iei-K2$f+D(EpQ)6#QWUm+f&F{x$T>A z0F$&l*2iNH#tyYI{QT3VS4@me+n=Rg?{kUy?|Y>Ga3KEAHWm6;wscYWlldnHxFIsK z{OfQPlm;E!x-<_~a4_gzz#vHL9Nx0witTC*;|B}E#}~h32UiJ}8uw%At+TG@(~+Y! z?k}+0$pWnBTNtj>`RLP5h{EF~!-PQt5GlgUNg5HvG1SsLL88$gEp0g9GAR_b!K$?! zEv7^H&8R;Dtr7;`Z0m(30;PFF=Ks*n{@>SRencCWlZJ?}*&yKrATHbV4b7}x<5I7v)+C-f2N~T@Yiq@}F$>zijnK{`gm&ZK6!n8b564)dyOjc1Jvi ztO0!hZ}6O80nVH$LO0rws&&GR`AoFU?G^Rft3ql^*`xt~=C9eR*-1l(`4rmiq~I#Y z4U#AM&HjP#aOJ=~Rx(TC{91lRA#5ijx9R>tQTfPXUKLIrR$RjJ zg~*Fyc20c_Nt_wImE{>jA`|CX$><@i@6xlx+&r9t(`v;iCQNt9cc|WUcwyr9$Fi|f zPs5}hFt0MY>Ny2F4Ia$~k;Cc)Xd}hmr^r!yvK#8RQ_x8TGLinGInRVRWIn`_1<)nG`)<+o|6CtyM>MF_t z=Yohb_UIuSl#yr1cnqv!Cr!n(I4en}t?%Gb=SV_zWgcdCRqpA`+ro4@Ulh@%KIYSr z=*zA{Yyd@M+>^aK5S*PJzY#7qKg;E%OVIfLMexK7|nrM2JYA0zf8aV0o#!C%NSEbH1? zeEiCVk}JgYDc$LgzSKF%y|NVQA`Uo`C#R(gHp26`sWfcbwDukJxYp31k6`F_Zj;b6 zK+{B9MZ1LN)Bado-B)HZEjsAcjM1s|X(8VcaT<@lb}pJ}V53b}1 zlO!rwvp!B+5xm0r<4s^a(fs~{Ux@v0--P^sVZ6^YV)m(|p=e_LSv_4%13Oe6+%dplp{_&oCd zI(NDp^?ToXj{4HF7m3h-aPiGqyd17s*v4z7C5(h66vcE^@u4XdFL&B}M|w%xba5fy zv^@1&$&iYbVqh(`!Lh|ghfrYa1m42K!$_DIiFFM9FHEMpmEfgDejd+8P!D&KO?K=H z(xA*S^AiUstG2t~+)1+&v(om7w%kSJ)C^Kh?t+U&xES+`;M_(>wjfYGv+mX4Om>D4<$@XEO*66+2tulr^(o}Q{l`uO=Y2(vZ95d1*9rP z+*y-R-VZtA=2+wnE>Za)MzY=_QbN+^T$DQq7+s=~)#53q5r2nYxbb>We1<&X*q!5NE0l!Ru*VM1y@ zhoS3^@p-FF%c}g*C5z`mXNOiTs6%3`jGl`@E>F;mkaX5Z$z4ia{lJ{3m$n$D_MWAS zJ#i$CHEA>Uuo}tVHR;O8SX)L?NiPAERh+i%;tP~%rIPW2(3xpPw=^@!rZ7s%>g?Yk zqq$-lJVgBOyd@fBnT6I5?wxdfixiLOPi+3{W&RSQSi5vtl ziC%@Gg9Ih6jn5k=E_EhhM({Y7Cjm6N{G64b>j^=Yqn4CTl2H|$R^n0}7{yyqfZ5d? z4tuvPb`xzf!xv1h7u6fLS=1DE@M7rPQLTY*r_UF-agzWDO~-;un!DuY_4{ZV=-< zN%i*1f4!`7(kp#yaa_fVP4N{#|8&49rJ{*3@5=kM9D#G*FcFy^p?K`!(*K4S-j z90WsP8VE=9NbqwzgB;{tHbX7wHAokFU$=Yi)e!y?&Q?l@9f!AsE=mzU$nyfGisH!N zT0_5Y5rJ}JM|x+}T4k>sK#;8g0c~@(Eg}r-z|VnI8h5BsY#}a>$@{H3D43pOEk-ju zZyRh-Y? zE6=o4x~eQjV|6Gncce_EbD7T9z`!8 zF|oj0&TKp`8!rs_nX!HU=Hmj>2M*yJ_(t~Fx|z6!0_7&9-i!1;S?NNYkrh2~82S(+ z=`@agc=9&@p$wT(w3xL%&}GpftMMnD771y1A(qen{kEL2XE@hjuZ*!1GC@ny0J+)C zp<%GD*To0XEDzYMEg<>KD@yCjH|WO~nh*KY-|`8)KOXE*yRRS#-=n^Nt9dVbKi*~-@NfP0vRcitoF z^ft)kj?m>Jk{kB`G)ELQ?9mm^5T8B%?_m+G0s%2FwStEy9Ieyz>U&bv%4v$VljgA3 zMW#@tV}oXoHYfD0o$}aMOZ5@Y2gl{9F7(7Mr^u>{1|1B)XTCqWgtOgVtMbp0l{xa? zbmeNdyprJg%ufPDoAqGRS)L94E7(yTbmniK-Xa0KuefZ7t`?u%~|Ft zlzyXib2;2sy)oId?P()`Ja}nalojR-463BZBeT$IV#b_G8Xfy4FKZdgq5ZH0K-FCt zW}xy*Pr7)hD5DZoHQj!KvuyDke$$cS@XDHoHv zo%*?%(d;?-N9d4=z1+{2-i7_7GE`y8BG%R-gy7Guacg0XqoMSF1MEIxkmE4$P$(DChk&5V?ep7l-SUb0ytS$I0&E@u;)={P+?g47S_wp0t z2!4P5b7m3KQ>1?Oi7S8GX#WSP_kU`%Kao{-)-KNfzDfMt4XELWp!%kQve9U*0*4Hz zrbY^in*&?gsFVx(W8>&j(MwhhO_@RlP1ycS%Y9M0X1@kH;|ws0%iY7^dn)4DT-hi# zz~OjU@NRQDn)bk)LpsPx@MC7pZ3rnECv#+gNH?vbKBuWQt|aQ`dm zwda@?`*Y6-vgB>jnPpq!b{b<}4&2oC!AoK|IB4dcs^Yp%kTRX=`f|7lLm6x-m*8;uFVcyyIQ^%-G9dlWps=?tQ7vUc@)hDxO0)d^} z*=(|Hs_*vuW|=$n2R2x0CL|_Z#Cw_1I83(Vn28Qj!<|f_q|O*waUaYbRYS)+VuAhe zsM+)%2xcNYX-Z{Qh*uAirw>fRUG%I=mB~sc2Fg4isSbr1M49ZfJu|z6bFTBh;qbL< zU$n^I%&Qu5n~;5rQ{byn+cqL^o8_MbDg7!;KD5klSsWwn2<53Ml}WA(B4rI;W=aJ` zr9&dyBB=rQFwFkkRGtoML$83*wz6F!NbW!jH0aB!w&))!&U;a^(MByOt&BzbsCNJw z$UFY@FzDfU3{wRGY(1zu`E*h+EL2p0FQv3Xx(S%ZcZ&2cJ}{xv?WY>EsNIX#^c^>R z{0P4c6OdE8x{=2!Qr_f5XXjXrgc{q^!vsk6QD1h^ZFmK?c%UQ-pgnR(6d(*yXD!%d za-T@`h`K!juVk+;81a9Jv+`6J+^O-rgrKkWjZ(1yFFT}wu0Iw9s@lpQm?xWC%Ml29 zft_6k0SUt)U*mtf?FV@x0sZmy5=B?McktNs5EF;h+Yghl{UqrgB7!jDx<<(;QO=FL zSgTmUn3S3IJ6?WT=pslt%Xfl&USG^8MFe&Qa-0PTqP+WxPDT-{K+imE^h`Lj4}gC6 z&!KycMJev+GAnn_K!RAqUSgMppT&8Z;5r!`io%?tX^b&A&eemZLO?o3^E-8UFwQVT zk2VxaEV4)i*QD!kUX!7oBYN9sMW2vB8OISE$6wp?h_65@#WMG<)VK_KmIg$LlbGO9iaibbJjS@gfFcs zP{07MfKU(`8cF&1Q&PeDow%3g6C}F^^>>Bpze!ON|KCa_WNu(>r|^r=9A~xDVJE3Tym>G?0-mCZ%ntp%M0Vs%JBf+#ilC zSOb5{NMX=~Ojcrg4oUD69@`+FVnV1yt|)sdEpDT(u7ficveepvJmOSVC>yeT2rf3x zMYn=@*v-075~b2u-%SX|4+I{(!Sr(YHuRHvo@BwavjY*G@A~YK8qnm1tK9$102IL{ zK@1aMM;@K^jsN=3MDCh8w^RFBtdalrr(fXzu$+s2LS;XP=>I^+rfkT5Lf%JyE5$c! zB||ID00)Mr646Ae6}kiUvs4g3g%)dbZp2>fx|U^ZWIlcAiPL4RkN87-`o|=l#9Fd? zFdOHm&a0oV*>uMH)BDj8{TI3GXoK%{zLN|$0GKZGxPTl6V|Pr+<-G)QkWdjdDEtTz zIVkqT)3XF?YPIB&tid~nx9-F;63po7!P#7k3e34?X6$DdBuJ4=Y@x?wzn$10K^=EB zl@73-ii>zVFS^vIv072tndL2KvD7K{fW)k2{$MT^1FH|cAQs;4*E z4*+Cflwj#6(l}yuLYqGxJX4TwI%X(IFNij75p}r3yGp;J#bJ|BqKX=xbb9%)oJ1_y z{<88Kw;Ip9&QaWwza$ zmP*05>qeUsEmnqZ<`-@j$7r#}A^0V~ z_#^<^3KX+PS`TEOF-;%K-tKX29PX<1U5n&^ady&l;|Q-Ai(c49CRXQkna&M#b7F{MzBONzwn? zE$e?X5fu8T;rRcU2$rZrxhpTCeOy`FG2N-dl5jvrQhW}~FN6_lD)s%ss~)tXjXze-wKTABra-)&A9Ghqqx z-#Tpi9OYi*dVM%uWsN*;F2ihtvi^XH3vA4<8!k4>bWRDZ$`{qWoyaUq5N1GSG@Mv& z#xc35KYkWf671)$qQs31Ms7soX*?Iu_w8owrpb(E#kzZCS;np1)|FT5?Gg}}jce&D z@a@mcr0SWSPhV_4f}n>^4GT(Gx+RS%^os-}FE-DrTeS<&UpN$XQDQTX8;P#7;L_LD z<0;sm&IC$b5R#g~CtI^&Csn6*ks`;6(u=pGEgK8V$(Yr(XPm*dwBjJaJ1TN2T$c$XUS;tra;0T}Hzs_1kNMrv>jq!7E1v z_L__hCA=)qH5G?mrk2c7}}3 zm70S#iMtqwztAY%R~8sIdG*x-}9=aa(9;Zsj?vo=h%KM^RE8SQ#P0xfo-RyS-Z zt#P|XUPpr@P11gb@)+i9R8`mnWT=h+nE}knGqHqU0Lk}G)H08*m1tGmvmEsyxD`6xN6*|B&xh!8|5D;n!S7xPNSfD$A!9ufG zCq3W@N6nI5VNep<$iiZ-USiN3+Q^z+w4)7Y#gbh{`2SG$jZu=dU9w#^vuxY8ZQHiZ zF59+kyQ<5!ZM(YIg}(I;?%ertzge@^&UH?nf4QHNPo9j39Z_DO2!d^7*V-k^wHTQ^ zm4L=%l+6hm72*j zrM;89ulEochJrIkNx{n)<-%1-spMFmHlhqKHqWK^hfa8jZmRXY30!^AW`b_2JX|vj ztudYJGF}F^oH)JoH#Bt9&f{-raOYzf6B|K8wrp6$wvLCA#1whvqW7ss;;Q&+!<f+F}IiLP+_rBgy@j>0~N#sM-uHWQ)o=$W0pcE&>7@IFm16Ec8dv7o31#7N1z`X zqmn`!AvzR8QF&+KMZ%-^?ZV4C8L{W>;^LUC=Nw3zt|*6k zxJ~uSIM)k|s5xATXA6wrU9Kwm+TxTq-x5_`E~z_bT+w!YaZWGMBXln0wIX7CgtPPj z2s!+{FQxGLVuJ8c6_>FfKV>l zLw7uSaQE3@+8qRb4G;0ri;y1RL7ngx(o=oRTj-1UsE4sqdGe!GHUz zgdh7MgQ+SVFf93IXyRF~*vs#93{iQP(XSz~V{7&$KsLFSd#71jY}gRI$_)59^2bEh zIhlHRs!aG|-KX(!ntXEGr}1E#Tsmh~k%j|Kj)FDH-kCGeKLD@VdaXw6S}m9Ecv>}w zs!ZAP<)G=hu+l6kmPM30VU&v(hj|HSks`l1(AGKTD12$Hkj_;_@t)2vI;p(yzU$7i zuf(Ta5`7>9tI!#VHm_f+hLu*X`4OpK*37`z&_Qzor{;J72SQgXt)a3ngWHaaV$&+K40TSwTuP#U7sy)dvk&G+XabmM^?RRsh5K+#h-EGf`TDX)e?ETL$3{JTVn9jCUrBGWYjaHTA9AP!(09OL= zO`#mC7oZektEYBT5!r!V<>XP#BL`IrVg%gjq1iGeH}R*qkL{dFZtCfFVcSD-u12YdUhEXRTo46vS zUM>csAnD@{DetzcuIUGh+T1}Tr6f6L=2}9!eq{k;@#jM#v=1*l`m_db{TVhtu$KoZ z6=RTn2h^%VE4%fU?4DTvRbv?MSzMnRBao|p_B+JhsIrXSQ>YmAJKkB=2t^QDnURDC+wnHde%1xAy2 zj#*mX@xEH>cEwTqSV!nzPlr;kM6e4-v@bEuJ8IRlpXOmsW&=LrTDo!4%d7~-n_H-E z@|6V5W$64rpSF$;cs1--J?$b?Z)jp0X5gdI>>|z^h5~A4YAEeHU{TLb9&U)ky&*T= z7rE3#q03RrkDcE3$B&ld$q{Q%ti+r<;ntzJ?=;Jt;`qF3;Mo5>kJl@A%xq>h423PE zauBu*DU-UF&LeXh!>gB`6j^4%YcCG7*tQAO)t+d>d&+Bd_zg|CHW)O8{p7F#+@P)4 zp_a358l+*Vlgkzqx3#}?)0NQES(Yz(QS;0|yF)yHXytlql~k!9`c{Kbv$w0}a?duI z?rsiS8adlACQu>E4>K|O;w=U}!2zW;Nyk(?f_Fy~)F~gQfp=p*KPNZd$|$wtv%6Fs z;;aQlwLT5EO-tJG-&AU5`~nPZCecKeg%6Z@R(OTFH=B1T&KiQ{S!)bBb_*Q!j4}Tv zEj%|>JN(@aQFkEN9Xfj7nK2qtZF({>b4aq{05hvB>djsh?}yXu1=nzgn<_&4TkEHG z`Ys1TwHnc~=w=7ch+QCi2$-}VjPdnopm44A^H(y!vXLKqy=mgD#psxi`JU7gGpBT~ z7xhre+ku$50|Hw|_aZ&|k(Zgnw{T10{JLf?8}%wQ45HgJ*K&c#6rpo@9Ny-xoJT&l z)pR!tNZsG7rsx`u>_nDqkCrX0&2!QhLKTO8VGn;>m2F~4~V zIBTmbR{7fBd+`|5qT(|3-WCuk;o*>M%aa$EbgIPaGE?(Wn&&xYB`*EG?^YgsWR1 zOO~ay(nWPcA}qbM>53(%WD#91wz$f$?JisZrE;f5T>7Y_C2FAhd&cyxH~TwTn=ZzS z9h@&He@}NpfcfQmy?cLu&c4mO@SnbWeD#RqLpXF7dhRLhQDkk}j5pDG)&^3l z_DgW!F${Rw43CuSEd#>EVjS9l<#icMf@3^-fZcVi_N;6)dkb{~gyJn}TTQh|kYFz0 z1_`R-l=EvX^mp1jJtG1osXwhjElH{E>5yvdW&%&7#Pgey?iJ{uLr_qhe=%SU-lrF2K}U-9vPWvNREE)d zFWRR&j(q!71f&NJJm#W$EE)rI1SL?YSLTFb#-ww(Pxx2zMc*#i9u?MxMvKZ+IR90*%y6t?s zqF2Spnz`#VSg|q&Eqh!g;p6!yTc#y3i%2?&T>7BwxNV{rVFmhPdpN(IH^OrZ^6%g>KHVi_-+&Yn*|-UND^yb1lOy)=a!#xn{xyhSSJfbu*zdjNWts%54Xe1FLlJSm zofXayyV7;o*jL{xnr-Z6+`l&(XT0|YEzkFuQ2dIF#_ux*xyhwE4M3C*#u?=KN^%_y zF(zDsLO5M8>k5qXnzUO3?a5GBEv>&^d{AXrYNK!%S%f7mcknUQPv)kVtSWeOC?xn_ zRy^38z3cC;>9uFZ&k(7NiLdg=H+UxZtEM4N`O?S3lgDK~^~cZL7O%WBPfw=!Mjcl@ z)imPkCv?Zg&dUaJlbjuq-0GU@CxJLcQa#NzfN9k0HJFFs?DoS(`}@}`Z2V$Zon8ER z;?v_FJQBSpe6`=M&K7!{e%H~uDP@?}cLIxhqB_C};paqrfx)3oiunb)!O&r$<3yzq z6k*E3DdAQ~F!!2pRd<|l_@Z^8P_NygrbH(P&~SOk1qU!#7Y-$%gAOU7$3#|lqHxL$ zl7sv0T7!zOk)fJId;!)hIAPYTI8m1-*Xm%&M)0+(3;_K_1_XWdGfN89mK{PnP zJsez;LsGQeyaQ}6Wm6mUFWV4?J6a_7@OI@P-4Kna%^t`-PI|6-SrMh7-+G{qZQlq&{u zgYeLyUhrLTIC)R_9wpN53lY^1bjWf_pp5o5NUj^ey#Z3^9KDe>lGhx$QCYYyQLl1v zI>u3xE4dft__?4wKkq7alP#-zW~Ec_7cn;d0Xv|8e4MFg?4 zev9e=+t+B}^cj3oJfov^77HdJuDJ6%8A^2k2;V;LPvC;wC+TNF#qO0?W|J@oyA8_7 zq)cUwME+hvmuCCX+qT0LpbwA2#3A{_*ZDz@dqU09cFG5AS(^8_XM8}}tqE!$&R2QGU7;SYfV9Il%?O>SX*{n`Ky~}9sb}4LjA`3iBlv<#2-b7MccOg#%Kk0qim4p@(@_{V* zkTto8qvKS%giRSrag3J2boz1luBujwR+-Wz(K9}K5rr#gP3+qZ-{UN`>*`V^UrLfc zo(eSdo-#E!syL7pFW>B8n?X{~#oEMn`fC{r|fME8i-KM}3D&IcE`nAdJJG1R_^&KqC ze^!Sx=M%Utpt0vVa!@C9w<3MIPKf+RDu*wrv^MIo^M$YL?mvt*e zV*pZZ?rm%Kt{u9(ls#H`VK4}ZtVn)x3gdt!7qZ3gH{&1O6cXJQ@wsQ@fg&H7$aZ5o zH4Pbq(gCG(q?1mSs6^Ny`QLRNfSr+ry14*a8DUgLK@`ncYd7JS z73>Zx?EQwL5RbDz;g=cg(G%=_sH0GJw%tn43J~z|bN|Q6ZrC6-_&q*Y7b3O_3fRY= zwm{nV=M6M|fWI3i4p0JnBAyNOnvj;w$+kZLAC=wwm0tes#o@*SSwj*qx}swz%0i1f zU#cRadiC~~E4xrA;z_nF6^G`U&sP&oG0IOHNwbq$q%D6g^xPP?)giFQt4IC9;4tZw~L#iqWAMX zpq(-VrfdiYBD_Xmnl{`Lkm}-PaO(7o6~e|zry`{~8SJjXyAaJhqwvj6nx=||7}wk> ziJ#oEaPEK1c(B+vH6~Pyq=g;{MK-Cy@8qHusM@4!78!R*W7ae;D);HExB1+W?Z=ECg#{w}6J)Lvqafkk*!XESh!%kGRG70w3l`I`QGZD%^_G@20a<&~JqTCqxyR~61nRYdVo)jT*aF5+a%aHqV|Ro#zo>za_Z z-ueFXP#uElg?tG8<3}|1zj~!P5Vy-oWU*Ki+kY)H^sESN5-zU9IqyTfDvoTXiu@WCVs}1qoXOyJzS(@Ar2dip zi!P|q5)MOUD!_F%pG-9wl0OoY1^;vGx=Ka58=7H=!f@`6!SMsK?%RMVQ!r6hxr8^C>5iPy>6~n9*zm%!g5`l@6+$Xz5vq;e z>Mrgm~sSR@p|(?+;W#t{Na#s25{eA%duEK#*w$)Z!qS zoNW0i#+VzNY6je+s0(K8(4AA|GVeI;E#Cbzit7&i3)*J~p45$^Nw@=7$PJ@;5Rdz+Wf07*eGcBf zZBW$BBMf)PGR%E_f7`8n4gUSwffATNV`Ad7kQcpQ>*N$4tSoHcJ9S7%anS4UAA?Z? zdFNv4HFedXpF>gCL+iZ-Eno#k-pV8!%D7ioFmOYG%eqtA+n5pHRqvjnEq#1guvd8D z!2|cMkXHFs)L7BO7KZ}*`X;x36snn#;UTyWAs2_oRt%c?QQ(JyNE8V+gijT^g#I=l z3&IQ?&MS->@JM)1oe|8O^-c#^&|t*aVid|Y!+YWc60Z~949wKdscn!-Fk6}16Lb=8 z4Ht>nMnDugmJ;vRD)68{5l@{Lx7-`#(AoD`t}bQN%nO*$r8}N8V?ToqI{uDKdb}U$ zcObXVHJ<3+r17n!M1jv#PY<2mVt(AW4e&6pV^krDo(I6%#fovc&c!5@;|LCD!i9q1 z`U(OU5qNwVkg!X^15Dzuu4ivUZ#@fc#7D~<3K`qd3bnDFxXbk|N3L#Zcrb$q@RA3?oP}O z6{>0AMqq@rQW^CO`wW4}Vs2z{*$b3tjpZ)O#Z|sb@suUoQ~JZz8=GkVMq$=~C13uI zsdcWj{|i1fIgM46D@IeTl@oD$nt73=246$ybJ{nEx1hc+suTS+B_S54Nwj*TKP$f z9Xe*{if9%&-z(5w*2#x_4g;<<`myh!fZ-|TR9zwr@rxyS&LS1#qU?9&r7*8kL+`!; z&yso%BjTkkJS^hDIO9D1833)A_m7eg?S6$;-gta!FXUN_B}{3%Q3>8h+U@aARH*QxW>egOQr;-hD=7= z#8|g#j_y4b(vE7jZx-*H6et+$|vlLSY@j$GF0nl+o0bO;ePT2t6K5bsLSCrjn1SotT(yTXWeV+Dz=ogq3DU zjBBU*?UrKUFiVywJ!vM?%xlJsb-hYdGe)tTdsOps@=gNh9rES%EvO``up3p#1=I5AIn(cG7#TXhAbuWZ{t9F*>Ba6q#F$)at_6 z$S+#Y<{YYO<`G99QMxy#(RnK7e75ka$=N~;bo%5G)7;9pX!sxj$iH0^Wxue=RNr4b zxOO10y&!~j2fHw2_eb2pwu5l}ptf9x9#kz7y(B)xf(-yHE(VYP(bj z2$fFFz`N?}PiTCVePJpejSy>b^>7!Ok2Bf8$Gh2BSBSnqIF6&Z;ytt4pGlGtKpq-jT z?}%zP!MU@%!G!^jy`zz8D%$Fuq=6ngOJyf#RDp48ZGB>z(qMRED?+mq(Yu>@Ltv!O z2h?_N`0Yh%b`rJ743Ja)vzp`D()^sfRGs+Jxo&!WEQ`6DG8Ej$V-4?;VtS*p6U$Il z&7%X1?XhwP0W zA5fKx$3e|hT3Vl)(+~4w`QIo1#7>_P2O=-cJ$r%(2mCkqO6(7Nd zP3WW>()I}BaWw!);+v!@kEZNO{yzZeXMEtkZGAy zD>t%Nfu-X zTS||*AK5S}XrIjD%rLRowc5`9zM@2x-u%7M?Hkz@)^we#p8futi?Il8Qzx}#X|}@f zfbXfzya8%(H*+_2J^BjYeNnm;b_#_yuVrVO-}Sf2G7UfbIK#$LKSzR+&Z}1z$+0A2 zM)RQ*dDh-MS1yd7$wm3;^~GBTQI-9U1MsxtLCO1Ga*4J5EYVnUi1d8{uci;h?8~UN zbb>JX!`?XQLPGaVolnvRiV!6~x2ca0i8EZD#Js-xcwDZ)xW0NnJ|%XYo{W!b`lERz z)Fa+s=0TG@WPtC^t4A*TSaQ>n2l4r?c2icg(Nm_svY%HBJK+qKb>0{)+3ym{I`mcl ziP?uYo~<3aDc37jm9Q_stw2&Q{4Ga;`{U&|50Y(C`iK9*ENR?9R9&8~N5ns;leA53m70w%`+kIrep zOXn)sjAtDx%P|5lGg2bw0Ym33L`~-|1W4sHq)z?KgutxMQGnMY=K)aT+Q+GO8lX`7 zZ4(2ya0mg+45e&+UjWy+4o2b`hJtG!foj{UkmCT6H$G{Rd;L}hK^bdY24nFoLb)3R z0V*AO0913g!NzM-KD2V-#?;EE46b&BABek!{V#VlSUlmI9qR@CFAcgu_|~sc*AsdbbBX6c67%lyjwaW)5lxgX<09h&S327j?OLM zar;1Uc%#&;9>Cu1=ZkxiTV?&u9tGgD&c9*o^nS_Nh5sRC?>jhI-Rd3#&@(-8^XLbu zGt5lqgZuyb&GJfov$`k0^~rp*Z&nB57mUumN4|FXGwdE0-UHg*@i!X;PYmuBXa^Mc z9;VGfaPi(>YA$x`a*(o4;Lw0r$cn?f>uDv#l;}c!@S6+AjxGvl~s@_c?|9(P< z4^(0kWNF52(ijx!ievG66)-yD#&vn z;zu_^|Ix>4kg12n3%LdP+lCl#43Fq9)nj!*_}T0kdOz5PSg@D0gcjc4bVq5G!v*34 z2Xk&t7?#)I5s?m5AG;?jzOd37-V&)Hm@Dht49uD?_7}va884{st(noIdb-AwsyoH5 zYV(B3p~9}K$^nD_);W4Fd^4cvRTu^*l#{P)lQWP#u0L;MYo>^UD|+|9V&$Ora5Od}BRiVHNusd+Bpo%wZ?Gk(gvZ-y09)scngwor*_n+e!)hR zK}ro^xerca@v<*Tf@ZMlbtJFuY15Z>R)ARa9J(I0kb1m}`ofeei*tB!XD(uA0OFss zKGcG)@JwK#S7tQeJjU+J+fenE3q3IPd9UYb$kxF%$KFL`q|{pftb;HT6&zZfFY7zopb*&+V8Pc*Mw=D2|Qq z6gFXPF%bS-*>#nKP@q?8fDTt`fDKo!eIHREFWds^gW~xx6A=A2B&7d@Zw9|nyWB*MQ$1Y< zE47tTKbdnKs4891|1~UOsU?Rk$t}%UU+DqG_MM`)eK9znR+&Y+tZ z$Dgx|Dbr!&EbD}EDJ&QItGRca*Cw%y?i`+&XKew&PWoAbf>f3dVwDipXsHq`%g$*T zg@_M2{44xO-r+;|*F4d_MS?@K1c#OjNAblUJ3FpVO(ZmPq&?JEGvYuxG7Jt+6ycR1T!ejUfvx5A*<9BnfTx^Yi-4Wu~3Pz9G>C2VZl{Y0VpFMboJ-I~Fv^hh8UD=Dh z1TK$ac)W@r@%B(vh3Xht1?%YM3#5(mzz2+%N^y%pCVE7^e*dR zjvU)7tMN5;CC;^gOxH{AiE4e~CO}ksyxYnJ)TgaUN|}@UZk?qGnK$R1%hGVn z%KD7@s7vVTVUt#{XYDfXveNycZC~n8X~y-Sx53LE=)9?Mi!g6?0rP^oL=lQ%L*+r= zcZb>4Po}{?xC?)9fd#Yj?U<`~2@zGmP}vR&KzaiSc&df-E1@D4T_L|;(2v;VQOLqkLqc!-~{eWm?@btxmZXg)K4)wQhm$wdHEkqOe0pq1K})-vpz9_eyR!fKNJ*4nBxY z4t9jif^+8znlYq&pFSRviA_lUQ!uB(Z&C3Sv~9ZxC0^K=exeq4(89&Ltr9tvZXQ40 ztu%}_bV`}`32b%SAyK=p++GlbqB*GEY24F&wl^tf*?TmL+%vq;}$-#69! z32YGc{mJQ`{ebFa6$}rJZqa{K1!@_0%l!fS6%uIllU0!M7rZjrh5We4W_TYoJ4VR_ z;X1z%aG5^pm1S#$xcEAutak2pxIe!CH%jqU@)zCJ0QjvaH!} zDYzab;X0bU9wGIp{0TU??_*ZJkQmX^gvH%|mPRrXTohAbK|GG#gVtZBf+zKbmRi!9 zS%R9`kGd7D!@8u<75TZ`D__0|cO4c9UVvy&H(qpQ|6?{qwG7As=S@KNS%oZ?vDJ@k)aBe@|U#WCSmyp%!9-mFaWsEIz4nMyuQuHa1xT z-SLLIeAL=noKXC$f6kg|Dm!5K=-}0MW9N3@m8;WvjqYRST{u=1y~+k7eXJ3tkLTDE zB=11FfZ?y}|8zm!y!ja7zwI}vuQL%>==@a)+F#)^Xj1|qm7=Fn8~m&2Ds)*2e~J2Y zt~%I|dD>RJu+)4C{#<~&804Cv7fho7jtH2AJX=@pGHHBULD(UY0wR5!|H;* z1R^{0;N!*kJ0fnbNt0s%2sgfnuPOjKB^3PIqKfsx@a*J0Ucpl>-zoMCH_ZIakvDQz z5M%h3u)Rk7K2zACG7O^6mOzz`6Hlc4`!aPhwfX&C8)CPSV8EuINnd0#9SmfD5E-a- z$AkhMA?S;6ffHrNnzuo%6K2Qy@t*1q%<=^4k(D}fpgNKlgn>W@)=oh;{*Ek;#cf)ZN7!X8TVeJON}>*<%N+wL-FpkwX!%yCSl9l0 zDU1+NsEtS+%pf0ZkRdXqmc^&q2z>JJ%yTrli7qUY#9mnE3<8=PJ4Pb$7~p1)JPZ5cC2duHE+krxPgLaR~AD{t{a z@L}02=rQa!D4&g^Ua=h#yCF5tVNc6>OcisRcTr$SkFWNIt1a{eMkcpt7>oqX;0{|I zx^v-!e0C|-oboA9-#}y?pD?}(XPIM+W@eNV7$v18|3xy#P&W+`kGj;c6Z2pfGCI%=TER>Y{*=lGvc%r&%aQ zK^shqIEZ${`V-x)WqPzsI8in2CAF<`z6_{bZX9vLXuVHkmnxT!2;QLh{=!r02Xq;r z+zQ@>`)CaJ)Dgd`w0ZHD51$!NUk^(})CVTgquz+^&~P;FhSFtiN{#T^Ok_PV1dXXv z+JB`)_Vp!Pf5F=;d;v+P_zPu#8I}wKn`>3?wXGQ>mHg16rMhZfD_B*6?22%YGtH!Q zhgW1QCT0YM0Yg>`kBY8P_&P`TToCfxCVePIJ^4jvXpX(^O?xZ};Tf8Ts7Giecse7cWB&Rs-5krjc!Pw4IgC$WbFkr#QD;n#Za<*NV`oSaW&ZH(8p{&7iZG7X zpPDbd$DK>^c@3R|7o^{;+F4UF=s}{%NN*fM%Um$01UsCHtYMG=mV$;}-J}3yoB^Uu zL*7pprTw!>3tc&|Y4b-|#pbYe=iKX^L4c7{X;MNhmL|*v@gpKjfBv5HKych1U;xhc z4w5H24h?02Tj1}lQZG^*_v!nR=KS zySf+}*_b-h|HrVMnC17I?}-~XOOyX}-N{ktk{kSvVwV*HmXz>Nc>`H+2n-xS6%wF< zjYS3(LK$;ZTM-=zn>mH_iwQ*7D?+q}HX?x*ar9<;AD&+pEsJ^ zkK?}X7V-$tDd?eH@JD_B=z*i0At!iy&C0mNoA41-R@Ts%Z;|pexJI-&S_R8A0@@rV z7Pp_7O%bQ;52ZQkY)2ZG8h6DL zyTWFJfj#!B_mcQIy_U>E5p|zc#(3qRA?or_xc(SuJD5`FoBS1m>H>(dZ4rHqff;rC zcfdc(LA*zXM(|BK0sl+VN#b9VPXBE=ME`4T{`=@7)4$VECGpczAcBa&RmM}9uflWa zcjf5VJz~KWNFiYTKVQ}}%yJlRCaz@e)_Gok@FjC}rP1Jt+|4PdvgosZzCC>b?cqQK zS9C|j3Zlwob}$-2hV`5&>Rq^E%c)z{tW{JVg&C1@A)d6*Yc@C4#niI}#Go{o=z8zt z1>T}#JO9pxOxz@sAkB67v>y=-t$`hc-3%^D>gHw!ziih{&*4M5@heSx!`EgnX{v&E z{g}ixw}mq7ZZ<6udK5~hxjbvx(jq4wfEOb$IsY9*NXjbLw8|xui2vxT^q#Zv3I0z@ z{o;+iw!a%z{oU68zh&6}V1E1mw)DR``X3$Cgz`yVb^IIWRwBRg>5>o9G-5DS0YZXE zFbLcjg4h~O!jSgMAZz(Tm`3k{Zf<<< zhkG^jTTd%ZVy6ac4HLBBGTP50_*un`4g^CQ;(vv5=ZQGlTbtRs&H>K0I zv|XS=a6$=x!^>O^Rfk2Z))cotD3UKiB{982hJ7lGRmodzss%THom zH4eI$HyQ-U2oT5x7A6RB`2vR`0d`f?>xbc*qcsLhNN3R6_nj-c^CmPFws0XeIcoO# zb+erFkS-8^kkz8`z&g9mg$Y)g68S*mK#gRf1nn4Xz}mC$qs5Q|6i8|pdo>=*QDrE! zr=Uq_Or>2yh*Xee9ygMGJXb!)1=0cN*N7-3HS0(cIP;%}1s((IWpsxQ1nJ=;a&zA^ zJxY7?1*F4Cb@(+2Gq@F&By-ZKz&Rs1$Blyp67I}3%|sE~X_f$ypaX|5xPYf4Tw->nFnsPB zJn(5O?C2Fc@xOA^c4Yy?eau+09CW2g!p75JrI}6{*=}OSFT?Lw@=#DtLQAHh2eSS7 zsBvMPOIaTZKFrgLlg#3!v3X(?y&bq-wA$Ho;x+%tE}xbPvU6scSc;8y z*sz|S@-i#PfjM8k)|Io7Wz-}Ri@ z$8+sJGwmg1QQwwR+LaJlEk)Fo7FnfAweA`Lb-gDMEzDSS%Ym{oQ;-I&D%F%&SS8co zH_l)|W9tqXAT6Ju!!;Ti4F`zJQbnMfJ;a`F404Yje0h|rI9!kEZHCw|MLOtaA>J)7 zCgc*dSY#(NZLr>f0_|##4xD&2833!(g!q6jNft&#j?_o5Bn>AymQ;-=j<1cN#8+D0 zbGlY|A@3w49dZwhu*)xVNryv>B2`I24TF@Hr6H@>o-EIq=cM5V4B z$8?Ew(!Ff2Z8Q`6D1zdk%bxd;FQ>B`jtvP^gND~mE>+kgy-k1aryq56&*Q}?lHFcT zBcYAa48y!7KI9U1ltD_@Gm@Rsn142;f6}x8gb*w9T1}zJ(qm+BO%g}A=uSzI7$X_^ z2r?k@7`f8#B6W9`R=;VrR?_(azn-$$ebSMR)P^d|=cvJzh-c5>A6 zHzPSGR2>f_!h;gRH^A~jc#vF|ypiXxyTq`B{fM}jre#I0A;j$lIw0eCTSbsJAe@mU z#dt7{jag&C1|+37^}j%d0;pIOZ1R_X;exkfS}@PqM$noOCT-44n)OuO&~6S7+eTE7OQ<$VC_d!XSuD-=~0%$N_v^4 zGY4Xvv+Z+w3#}UdJIAi?_7;Whq)jqrR8idK5+@RMfomiTs;y=x`D)bW$dgnpP0pj{ zR(7SDi4No7%kPVGzPv@;Xr-*3gCg&P3S~BIshXVBB@uk|R@r6PvF5X1F72r@6Un`y zB}or4DE3TrV*?zmc1a~>OsN{pVUdT|Gl0k~*VU65HA%__rmWMXD3&Q1BHs}0M$?ZG z%wrqke|sK_6SD{W%TEnAnSMl>`%31G}qS*N2SJTpbz>_^Ut zF>~OMmCJEJ5=$pA1Gq0OqZ+f>fUjNH^*CJ%O(L7k0U40#5f0sAFMJFYP?#;fR;B*b z)?;4Wi)UU{)T7+Fo=$ERCzg2Zo>l9KvXfKXE1fj$>10Z+vbTw48E@KUQ;n8XRyjBr z)3kq4RNm@#I@ zs6;c;EW>mP@!p8t5oxlWsJbkQVg2;&h)>mmjRdTi31Gki)dIZES!##wQ-JpI( z`5?RO(t#-e?lm>S_0<}HeQyi6y#L-bU$Ft!DJ=V_0NPh=0QFsE1l%h(VENS>p!!-H z@v?`na?YPAv6m>ii zv)b^dcuRod|7!YSeg`1sSAAe65e)k1rhnfj{s!AzT}ZpFdik+EaO46`ApyHrL$iH|})QO7(USn@CZi zxToyU8y7<0BPx+n^SWcqIPD)bO@%Nokr`J)$c@)R$W7)#;3JGmp}F6q%((7fwA$e8 z=npb~j5asvMK5zm5wTNIIvhS^8jXsZfTrgg$A2Ly98yub87?!)K>u{gLC;H-qW=PUpdrzx9MzixPxTUd#b3rQN;Dt5-F^@ls9TULL68uAZfSY8N2a&W z{NuJ(#qpPB1<@cL6s|Xk#8tvtz}R5+>7MlmS-x0b--JJC4zGNv*uWHC1Yhhh#V@pO z;544GIxfh+AWl_bCa0XHNo`3d>rvLnxW%P|KlxatcSbmmawv28k2Uho@_|&yb9l(| ztmD)Wq*WLwvg8O?U1RlMU^cAih|hP9tgc3{GChM9m`JkZiFaEn@I}dWnd;0GTC;op z^kB;wcU3t`z`uQK11n&qnIOJ&^1MZkX$PI6sXc4Ki||c*yP=DA(zt0Na9DC#Om-|i zsA2VYN}AO5PqV|i7VWN0d4U{ljHrzrA^KYT!`!AsAUO8HM+SKIZh%=g z#Z%n&6l*#wyZ)zF=&hyOGFtx`0SHZslLICYpY#%WQrHVaUFX2)qNU@5_WYA54(G@Q zA0+dQG=zzqElBtXjWPadCvG_|K| zRHZKRa9avfUBRx%?A#)O*&>N{u7pIJ%WAr6fIoDIyxVPfgkz?$V zV@Aj$66P7+H|!{e{d)CzUX1{1iIem-iTHxa!1?&&FwUm7^7F-ltOlHo8gL?zI)g zT}N1PQ@`>)X9y`Y>2}BR?UN^jsj;x2DA4tiXVLC9f_vF(k5?VvOMS4W|8$hcMr!-2 zetGq~&q+NFlAC?p?4$R)<7WI8GfmG`SctIGOT7q%$`SR(Eq%`t!{oBULfl*LLS&+s ze?y&z#$WknDYPn+{c+?9ii&jC=L_q~N50BE2Nebq+{yzcygN_&q7S0nt-gWNCsf^d zkgo&3YBl+jS7_xJqeDuM>!x=>_47+X|8Y?s!31Q~j!FIM{wGv~iPl95oQ&Q1^U0Tv zYtYP+wms_SV}z(^;m!V*Y0e#%s&ea8@I-`mlU4d!z)QuT3&w zi&*bO4XLh5Lr$WDhYt1O+XDdTejLUr$Vc{MoZ3TE?{M=hk|veiBqAnS&<#1n3K}!} zx)423&NEWNBNry@=&&7raOi^4vf1(Qq-rjX!u-vraM=*)T@MJ~Fy+cOghqxQ@e}5r zhWf6`BkAc0>|55DRZw*A&Yyl_hPlFU+%8LF_$Nu{>f9(jXGR;VzLGddyM4k@k{l2P3N0SpsC*2=8q2 znXYtlBMmTH4Rx(Btezy1@E zJPYtVlHvcM?H!ymi`q5sPRHhxJhAPLZQHi(bZm5N+qP}nw$(8^olMUA);V+LtNPxV zGpD9%?|)#`UiV(>zOUk4Z5j@%KI;Fc2FNh>}z+*X&w67tG7i-r2wFYFqm zRU&e*in=9S9&5m)mAXd6ngt=*b>Xs=<+CHx;PE94_Nbo_I=3&@Q&ThOH=)RH^%0ka z%DI$4AZ=5fZ5j8*#;}fDYc)686iuVCMflS!z{57P#hjOug|DN*)$~Wty)Fv@F|Vck zlTcUg1gWp*ss_F+ibGWpvO4J@BUiY^rUOG52c%M~ zl$f>}Zx_@-)GVyB^e>$_94byvGX{NT5T=qpI!juNiLQcJX&$`?>hgPT31sFqD;8m= zP1Van`P_IoH{$0m>CSHuow5GCHu207*Ux}jM~#Z2m2UnOC{xM~{yC+?Q%LrvqM6dg z?%i!M&7;~%r(&XS9e=cRtw4{|ve zo062vXVn#V%Ri-kfcYBZvxkt(?uyP!vyqA=976XbMRjDW3}cQVgIKZZlwAld3S(&q3U|b+O>hm+viRQwtxHRE1qa2LcSWEW8nX)IPm{pH9IA2?Cl(#|Go8WBj5LBnLzReg@U2T z4~yfAjlkv^4?{|d8bV>fdeoOpW0sOkv2GFdo%&KciD9;AmqLf8jd>=dJ)8RY^mK!0 z@21xBCAJK-+zP*;zTQX^NSJ$kDEV7%{Yg;Rp=OBsb+t-illYgUamleLs_SEyp`nlF zIMKcpY8w<8Qi9}tEkH=Bb)F0bXV@~S9_mDO(mh#(XfXub&NO(FCjMf`dVJc3TrS1E zy&_L_fNt;ba%tmKx=KM}@uD5{Z3AnY@2~cfahQq}x}&wTF}sWyr-EvR?(-0jX>P(I zM3^_+ek62>mRHsZQP7*R8QCE=z-b9S|4cf0&Osr-Ggyf9l0%zvw|zjl7e0|H2p8vD zwd$NB&7S#|)#pE8aw^qPAlP4(r|$n@_4)U9^A`;iRSeCC4q5}ssxMJ z4OY0e6-;hNDXoNhXzN72Y zbk?7{O|##V-LKCzJs@6z_?)w%-w2a2HN%ESf(B_fngTWYi`pcMI_tDOl$Yw|c9YB(o3o)D1h@TtZkT^nHvl~x2M~D{yI$k zKe`)@b0@(%*TL}1orA`??zR%AJ7GYFSF~O2NUMzNS~Ge@Ul|7IO6nc7WzLTlo<2J0X3;GxX_uziUc8 z&i6~iVWpvi0@X*rE40W&(BS3grf2Z}C>>t&9!oWPLyrNYNJr@)1MYQ9%tsjH{Cky- zuNQ_CW93J9bpI$dP{!LJG>-(c(%(SZfYF0ZAexD07LL;bU1HuL`rXQ*B@E}NGtYA$4vVb)vo#ag2!QyIqrGTIJRvwL@DM((A0zL$=w~5 zwlB$VHMzlgZ^~%51bVCFd8<_Q!svznT5TA-<6!%WSt)YGziB*o{SWB$Por(gY_-GUurXUChl~dnmuk-747StSym9xe}Ya z6JmGGnW_Ie3hpml2j&yhNr4x*^xAjUS@l=iRynA0L~=@X7$Vq~Pd)wB%5N;QKYef`k$er2V%0^-~P`m(}{e zu&7GT2DZiqj>i9UZU5K7ZIe2zmzD|O(^n=TW8{ij3-V{L=F_C=dL-ld=YYe6Ob zvchF?uZ&~Hb{yH(luV0kRxP{&m{;Jg6O}5ap@2Cy*#V&~I{-~YL3rp{3vK80`1Q9; zdZEO+^}>!1*K7BEmQ%OW^v~(fKejPBZii5QuxmtInwP8QBV-V)Ieq&Y>z1>4fwo2z zkBxU@+Im&xE9G^XzS{5?O&@#f0<`Ty(5Fp>CRzoe%HFg>8VNWW`74&={LbQKCic#@ z-OZjCZ&hk8OqE;P=u3jSq)4ieM&WEoi(LXk_=xVH3Np7}xpVy5DSr(}k8Q4^hnxKB z72v705<%SU<)eaBnHn?W{G%NCV=M=ZM~EN;;pjMUwsS>|WmF6g%`I7_=VAj;pzj1K zWungDTt5qQr*abO!QKSnWb?Bex-^!|WuSzKg~Epc-^VUv1^JbXbqpxjAd7{=3`M~j1vu%PC;=p|n`S}At)!_&cUH3Eb1RU}F5(v9qHl}x z+6gW!ScE2;;*giJQy~)4DN9h#r2$N5UV&TT)k@Rmp8L$y-j3YTd5H^!qzi%P)}kFa zaYCC2JC;V=II|e|8m*4Vd1l$nM<@NHu7Zw@}G3$%sg?OOk)Ztd+5~@mmZ+opW2}hZv)> z$fL5{JXt`25s7vKr>A)liF z+}!vAiHYBS@s-o=;NV&^U^SE!{AG&=b)C^AB>NvvXt5@F(!+Z|+}Ls-E#_)SmH6fb z6`cH0!()3$Ibh%ZA-K&7ncbn}{a*YUQW2vI;@@A4w6X1N9N$Lv0|OOg)B=ua7qCc7 z%eHIoE`(yR*kzI*OT%ssr>aX`yHFYn77;>m=|D`rFGIB|_iBQqK&zAMclk|#H^Q_E z_L_p&d|wB5hB`%?CEb+-(E@XZU8UNk0^#{yjeg?+()GO=dX;V${`)q?E>?Ix?H{sS z@|ph36eYUj_|^PP3{~B>p@r}wssyl=BMcfWgRwyok@V4C^?6MVf_ThDFA>Y5CtY1R zGcdXN_6In7=1)&k2|PiA$*i7S{ln;#IQvf@_6Ae zlJVGwcZ))qUMeI91Y=Cx)U8CT^nZD7W6R=SpnQVwX1T&%gmd>hdkJXp&vfxW+JHMg>b zJiZd4(oD@PQZ7%`$6vOykGSK zLQc=&@Qv^Autjz=2;bq3i#+W!3H5qVjl(@TfsfsRI{T-n%<7wBEt`nNiVQ=cC8}`qQC&qTjiFPX{-_aok zT_-4CNzEo%KXFJntH*}(Amn>^^U}Mb>wV98h^Mj4(LITiEUS|nL(}f5s!$mpCFcT5 zzr4~5Xn{W)%yfw`V!$568=|hLzBO-@Q!RP?hpY7L&k3MWw_+J{ zpD7c`D$SdGljJh-&jC%oaj#}*RYfyQBlH{sXfcNh5|Y(562p{BvAUED!ZnBYEwhA6 zXx31z(qfZP7xp+MP(ziYNURfvWiY!zZzW<`Kkt7 zJX7DM_TNsF&0xu~VN7lZVhS$#zH;hvYQ$`>C%*`lj`E>Eaxu~kMt0H*u#de49fCEK z$svY5FvrMYlfwWfu#r}H@__>&QOu>$qz8sIv74kLi8}be7R5n! zXvzq_fYy{)3XLO-85qX(`>&&NBYlwysJwy>>ly)X zcdX|vRID)2*TvIi2Fk>47=S-NT)8w_qp%D}x%j)g@V^hag1W4EQb7Lr%LRKK7`VT| z|JsU+vx2^>*@jOU*u0V*5kDX)OAcf)KBssjCpYeFOJFsAnO9)n!5C6**0N7}c@qfw5{j zUXg5wXw!=y2qVu|oQq=CqCB<+ob&+)L8LJ(oW17DKU9zJR{3z#U!)F5ynl5s`R}z` znf{~QDvPRsrc;vDJde z8Pl2iOB6qH<|8QVxrX646Ej*985o}FQ#OxhP16c*N=(mo7bHWV7TlbdK>{JKU59J! zXfGAq-)DNgnlg}RJxhDi_oMUg5K%wqCj zLeAJ>9Hcvtv3qUtEHm@x;i$;Y}TUH z58(I6W2Fg_{IdD&zMGYuoQGu;12ov(U2K!jPhzxoM3|H8R6ccA+ALd4cmPvG$nZxU z)}!BT7Q@~@HQBKg(h%=TQk~gcIho{QqSjINo;?ArHZFZ zeo~-FevYH>7PvJ@Wfr<7(U5nH_wI+kbH1a*^=8K(w!pC|HA}=K)}jFD5q_c{L7`8C z{_xN`In+Q zL~(x&p|n10r1qdQJErDrE#Unhx=C!F)bpmV?kvNaD>&rTebe2{aM_eb}Y)p1!2@X*2e;&=IJFd5#rn{c4pELi2 z@IG%1`~lIgj4$cGhf4M;**Su0$3kv=Cuf144E7Stu7=3ewP+^P}%gxt%Ez_hn%A)*7mNcR}j69owFZL=TGypN~V7T9{AVQ zWo4`~X7DF#SmjuavsaR??@wCZ-s$dt+-1=s*fB|&2+IL4v={U2!e_%L&24;kEY~#% zb}sU_z`b89fDOWW97ZQJv%$zs$&|2D02Ut_*d4Geo|d|TD9N8wXIP>r3<7v_+^HxVChqUA!|v2zPYr+{M~b9~9f#%R>H1H!@@N0yGR z2poTwpzFwV{~IT`ld!u1SLgHMDVt~)h&uh-AmK>mi9{GgQP`^`ypX z(G>F2T-vb{?Uv0FYg9xnBjGowzo%1IKUriEgI|LM#A>r<6|pS9jXxhs+MSySjN9|k zgkgVhs^?eVujAq+hg($%%cjh{Q@$?Cd(MTh8kWRg@e->IMjxad(6Z1)M`X%_ zWNZ*E4353}ag{7Aeb5$HEiWJb8{Xmgo@l;<04>T!fm|}0dU+J8D5oremWW$_xZ24L zcdGMavUIxH{BG9pkYDzv&}<97zIzqov{sQ7=N4ej+O(Bt=fsro8Tuy;!96_KU+luk zNM2Q`gaKN_D`(!zbKI&)-kPw;IQw#=WzN>I1w3=c$8*9`SwvppQsxfxc^|Nn2`94g z9dQBf+0|3aO3S>1k?Z_w?cbJ`@gqMA*+MiOI zWbHU?(`z}cz0%&0hK^OPP*x;ynRH~LT@kBRi1Z4jjK_<|K!A0e#yeO&!Zb;71vuTl z&LcEAzCNS)_xYjyPqFx0`1RkIEbzlns#dy>yMI|SO>Q+3ByGEVn$BG?GH|mX*7rYp zFD2;x(P4=aHaSsSX=mS4$Imzk!zg$8GOX7x_Fv!w-5K*jQ|8EjRMrsYUhLGq{`#<~ zSK{lZ*voIhljCohkZ-3{nSGqRohV|%c*UI@6?I(}M;3~aEdN-h(DL_i1i(1jY8GjQ z#89|sZHkKL!FPbFAk-|7QYvlwyF0n3hTybYh@u49lTIOao{j7(TMA& z`U{1Lb5?eXqUGzU6)T5bG7;v2}&^RFtx`U#U4!}z7l9Dv2NeFUd_e# zSYzyJjPH)CrpgJux8?BF?flJe?pgl{CzdM`5|`Q?jKkzecvy7x^PdVYRkUXJ`Nj9ERE`a%Z17 zaJqxIFjl{H*nD^q=b{Q`ZP|2_t)NG`3*i)#pLty9tPi~DB;*@=7~VB@8?!TkTjbFy z`svCUAELJI7!s4Y63Ktf**}&Dk&I=bPkEG8^y8Z5C@d%~+_No);qt!hVQgw~spCr^YtPjnTS?3ZgAvT?C{nrVKQUVcN# zM25+H&?!0j11DgFRPchbA{!@#Vi(3S8w(1$%F~!lSTPOGT}EXw4A&)7S~^;wGr?Tb zPJ*~2XI%?@FR+S2fKZJkVZ++tp66-`r)n6_sp*&f8{>j7N{mET@lpLXd+7)+#^cLD zKJQ~|X<1O!InSe@yDvj1VrjUs)cbEUK>vdg`EOO^8FpK|gJ}P-Jz|FepLuDI?kjQK z5*7!M79%4-B2+zQ<6-l_&ynKhe0g#hp(f7`!tVFG1=?1 zWJpH#vZt|xnkt~D_X3@$Km!OF&)q*@VC#m`qF;C7?NwO{YAQ?=ARhOF4zp4H1ZU~M z8z%>&IFoO>TnOXm?YVwX95gi1k^@ejO9!$rh4}Xg3blxM{wU?TK+oaji3vt%r1x&q zc!ylNM9GuqNbL5B@B(SjqUtSF=g`@Zr(di)2T-i9?^RF*Js9N5S&uaF!B-XSSNSJx zW&6;HV@jk{kSs$CX_i6rk#Rf(OM}`7(!W9I$K|XheJtDgqvm4iXD^E<$9k5p;BMos ze(W2lVyon9r*f?Tc`$8!@bwU9n17Qj-87lz%woiebc4U8KvUhU_veXPSe;;P<718g z&JF9tXcNtcyS79KvU1vLd=O zCaSu1ijK1q@IYDA4wXdv-uZPi|FB6L*$T4)5L3# zWWvNyJ`OF=4M2_@bG5s2}vM^4UrLQyfAqIVFu0V>xR8D-TFW{ib+9dzHm;qXKomI zuA5%PS4>jE8YN*0Ng&R++?T)@gx9QeD^M{XC#g1+w0C)7=67CcD0dQ4=yN1+939$9 zSehhflV?*+l0HU+>q%UR5|`#&`jj@~ZJUl<_eMV?LhjqZs(rs#%0s$cz&9taNYr=z zAj}yqkjR1*4^6{p9$~g(8aZ=XXee@Fa$<)_&h9k3$Ra7ze$=9QnXdGA;TO`G?Hc`8 zV1j&PO)T?li@tPcXRV%q%(Lx>j-GBG;{$!n5xy+rJ$(M z@<<%3+qS;11B9+UZ`-17ovOFvQHL;skNqV|3}&X|sGbwuragR+H@LAgI#>dPSt08# zzu2}*6&nIkf9g2=?t0`Q`Qx-|EBnx;GEf_YCc4GIEihJea5JWnj6_}B85?J0OaxQl zsNbo;7!m0kBMqCSK8va=6R@*B&SA(hf57rUg0MsF(JymOr6~*a93<_GJ(i@_?MI;p zP*JEOLo&(g!Oh4&p&&Xq;|#vIs|essx?K=1x{m<-JnN*Dd|Z!jCvnM97g^HPh3dYP z=Fj4M=)RKsPymEv9?~$Q_9AbE)G8YU9;-zirtJCllK6qIcPs8()-QkR-BJ#X@2_cV zb!cYC$_fY%>3Nq4dxsXvj+X2RZp@(vBYDRB@xj7!Slf(FLgjU4EcQycdX4x~wcn8n zCL0aTz|`JD06WMzaN4wMoI@6G;>co?Hi*PM1l+@bX{52Ub?80OO~kVw)kGm;r-jb? z?Bf7>w#(&=ODj8?M1Vd zfm8{k#(e+P*96C0Yi@23i*SaeiTN<{hj}&d*-AbD5ebHOv?`RjRG%TEuLW*;ga_-1 z^c#jg1Yq$Nd#ChS0%_sKZzSN;Z!O^I28FP+2XoPK=Jc6(C*ZOVOgeM>u)Mn0tLtdX&~0%-WWy=Vl$%Y4C?mJ@)yGa`J>?pgZ9+2$bT_2Er%o-m&29XSX2_3 zQU`kna+ksvfOhFXo1wFQvmvTIlUdWDG;aARP$ywPpu1`&b$OLr@##cvvOpFf<<|mm z(yX>OTxtji5ezrXq&}!m8Q4(SxcLDG!2lf8X9y&OyTg<=U`XmSgz$mDu41Yb zm>9yMu0}f1xTUGv4yP93g8;=uV<1Qr)oqnxuUZ|fGKHXp+cZo9s6}wVp=-{OhiE!< zv1jygQrjX?SGLC8vW6w8a_hkv@qY<$PZ;c1?L$f%_h=Xc1nS_;A`*a!3=~H8Fo6zm zRG6*SZV&~Tgk((S#Z8i13g_7H(s*wd&H)~)=J zEqj8DDIi^R=#Q-2T3|MA(d=n`&e+-1rmM4r#f+=^LM7@}11!?bqBM1RV$!t+6+o*2 z);Z&Wd$(TtWJdE^1Adwo19>p()oBW=;H*Az2mq@#x#-%BphGo0Jvu68=5%hF04yk5 z;1U$23fdlWWn2yzVdf$aBgN5aMDCJX7hTW$Pm8-0+a}wZita9#q=_E!PfQ)zs+qGJ z8i$vycU$MDh~JyD=vcM%vvSjVTC}x z+V`zrVulo=l3hRe(!=k5y?S$8!Ou5;Y(4bMJwCzznxt-D7xzdn{Lu;O>3#4a@7l52 z|CI8uW9a%!|2Pebwc*q{wKy^YCFtPG;e6nQqtOp!&ab`u9D*RY`FuOn4{bGsET!xq z6mgfgZqL!6NCR6S8P_I_@I1s1w!k8GY(!N`dZRn*w}1~u44cZ@mjRQS&~@;p?O|Qy z$$Rb&o~6{yw+wqxTT|j3qK1muyL^k6z2$r?z6#lUVlMb;Az~TF)1=f%rVnXe|EdKd z<^FCGge$gV?6G!E!`q5IAC8De(H@iR^26Hi-h%ODAo#9q^a$hoH4{|ZtSr#VfT%Li zy%sMSwK-wEYOy7Hm@WYJ2p!f!s*!NgpbR+)1CY!&C*#*pT7=}Hml~laR30w_{A+HC zYo!LX!kDVMIIt2Ab@kegeKMxx_v=RdHGv=?ilINC>#!2I|HGq)p5{h69rRRMP6)o9 zk(kEqkXZL5$Onb1;;5m&Yk#euE>j}Xc9WQn)>z~cz_(5A(=Misgt>}hVOxAW4w3I^ z9J4BUMY;HQfM?%JadG*w8#g~93ZQ#*2c$fW zwL;u=a__}LovXp{n++vO3Semax(>dBBx(Y_@dB(C#wtJn(V(77hu!O{Tz-5RM*HA6Ypj1qp0ONGp-rx52 z5YpX%kG-TjNc~-ef3={gSP1P$-W5LfGaRVBDkTDL+M)~Yes|Lnz3@nE$4oYjkWHG;eaSRxUZ4557}P5 zfMsVE(H0l+c-rT23$j=P zToxq6xF`t6dSkde)|aPf{U%P*)XJQLHN<;@!)BL1Fs;+4XLj#MAHi>(hz(0nFrrsw ziRBl^7Pp%r&#)kL00;cK%v2`mGnh;#raASRKh6^loH^{ zXHhP!&7`~RKY|Yy@e~>1y+y^Hh@D@pO`NV4Zz@4|*((m&Pwd)n`-(UCo)qZn*VU?& zC(#0GU>0QZ)X5VZRE)ySV9uo;X-=+BkR^3tA#!1m;B^i|9}1^=buH24>(~8)05|wE z4;T}B$V(jhiKG1jo+KgGD`#|)@J3H2)DG9fD&c6Q9l{5o&mtjOG{(!PiOLWr67 zy{Lz%6utSBVMXRht z@DOCO>#x}v{KOugsm`}YE)+c$(s%>Rx>ziZpR7&APZ)|V7(m8E`@v3uHU?F|9iH^) zC5=VqtZtqxD)H9(M* z@HqQ6Ah=ri+|4fvKhVX`N{WCKsAm}kn4Dif%CaR(p+1R(`3KQrO^(o^})tCqL=L|VZLV{9Qz`El^Bu052vOW9B zS9(sJFn&Y?HUbIf2Rvmp?~a~vz*g5If;gk)Z5r?M^OE|Ao&{7mo5_%!99 zDP(jOa*-a9gMvw@>j8#rL)nf{WaDnM7Lr7^YW%h(1wX@UkVf|$9sI_wi0VrVl~4vb z>*Hh&*)e*@_6>nVbpCOMOo`!A2Jx%kS@wU_r&R5tZ0HBJ;;=^G_p>^X&XSOItYIYY z@y72Zk<@U%a7^ZzlZgwk^$WQHH2TF`5uOwyX2vDmkmyMzmgPO>1ge-7b*b=JH$&s4 zszq`MB!|(1j$ahO}8a{TvEOGO<3Lw0aHpMJGxoq-#ac)D2Q@;EL-p}U$Mf6@gz6|?(E zCD~Q0p++PjN5*Au+0NCH9AV22@S)%V>mQC8ind$upjVpNE;w!VlGBrz@L3aDG_6D7 z?#tX8Hex#y4TnXS-z#{U=w=kNQ4kVZ#+u|S-@Cp`{R}MXE)?QcnY7SHka#6~z_eAC zOCtQ`9ZShcD8>!rT89r24k}NFR{(VbHi-mj5bTDMKBVN#i5rybhRzyxvMYGYZSnFg zcsyl~%mHYNUehmo+n%VK0B7D3TJ*Cc4%Vdq@dt!FGDybPwJ7M2HMV?RZy{Zg!mKoy z6H6wzOdk9>;l3QLwxkb~dHhuYeN${*E;IwW1;&m!=^N+A%;O}K9y3kBxVY$*_S>>AE7v_m&&8Ang~?Zzbjhyac0rMIF$G3khjreo3u6Qi#!1ngiH@+i4pL`vW@`uo z&N;M)1@XX-(5xrDd5bZf=ddg-MF#pJ<4+s0n)V!5hAhb`RmFM+%2yr5yBzT`Uo!9> zvEvVrNMwA))=wz1@R&SBFPMcPGkJ2}(4l=;#TPxwLtlxLeKq^+7xGHLPA|N$Q^iY+ z#26Pm$5HQ+^3dN%Q#|ppH4Zl>30rpUZwNpEMQm{FU8=IfANgF^c0{Cdg`5uPzX{G% z`xR5e5{>7|F%&#_ulS$3r>{qwi2cDY6i zTjL926Vc*h;=dauDpM%U>*wbS7R4hhoQanyF{@V^^D~XLsf>ZpXQ`i1{?)H?MA_tL zZlNOojA5~#c{blg5duYx76PqshS%=LQcqF`9qL;4`|*pJA&5Cv4htxW1(d}C3Sa>x zuz(_16a?^S@etwSphJcJit}I6x?cAAUa)z74hwyDi`|FMItZUz9<0{c+1}QJ+1|Bw z2s&f<%q(?KBaa&Yu|j{z`CjGuUgr5;xOskng+7@@ZaOnV2D7{nR_fOyg;h!nKS>Us zDS@RfjHND(l`4Rx{=~QRO^}7R*oyx(sJ1K-RcZ2>hElM{6%$ROMs}{E#7gK)8AFv# z{VDv)B~R45RA7ypaC?(-Tddd6Q*uoAHh1pcpd~woh^O$Fk6`n=$g#D3VKzMaMc|L% zj{@mDN>Ca`sA?uuxD+tvhwALiLy?p|Wz%==OjR#sMZ;Ph%UaqUa@$hzq?AyAMe&AE zefo#1)ag@f1RpD~o4*m*x!qDShDCR^3o`9^)E}LS!Aj)3)YO(o^awq?2Pp3_Xx4$R zVTc;xpzdb!Vlj5-w_XQnbDba@z3g9*0GN0VAtKnPB?_1*ru(>$a369$ttuUHD!Sti zOUAG389aR8jW}7Hxjr&-r?kAOty9U|f{VI(vDY8`A&hcW4{jJOGBb$s^0;*$*Zrn9 zsCIZS#V8<6B9uWvcDpdT`nymPCQ&7}h<(f^ebgp>%tTYadOsv--13IfY8Pb)R*izU zRl_0>GST%^ak<|v(dDMQ9*?)^L~UHOkurlpjRRjQ5w>dPbA`8s)14m$%;HvGfOvGp~KwKD)lrnllo?43FD(v|9!e+|?-2?1Dm85}o0 zz@T~-Fg8vsU&Re$M)Aj>+wt3U(TU}egJV0neug8GE0tXT*0|D*l!vdnJ94(XZoo-m z%AU#*z_DFzPwS`!YW$*aby5GUh{*1nP|2bRAJ5bFKqZ4bO?Nwr;rBCuPMR6=T zZb$yD>}@3S6tTyD_F0SwQzRQ#N>CI_s(xMghi0z8kMWn`gyH90#KGlIPZ?%#2USrq zp-bjRvUtW9!OW>mT&KODE3)|h){He2t_c`a31lCf(8KptJH~!t#mLV{p?VhAkoc}7~Z9*-yJS4Tr?S-uI7hK1)Cqa8kCX8IEA#B9=+W9V&ZU7F!7x*p_i^L!u zRlN>CtxaprE-4=L_k)5!lFd=egT(H&8dpFJ!C`tP-adB2ZGNHCuMu(G{)a1Oz>F`1 z_{$Nq`7gP(ToXWc z1@mT#!n(Dj7U`Krj@M<+Ct5na?GA_PdYe6b4x6wl9J*0|afJb%P)XVGGV$>~;ssh) zQ1jE3*!kGyTq~fyx}`416{m@(OU=$u{Illu_Rvwqi=Ht0>&8?My>OTNoVR)x`ZOnD zRia03i!_^e^Ft5Lj8);$1RlZkbbiX^sX})f^KtN`_JqbV&V%4Z4&A)GuTraU_Vrh0)Ma}#j_pNjm;x?LDgrz>u7vbOt3TIYV4n`hrj!BH5SqmE z!l+S*?qSGIF<#Qz1I-E|#UeW5^E<21#|~&(N-dnnzlrxWHDo27a|W3)IDZekL~B*_Z^lmbSm%wM7DhattqYB~BrE4RJyT;^wZElFbQso|Ey@F5F@-32h2L|-O zv2>My#CZQ#Hi;qP^zZaeC>>(e<|ksFYJ#0g!%jr4#Pip zhfOr&zX2FTKFyge3#!;=hx<6Ykf10$0;V_zN7I8`)VMQ(A#dajn_=>m;BsDbo=+Zq zxIroz$tI`Ii&sm_cWr#oub?DsV9{;HkEtqSqGRI!1i07)AJMIIC1JNYdX#o8)l)`Y z9_6POSHko!LTqU;Qi#UXY8dNn@;7ul9*MATQT~*y|D6=rKue?Xkqve4+f{)?BF$+f z4kQo+hC_M71@@P2@eJbso14y0)d{5HOT-BJRXhIw@sJY#9hoDEl8J$%k-4Ou;XhZX zO3l+t=_laxW1f|*tu45@GRwgz5MEsqVlNNwyXuB~Z7g~r_;7K*jfaKOJjpQ`t~92T z>{@ZF%n8!wDu3<*qlxtcNWyb(ULcRNb-rv?{!1$7$K9<%w$rsudb0%|<>i9h4A1lX z^y~J0H(SZ)&s`+HverYt0slAzG*0=$UKIp1E_ot?D2ekt@dcnij+{l4KnmsqtG~7! z%g*Xa5K*3R8-I6C{<0oGT|-Szp{G$ccXX!`e5KZf2G3?L02;p!ZMv#lo72~1sY>Oe z=n;_QPo-L^Spl8^-9%Vbl4)m@(_$7R~L|9MYTl~K9JF+1tJVNPhm$6v)E}b6pXpaFLW(M z$UK`S)Kl%s2a+s}$efv!Jk>9FteqvQG{xb?i77KxSD%t`V>h~5Nka8<&8uQ$2{99mSvq7`nbq|TCB z%oUQB&m)tfES6UthDESb>q>Q#V38u?3@(i<5tLC3(!~s~oH8D$+N!$vR;7zO5}<4? zT3U_qBb+7UXJQrpz=UCQEEdHi9}}jy ztok*w5NY{Mr3cz9!BoXIt?b#KVC|rxd^^828 z1q}zS!B@?R(q2BIY7J!eE`C@>X$sYkDa%T=wXjWnZwRp|SSdwr3e$PgYrbN4`i?G) z4MtTjTqYaHs6`nose1%4lE#MkwG?5YPGSLzxuuYfNrIMF{HxReb;@!by8&qLe=B5B z^yp=w>T!IS2%pzc7^;OM%Nk77I154bZ#2aU(F6hFVl%ixG2%7(g@qL($R*1#)>GXA z%r`LPr3^t`orsp;fb=h$ymZxrL|rx-hhf>3{OZ86Sc-WCWx477DwUipjl|niYn=-e z(RPE6<0!`bVqjxl0ynVD<5aeN)rDGALk?CXKf^;sPslRt7%6N0)v$6$cySZse~|W$ zL6$|?x@cvkZQHh8Y3;O8Y1_7K+qP|IrES|;Y2NJa)9>B;`Jhkhv2gLPQ@E`jmymo!YOG$SkQ`iwBWL%m<> z&N>q6^%(>3dmnkZKUAroS+3-2G4K@_ex9R7>eu7QfWE|{Zj25N7-A-r*;1wsli-K@ z$LvNxRS)n&4KtP*Fd^zF++dQuw5s-50gCr0psf2{ohbsZ;KalBmQ8< zhmTEghkh^#8_QRL&5l1h8THU{Z_)&|!zC=5p^=>k{;4nM?bc<9M5?&Ofc7_N@*W~G z^%LWq;;7>>AI`Qv;%`@F6p77e2e`-Gq4fG=yGCgGWxT-leB=_Zw&I-&D4i`v{g^Dl zIMUPM^`DoiQ*)?%$9b61nV1UP)lS?IMP_^*MTgBU`z>rVJ*r4U3Uvl=Z`Y2yP1f%c zx!CBSb1)?^EbmdUn(`OTF1sa~vDZ^ZtMv1IQ|*7FTZD+*UGuqHu#Z98Z-VJ#UUZ&!*ss*w4QOg`juf$5!gl)$}* zt?S5Zo^h;4BpR_0w1XJ{_HU^ukVMvE;4h{vSA(*nlpUD$8_~Dct59xD)2GQ8 zx2lgKGQft>Mpb5v0|6C1E!2W2_$QDzq7@kOP) zP_czw>XZL=33u*ZgR+8OVViYIxFqbJqv^CTl_h?KfV!m!r+l1s{fT@-l4msnxajq~ z$R};hX#Sphw3O6gdeov%@BFwW7r%zd9&o!DA*DL@nW03{zy>`*E4cAbjU3QNiw?EN zL1n~2f7%hLgCrkfYv&94(8r&WQ_MsSxe4bGn$_yH*yHV_`;1Vva?Wf(-IHE-?KG+w zbX)&PCB~a%g1Xh*Bsb6^AH6icDmv$Zfo{cZYV4NnGP53Nyp(S8&5eR)nH_2dx1(N~ zC&Q3tV<(Wfm95hiag|n_Swg=WM$rw7#LD2xKx3Gq;KL_Mgm6{?FG#)gQ;Vvjlqq82T9FrpZ=bYt3Fy zI6@>D)S!;Exh|Ms)fmaUzl}KR9O1#lu8iP6 zXumddN}!^?8b_U+OV9KydAiI<)2F!D?!aRCYCrL+_CXQKZDC=CSw5XA+nRbyHfe05 z;yUesDfycBFFq~r!nA5JE2VR3hRJeKpodr+!yt6Qip9Qyqm2F{zRHK{n=$Q779fRz zNX|3jJqThHZDwI^z`P35Y*2j$UQ0=iR5ij$vI7j;VUinm((S`y+Axt!bV$iP;H*il z6`$U9cSvtBzdcO>;=WvSvaauyEj<%{v?bXRk8yn%ZLTqp`6a4Ux01i?&cR|G)o~+ZCI?r z1{-v_PD8cANRHLFDl)JxAKrIk&|#zXoVJ{AltEhD{;YMH)SAZ;;&Dl=t9CK&#Bw}H z*RwAyedqCFE)o`O1QsU|5ep3dWZD82iYg>^k4BO`7|GFRpPeM=}M$zOogH+4E`CA{1bt^UMVS7g%4daI8Oj7;zC;eWoZILuED$G*j9+W({Y%>OW|Gctc!HnY`Lll{V;~HNwN}yf=f_GVZnBfP*gFKuW2q3D=w;t9N{TF+T3Pnz zGkMVlDqnCUmjcuqY*O!%P=9N;-2P z=gb6zkR2dGcsI<{bOh}DQ<0H#jCdvYyPJLbzW)1u_x~*_05bXxD!(C$KTanRq;ud$~$#v`M$I%Vu zs~~DHoiQb;L~tKCd}75K+yG0ZP!G~!VaFu;l8sfYsSs!qo(A3;Oo7DBxeh=UW}kmM&5Pk#OgYKFSwfU9AOg-ZQ*?Z% zZya|W_TeJ>3i=--fu86Y_NwpjJpRWJ{SN{=|HF%;Xk_nfW?=NMV<#(y(c-7Tw`OJf zyi~p)3*}H^@tD39sU(T5F5$}cCEUok8@BTk+=m6)=MSGmLs^tQ1n81fc7_3u?F;yI zTwfqelYI|q;Lp@)wQ)4O`NCO2$l~WLq*U2iy`I-pRMt0pXv!S=WH%qeBW5M{)!Djqz z_}7`Pj%Od!U+QAum2H$&h4fj9)SZDCP9lgxD?xsFZgUW_VpfY-%~>F}>` zHF-dKY7X6g{oz}cP1e>Qi59Xv=CfK27lMoD2n(1V45POs@7uLCRBsls9E&@^iM0=I z*hnPK+Ys{wgFwN-20os35J1bBrilN1%B*1Vx3QyyqzL z??44Td==`h)SF6tSA-#RKl2(R%~_BwGAXQ!+CGU&w>2A3t-O8h%u_f+ z;E%tDL`}+m{H&fNw2`%)-D~~4wfi8o`zW&eFtYnNwEIBbd!_zfh)3yfs8&%xUzm6< zrIW|-O`vZ));1-}^L`Agf13JGPgX9WToH`ZL(a{@E2{FV^6ToVWYGf{M*hsMEYx3o<;`zj6Q4pGr2hP@_N{2CnqS{HJHPSpkDqTC!6vbT7Cnpv#-UfRF7K|a zHV+)-EUE)U~rF`6*9pPHmy zG$bS8M=eQYCM4Iem8{~QQNFNya((m9)^Fk8p@ehw|NQh_N2aM}bQWkpRRzzJb$WPk zQ=3J;7yW)4?ZC}6-FtX;>@H9KdU)j}cX>5dIeNABU!UIucY5RZ3wsr|Zyzs#lbr&y z{^rx@@c$#8{%2;yyo*oP%g3gJ90AijdGzdeS0%HTX$AGcRrT8Z$gjdd%Hmrt*&6=Z zmbU4`M`6QJbZI&rbl9S{pFqpnEj=-gRt`aeKsFveqe9sI&I+y_+uQqgFU_s)uVKqe zc&oT(`CUB?34TS5*Gb41cdL6fC(g4cAO*_+B(L8PDlP^qaX}p!!X05%TszmafX2o;;Ar*BQIAGr6ayN^$39_yz$9X%WetH@N<1z8>KJd2;dY9fq_+6vBO zikwSQegI~$KY&s``z1eOC(fZI+d91}xb2q|HX9X#^fUu2 zZ6;a~?DGApZE~_G!$7{eQ&j9{RQ~a8l<@y@tEoD(elL;}F-AvhR^q7Q% zMM>e{UuIdH9_HETfnD2IYzgs&1q{7=w>_Zi*-E<5g%Lbvc~=pAnxhW` zK1WnLf9aadlQPQPsk#@=dw|FQ4%a4Mo9oKZob~bE#my@U2tErpW_l7l!~_FKt)bIDk*DfG~NKTY$V&rH1?q0b* z3I%GWk0F&V?L1x`-&Q;O>K}7^#M-|AHnoCyud`35uqy5yorJ69XO{*|387fw^h$ZI zkunSicelw3oqg`AylqsxyuS|^J9xm3wS&`ESae-ER*gxWK{2q&^35b_Yz*=+iI1mj< zABFAe!b9#c1D@Rc{6!%u_^c!yhEK(Ae{M&tY zs|@!xDksWBTMbdNoL0~kK4`b;_@R`9Diu?f6r?S>L9t55%%y~U+Zr}2;I$Wc@++%i z`bTYvtE`Qz9mUQaC}$FCOQ0qUfe#K`LOFWm02U`<12UttoV@(1T#1+v6&>;|$e{$~ z5AI}4-yAjxTZHVecgA!Bw>}NGQ@))E(SyE{+3i>@r67Dob;MMNgHfXYIs=sw=2k zKqqAgdfI}?+STyk(nyXv!2cDtWcQu zGZdBy?%Q^7cLo*?9~@5%@4!_U2p5Iy0QA$-zMkm^YmPq-CH`QlN07FtSgI#)c;_#I z_2<(M_JHVF?LpqpA>XvQ>u<2gTX9)bMigZm97hfzRZ|?3*$IfG@}s4c^;3z5%hJQ6 zNB3dV)t_7mE8rT~vIS{|!DksR{VnFXB9qNwq%w%o-UQ$$3Hb2a+&>*bc^;Ko?!G!4 zmg0EH3kB?&YUJzjD7uw1o{^ZKCh4Qx)9NDQ<4)J|yP z+=Do~ZN3is4;|7y!QGu7$yFM$^w8jHY5}>;11=pv4g00e_g@8SYAoxmlz5Z*%n+cZ zjJ(}lpX3C7!M>;ydpeynZ+p;q5|-eM!GH9Y#!#CpP zAuZUIfZSKa1+jlCMu;M{fD{f8M}_HfqsA73(nE60E1tSMosVS>3%U>CbXgsOjkLlS zft~X8|4;}JRgS}Ac@M*S4W9S^xZG_fB|&bC!r!$aOqOd&nW&I+>FwdZaxDyoAu~TY zlYo4&@Kgxw$>Xe4WIbSy)P)u49s$6-u)jHawnswF0#Oq2uCW`Jh(Hm}c~cbE6XbQh z$4c}L$J}sHcHHZhj++3ldhgLGSRHH6KLL9YJPvoPqqHS$dZ9$4mJfwqJ%G^WP_vbG zDN(akb~UMZ3i=zUc)oQws5~`;(3Lof|HTw_QF2uex-P%rMb(zyRYuiT+;u|TlG~L= z?XKyES9;Ea@{!w(p?a4H;;*+ex|Zh^wDxCw*$lHcv2 z@+|K+q4KPb_eWGlp`xPFPy)y^DvKzKRD_#RttmBDl$LS$`TxF5efow2-Y-YD4$hi3 zo3ZQ#vSh1c`?|M#ydH*VA1*~Z^XH{Bh83_d)Jd@GKeJ4}~ z@HgSzOJC(DpFz`^;>r>U6pKZCy;d0yRNXDbOB$_3b7CY+Q_;&< zFCOPgy^)jOdl?OJ4?#RB4F8|8n8?9G=ub>`>OXiN>0-=eBaxyCLe8I~@}HL+$-MC_ z`YTbhaTjrp@mV?vww{vS(tGHPcTw_Niv71%G^PixuwS}a&mwS7xAxq|g8XT^-8FWS)Z&2!0r_%cspBfx1 zjy!A4MsmfZj=Z%GuG+9Px6%V}9*}FJZ(l+kY~LdTU0kCb_ZiaboxBC=dnAsJ$%jUR zWs{S5I(2bM<6=N?ZW0a;;h{49k?uwg%U;52he@ftWDOu9qye|ilAiF(1Ad&SH}Ed@ zRY76>0{vWV3_vFRbLzvsbBqxUEA=FL9KT~J_{g9Nqd_8BA%jUOLH8}$iJU}`nk9eO zPNZbFS-sPW<)65AgfbkFL(M`8UYrd^$8rQ%N{%-YN1P5~=CM(lL7p8B?y-@O(p87b z(3CS#$`|W%)}<;-h?WXFNX2J-&l`tg;`;mO39Yn{aSsyayr(wcw;|kmiz)X{{?G5phE8#%gAxZiB_!&8 zm4Ipuah9exsbu(q;Lcg%?sFfsTQQx251%Gce;jo6!8fCbLi#$w>6EhE?m@1i7gpj; z;=Y+um(Tgn5Joya<+}Iz9<6k#PvYg*)@gM}8M$~dx34dLWs;68e_AY>z7Q6*;287T z%rJEPgmAikL`-KSc>_O2#YWnYfDEfq3+f(--Y z-ZTqG#Mmle%EX>Bp@xyO_kbL*Md&|~n%Qd@we{K-EbX+*%lH{F@>$iVdTWq<3+eJzup9QQ zBYIN?2K25K0Q-~W1YMjyP$U3b7|P0Tj3v*!)fXZV1oP~tKysU0tUMgl+;fyai+3AA zl#U3v_m7PzkVDD|}!&LuSvqLVU+UL;UkN z)T|McF)Pi)+%_n+NUtrms?SJ28f-bD?c4d`$ZUrE2-&vIml2sWW^554IV1?X6y^y# zo~9K36LvgMC;&=coEu%Fvy~avW9Zh*HAyWwcsZ05ki1r_iBq4aT4`(_20M*V#I`}W z!KSZ0alnK9I_Qr5DiQ(vCd`=tg?)9fBx4O4G!aZVYc}9rmpKN>wlR6<9N|u8#kN7+ zZs}S~p{FolNSt6yww~6=+%_6)a@*K22u5ZFn9{8e7;|FV7%_OmSmU!xfbAiAWPS;T zojyW84xLYZPQ$6)ZR0sV37V-J;|DTiE{vRi4g|>H8QoIH5XoW~UW#FB(9oIPdV|450$^>> zJ<>L;2Dk^)*g6$Ghk{)imag==J%$R{I%P8l4)D0O36>bm8uz{JkP^tqyqr7bv~)+P zg((v@ojYYLoA;Lop~y5-EgSY9^pkLH5XjeWMeF9G*~6-wc?dMp?$>UOvppJCOh#%V zpf6paU2G7O0O@HL#`Pg%d}J-Fw<>nYxHiZw>$h}vL+9;J$Dbuhjd_ zfVT_Rp4RPX_)w3_XV^Mu!hv^wOuJ{%TBT9`$rcg53DB38ozZQx=GKE8LX*4g*C$Im z(9R8Zu#!Qzt4rt}af?Uim(u=&o}$K67q;&5Udv7>7vL{?XSV2<1q~4^s7v2*(KA#< z_|vpK4yx|I5Uha;6F%z%;M9p+`RP->L!)27I#^Q(;fyZ|a=n7nFEQaGXJAQY(LhG- zU4JnQIdOx8#@#`)`?lJJbXPT42(q~V`b?&WX|5%8;&imYa?(Ug^F-Jum!hc>W5#F; z6G6D`wvIb42ixj@Mt*t*7OI)5Hrx{K#HIna>^(tSVn`(5NQ+%f=rRsIK%pkQ=v4)oht?zrBcxP;w*M*1&g(Q&zxm_1uV*vhLy}_ zuxWU4S6#`tKYT-z)we`Bnc+%#|56a(|=BB%i<=(vWi>QWL+UN%-V2Hr_i9H)f5+7;Z7Le7w|}Iwx`hx+ zooI3g=w1MboywdvBjkcy zSBxs@6w2M--khLY{z;7rSk<{7QB*o%qdj!mpRgofqVYcS9CsFJ|!RH~bjnpM*$X3}O6CWS-dQe}bQnO$R({HE?A4(-d-C zek@UttHJpVq{UmEI>(Nk&c@BvSvKI*TEfGto0|53Hqb6yx9$JE#{W5)$ANl0AFzjh zu{Tw)*JK)*E<^?D8mZ!*IRhJOf?w3j2q9JW8*U(xK07`%W*%(FV+v=&_jydEBw(8xd@yFOk6)@cr(pk`r>F&;;uW``@r@|+2Ynxw z>ncb$OxANLh>oagZ4r`Z8Vm#ur0O2eJDDH7FHI(3y|%V)5C-_Yc7xzo)INq1cW`16 z1h}r%Zf?AWDof!X0SdzTKa+JZl+1B=ceD>O0pyz!WoB);D&dC=Jvn~1H-B3U?-c;E z=gQ$)HS#EKxOcm-YOpr_8s;@2`04geu*Lfk_Q0&ELbT=jC+%q=Vvt&VhWmCb#S{;s zfVu6iv5fr;=(0%mJLEN@nq`*At)&9}Qfs;Q?(D`_pbBn9!}w|+F<26x2IFEJ|3pBL zXz;B9ToitCAOR7$ zKInmbHXd0*VjoFnsH|XlJtW6I)J0#!VKj3jErMVXc;D=e7zLX|% zjuUszgQISOPq^=L_{ueZ@088^1JkizJ2NuFnrF1T90OW*9^G5p=Su<2x^>Hy|7TcM ztZCzsuv+M;VTA-4$sr;MJXutsF%HSOm`J>|crikJSs+PB>;b8;;FIH~n7EI7S(gdM zw8dmCF6#BtoWM3B-^t~I+HjQ0A!TP#v^zC|;b~POp1*?F>^19Kn&o4=5RW_t)s@9BRX_GK! zJJN-h1Q(+vfL|h=iY9V`2_C&Dj;Yqn8w@zP1?(jdFZ2jpZ~yxEvi%b6@*#fsn)t}L z|CC<%x`!|`16F`L!%#?u*g20%x^mg(jSq5~U19@GSC^GUNnA9DjMJaAp$mdG?vnaXz$I7r; z@sA7Y&&Ny<71JLL{aVkAhlgsq;6a-|oNMfCrI3CoiZ_A7$u)X|!7p%|_4bn(DP^{E zHz7`42F`;f)MeSWOVr^WXyDoEqEohHMCU9!Zb;Vt?4e~$5oVyDWt^|JR12ez?MR;u z31o$AT1!y0pznJ?)Z#B|irKj$X#x|k>f>ngriN_NCYX!=k(`ZFy9r_m540}TJ4K>v zf>`SXazSm^n=SoQt%!obchdl*(8&=1MRE3xeBp=h{~q*ZoN17TL|~M6j<;^5Yja%w z0PMt{3kM46?k{nHR1-lL=pL#f@x;i?y)Yosf1_~mkM@FU(dZe6BAr0)F(DnZ0!Ln~BmDH#l8B=4@o{@%Nn4h8KO?~+zmiDZ;Aw3cM*UVb_H~J&hf%irE1N0f-%Cpz#$V*jyacc^R_NeC8S;@S(h>u6idX>sB-Y|pe)Vz|z zgTM;;=p0Yd@Q3UaK*0O7d=W(Zfwak}Vg+1N+GhH&Ar_-p+>zCvb5Fw)@a?)haphs6 znRXd$wM zBOn#Jt80Qp6x18?M>X=tp$6PZ;1&@DA0P(2w0^G2xZ2QBAvz4TpY(7a}0zUe3pTAF22qbidD~$ zpO+I1;5|~ytEzw-6_K4Prkzz&U}mxB_x9T9f`lDA_l}VGlLzn}HY)xzia2flLJkDU z5))77M_>hQ#DZ8P-*WOUetzf{L~W{AEA^ATCC77jgH=PT$9W4C} z$Fkco6Lj6j`3$5L*b_p1Bh-rY^~>*Fs1^Fla{T&9Sf-CR`0T9BEi z_-Vf;5_&3qH0Tziko(@&*_U5fJs%y-4R$C-pDrZmj#~r^wFVy}-g(}<@~9|a&jxs} zKy0YjH@@Rk{`Q%1l!%L93lpKoS-eKV1tz@30vdeKrkfJ4#O2oS#30o-M=tse{$Sr{ z44N+@@Ej7wv3a!U@0b_+zQKE6gikk%)+67ZUQ*@>hEi^FH3+p?61yuU6XGJ!2rMNj zgd@J1bkKS3^S9B%V~mIA-tjRenBgw?)fWqy2O^ z3gxJwZ#V?@0O#6ssUe6Cp1j(r!G7Zy;tMFo2?Xc%TS_~y)hmaki$K9m%@h9!vDS9V z!ZR`|9kSn4;R+Of#`0cqw3)?)+{F0>I0rM?Hq_?vkvtXAvp3t^CF}uVN_~#Zlq+1|Q+Xo#5BU}_)_*PrvgB#C^s4iKHqiWYi;KmZVi%)hjs6OlR@%|l> zQE>aA62_az`P5HlM^^SqvqCoo*201A9PyU|;UXkrD9ACFE+Av*&^Dy?=M|!AKk>aM zKuhFXH&96M>m^@FwLlNbdXw_p14t;Cl4%Eio?1b_;l*SjwNBuRc%AUynVtkTgi3(*|xG@ z<5u``fS%adVKSA4C3;%D(?W4+w zJSjIcFYtI`d%oC^yuW7I4^AJ@?eR*d#QU$;P%RfSRJxGKWu{wRDA*b~aaYu%(B)B8 zosghCY2;VWeMNNgN?ar_E<-)Eq+kA5acC#Ks)sEf*douWQ&qu-CX$9i3$ggfrR*e2R zaeQZ?L9l^&2h6$L=R-1e0hsU-@IgiJJ(4qoFB!B?F=47N&#vF?C{$7L4M$(!_#|)$ zoN52NQ^FrVh}HfRUWxWULr5fqgeCroA~E?lC@D!^^B=5AoR*?IKSAidpAfgtgg2Y~ z8nHyE@@3?Pd$Q?@Pmeem z|MsDQF2Dod|61G9UFaG_Zl-)AxUQOQJM0^xe@F*TI$2Cqz618N6^14|Y>9Wh;Y~t5 zu_jrr8F5gz2I#W01-qt79FHpYm(i-tW=)NPBNF{`6PD_2$@k-p(fI5MxGJ9;^z*?! zQEt7qIXTC*H0arU`6r4;7B9Ds;v2!k{r^I({N4g3fS!}Jf$2AN&e+Vv$zIRV%*Oir z#^Kw3%<;dVJxM8M9_zvgBVxQMf@T@Tr)gU*;nMUJiBieS(O9cU@tJIg2+;)`GPv9v z&UqV8UigRI-C*?3KRhY$jGZ`$rOJ1Mp2lpBdMdKAR*8MS{vPZ6utocf)de(L&G(6_ zkl_w2pjxX(r>E$q9FHn1(Ow_83b3~oj3w1GQTBx%E6ga#v0h=+M-3}xGfq1s>BnWj z(NA#Rr*)QUu-VHjmlSibFW56mbJJ#&KZyx*V=e9pOV-o&eU`SBo^q<6!|O@ZvQi-s zUPh%$b{1wZ%gD?pQBrG#b)zr$FQNWU(B(Nh2~lEs2=~K<7yU@?Lv6~X(wCQ>pd1rz zO|3xEWV0$MJZ=N=0Q=qU$6J@7k-Q_6|IqdP;4FootS&$zk+s~e24@;@7qkRRTp3`e{U~9%Vj^bM7okf zhd{ZCX7^_B+8jQFt92N!k=(>kTG7rKB(i&;jC`2NgTtREIBOF|g+M85|Mn2Pr6{3& zt9MH{5sP}Iw$a?hrB!2?6b7kfO==UOfY^6p&a1~4kQL}bVvd#pN*sYT303UM!`b1c z9ZQXMba0YY-$S)NAgw@Q^xF`10`PYa2T`Ueaw06^l;Gss9V|#5!bl8~nV=7Cdu@BO zHSVXBEk|hTNMM-`1cxwO14(_I!AxJxu6CSmNv-O5-_p*DT*AeziM^7mKBmhZSIfza zSp2uAqB4vSyH(xK`0%{47Y4glPT0zmxKPs34H;rUp8%)S{@AKk}sv z@BUJH)FCRnV#fJiO`MsEN7b5O@oKelM);8*hzVGd1NGmu*A2_kNB-5696Ta)_1-QI4iU7rm-+$WI;qQzT0DtmEgHl+ znS;FuQck*J)!mmb;%l8~Grf&lH>N_xJ8n{1=Pxu`G5WRrFM*4y6W4GCPq3j!rJb0b zkhyWQ9aKjKk)tm9cW_aSQ*s{8XqdQH^iN!+t%lxhc=V7`{g{|s9gW?>P6>Z)GXXLl zfjOwQ_RbBG9ByHO&O<7 zn|3K{zg1F0MP@e; zq!n3OFe8~=1N#bK@Jwz%fYSt`{rU-}eVHj3D40?WbD3KEb;JFJa|d(({4&vHaQ!xv z=+)O{E@enHwoU3|1!IP(W_Atln}^BPyP*LN>2rW7hcU+dV-+~UCJ38@vv&4j>ckzT z@=@=q2qrJ1n!&5}SK7^`ZC{^mgVPfeMl&rE1Cd+(QoG~`4NKZ30EE9U2IGo!1@>*% zBz6bAPU{Bg?jx{AkWcoR?M}U4hd77$9rg}5(1uWl=$-dYq@SLEU;J6*AOvDtxcgUY zKxe{@$*2dxx(T`){jS@ASK#@mh4`0h>(zgLaRpIr>Xa|H($UB2p^k9GJ7wdrsM30{*{ccNa3xYTHi*?x-OC=!zRd!)%@W`o%FszcJ!*XPsm_7Ak%U%BKyc2c=t<>;=rtUz_N49(Oz-~QDIVF)dAMrCK2FydC(vjdJS~+3Xu!Dd01vofz zjtXjhO<6wAlYc=rKiP4y%Nb!by#{0of4C)J#XOsi?G}d(=0_>{nB=T@O14N%CN@y%c)q2bJG@}HC}%DdfTE8SfoBlnloWi?NSev|?S}l^~{uI;26yjP)UJ&vHDO-R({nxzkY8??l~$ciq(h+L>Xt*oko+#> zyl1lJO|UxxXJyCevz0|gsk6Gnp5qglZ2Ke9%E4$5(4Ar22`<9v?myV}q(=}v-W73L zYX`;4Ru8cM{xfiGSeRz3ZBtq9~c6=Al0Nyw*WsPAaxKa zfj-T1=)i(3CCzi-K$C2n@g;imi&y39*FJB(l(==V;lC<*BIzS#9`jVj zq{vEKE82nx${}$(`vn0LWyI;_%dyyROBK1RL^@FB8mt%uQ-XvgbIAIxG(KJ2igR7& z+esIf0vpdV#&#ReoUxP4oRWL-hrIRlz#VzR*4_(}cl?38_41$+#A53Cmp`hBCqrL- z!UTz$({Kn9N)~$QyRpn?n(44BVr%rs3egx@nx`(zag;X*bfE56Pe0oV>aokl*$cEH zyadI3yTmzI6;joD8!y_c zfKR7D@+5vm>K$!)m4SS^xENOMXy`{ETWD}Raq{!i9@j0=8q!8bR9?%Rax zzh@z^{^t+CcS-pVWcdG4PyP!b9;7h#Pt6n|vs@$EL@(|<6>+spP65qANtz@moE={P zldxzRE+^dHI>!x=CyIV12$e7>`1uR(bmt$y(Z~J+><>7-6oI0}j_w|g?z1gNj6bhn zK|^eOg?gdE+Cq&ewq(c?xmTfVu2jSqooY&93sib?q+Y2^0+s7iiw?ND+2@EI2*7_H zv`H=s*nq*f2Vc!_EDRVqB#clR8{HH2WYr>u+ot)$O!|oP1ifEw0{POCl4|eLI$PNY z#rWgx{5Rlf;I%L}N{HNAk`@!!i-MUN^=qGq2Zqv=)H#1$ah-QQV;uV}lGIS;Jz@fU z7?)>B03LD=y2AnLU`-8reqI)ZP%#)Ztmy>@?geh_8edgxHkcO)liRe;Jz%nQlRgC@ zb<8X&gHT2`!ijSv)K-zOulIj}iMAbbUuvST4*aN7e!g+BdN(5&fkns_ROQ2PIdNeR z4(kGyldeIjmAs)*lDez=OWUf7rbm1(Nu&iHUKDBVDEaNz#^i~sH;F8*U5LH9py`v2F;{gd(d;5S7Xf0&WQqW~(;UX*c zcgfhq!NNh4y?;YFYZCUHYYo?GQ&TzcsG%ccz5Q7_&6$M|<$Q+d94iHMcmgc)P6c$M z`f|WKhJIlN{qEUovm<1)P|L90O?C7VdJam$%FQN@}1x{xa_ol70VdEP;&oFUL z{`#p74D>ZqIZQS}lV^r92-v8N)zqKI_~5OVrekLt_4jEGkpw;x1fr&(g+nN2tK9ka>FZ zf@iyFKzZNk1K7{5h`wk`! zWb3nBsHvMmey$J6%<<#v$GTW>m{1Cjc2nvI12g3HQO>^9E2pO0yE7VY}hB zXSfM<&*F>G3?(4g7f%#EV6!Qz9T$^b2@+BTKi!B{P z_!#zx$`bgeSoR~>!kf2_MqRV~EC+WF?DrkPV-KuC(@H8CJOZi=CwONMSJp}kr}p5^ zuCJzwN1s~)t6G9S_`vCsDKY4MMEo5ac{df7Jnj$i!Gwa1!8!pvmyoUMR90=<$T*MS zkb23l!;jm$(N9wO8F~368@grTz1;V2{lf+>7IP#rigqxhfl1=}AcjJ%^cZ$-ko*(4 zk6~~sA+7Kvv-~!_zZ|%d{S04^U@`8}*B?OXCj-T#z^zO7#bSCJ$&$(x z3-C4R`%5TI?-~v1v1HGi(y8MTtk!V&&$I3o7?v-~j|Hx- z-N7mdk62z<1Nj*l8WtAY}>YN+fGhw+eXEzF6RxeLUJvde zI`!Rh&mf8HzXyeYt`k6yMcbjXmW{6h;|uU2V~H zt9M2~!y_fEo^fdA zz)?(+y(tuLuh+OvgD%L@D6f|VFGS5wH^|SL064^ zLcJzjF5?(I;%nnXjL;V!#g&n$C5mpC>jk$$Vuc=0s6AC`UrZkYv9WSTS|eb!k1m*( z`3pu~kEztT#QXsEu@#SSI5yLq=HU+zE!W260`{2-x5r*89`pYN1EwvMW&15L3(ezn z9-81j>tr2c%a8F8p$t0v9cnk)-k_HR<=#3$rSXRqHDM(^Ysar3y#1#GgG*t+I^Jox zWx|8lx#BLW_m;$&i{wzuUh$2FToZYz@je8{KG+77OKmaJJDM!g{eHYysW(P`kl;_9 zM_Q?{lQ5enbW%~4v%gY|M<{~k_1M$VoFC6z}*m-dRP+ zB8{;_r)~0i(}v{l5V2NJm=W3?xYFv;$#z9A6Jnk^) zpqA{+Ns3Y4DlF|a1Y!~BDQ*wr==6Nx!g0_`**CmU{&B2Pe?+d6X--?yJR`JQF8JNy zUgnSBC&11wp>BdJ&2a`q-(wKi6xvt|e;Bw8EzQnf1dV+jn6JJ^jv7z_>SOs0fNGrt zZqeF-gMOa?o(_|z>`Nx}QVFUF2P8x2q3>c5dMO3jh2Pj9R-^4=B6bn=Wf8t>2kC{~ zNFhE&0{DYEgkO>&Tq6PUK?;aN!oScB1cQVKvC(#y39%6k6oWj4Th)Tzgj@B3w!?0; z5OEQ9OCg4ZU$P*&(RT$9Kk@s72)U{I@I>5%gTzh~^dDrJ=xr6-re+d!S{6EKcD7H? z9@~lTXIn7Sr=5p3Rbfm=X)IW^*eVj#$lheJ*13^BDMtCghQ&t1EnxWYTZjuJ+UO4G zW=DUKT*HL_Z3I~$vy6V}aF;CndleFvQYegqQzhI?OH!ZIj<&ayj?{wkhPJ16Bwdw( zzYsA{%J2a~Kqnbsy`WG_Wy|ZHZp;rJ9?ruO?Br~B>lEI)MuTPV{JC94FL8Cyq!jhG%z?yUDtc5C za%L?W=^$bnvwOnc%FB`^?!%q zHkz843`&b4nuXcbAsHaCDv>IP*2UhI3vvjM(0Da_Wx6OcA(I=Ftd^)g7+u&tI;ebL z8I7+b&+-9=&OEUjqe{#m&jmCsBibx107qIR%}AS{rw51`zLPsc1vabBv~ zD6O}`L&ZL8sW{9)*|;klS=$y8U!)Y;2=eaPV_z08s-%;hOZhc_!@74Td}jwsT*6Ed zJU@-$ZmWo0WtWyJZGsw^Of5Ae>uN@va&IIb-3>_{%hzoT+f%>tlOz0Vr8f zBEN(d{E*h~i8zMTA39Z*4~iZM7!z#et=}f2eLrRm=nv(mCUY;aT7d7PE$bEP^z?(w zUt)Ph(}rLL-j2tLMC&UQ*J75mCYYF&-!Ge2<1R;+XI+eld}17&3?~(>o>G$s8yU$A z^UqJt_s!+@I1$7$DJi(*PaHXB%%*5cFhGnV?ElnHAo}WqDM50r$1LPiJ$4j>%-6~W zoWew4B+;k!<|3byn2QO%B4^VIz-ChjfU`=@M9UyK88m>H8AO6?|5OO@WgPht2~t8| zYF3-s3-yhpQDsu^@9EX233P^`H347*j$>Sy+>n6DF}Y>;Lc`DkQH|G10GMo(c7VCH z0zg-YdX-?%c1R&LF<^F0A-!M%U<6@k4R2TjH8%)*QQcxdl3P^*?r*svKchR5k__;| zjc-sd$OKMOb~Lf$a^b;AP6qEuRswh-b^D-+*zbvEy^WUBv;oR|jo6NN)Bm zAV7cQ12)|dr*)`%qhUmEkd9i!0u0^*Kss(Bk^V%bO5RZFlJ=g%WcQ4dtb}=zl=e{( zyFqso_u~6#1VCf_3DAq*!E-AD`S#s*ht^BX#jHu_3D!&9!F~?`@p&%>;kwa6vhKH& zx*^n^JkurW-G9MZI@E-0-gm8HN3}BsAP3^nzYqjwU~Kg5h{5<+i*V@R8Fu2*IvYSv~#S{T^}zBx}dtMos=Z2F~jM+UrM z;22(h28#XS9@{|$!&{+`ysc03Mk6v~a6oGq>kIwGJ+TwZI?=nmCVspAYh!8$4$PJD zg(Fap{)Hs)1Ln%`h6>D;>6a1x)D94sui?$Fz+nvT-W>@rUy~c|z-}hD<&d_Q5ZHT- zZeTDGnBrX}*32opK{vcWGi&yrVi?$lH&$R`zogdyr2CTtIjaCP+*$()cqw=GjBQgY zJ8+Emm|iIu-R50vuZ&(#n9u1D$6E`mss3&Tx2X`77c;Qwwc7MH<$b5tBl0y|Gn1=veBt+B4%PrrZf;ew`vS7E_A=-t+UeX_O|4IGl#GOVEpA=5 zq`6&{pZu&S0*FgMQ0TMbeomO^{9UX*=+>EFhpv)Q%wHlt!?4W7*k#cj=F$?1Lj_S3 zd=x5k4G_g=FGSIo?e>__OwRjXGwO5EUt;?d?YF)bnMGJ%cpv0gG|%Nrp~Fl~Qcvjs3oe zFaguV(;w9&klWusB4lmwHUJMwKWyO=yaB}qwUvC{NFdt{vqlc5Tj*BY%_RV=c}|*^ zW7+BiB(d^zu)KJD@#iQu`k83(Au6&Uzh9VJ#-FD3kolgkIwXAZaFNbdB^is0Ih}vr7Q$`T8{OmaGHrX937QClma3#7rRI*JngZsBQT@-Y56e4+F@UxWO&d8YV zbpUV2hx2v2NBV_^MFhU*6rjAsr59g#<_(2&29_q`LG=8qoEJ;wI&HW<_S?=@tD=-a z#vKK__YY(*QBP+Y8e}x}8fDKl1q5#4im$k9-@URugqfA#7O}Oeqi18BT+*^g=@lm0Z%o)j^rpEWoaBl zeenhIm}X0Jv%r)8F`%RTo_BA65%Uy4313iTCOu+(I73xgPFK0fM;RNS-UdI>c7uD0obh|BsQfLPRvL;WJopar zo}qoVz`?a_BXUL~4>ETK8&#F_Szv8w>?3IEJFy*$pte6BCj5rSi))Q_+KW)O2cG-_ zosJuX%@o(Zh8)Bxnet0VCT=$8^>3xyZ!2$gE^iGOJLxpp_;G6Cntl~k9cDhyKsz&` zn)^H279wams=G#Y^pIh-NHON%&r-ROJZ5#w>POqnXDa|~Iib0qy{5!Ndc{Fbh4^>^ z-_%b7e-EWy`(OsHWX_op9nAojy5B47nR+=%vzk(cpW?66TFZ~f(&AAO#n!Z?`5&VJ z7PZKsDq0I8T0e3*3H7Dv{N|m)X?0K&hMt*|TQfjvRqoQ#98mZ~gO?&CEdvcT@e40^ zq%EsV1!z;wsMAX*a=^dx!6Fx5ss5@!!abHc^pTkqGp+x+-eyOyx6h8Ti5X%IjWKDS zNU{A*x$e;fV{BzT3N#elU<4~)%*5ZEayo9GF;*hL;+O0K=QL(zw3si&wRE;nZ)vHq z>!D3i@pv3`u{2m;aLz}|2h=g?);v}%!lT8D%MOM%kH~y|{H)N6sI*?%fHwMq#Cq+9 zC_1qQn?|sGx!BX8?wnW;b;dT0g}z39C!43o@iBIyCa^YD_~!~6HDwkcAw1<(k1a1D zPFA5&8)|GrD7OaV-U__>DnoM_aWhqsD2-3yR!XbS1Q9MQpwj+6!CZ*)`5Z$bo)AW~9`#sQ4=ECtZZ35__ zV8_xMw3#a`O{xlqI)LEKZ+uqnk2p~df&7`NVZZ7gG;@O-XtrIkZe{JqyIS@? z0fZszL!Kw>GQ&Fv7+$R5+~>Laj8za~zk~Cmpt~Qz(lE1;-Dz!t8LiCD6!Izpa*PB& zct?)eG%vQmF>DqK`b^uUrMq!iDZae9@`=cS!bMJ%2kI#1nxMT*~*)7r3S zg~-J3HsTU@+gy~h-YP#Hw8r&sw05rn{8(3j%#;vO7=vYz*6PSoG6(0b=z}&ev@|#h960`&**>#zQBH3es^+OPOpDiy-;h4={v!$ zdaio}{-BZGa;`2|y*%vVE-ttOz^MylgWr-fc0wJ#nu6&wThn6(;4cBtO-Q6GB0#!g zcHj4wO|YH^Tk1P@ewwTbeZElFvZGVR^;0Xq3i5;56b-v1(2bNDf2~IV1xgx3$Rx30 zDMR`59i3K>UUVvwYy!z*p?er>iJ3*`$p7w8IX+D|Iz`fG5wQhQwd&BSIEv-I%89)r zZHuNYVh+d|;C!}e99*}Ebd|qso2T!sT6}RS_kwQ2I@qhaDXtJ8xc_87q7CRS>{*pd z$HTvFjf{BMtZ>*3R4|wt8qiP;t{)t@aYE7@YyAWJ`+c+34WV#v0PWy|qd*oPNG^&YMgBt!;c&)*`c{A>)j8WY?f&c|NH9QYyZ1FITfy zH?|$%61iD^D<=PfTmj+RFs4V10}^#>f+fB57Tdr6;Wsz3Qf=1+Qd%ih}y&?MFKAb4Ji_7VJnA$&i| zJCVpiK~fD~prjXe$`0~Q4_O{~PJpggIxV*x!m$}a*mN)MJC}AiT@T9(;YJ8uFMAiv z^FH4W5GG$pP2c_tn1oMcdQ8hMj~6)2iyifVt37L%80Vk!TXax+?ZUOvLtBp3;rMLH9LvU$YzWmKVF3Y)l%sHm#E_3 z7i@>BHfmTRC_W)SphxcvHD~-(h1W>6#5K#C*4Chc44M6tK*$9KCru%=*g7&dWvspe zk6-={;_ZS@pEj3x#0*b=BKU?3b0roXR`GXPPW|>YyW(~|nsT%=eX8;GdHdOen#L3M z#BUNttW*KB$tJV@?T%Fo6{vaq8Fk%Z+H~p|Vt{${SZrfG&GD3?Vb|Vn$I05i*p93poG8!{DQJ7?WJiD&BGq(OI1Th#+tv_H47RX>Uuo)?{z({h+~a`AC7 zF);9PZ&22yw4F*~gJxrZ`*K8 zukP)Xww<)^zH@O3q+_$us?khJfeyWuS!csSL54l*W_^*Rk~w|?eh$jEB1ztzyY>62 z5j(>Qqmy0Jf#SSypOrONAi7A9&-r09Z^VAj-$Lp%?tp75GYzoTLc;a6rEzQ#XhUdP zB#RQA+#nHXA453HMAr$0lY@SOI8ULF#X;4fg3(^H=@fWMJGp9=rD_W_6nx5poOA!W4^_639|lN`=?MlUmUnizgM!T*??LhW2h&*HP1j&)fJ>e^|p?PYIWrhIv+xRTV@q)@_?d>n3Cth=53}sw* zBALBQxpb2buo#FJXYo4S$v4-EE2A>gY0gD*pRXsPkmS>Mgb$}FdZGN6Kx%{n!BDW9 zRv3e^a%R5?YK@WRpjK=7p3I*LL*QlQKmO0kPK5b;D%xs!J3mo3TM4Y$R0aSQ=oA}h zdqf1LL20OlvSF17_ktUUh5})+!6PE}xH-akyGjITMrne)Am_T1#X=)t8a7fR-AC)%;XwW^r;WNs@k`(##_3 zi(s9>0@Sb~z{o9y>VAx`DOtZ$s%;ZuBzMqn46&6e$rbTl`h$2!L%q>&kp-=Mp{Ga2 zZRvwvGDz|nr7d)ty#%bBg*BM1MDb5liur^#(;k&pDQFd`7OUnp3trMT?J0TbChVN@ z<;f`8y+ZPOA}&FoBHz$NcL~vTkpcVi!|~+@{&-+?9*pgmRpvk-g!#n-#LWC zvu~EsBAgy#`W(GqMWLr=3~rHn_;d;gb0RP?WmpoW9j&m5g0TBA3!0-qVL z?1!biPt(trIWp}^7EhBvx_$I|k%L{RzZVeYS(i?a22(;@RId^sT=mOmkeglxZ4F_U*Vuc(=( zDf#@=Lp{28*wz#5H`4)E14>oA_4VnZ#q;T6b<^?l?{y2`kBvShNMs~gadwJb8OUXl zjW~dkps1i~9~Y9XMC&AdeQVo7IX#uk;pt!V&^rzBDUiv!wfT2Z{SkhPp+&6{9%CT?6(sbCX4W7!dwB(-M5^T;u; ztx(xKR(pdh6Db>#MksZL!d9oITtq|73dS+-!}&1{jwjurT0wn2vdTk*;(%ELn>6up zqNltW6I7$7)EM(3{nyQ{2F$XcpwhU>7}s{3B#u%MRyKIl^=$lh2IL)xf+_7W^m;Ykj0243k!4%*wzRt+lrvKD*u}W+M z21%Le=0svX=&Iz-d)zkCd|9U^+jFxwPylhKNIwTtM9nGx_B2+^0gdcsY0&@)NpH+HxWoMJ;_w;$z- zF|+(a&Nq0iwbcp1+w@jN)hiOZ|2nB6GOJLK-p+4It1H<);DU z2uusrO1x9=M+JNYs*QSsdsR|Lxx-9p;T2?wX;;7s23qdd?l%p>48ja*4y*~h1nNbr zFVs`)M+f4?5rgz#pLE;g2M*kYF^t(|$gT;&_quOivm_!{>hh+QhPZ6Xu26@q3q7oY zyid(3cs;5cJH$me3@%qKd<{ra0AqA^O*j)m&0lm^h?AcZcA!i^Cv>MsNF{P7NiYMT z!2ngo?ikH&W6oX2``C(q1wEXaZ)+3Ni8>@0U!)Rw^X{RCyl|gJ3VFmoSP6OfKUD1U zrdwwA*(dN)Yzs^#&Wxl~1$EeKP+2&wq|`bTP` z)&N2G`Yt1k-)`~$wJhqtRTT<4m>5_A>?~}Z{!b(0rua$80eX~RxgksE_pj9#uy%&l z>?|U|Ji^j2z6$2ffvDfbg{Rz^(0DzeNQqD`XaN(3^&_x)Q{OjiAMYMtKL9a0As>D5 zZWUG4?=LFK5t1SO*(NIc!3^=Z4~=a_WmzI_g}xx|is;?jFrLT^$Qwc2K1$N!U;|Z3 znT4~?LfR?WsmhHJQs-f2`&*gkLrNmFgO(92A;XDYTO7yfYY8yZv_x&_vhjEyM3)^= zvUn-z9}_o?;t%77MiqxqS*~1GoviPg3pyqH-Dr+z&M^I4>zop5Yw{~|oQea9#4wN{ zyS?;1qG}k;?d<`Rx%w-R&p+0;|M6)(n6heKzUyzuzpNT`|7C^#{+K2Xwg%S!wDeVW zF!76Uf{+6Q7NgOE77=agc||r*NhrpNiYWMXc{9a88ocbl8V<&g z;&^Z9uK|CW>3>Qv%^!tNJQQ$lilq>20H+z?WpyrhRW&$2T>JWdz~q+2aTc4@0~eNQ$Y@RQV5%?y zgFqpSzq#}p9+;@h2CL2jtYdB5fDeGj-v&?X%{W~|_?bM9&Q(qF&ADimoMUXr8SSVa z?6y2rt$=6~C_C{2>%k*THd{t0=S(H(>dHCCH(2I#WstYI=?-zmnahvZEgY(+q7k?9 z{X`p(258b<;<;5HSaiO}nbOh}-QA)qtKxgAi5s}m`fRKho!V6ogkrP}3MNX%qoBnn zPFse-ux*FnqNspWs26dJg)Ss+O6x$3u99OKQ3+3o>L5Vy4gslOg#d0ct{HVsIa(Yy zt__lNb(NM%OKmMOAzt9+1^SH7k4c$oJ5SSa3Z|4R8ZKK2{&jHr#lLU|PLv`_Wy*5o z(%HQ9SXJ0KxhXoF4bHZD#j8^NQT%j>&D3ZaZyfDdu#czlpY#5(Py&E${Qy zgoL@5%?PU_TM71x!{88eB2G|le}}CTwhI%35;yjP^9WCxo0-PVT&_`EAQa1Sf%Az` zvP0@s?6kWO<``eHuVQw2fV5X-1-k%$`jGD2wEg8lcMFOzKb5o$-CiX+>)ih{=d3(V zCltJM{C#J@fP2S&sc#$dk{DBbFZA>bciajVbN;YZ*K@C|eZkq8Tfi~Jj9jjFo0;&6 z6|LYPD~cV>h}jx=5qivXpt1 z?uAELgR9I-w+y4WbgL5>ozY9m9)og>aktOb2TNhCQXIF3463@mv%(yrX2 z>;1qxJH)$tH-oo?KUnYj;3Sp2*VT)B&uPxUiK^mt8knM=C8?lY(KAfXl_x4CNv3G8d+u9`6Cji2zxb4#bU zqDJYXQc~Z!(8n_3Dse?NVyeSy;^qz!QzL*1HFiW{5E=wAZV86$Z4veTwFr5;;W@-5 z5KO0+K6oY2P+2EmJ*!2V>40Nn_wXkK@BSxlm)e;=SWsmRzNtD*4F;jTyXc#+uS7fMJ$4dDe*0Ab_z+U!G6BrueUC{R??-5cU& zMHSqp>GcHY&4{>CBVeKN7b)@!Uc|lNP*Xngp-f@Hqb~H8eJwn)RQfM$DqP{S#EcSAWcKpz4GQnV4)|M5ew+t(jJI9uj9bVpS zRj&5^ESE>ed7X#)M`|(`z00H__|g}HY@|=SrQs;`q@sY0pzzFagM(0pXhEn%^5Pp3 z*%K4iL3M^`ip+(`qEx#_2g#ioKX2Z$I(I!vh14yUjw^abMH?1tv&E;R zr+)pj64ha=5vj3wcELXq5QOyA?)NRM0vQLd)N>8M&|&D=dk;pKLao0@feOeSSvnxu zv6JA9_+o+wBPW(}>d4YOqj~7)y+0@Nb_1T|GTZbAByYjlxebi>9Bb%RxNl*O4PS6>)n8?`jrWj;#yzjMWO*)nrHMu# ze|1uu@yM29o5l?*tf55!S+_wW#pG8(9)OL#5@T*Yj(d0^@urBHb37}&?G9mn&% zp2uf3P7g^Bw34}d)GxXBncJ42V*BJA1Ntl8o;$(*34``m81cI&RRdmFsM%;b)~S1aYKGqPl<#5b2Q zZ*(U;w|{#hy(=r3bNIeH3Hu*1LH^G+#_<1Z6dmb=1dNRxOdK8mt+n~L=JDV4^eX4F z$O0&z#WdC$XP_Y0xxh<`xm0_w0<}pA2>dcy5(9X~?KtOWE~yt&nBG($pbWF%H+fNJ z%~sHj4CEH=#}mKry^mSB-tL!M@P3#oNavG<1BJMmI%MRz&N@)H4bUr(EL&#Zd_)Y( z)E#TaOl+F8s;*4dRHsB7-q{u<(V^&dsr%}#ZjPn0Mv#Ct3vvHZHJWKl%2t6byulEa zX)#b&`J3TSFi2)$jmS_F$+Bz(kWknb9pl#-L6y6KH|T+CW6UI5M|E%B+g$mS z^*}|dG_{ANt#gt`s)}fTut2n(tsuIqUd6Q)hFe4%?yc5zHQ)}bK-lQlAS}JM2py?7 z?W`J+XgA2IG80cuf=LW9(Q4x6@P19+IFrX2vA?}TCVzIL@_hKn95HGyvjRDAWF=(6 z$7x7jShPJe2SV;^WuidC!z-H{X3;yQ=1U>W(>q*^Mv!) zFfD@_muS!$Q$%#kcx0eatF!-!bNoGe=^xo?n;V)VW*aDvj3m=i zW(f<)B8nu_j`@RT4chRzC7mf<7p@d?1E#Ier`B_NEpUwcH>LDqiV}{9tB;JE{gMG!$bp`h}mjx)&)uY;d4|4|y!ZnT7XsR^@QYWKTabb3c`JI123<6|VeDJF z>z@(qctT;7+*RE>uzE+eUUl_3D%u)y^|;X!H97k}M4eXuG>Ivh4>lV5&L1iN^5IA5 ze~>@^Q~yr<@7vHS6|HalJIZGWFtmxECeR>st}6LqeVE%Jsq%tlBve@ZuYDJ;GU)Y9 zQ&+2pP4KT6$ibaJz8*XiZYCPgHi-Zk58IEaRlBKGrjN(BVYwe{wQE82Lgc)yWAb=< ziRJcV4wd>L{#6Wsd1O(1#*h{QZinFg)IaH1qmj9WWfrPnF{3bHx+XCtpF>b7L^yTurs7oS7&NKJ2%x1&5f9(YX} zr16TlSZD5@>AfOdKyK5x7vDTCOzj#D`=^wX_K(=tE?2kgqQfdtCu0wftOZ^3h0$^N zs~~tJWCqI>lY^z4(=)ph+P(T0A`wEcY@_#TBelR}aw3&e$9twQn3=71Ff~~kEzFk@W&t4t>03DWjEfF; zi7=PR`V_U+JVq!Kj9I*cx#Yf2%&&F!!TACaH7udz(v2jl`0NyOlVa0gXMVFuvmWUjZBga3F!+y%Yo;7oTfT@;iq zv=>+B)!Zs|a(~4_iLqg_(-IEZ11)n*73AzA?O{Kb?uQW$%m#sok%h1`!+h^Kf(m|e ziV+PJegm9zHMQX65nQ?a(Qo3ZQEDUB`msazGAFVjOh zE!|QcDtd3~&t{3n(S-9;&F2QgL&Swye}oB}z$X4YQl@kXgmQ zi_Uq6=P}}vhK#F=Mt`{%msHUlfJQwhm`LD6EZ{Al{}UH*K_+5Q3s0P|7)Ql-z=j}7RAdZKWX>JnYX#Dp!^2h^arRK@K*nSNCVE0<$d zZH2O`JxGBCGLv?>gw1NlejY{scC~ydawM~SN^(K$JY+D`4nZp>e2{Hj)~-Y&58NGC zIAyDh<6x>{tv9XC+Mz&o+?Hc7=barUdS7;VaN7kT6*oEk0-HNg0)w&v=96g3Tyxk3&(9q(^(v@3I!NKDHS` zN9%%v>j^f_iN%afG$#mmp08r!GSYG1)lF{yAflR!BY8@rqNB8l#rem+SmyxCX0v1p z&%z1Yw92#aF{;N&r{A3{)FuV1~@-Zr!6b%I2{|M^@sAb(-Sf_n)R7yYV@Yt8eL{ zU7w-^uAJsPK_L_u3$<7bu$(Ry>{Ejv^&2VkH@LR;0L=;sd?EuS%W>Zb`s zrE%}*&4wM>2A)!)WuonCtqHW3aVLW5m+)~}T zK)z>_!fbP-xy6Xp;moGGVfWI(E_)l=my@Uk`md{UdPBG8iIZ=(*_`Z+fH|1~w-X4k zAtdVVjYIg@>}S~SVx8@rA3qbGL@4+J5i&Go9i-!*BCaDv|L`eRvDFHH?Ce3ufGT(b z=`g>^7K{{Wy~Ie^cwb=SBXC?`yMCPQ?`q>)8lOa-tezXyb>o zGYp!l&9NLK;tR$$1w;aCBN1HP{)C!Z6$?|ahu36ckIBjdJ-v1hkDdzHSS`lCwi74` znn!KU!&(oJg)7n84zYEJbeU~7PnBGDi9bo80rzSNk0tX|zJVR`0MR>w*Vg&%2KPob zf;>Hgb-pTGbUM&oMXTUR^N0zH4Lh5)y{%A#H*i(+3Hpz5>vxf{7tXi+4mRw+8n^yy z2IznP3i5xCT1CnR-#rt8w-mHmwMcFNIaGu>1*ivp7$Jl|8j>K85F(Ke{`$Ele6{Q3 z=F(30oE!r32hb<^{>CG9FsmrD%y$Mp?sR8rY2own`GC_0qe5&Hn;A!tjKQOKqQ*!e zNX7WeSTUGSr0qJ1_+Ds;l_D+Yxm&Pk?PAB1!>75frMKzP)X~;3-2)fyhaL$-nL5V+ zr9z<{Vz5bTCF=j_p^~_#Y`H!#B4ya`GN!HA_Uu2eg>;uc$6LhsAa9+)Mb-x?52N!q z^H~B_#buFI;-MNo7yBw!{dP`(vnSRiph;oq{)D;RSbT09nbCn(wfJ0Pt&u0rc=P=bP8?xzMId)>n(XW;8t6K3 zqcR9Lc5F1+le|+bIzpbuKd&X}7reV})WulLdv>R5jC-vnXw+gyYqzfQI@ff@s+*KF zgdqC9XdyN{8B&K~AT|mkJhYK6{WZ`S;W?uWV>IVEQQ8{Y7y+JU_{-d$&7I^#+QdA} zNygZEJb5Dle4}zsvnq#wnM>#a<5GDXv|ZS(7iCMK!PyoUFnqHlAV2wbY5l9X2VxNi ztRLY6eAYkISa0TWRkWM_bpeJ4ot#lBCEi9Z%it<9r(RetnYuKP9!>?S1Npni5?fFoN5E^GHxB^_jyA%|2&3f7$anicnLLBYvzVLFBoIQW4k;o1Tx z4=3F-*L7hUOz^gO`jHXG2QWrAd(__!AwS=Obn!I2%5l`c4S2R8N97#0{=}B6R-9mC zUdJo_Gt*mpam@GiZxMB%3c0rNy&8=M`&SY5Kk9D&?@+4JfObP!cK(cYDZ;pn(X9Zd z)|b-fpM$c1ZFUa}g%wPLMH+(mW{M9`SrCJ%b{OLQ!Cqe(im^#J+GT~5$aP*%Dkf=` zFye`eMjn17iq2@X*E;K(XSUdHl=&+=zrx{a>f++!>OykSSHk3amFalpJN}2N2dVaTg<{uti&h2chBEL{x+-X=>xp=B{We+pFV9 zM?VdPEQ*__&1fsTQe*QK4n1Sznbkz5=hqQy#hNRqBGH5ITfWS=Nk@`qKvbtJ#nC>W zIr#0^LWZNej{CVK+05i?Iw0q{M4BvlQA>w*kx@@JH?7*BPF@jNGLKqT-_VPd z1(*!M%8_#OR*OEupXy`eJ*!_sW}oKHOG`Z_6DF;zUaaM*@1rX1nN`;Ri{w!A^`kPv%fyQELR}+m^zdFpM=(eG}fmtn#b1cqK(H9?N zj?K_Grm|kHWz+wA*uzZZTD;}5%8(e#cV6|&;Mb8z(x}xFvQdO);m~o1VZ+a_BzgYcTc~noZK!LOYqmptq z9+j5?*(guC7||<#9MJpHgeWtRzi}chqAsx4+`Fu4dl^wE+El8e7Bz=1H5j^ZxqDJu zi?HN93SdkYZxJDPi*M~b{vqb0-h=8B{fO>!9cCG-RK8gQG25m7E^o-qJs`;f?sWaz zW^78rs3hHc>``+eeiJu7gju$gY(=FhWo6=<7DmZB)$C>+bHGZzeRuDHzxi44~RdVK^-HsbYgb*dzK&` z(jOa|qv$tx!ZV`E&K}l9D6C_492=4jX>^dhq*t;8FWHCV*>?(ST#J_o33;6(Y;U%1 z`4gtO6u^eAG?Cx4N0@&48|6M_WbegUggFsySStdhyt*n+I-8^sRR#5u))sR;cE(2q zHLmvWriygmSOp{Vl3Qd0tgqVspAMLP7zQK(Emqc%!9p$HCfWL^_5FQ9O;Ma0<7@>~6xV;7 z-x+6Hoc~xR5nr-cI%7whYiG^LwXCyGk>a2on?zq_;Blbp!y$vQbewj>LBlW-&KvK{ zh*Z<;C}%==%&(9=f(>1c)Mm1sF+zDA?&R)D_E277OeXJo=QngtV3tsn6m<$J<1{n} zIyX7Za66-ueAYq&=9_e_fyzi}qC8rfqCjNS6&1{wGOA8npfh9uxh!cOPfu*19zbaz z+*ca(6NwoToCG@oAs!GL1TWF5*5{3Ml?qVo`-y~`bQ2e(g!I2id&lTZw{2UvV%xTD zCl%YaE4E#+Q?YH^wr$%^#lESv_Bs20_qMy*Y5V*4zQ3P2=NO}p4&21+kN`MISEXJ< zMBF4>jb2e=Po-Wu@u%c~Uy@G&0kZbv9`-UIp5fQ``@LdpMhkYA>aUkJLRe7AlN1Y~Sjto9B~c5BXv&f%3@Xs5%JsFomr6=}oi)PY{(*|4 zh6@QUsEbbH?v_a82C*44YAuZg3%=k^G;SHYrCM9DvhXvyNeBIe;)$&*RF}(9@8^X* zIef&GXOno#bES!8dojFk_99$lkoA+frWF@2p2T&t-|<^=3huSbZR&{1+fh*G)6;&m z8ih{C&-WIKmp7J!2hM32_)X9_Jl_Y-<+7{N#3s-nbzkcb*@W z;0g<#r}PTc(lFNf3_ShVWnu^)Ya{EfZM z(vu3&MKZuOM~TRjsXs-r?14k}g#RqghWO0K$M2UGaNG%obcVERgKrCT?Sj{Z-)#y= z4sJq*-W7$k?%|_i_xF*%26!v;!@4#Ed4CG^lik}wcHG-SvF!69cg6cq{L-8xRlnPS z$P-u($f8&dep0GMWKk^R_fI_WfpmptQJMCw_127U+SsxZzVO zUjrvlEDOcTCAvXVs=^Zr*Hez(Kq^DZAM^lk?Dh~(-0Fp$@+236!qLh{!b1h9o%cX5 zK+X^g6@g8KE;`f;h1?5RUT?eUd#Hz0%{1V)i$w|m^SGugy18bX6PO1UBN^nthX<&U z3e~|^2$UljmpQE zPGi#P;Ag?#1~!j`SHgeRG{plxNJ1*lQ>|DgN$$?A3!>=+4eB~XrPP=U6U zD?-;P4M6u1(%Sx{s6o;X<0;nkxgl^JWkapqK6TfnmpmkU<8dGtf93pwi_*1Qd^(eR zIyt|bjk!fM8`zB9AJiMuvC~YtIU)1QZeq1iSn1KA-H*z4=j_Sr4MXCIuMT6IOffA> z8o$RF-Ya>_ef!WQn}A-trW=~}v5m~^s;-`9+dZ+B4wB0~z2Mh<_nkeHXxWM(57Pnj zBY6;uH;xa~4O+R|zCP5>Grt)5-Vxw~=MuEe1zdfFX_d*9xrte~E+@Z#%chNSOGeBF z0N=yuCL0E>)K%_1g{LZ>9RTbeovTc4L;TUvtfq8xkk|b0Vcq_%ym;IL9fq!@XOqCd z^MKHDeb6fPVv*nS%BMQ7@*oLETn2*kdIaXx@GNQ}nAAcrq`9TsLN?b^R!=!CkT`Fo zp3Oz3TTF{j#_qcFs3uJ)NA#!TE9*w9?m)UZmk#7ky0+TGc6RfJy%x>GkT6Bmb1ND_ zH1(7~NXQQf&!(xDb_8g%;%QwHU_My`nuT2%=duC)Xx9l1($jL?M?a?U_EoHt@%G?( zqA=4Jz1YxIRFb_+54IH+$Ux<@ekXQ* z&on{L7l8Cx&y(x&Imux1_w zYqfhXbTGN*`3wN#BUL3oJH>auX9Sw3=Jqe8z)Z_F)k~F0z)y0wsk!;p?ETiy+J$M+jOpwa$)jf7 z#4ctWXv6TJ$z>YcGWzkIuZZ_?L#rB)S3RG<$H!Z17~`V|J21;(*K?@xw|8*DRYMSX z>PQ3gT1KY?@ydGqVT<~>ddIifot0<>67GFLoCOr&R`jmk0oo4GLHOH%Hl}n?Ep`9> zc?}KlP*naLi|Ox?jr@lPFocvJzixXO#P>K}LsP>8_Fxh{(OEVEq-G_wJjqUMC!KT8 zU~YVtC^YSU=PrEFW}-%wRw%X! zv(CuYeg%%mxS-3c$%sksdt=QSo9>vuGMA;Y^J}3&S|#CzHzhJ!4S;OLU~z<6HG@)- zM`N8;IWM&0JpKtV6cIme5SZlC%wSf5(1^Tk5@Te`kv8V8=d~Tgrv0+}4*neR!;IZN%c` zopLSdw*&q(t9T!mcG@7NKizm=Wnahqj1+J=TmMv#-0dT!4@2-2krcq`vXpEhsuPNPJ`_doBM85+^cEn zz>N*kilx9=1!w~rw!W^Nx~chG&N4InnSwN#nT5ex$BwTXb9eYTb@L6a=iDT31^32f zg(o@&nOf=DnN0P%SEU12(sSaSnqr4%su8LybRB*$DyC7!0*3Cbzn)f~zTGI>%hGiA z&qB{4-)E8i9#hr#B3Q%JwYil9B&4ml9-DJ)4^W((BWl>`L)%@wXX)T`krYf5wEx9W_f%!>GX4p0rc7<5iDhvry3BkLc$b$22!&}4Z&dYM%@ z9*!T047oVXnN}o&4FFUvB)3i%)Tu4XGC=8Ci`Q-gf_rbsWC&FmH+KkLE<6IiP7W%7 zt9qXvQ*WOB8r_Mr0!5_YzL?Dv|1`SG{U?iwe~<1WW|m+4XJJ=IV{3=6)PukI2N^0` zifdnc3Zpg^c)y=!3Z@bS^*?w-v95y}Wx`J&vK3oswsOlGuDCs){GlbWMcrxwqm2+&=Z`Xne%U8BdT?nqXfeKc)M zCf1i4*fGZOsIusyq`9psRxPE~{Fu)aP-sJkIuXb3j8jFoG%P0(HX(AoCedZHlrqYi z+##_bGuGiT&|JOY*W$c=hIM$stX<9?t1rveuT0Y-PsTZ5t6N@CYlQGB>bRkUXbSloBcbtTS4Xe?^__L~cK7ebth8nY!CnUwV85NJKnBtlVIdn*TPgf{uvdl)JU!P{~=Jn_pxy*Kw z(Rh_xw~*6PJQy_{;=v$-H);=#j<60`p(YgUrB3srFof3~IUY!lfTbRZz7ZSzh9pis z)*OU_fwyOe#Ve>H0D6WvSWU*?g9Nen)SA&*oF-+-R5RAENSfJTh-e{YNnbP2&vudA z8}-w-jBXj7$}ckugwU5)@gvT(?nsc%>@2}Rrmk@zoqw&SJViB9dtr8ERZ&9o$H1rs zvTC2zC?^nS;~f+O<1t(}ODYluv8?GmJVGi!%|1pZnXcf6v(O}fwQTR z%KOMxwJyj_jC4V1_U=dT24$4M6IO}t+chGa%ycsJ_d5@GME7fmOQfItR4NxocWqJ1 zaOVLcD!P8Y2oh1kSz3}=d2AUE-;21X@1{b)lYGg@Z^dD`k3oN1Na`WawbyEL2g*r9 zHif>ey1%v~cf#$6I=Y8@g3Ho9?($|VfH|6)0Ny`5S9{@F!drreX$b%JQC&?vZtgmxspNLf0t`q9HQ~t}{IJvVeG<)-{Q7Mf`-7 zNtP2Pz?K@cnq|#c&iJN@!>cC>)EMN|`1`H$TVDSny`e>Po@+$M;1e#<0rZx3kP}ve zEH*b8FD&469`9YTss;S&K0?$d(4W1)J*uV9AL?`EKguwL|C6Wi5C7`_qDCtHiyB!$ zO)U%naswEKW?AMe->#29-9Q}R7o>uC1D0Yv)Y`mZ(9&@cy-&V=FkC} zgnT8PAF&Xqbr0-=CQ=qn)knU<+VUvliV&usZ&m7PIqMzrU>tTdKjM|ub@Uf4a*g@Q z{l1*us_Z1ZTs>|jwHWli{KUQfg1UNOlwK5`$PXQuK_DatUt}j`R##%IaMk*=r)Fm{ zz^WV#_5?%a^>r@giw@cJbHN$PlSucTWaq#q2K#~el)$+2cN4L;O-`Hm=mr$F8B4Kn zJ%u;Es96haUpAR1+qG0{X@IB2Go~X<9_AoR`l78!UqFyJj0wh|n=T}DR!YEZkRUelHXtndW!?R6+*TIdavgVGA^KqlAtWx$v7Wn{T#1Jw& zM7CJ=KqW-+{5bSMX(wCBA-DAfI|LWUas0AG5S%3Xsy#;N)`Lrg62ECKx@nx5e9Go1 zx)vgrW}Imqn@=jw`$~uw6y{RqA=d@e)8{tQCYNTD5-+3lbLQFpaM++xm5m+7Yh*hP z%idIDsBwiKOnS+MSKOesf%}LP&*<-n`HC&|hr_ksV`I2up8deG1e1(4oMQ3S099)Q zG-?k59GXQG5R5_u5Y&vMqp>H~xx05OPUu{VO?O32XNj2zqzex)XUMG}mjqAsq2-I! zieUtZ-sYUuoLEIoWW`ihrU>y!-P6t;P2@>b1$D!?zqSmOhWN~r!99iqo&kTjkcb&F z5p_V^5}tj5sy9+^-yX-nnwO++uEnrObKl@@b9}L1`2Jqb$pKDNBYqJjTU#BReOD%<~IiL&BHCmw>Rfgk4Sp!G}qDIoZdGNT1QrK%n)K z1FAv$#s9cTKpOOmBDx*SxVdEYbDD&d^`z}F!{gHJv2){c>FSCPpnO*tTRce3x?~c5 z3MRgF!tYG6*q@bU^MZ47M!V*ogO*=Wny=~%xR4{koT|keGX7k>n z(_)n-Xg||C+al4rslH+mm+h@9o0rN9mlC*eVV_ozH3GQP%nW7jmb`v~hs+j6=f&u{ z@sAnz?M55eVtY|) ziT$A9g?n5lA^ej6&eQ43|xS_hW9B2qX< z3~gn5L!3;RC5-sJ6n%n}2N$~r%PK4lhwaB45Sbp${Rl~hor|Z1pwL1(3c)&uXwTym zqJBj=wFmnJyY=?{#fs74D;3H0`*5F8p??Fc3Y=i3P{H_vOiH$voR6J?wBF9RxVjV~ z?C)EBY1xl2Q6?BTTe3x=`PZs!_p8wSzeSq=$@vx(b~d(l{P!vUuS}T#BJ6=eLK(+v z&~BnM2v8(}2n${N(G-h8fro_JtX<@nTe_reP|UdKzB7;_`@?;F^NGJ1uSXUZLbRN9 zICJUbI2te5^6`8J)x)+~g*P^pfwiU=inU2F_d0fs@*MBpWVGdiPekURT1EtD>4l== z?~6nUEMMV32vU)kJI-jZN~t_RnK*dk(w79ytN+ZC{~fwoG_KA^p4#i2VNWjAhCksq ztQuChCywBnXtC;zKh9mzq5MFBo|^J(wKL*K)Emu9BW#eqb7(_MNd%vx3t@?n3iWD5 z8U<9bC><2Dr)Tq~M@6mKs8->cncxDk^-0#bD_%rA4$X0UWhI{&b;VE*l6xGWkT5F+ zzZxVrT%-Uh(@7Y5JYHozJT3gepZ2ORtx|w!SkJJQm{tu55>&VP5-0^G z!D;g@n4+>rS-q9w>kPEsjR9l=G=FUX6b_^Js6HsldDKMd%PC+HPEW<&-g$(RhsxY^kDf;Q*AL8CoOf6U} zSr5hNOkT84nF3+~y!Kd99&(L?#Jth20uNSx#FZI4)bHI%uBYG;HOD*^Q|ukk-MB+sum>0+tvg z`?;brJS%Pv$BSpbqfq=k4gF#r-^ud5&;khx*{bgs_hBYpYxZpA-SXZ%=-PAs?uX5O zVHbHC7}hx?sEUf;4D49IE6jK`=0fTVb7t@qki3YRCDo~nXkxY`TIpDn20YE1!%RwI zC>cw_V<-<5cxaUK6?L!Q>L#_wFczRA)P}B8sbyFX_5fo!H$mdy!(NF}S)5rL1n0T> z+x^FJ6H}|hg;CZ9Bo!PyhFSQZ?Nq{P&j~fB#IJS-dR9AH{UKI|#EI#J7nw8lM3!bW zHOq8@YdNEH-Bp~r?%)I$EKLiI+h=ReT*Fv45b|E`kN(Q-U?ApM;{K{g4gXk?{^Pdr z-xu~@iWwyf#kuduJZq>L0tm(1K>XLr6273oc;KVo15;o@u)ky90M&^vVT#4c)Y@I^ zo{(`)9>ZOWa%|?;)ED3xrOPhYYZ?r$Y}GFxD!PD#6U7#irE9K3ni99&&Y+vuGH0OHD3(4k}?*OC~T=Ki9Iw6$u> z!$f|x7D?EVE?Difwo`v4_4Sglyr6UX8xzp2V#CMl|FmCQ=RlEB8<<`a!|^OpSQotE zy{{Vu=G)0?F}E)(|B#+ok>Mb7oGWf6EJ`w}BxbHkpZl_UUmQ6thc=^>??X(Gn9mlv zmz;mI*z%!*iTkm34oytCqqbhIY6|16sy(N5VyoTwV64_fDIa(I(ixq)P!_wtW?T<@ z*@rU~D-t+ZsJADDrfjy1D%guqdBMSHREOhRmXatVEt+SL6i|Yi zYJ}rtq&E7Nw%F*!`P=3|0W1YCRiSM)blTYDKvVT}P0K@F9FajNt~n@J{BBSFPs4XC zJgA$jV2i~8;zD1hhphgYLy6uO;n$X2=ra8we)D`neqaW6;&){AhaVEWen+l?2{v^v z3#WYPiV|7LwhnrJP7XK2p`U>}4BrM88$D;iHe2cj!PzxWp7bLXO+Mh*?!{o>4bW|Zeu(>WYs6Mxj0 z?60i%(-)P#g&pKFeTD}hqN}_WQ<&RVmhlEfYE~F7?9xBf5X9}Q4}d@QZg;7~aqO$! z@%d++$tX(?g9un33dWR_(HJtS#7LZuKoDh%F!meeuc`k z2d!QYhkdn^ve}+q*~xe4vFcfY8MCa3%FXf0%}miM4;&GM6b-aaqC;PIx!eY7(Jg?& zpLR0ZjnxdpxEe$ZLQCPaFTB8UjyF;q!CNC)pT5DAaNB3_(AU}L+cWpR!DcT&o#9$$ z=3<3s9fu~eOhl2(&MjmaJ&h_UHcRp=O|Q09mup9>zP&)5x=(xxRlmRfJV$#`Amgg* zDioV|tSmvRTgP~{Wlq<%o?C!gv5K$<1htgA`fUa)$8O?5fQBl;^1-AR>b_hByN*tw z`dr8mnw;#aF=#zdEE~J~2tnXzVo2AO)pzllV>X+)?%1^MXV?3~_z8>NR-B;%49dB4 zuy?>o>l%40-`Sa+^z2;q9E9k|tin<5@1W+N`THJ#$aZztnobSME96_O zDJU#x%d~jchS6*X3a>Uq2?Tnry7pFm)nl8$AY{A(d1U@>3xk2%GcAR6wi~@{(*0Pv zr&n@=lx%2|Vb%Q)kDVdvAVq1_=Q-L553^43n{~{dtsA&?+h$EB?>1a_ZyGY{p-mW} z$K=rQqJyh<5*SaKIKqda5f~7 z2L1w8LJq>!1=cy%tY4sbUW8>n#+)=opSM-%nH2mUK~Rt8y?%R3$D`V z4ZDmes=dOoL{Bbjc%axd`qs1}z(KHku?IdsFvGbnQe6d*9HEA|&@ye7FH4)h| zIFR=}FfFcbw_HR))}`z%xaJS7ol2x!L?50#2yhL0dFM7?WN@dCOzJAzja%h{o8?DK z?J*C|9gDI?GLz08_wh7D&)H$XIcW{VM`1Nr;m&bd@A^h*CL5t&I_{Nzcifj=C2PHt znt~yAIY4z0NIjcCBbGZ_a~7s3S3Q>4M-eSv>aJ_98}QPcFg$whlWFDN3*3}$JG94m zk#J=)?+?2Gm$*hXPVHvV0_!7jG>kt7^x{UmlblHoD?C#CEfr&I)K=?}{EWz-IipAh z6#;LH?1ou@g^!3uR0ez*8-Q3nl18|el(9UtzES3ptjst9#He126eHCL5NSMrOn50Y z>vcSE0lpE8Yuc}C9;9r6p`n>yGwKceBfgm5d$pxGHU?ZW1`H`H&B;-8a)jKKFgJ@( zfRK=SuuRb35>HlP%l1H-F>QTlZ^Db4laj$98%EIXqrwwCk?8G>?oWYvFC(cS`D)J! z{;@s#PX?-g7Z^Evn=eN-tA7Co6{=7!N((3-)`ycsOl$P%J8GqTDfbwe!7Z{YOSXrQ~30%vcauEhbD1|jdE^1VGwP~RFbT^jy zWM8;UcEqJbBjkQrXs>%cte9kVbiK2iY`#yOkpXB$bv180<*Wu`q9rz0&jyZZ6+7ij z2D+oMHrx6`VQC*b?vSE^YN6W^6n=xWY$y}3KUd9O4C)`UlcvTPD_4}8S*`W1t|)Wx zDyExXDCu5Wo!hLfX``B7AzSvkV7rG2TBK^O2JWgW$kXO`nvrmkRkdjDFs%M^#5VMp zDvx|V==8O=)|xjzj=3-_QDdC5$`9IgC*)aG#fFBSe8@4*6cB3Pn_qf3nj=YOTTT`fja@rHYiAX zjm?7wxt$k|e<8Y|PCDGeT)}`CBpR8~3xWL=HlYlnvou}d&dlVWpqfAE#;T2&wMclq zaYLAf4KbE25l6n9PkP7Pz>f3-I+-1U36CoF#cIG>Ie)ir;P(3{y48H%&9a(?O$4k7 zX7GK^xv611J{xLm_b4m~6$Ng6zdte@WKVX28>v>#zL*4mUy7eX6-A~P!(xw|W=&So z6hE&gC~HN*qpdWlZ%fOz5U1L*<$?K2dpt7aWh{n7KWrbQG$;C~$xK)s1d2e5eWMy{ zN+`*l9v0a}+cMtxtlIAqKLVytGb`8AKY-N6(g?VlR&z~l6OYx) z!nrDw$D&g12ei-ljF(I(U`y2zcwOA&&Sxte;xyeKvGlP7x0+X#ngg=p}RL zhu9q#CTTPUNMc(Y#V()9V_*{G?ppF%U*B#|9kO`5KTMK-8jK}=riEg%>Xif`Fq98k z!!(8I!#tRp_HJM<8u$j$h3)`S&p(}6>4g$xWv1P$UA>2ZE>7;Vqq8mcTMe9Q{Sf&di8@L8y zc$#H+( zszLWA3_9w+Zbv8OUJgYYxQ+#DyRLs)U^|1fK>mKqGd;L{1G14QQOFc?!q(;SB0f0O z+upm@I_0V2HjqcPY14sBUD&1yY7FF)rH26{``e@z$y+O6<89&9V{%lk=Xp1`MNLumrp*em%*xhx`)+5zP~U+eyIhy=C`JwVWHAPlGGw0V_q=moA0wVV)%fI8ymFwVobd;p7bA1zc(ko#$hUv{8C0-EQvWzvy zFHqm~Q!^7%{;WC@RXRCcMxn}wXk6Rakmw!Xq1$Elas!`>BRMzq1=c$EzKI3+B#_D@)&!)G6lEGD+zQChZR&i0r_NA`~mNDciy=pwM2=#zQ{!A!ASufjPT zUy5~%VUJo`{0wWA_fuq%ck>>bwu%uubp5W4Bee@B_XOb;TRxNf11|;PslvI5}Pue`B|-; zgBu^rGykG0I@=7W!NXg~@S8bTNFDP!^`Cy>w#TzsAB6tC`vtZ`(49K}t)2Q0MjO+dApQK=$VV zJ$Cd7*ufA+>A9`xq1_3rPoLoIem$}m@Sq{F*@l^)K&`xGZHe@8arnUR@rl>t8(bk+ z_dl|u)7gI`f0*5Ty+#$h=e-;fb^Tey+aK$x26_j9bb0bK6BVt#{<6Ng%9x5hvO*<~ zE3%4ST1k9EYLu2@1{OOOab!FH9WNV4*RZOj*MpH}^h7i^)QK!j@@EP0Y_Fhht5K=x zU9mE$7|7gj&J_FvMjBj(If3Wt(gL3)oPitL_qA#&r2B{(N<(T13y%3wbH~Q0dyNsbI9UVTU^dWc2m@ zn-t_YJnpKyM_T$okr`KBIM+^hI2o{E~7q22*U@eub$W?)2GjC4dw}n8^%XjUWNjnJq<3|hg^0!B z1jVmcpsbUUZph}_MK||-4i+5IXfy`(w8_dk#T%CjpqKBZ)U;WLC!`XhrDDNcF;dt9 z{rJYB?%Mvg+>!#?@Rs_r+p0tRrZZVsPo1YBEy`b{dEsKxGz4_BEW{3)OL}4$P_eEXeA{H_c&8( zDfGbQ%qgP&uARp%V02WpjQgWWlZVbg%juX>)^M42PdZgMmf$A2Mjc;?F$%#G}udlQ8C0#9D#46{p^bHLm{EW!Cc7JQq z{B}XQ7ZSrO9h+&{pe5&#DzuV{D_2&fO2Xfq#0foGIhpZxT@#rpnHe?8Gf#6*1<_Y= zc2+a<=FY;$eg&0%SDvoOR_&1n@q$!xih0E=?FJg$QBv9%+XHl&oL}ml{SO_4LaOE7_dYq+!uhufcA zL0z!^r`FT5J@gva9&h22Yy z_-Xn>k4fA{G!QSh5!AEvA{agWnvf&oq>YBAZY&M1p&cTb&1&-iq#F}4XPE|15utnjkG`R#VE{MtreWJiKIRTXGF08 zoOAd}m<$0pC4mMgG4D8gkAeA?r$0^ZZxt@!q#ztza^n$%!@`IW^ustKyX3pf4J+>v z1znPF9+Ro*bTb%&kN_< zF}U%uxQ=lc@HrotTISep>CunSgCYrCx*SbIuOlaXM6LzE7FnKv_s2((^UY;tTgHQF zx8d;8gn-TE75lg%Hf4gLNq(K0kAktYD(2T*1xjtjrRk;R2Hwn1RY*}VbB;^GQ9H0- z9M*Zkd$lAqN7q(pb8!afISa%;(a5b@{rmL5s@24rw&y5VVy@wbP4X zf{lTG+6p~#du}-0AE6h zy`2$(qZgyJ3qL|B#@8z`69`0|z`+FO>hX5z?BqurX`3?H7$#q?pPFe|Y;vl7z?r`g z!drUO@#Tp@RC?$?S}!GqaYj6z`j;n07vCS`hJWTLlKu<1`DafIk^kg^{vWIGe-*v2 z91l!UWN*}IVIk>IgSbTzX#<3W$kcifm`M0p#2XS*=>|GS-;*Cs+Q*&w7e1z+lCQ#X z?lP}6M|YwJ`;*mxel;3>9P2494p$CYEsvL%Z?7*?UEib(*+M4q1^Bh#cKz{rVXPR@SY0TB|7$;PW zh%IP&WnQEXFuzSIHIesM({HRW&p$0GGbhb!JB3naP*PN^4eDWDU>6yC(=t#Ntx84& z#S+0n-kevcw2tSf!L8ZjY|SYzR_5&YMtX1@m_;l%I#y02kuWBc{~@d@8Bd8y12Q3^ z5GCvW2#q(W9p;qer-r5^8AtD-&z7OUE2tB8R1lp+*p7TzaIQK!E?0Yknu&-iT*zHBxJC<}oFVwZ^5sul|OEB}U+975H~Spo?-{fLtXn7>HDf(@cGiyA{7!=G_8iGg^J2!qWC zdJH{=fpU+O$E0PERy%q+iEAc1U;KbJjTaDOEF+<_osC5BK&sCK#bT#KZ8^Qeef_P|68L?0% zZ>jLN4x5qBrzPwCcvHMra9k=E$)a1X;_?AhpcR~Ltk{kZ&Te`JKH(c`n`ctj7}Doc z)Nhv$>;QxS>_O%6V1{nth;V$=-s3(4^rjp92r99l8ULwXS2#)i2!a7=+(7uDJ$TaS zgIx%;G6LdenUc_{mM6b(V_JKy@?cvq**1pI1nXAL@|n7&)H&cIiK-@MFU{k%l*;7B zywu4=^X7Wk1>N{Jz-Sif9|bTAjn7`$bVX^F3mbH^O$mI)Z%(QdC4-6PC!QA+d1MK9 zC=aZytd0{(IIRkD=`bx-_cm$nZA#YnZp-Ib`*qr@r=~24d!Xscx!`~L#;P%k-6{6(C z*}dC?4(0diG@s_fx57OLKge;i)2i!V!<93S^;4}qR6jzgxDDIIRPHDHk)ESF&ffQp zVA!#fgVV;}Ldo`isb$h#i>dy!NZ<*0iCEqC?1MfUY%Pf23lt0dbNDH z{BdQqI6O{{>-v0tkp09mr4Xa|%MM73U!*7BuiTFUWbVuTCnkm3)p@LL4KX&w&-UdI zX3Q3iSd5ug-p5b54AH2T)dd@Z;;^+*-nu0nyQQ}8+&CQgJy+R2Rla9T zv%qtCI7iBV;Eu(&SZ%?f!w^~6=a5jER`%PzEU}E)G80PC^#Xdv&aW~n#~k-cZx=dc z&U6LEJ4;D7*j|xtpUp~TXCjDTSn|dlbB~o|EK9ACW9^od z{l#F#&a4wFaQt0U%$vgT%@KDBRbe!{i9(dF{>-9XQ7DDsRBI}(?hR*P*W^w@RlnzR z%f=DqY41Izoh(f!X%;p_qBm5f-XS-4PNrUFKrbIW?lNj;I5{RJE@#YDa}WmOYPgw# zpX##KCdHbutS|}OWZ{q)`Z&)) zHUlg4j+^r8cNkaG_gmT@q8QM2o8VZ5 z0hKt#dQswOIDN2jH&8jz4uIw91qxHG;v7@oh~PXh2|~{PG~7mB`xzBbm}y6_2QEh- z#6FJ`B${2)VR&Lt5;-83mTtsGQ4MHA+`I!=6xt1FgJ?`)V#qNoMSwfL$Ir0Da}K|l z?ps?6ug&d>;YLuupHVfAa4tP0yLPun+d5Z%XQ4v}Q#~C)0zcDWZ2fU7W#gi%)4HpQ zT;T}Yd(bx%qD_!wiG5c0?!nr3@zmV8okB7aPD+T9d7dCn?+_k{xdjzCb*!e-+GMt1 zIAus|7UZ+g$~na>Is{(x;(YaApz!9#O^I!sS5nrEP1cUiBPPAN)8Htz^CWzJGb#0Y z-$J<~O~n<}>4wrbpdVU|7EQGaGKA$S*J^Cd1C$oQP172kyVWD;q9u0vC3R2>wOkF^ z9k5^W+Fj7Dt8z6PYKO^+_oHsjIfPvSN!0(+gz25HO|^gic2K@3spm|n*G1e}^wTGM z?#+-L?<2Cjxp1yzIr-^(*rPPq%bflKHQpDypo^{mh4ahGH{h%GfaB>{{GpV(w zHELu>;f+gOUUGO$ZEV!F{k>U7YLmYcW$1=iSLZQGmQ40&N1R70^!Re1cAtacj{9;R zdcmm2Nuwm9z8P1syc*V$xD#F3g=%S?uBvS$pER!0SFTlj6wU zouJ?%30*Bwzfewz(OrXwUGCOhoCa+UGN(Op^e}<&U>$PkF=3ty`t&1o84yN;;Wewof+?2h^;Cu2? z!gj*F%>fV)afp=?$v@DiGMcQ?^vNFi!gB%RsLDD{Wh%6c2IkaG4>d*GH|n}YssPc7 zA9`$t5c(9blZ2w-Lk*#+?6lDMd(E-gs!@l?7lW%q+6XQC>3<19H`(z8fvh8a?ef4F z)_tX{i#8}t&@a#L<$n<)r*)>p z2{WAVJAYJn7$S7QJ_iA>X7ML`v`hl-^*|ehLT$y*)MeM@!IF!JDTFBJ9rc$ybfJJ` zVg}K9q^(0XYHY8b2Q=>I2$Q{Yq( zNMc<@F(tRera5sJ4aein~>!5q3@j#mF~LNWLM z_~QKAPEbkT-o)7PU$avzza$U?e4y@X>)E1)1r2y6Pd%DH8XXUBZB7wk7eMnE&H~zXE=;_(n0mLpUo1K>+KFmj6g*QgXq@%}2!skvw z!;yp{g1^r@q7#~gcB($2m7=scj+*cGoLgN&oMBQxRC1&L0iiX9RLva|8zd z)02|spJmpmtrqZwcvH;-hmd-IbP2W*lc_3So(N+zUTUhQa%u^ z7qXw^f^J~k$7nU@Ge|Fg2^NR7mNsRvurYD(o}gbSZ)I)8M!B$oD<#yicHo>wu(|Ug zqSr*T8J_kfR=^4B|68o!QeUz7mskOS$^ms1T&iqBJ4h=T!gFr+wD3s2wC69e!n@ve zV z=OcGVUq`0KSs9ChMUDnmF-y*(Km)4~&iz)(zCkC`u?pvO#ZQ}#1boTl_-wJ{SbCZr zK*3sPXDSKk+Xi_U1^bEzyn`5T)-G<#38hX(K)zpLYjyMyTYMt1G%#^6X>dj?5t~@l9iTT> zXTCxaU$fVtv0U{vu+>Y+g>^5{pY60j`}S;wT!ffK>;fQv1q>5mqKt%-Wg3yWK7pJT zMSsMXOX1G*z5~cX%HN3iNUDxN-MH?cud1u3hNQ?9-ie9rhN+2K>iPJwDFqK7@Cwpk z@AT}H*$lVK7|Gf`qCbMSWDVo$--A;H6UgQ&9KMuE#i7pYM*N60y!n-2pG<&_oYa?^ z`Sus(?G2|Y=f~H99{)$30>}UGS^3wYRxma(bNEsM|NW*6sD*kUEg^jJs6QB(F|dLl zfyGVt7Yg*MRQtk5hnseYcgE(9j4Um>pfwo|#?;<47g#h^?2IWi^Y7F06+! zquR?aCq9Q;*aqqsqnf^I9BQxE4wwB!VoE-Gr?%5{kLf|TR ziSs`xr3d!Cg^%!{8+Jk%Y0czU^opS@YK?~bQW2GvCknVS;sYb>CH({BQ$}+90ad;sHc~ixU)3n%g$2~qyjI>qI?cfu7ZNUUu zL_~f(_qd!dH|`l)7sv0^wBLuCqS0EX(Q(2Qg$eNjgKW?QIhNey#w$;dZ{Sv9%mGzU}ald0wT>r{S8D9;;TW&U(!c+>tjg z>u&+4_+eP|pEjHO(n^Yb?96}6tsr9J5g8qB%n9*An*0u-FTSvw9zV0@JCUUFB>8VA zJ$uT)<~VOljn~Gc3Fmc4oaUUK^;pbP;pN-pZ5@nqN&27cHmX zk|s?x+1l1h2VW|edSMjk`ilP8k1Y%cYALZLavp|a_;>W*RxSx@OTipHOfT!yWfIq= z>#J?CksSn_s$J4BD9mn4OKvo2&Q4jIU4ZS(o9MD5NY;@O1UE8{L`8yJ84Q67{g*S1 z}R$!5?V9+N-~*XQMv$5bHB2zo^PzKM{Z`mc^}J$|?lHkh+Sxyro= zU_6lLD8K^0t?zaywc@{0{JOrkL!P4o8~n5(?th%1&r;;-|MDAFrsN?Swos{K6ywO4Bx;U2t5?gRtlRg-q3|D zL(f@$sFRzd%!@TZup=3Is>=$($Z_+p8;5GhwA1Ud5?DFVE<^DSja$ixGGXfsMkM8H z)QX^9n1xf2Y>SXxryZ*;59!cw7lSxe6?<=)U4}}2)r`7!AJb&uZT?O8SMn3{>PzW$ z%tU!Pf=hE-kO*rkzmbFy^8<{97_f_kyf+A55=KbT;;0l_7-kJr8Wi&q83fxTGoq6V zx9ArawHeqVZr;I1UfI_}z8df*Uf%UVuF9+&0Vl2=7AAh&H$m`zVatbE43CJ|^d}Hk_m7CG>|4t5kByaBGsVobGDdJ=4qrpcbzk;}UZ=wn z46Ey=4yx;LhM04@Cnp?pzR*(S>>r5Abx)3A%l+9oprz2?Kfuk*bQ0`u(Mj!3(fP4Y zCZ~6NKquFI+Rv&7+$Yp?-FNNW8%FN@I}Fi%GW-+tCwd>W01ugCUOGYAl!f_YtMH8y z-dTOdt0dRjMff)Zr;&oHX%z$cY5U8@v{E=5k!VtA{0)^RZVRWia5zw{->khd#{-a< z8uhfW+;6}M(+f!fd57Bgidv(W_UHjP;riV8+7|mx# zcDLhLV%on4Ract3H-xa>P-j96$kze?kMPq>8dEG6{Al4DT>W5`g@#;Y^#4$Xw);8C(Bj`QQmhC2L<=9AT54Lv3+%S<;(-xcu%T-)5)^`z(z9 znC*XeJ={QgnhRbJ=J>}hAIJ!ay9!rr2)m{zdqat@zs<$;lfE-R}DJy9yF*fK| zWv*+6yx+!|%6FnxjwE*wF;R zUTZK7^#bCr*(KjP{kR{EM`F`3f(d8j&dHM$rM zpEXi$=Axl&>BOh5zh!u()Xtr0_g-NswVrrG%_B3&ugEL4s(_yL{1dvQrn^JT9z9|P zGMKSfgEkng?f&JEKgK>+gu5#E@`d!wnFn#t>szUPVE)I(!P+Q$l+cfF->k6yr|kQG znW+3XMEUQ=hz>s?FB-rMWt|G1v$?#!6iYPX+!y|}Kn z-Y&VG&W|^Fcpulm5y5(Ck>$R#LC?n%@m07*GXhX`MU-^^5*EebtucoZW*4@OfHLw>8$%A#I-S&S-?kwT^D@BIX3_ zlvitY6`MY+udlbWAk`mO$SO;#Iyo%?tk+e$rcv)bn;YN8%|xS*2n)r;HuySte^52a zPQj}pr%UL>T2@+>T575;$tXzOp+SC{+P!uLO`PO&x7O;}r1EHBsO zjUBa@n?A77aWmx$QA<2EHZPywx&)nlUJ8w;%qn)JvFA%_f{940h-Hxl~9I-v`o0Ej99ixn&Fu+fcXPjRX0{=55)Eltvag?SH0_v?CS|>1mmg8nuVO`Z zA`c~97O^)lZ}WxyaPJr&=-%4B1?W>Agwx920JzuRwL1c`YXxTeO8sMM(HNF+@7?>m zi*tP|dIlDzGe*OgHh8Q2o!m{;XB9*$7|;*^VcYp?zSe@`ggUcFR~B^F7nh`$UR97u zkO#bww9ApPi_IH{Zag|;ErWG?7&;JQ4({GO*&1oE*tHo(@?UIs&Tn7-?X&Z zOGUBHt9!vJQQ)6g)3+c9gZTG+Y1NsR+{$J=QKq3dW}(V0QX-vgX|>4-cBU0nTrp4) z87EP|twz02_B8v>9#psN8Pz*kcZf_4?>xXX7IvB%kKKj6>?y)jxuV*gi+!ufYjZ_> zpem@J5xeZ+O{AN=FoybJ>!V-M4PRr!o>D6Z-;!rZqw~Dgvyut#4B2(mA*){u25Pd) zAob8bw!C8Q>^Dh%nIK)Uw&mchT>|#Oc`Kzi4FC9HY}mlC*tDRP+Bt<XnM(l?#G0-n%25+ z-y8FjU!MZn3Q|2@V6d*QX6)YTQl_-o;y%<$>%(x1w{cv^^;uY!=5Vpx?;!Mi53!28 ziQy@@Q_$C(^OthjtIA-1zq}=XAgruA&xQJQA5oWsl8Ky~_!gVBtEYEXduWlknub4S z8gn!!yQ`I^x;CzT9LqKM5~gP0y7y1*frCvcPd`ddXszt?len0~t=+q(5E&*RYaY#| z!r(-N?Y75XGKEZ4#9OWk)%MUfYjSe3FCZ6nb8|vU#l)EEEQrIB#9yA)Xx!0cuQua4 zru_CDJuC+_cg-Oa>!y=QORVGhR;nweva&Sl%Zrue*1YI>sd3}*g^ohh_ND~1Pk?~# zTdUL9rTcQI#o3Cp$-|#{wc;MY7o>_Zd}c9S=NQM>Zv*2s=mWILNuv28P#f>a`*bVP zg~6KaMl#@re@>8y>8AUUN!XuV0Rf)*WO!|6`3)05zy`L(Lz6TwOR89mA^F%)!C)9Q zc0&&#e^YgXSQLTeuK`VC!Wh1sELMo-7)zH0v%@SdS}ENoJV>lDM)^c;!bJ zO@H<U7jX_j0{VI&O;CpqT3Jayqm% zeEZgQO7B1o5SGe<0AP&rruKnUbK!D>OCR*C<*qN_{L2amTS zkM;+Q4lMp$TLDNZi zmY8q02m?`$&$pAP`vb|%s^@@?A2bClScH&4=RakX%v09rVxg6|Hqa})QuwVa6$8zB zJ5p(z_OgMPIfRF!8i``yx7r($oWIQu<|JT6T~f5dVm-xNiK%&6H?%O}ZM^BCEA`m9 zOn4}RpBMKL-}o+;E%{Bd%!Cw6(&8?hk?Z9!*_q;rg-Ao9lER6!Ff8^l_u=*m$!R1q z#@PilBgzR3zCQc2_rLMVYrj~M7 z=E%2`SMioGyxd0a@bXe{xToXDe~!%8zMvk*u0an8N~_!;vUBEhnj9|+hl^Xt4_i+- z+b~^!Qmh1sHpyB-XgdYNW|(c2U2STe>V9-;owEKG)mFve43$>RU~QFF)!+@4R^4D8 zl@rBXIrK}VT|0E2!hU{qpUQrDmFF^;H`P}0U{BRn`QSHI&Rn4y7%0^f74a z{y=IxwOt}~e6`&$7;)9-G?>`ZYbSIcf5tYS)PzwXB|GnPO;R(Z6*$==gw(|ul6y;^ z4`{ZoAouxECfP*I46#@i7{Emr#T7fAnavXyH(nPIWtysBD11Cd#NcKW8qNj^+V@f6 z*#TEbh#Ci9(jMBf%9GUERAFv!DUkN_`_G?>d=DaJVo%N@WsV|=doC_Pod#&5idopZ zYEgid#+5Kpg62aaDb<2pv=&<;9F{ZjMT^<-)4;066mP8*T~5Z|H}>e7!J;?uny!Yr zn=f_m#>0dJ0J*!XpNhB{cP@dGh|NAE_KZLu65r7#UyTMjEKYTt0Lvsy1Z=-L4l>f= z%si&OEng(Hwb9xr9wda=e$>hzv`d+agt!`o#cja_)v%pw{d0C^?o7t9V$-Gl`4e1~ zYWrv@iiVnprl%)$MzE8ehNeF?3=2(@v%lq6vDTG$Q$n8-kWi|D)964_M4QS=YlG|V->HD3Hvu9CMq+zK_mRPMPw%h+ z^uMP7XapB_RfNg``exU7fydaLy#~|a6k+yKew z8Y560h}}cC-(m&-88yMiiEGXJOcqF6xs;nK$PrkA)j7Ju0HIN>YRtiD|n(0&tQUtQKiUr#5Xu(s*O*&Ck zuk6Td=Js6y3jqI2fCzT;gkk1Zwb&fiwdga;x$u0G2N<7!4_nmWm-FSp2?AXKceS#C z0()xk@2#@nh_7s`0UK-@u{^9GL~tC4+5{?8P-Y)0C66F8z5i` zL=5cV+I4!z3Cv-9E)iMn5x~I11eN1rM6Wlo z<4$q3%aFy1;JZKQb?$(|fXUJt)K>)8-M6C+M{f><45Y#K%II^$@=ED@!qS=8;RXm8 z0Ko%su{S4o*a2>gt&x3OaF0ySOo5)*_spE5xjB7A0C6ll(`#5jkI6MeUbU9J~ zMKIcx60rPSO8kbbH2Dw8@N*mIteh+;4(DycR4h}!v#}k4`(3TYQ;6uZkFx5|_U^(} z^2!M;^BMS`9|26Ki~kaos=m}6sWO03NPo#xNP479Bd`-mY*l`BEP1KcTS+c;e(PwL zMEg@Ngy97@v?&(+#oe)esMhJAo1K}DBu0+d{Uw99y(xv*IpsZFvjqvnoh z$|GlCkDD(RDSEYD-ovl-4)p`K!18-P;rL5*(~mvYzu1=}h_9km--rw6ZKnAqvp7R{ zcqNEHT#|cG6lAy1D)7a<=n4S!ew$}@^pvY#=w6s!K(?glt3G!iylTvuNL($9v*wPh z&JV(E{2{4dFKRJPh3}fJBXJ+f3YKudKFkz8wdtVALH@c$2Q2=L+{Eh30Yp#HIf zJ<;nBtX+H3U3=nPd-7d-qFwvIgfS0?6RMr>(qNcaFgq

B|D8RyfJP>xL)E&OHX0p0)F(6 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�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%0D@@?DpiyC@Z1 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�j8#h132_z8sF_{koCB3iHl0jm|4dbd{KT}jlV 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


iE}J2snor! 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 literal 0 HcmV?d00001 diff --git a/org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.debug.edc.tcf.extension_2.0.0.201109151658.jar b/org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.debug.edc.tcf.extension_2.0.0.201109151658.jar new file mode 100644 index 0000000000000000000000000000000000000000..bd617f9231067b4b85e1a3faf4d607ceb37fefea GIT binary patch literal 60400 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 literal 0 HcmV?d00001 diff --git a/org.tizen.dynamicanalyzer/lib/org.eclipse.cdt.dsf_2.2.0.201109151620.jar b/org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.dsf_2.2.0.201109151620.jar similarity index 100% rename from org.tizen.dynamicanalyzer/lib/org.eclipse.cdt.dsf_2.2.0.201109151620.jar rename to org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.dsf_2.2.0.201109151620.jar diff --git a/org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.launch_7.0.0.201109151620.jar b/org.eclipse.cdt.debug.edc/lib/org.eclipse.cdt.launch_7.0.0.201109151620.jar new file mode 100644 index 0000000000000000000000000000000000000000..f38eecd0708efa55c7eb57d997e0a1dccea29ff0 GIT binary patch literal 224614 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%0A0{^=d=&< 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π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

Y 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ⅆ&?XxbN;802<$=_n#S|z*FVmP&z+DdjAo; zZKXBtyvAvH5?0Exs4RkKk#ejaD)gRNvLzm(efdnA$*@yY0%83nd1{S|*+-Yf#L1C5 zg?Xit8{9wO0Y1FNRi3HcXgt@W6RP;IcO`9TX}3T+W$7wfw22vW1BUIyX#`@Fxs_fT ztPk~3Z;?tnw8l7`<49z-Z#nr&SUrQDk>oa9$RHb)0_jIN@Amvvx{jxrYPC@idB9X) zC(aBPGzD^R3tJ&ikW5NEiYOXZDnGeP_HuL z!dRPjPk?E|*fMUOR<9#k7F`~#Wqg%XF{CUaX|r3LtG?Nig4YyxPm=VL`>6?=r##DS|^K*H3~Mm!|taz|RVfSN>>+c*`z>vinm+Q@z+(k(W*$>Vp>eK*o?EG~+J2Riw>!n-3U{EM z^dsH_kL9L=&`-X!qagFou?yqs3Eh2%x7c*h>bp1OQ4r-HJnR|2ai>8yxbzW%l3+Aa7Q7+7VW7l?SHRwo(0?9ML$hNnE|ABIXjhz`&W2m>VVBY|Ds zk$`pHnbf~fg^2G}33|(fi-o*-B6{5wBg(-r&|K8hsRaf^y;O!5jkeW*h68g>ujiM-hNM5EH;i zCm+CN*93)|MJvD`4SrKa0>8T^JbUXwB#Vk4a(g2;={AZf#QL+@#nymE};rzEuR#t*Hk%(C%p z!1}}NQYO13j*m+cyHj8iaF@_|Ys~Z;OvwRgK6c(;PJzXJNaqhdw=}#qOTc*UOd7>y z>3tY*_OO2O7x%

0MTM-HP0y4T5XfYzz@1T%HxXl3#YjpCiTe$w6)r_9Rb|S#alh zFRJl58B6cz)(Zlv*Tl$=D-J%y*7B8Ng-YC5ZZqLc)aUN9PG8f;*QGFRg7r?c0Ms8v1yl{s1JuZ;) zn0?O=V8OjE268F>bO?ld(hU>q+C7JMjWV&bG}8M^bSYjH7-#@ZK(fCF1+7IQH6;Nl zq*~%*I{a`uM11CQK)@UJVRdD@kL0R@de*)*a;D;J(@b`l8g2~e(j3nrzQHv61Ic82 z?Az*ivd@c$Z9^AeG}_Vk8Rbc^`ZX%jnI!#I6Kp=n>`Ufw+REV}MaXo6*qT0)gF76-xmGhA{y~i(Cp}e0rR8`aCpbWjeeb{9M z7v@bHU{v!J|IMA+PGa-C2zcOPhW|YbcXgqoiIQ72=KF$apZv)x8jN=c^Tv)pK{mEn zHW%nX_(^R$^yrN*OaDSlUF?8v(1yS04p}BXz&!7RG zkUg+ZnD$05g)-9i6a-#+L;|DU*Kk*f!f8s0uTMPG5)R9}1 z$MEfFPL3H+zlT939jK#<_S_E

yBiGo+2LOxu!sL)DlNPJ0#q5Y)#0+JyXmiYtp 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 literal 0 HcmV?d00001 diff --git a/org.eclipse.cdt.debug.edc/lib/org.eclipse.tm.tcf.core_0.4.1.201109151255.jar b/org.eclipse.cdt.debug.edc/lib/org.eclipse.tm.tcf.core_0.4.1.201109151255.jar new file mode 100644 index 0000000000000000000000000000000000000000..489327930da3bf2e9fda402a5d89c4624c16669e GIT binary patch literal 489956 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

+bFM%SIIQ+39h~@u2GX5 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

  • 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İF`Z7;Ko>z(m>ITXDZpDvdV~wrCsMJ85@M=q$hlo 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

    xX14~zu#%c0cs-)}ixhv_<|iG3 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 Tz3Ba2d5u12zzxkT^y~isKiMC2 literal 0 HcmV?d00001 diff --git a/org.eclipse.cdt.debug.edc/lib/truezip-6.jar b/org.eclipse.cdt.debug.edc/lib/truezip-6.jar new file mode 100644 index 0000000000000000000000000000000000000000..92a89686ba5ed509917700d5a91cecf8855b9b46 GIT binary patch literal 486450 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�f@A>EQ#!<%)0( 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

    + * The goals of the logging and the showing are different: + *

    + * A logged message should retain enough information so it's not useless, while + * not having empty top-level messages or unnecessary levels of nesting. + *

    + * A reported message, which is meant to be more user-friendly, does not show a + * stack trace or exception names, so it should not expose the StatusDialog's + * weaknesses of reporting empty messages, empty details, or details which are + * the same as the main message. + */ +public abstract class MessageLogger { + + public static final String MISSING_MESSAGE_PLACEHOLDER = "Internal error"; + public static final String MULTIPLE_MESSAGE_PLACEHOLDER = "Multiple problems have occurred"; + + public interface Listener { + void statusLogged(IStatus status); + } + + private static List listeners = new ArrayList(); + + public MessageLogger() { + } + + /** + * Add listener to logged errors for all instances of ErrorLogger. + * + * @param listener + * listener, duplicates ignored + */ + public static synchronized void addListener(Listener listener) { + if (!listeners.contains(listener)) + listeners.add(listener); + } + + /** + * Remove listener for logged errors for all instances of ErrorLogger. + * + * @param listener + * listener,missing ignored + */ + public static synchronized void removeListener(Listener listener) { + listeners.remove(listener); + } + + protected static void fireListener(IStatus status) { + Listener[] array; + synchronized (listeners) { + array = listeners.toArray(new Listener[listeners.size()]); + } + for (Listener listener : array) { + listener.statusLogged(status); + } + } + + /** + * Log a finalized status message. + * + * @param status + */ + protected void doLog(IStatus status) { + if (getPlugin() != null) { + getPlugin().getLog().log(status); + } else { + System.err.println(status.toString()); + if (status.getException() != null) + status.getException().printStackTrace(System.err); + } + + fireListener(status); + } + + /** + * Create a status with as much information as possible at the top level + * (IStatus#getMessage), reading the message from the exception or a nested + * exception if possible. Favor a CoreException's IStatus if the mainMessage + * is null. + * + * @param severity + * @param mainMessage + * @param exception + * @return new or existing IStatus + * @since 2.0 + */ + public IStatus createStatus(int severity, String mainMessage, Throwable exception) { + String pluginID = getPluginID(); + IStatus status; + + // use an available status if possible + if (isEmpty(mainMessage) && exception instanceof CoreException) { + status = ((CoreException) exception).getStatus(); + exception = null; + + // the CoreException message is just the status message + if (!isEmpty(status.getMessage())) { + if (!isRealMultiStatus(status)) + return status; + mainMessage = MULTIPLE_MESSAGE_PLACEHOLDER; + } + + if (status.getException() != null && status.getException().getMessage() != null) { + // make a new status -- the current one isn't very useful + mainMessage = status.getException().getMessage(); + exception = status.getException(); + } else { + return status; + } + } + + // peek to see if the exception is a simple wrapper + if (isEmpty(mainMessage)) { + Throwable base = exception; + while (base != null && isEmpty(base.getMessage())) + base = base.getCause(); + if (base != null && !isEmpty(base.getMessage())) + mainMessage = base.getMessage(); + else + mainMessage = MISSING_MESSAGE_PLACEHOLDER; + } + + status = new Status(severity, pluginID, mainMessage, exception); + return status; + } + + private static boolean isEmpty(String text) { + return text == null || text.length() == 0; + } + + /** + * Log a status message. + * + * @param status + */ + public void log(IStatus status) { + if (status.getSeverity() == IStatus.CANCEL) + return; + if (isEmpty(status.getMessage()) && !isRealMultiStatus(status)) + status = createStatus(status.getSeverity(), null, status.getException()); + doLog(status); + } + + /** + * @param status + * @return + */ + private boolean isRealMultiStatus(IStatus status) { + return status.isMultiStatus() && ((MultiStatus) status).getChildren().length > 0; + } + + /** + * Log a message + * + * @param severity + * one of {@value IStatus#ERROR} {@value IStatus#WARNING} + * {@value IStatus#INFO} + * @param mainMessage + * the error message (may be null to use the + * exception message) + * @param exception + * the exception caused by the error (may be null) + */ + public void log(int severity, String mainMessage, Throwable exception) { + IStatus status = createStatus(severity, mainMessage, exception); + log(status); + } + + /** + * Log an error. + * + * @param mainMessage + * the error message (may be null to use the + * exception message) + * @param exception + * the exception caused by the error (may be null) + */ + public void logError(String mainMessage, Throwable t) { + log(IStatus.ERROR, mainMessage, t); + } + + /** + * Log an exception. + * + * @param exception + * the exception caused by the error (may be null) + * @since 2.0 + */ + public void logException(Throwable t) { + log(IStatus.ERROR, null, t); + } + + public abstract Plugin getPlugin(); + + public abstract String getPluginID(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AbstractFormattedValuesRequestCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AbstractFormattedValuesRequestCache.java new file mode 100644 index 0000000..72f78d6 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AbstractFormattedValuesRequestCache.java @@ -0,0 +1,36 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; + +/** + * Base class for ACPM objects that cache information obtained from + * {@link IFormattedValues} + * + * @param + * the specific type of information requested + * @since 2.0 + */ +public abstract class AbstractFormattedValuesRequestCache extends BaseRequestCache { + + /** Constructor */ + public AbstractFormattedValuesRequestCache(IFormattedValues service, IDMContext ctx) { + super(service, ctx); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.acmp.BaseRequestCache#resumedEventHandler(org.eclipse.cdt.dsf.datamodel.IDMEvent) + */ + @DsfServiceEventHandler + public void resumedEventHandler(IDMEvent e) { + // TODO: for now, we defer to the default behavior of losing confidence + // in our data on *any* debug event. We should be more discriminating, + // but this will be tricky from here since technically we're dealing + // with a generic IFormattedValues object. Could be a register, an + // expression, or something else. I don't know that we can cleanly + // determine what events will invalidate out data. + super.resumedEventHandler(e); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AbstractRegisterRequestCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AbstractRegisterRequestCache.java new file mode 100644 index 0000000..99227a7 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AbstractRegisterRequestCache.java @@ -0,0 +1,33 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRegisters; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; + +/** + * Base class for ACPM objects that cache information obtained from + * {@link IRegisters} + * + * @param + * the specific type of information requested + * @since 2.0 + */ +public abstract class AbstractRegisterRequestCache extends BaseRequestCache { + + /** Constructor */ + public AbstractRegisterRequestCache(IRegisters service, IDMContext ctx) { + super(service, ctx); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.acmp.BaseRequestCache#resumedEventHandler(org.eclipse.cdt.dsf.datamodel.IDMEvent) + */ + @DsfServiceEventHandler + public void resumedEventHandler(IDMEvent e) { + // By default, don't invalidate our data on any event. Our derivatives + // store information *about* the registers, not the contents of + // registers. The former typically does not change over the course + // of a debug session + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AvailableFormatsRequestCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AvailableFormatsRequestCache.java new file mode 100644 index 0000000..e85df53 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/AvailableFormatsRequestCache.java @@ -0,0 +1,33 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.IFormattedDataDMContext; + +/** + * Cached result of {@link IFormattedValues#getAvailableFormats(IFormattedDataDMContext, DataRequestMonitor)} + * + * @param + * the specific type of information requested + * @since 2.0 + */ +public class AvailableFormatsRequestCache extends AbstractFormattedValuesRequestCache { + + /** Constructor */ + public AvailableFormatsRequestCache(IFormattedValues service, IDMContext ctx) { + super(service, ctx); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RequestCache#retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + protected void retrieve(final DataRequestMonitor rm) { + ((IFormattedValues)fService).getAvailableFormats((IFormattedDataDMContext)fCtx, new DataRequestMonitor(fService.getExecutor(), rm) { + public void handleSuccess() { + rm.setData(getData()); + rm.done(); + } + }); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/BaseRangeCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/BaseRangeCache.java new file mode 100644 index 0000000..0271eab --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/BaseRangeCache.java @@ -0,0 +1,113 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import java.util.List; + +import org.eclipse.cdt.dsf.concurrent.ImmediateInDsfExecutor; +import org.eclipse.cdt.dsf.concurrent.RangeCache; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.IDsfService; +import org.eclipse.core.runtime.IStatus; + +/** + * Base EDC class for ACPM range-based caches. See {@link RangeCache}. + * @since 2.0 + */ +public abstract class BaseRangeCache extends RangeCache implements ICacheEntry { + + /** See {@link #getService()} */ + protected final IDsfService fService; + + /** See {@link #getContext()} */ + protected final IDMContext fCtx; + + /** See {@link #getMetaData()} */ + private Object fMetaData; + + /** + * Constructor + * + * @param service + * The DSF service that will provide the data + * @param ctx + * The primary context the data is for + */ + public BaseRangeCache(IDsfService service, IDMContext ctx) { + super(new ImmediateInDsfExecutor(service.getExecutor())); + fService = service; + fCtx = ctx; + } + + /** Returns the DSF service that provides the data */ + public IDsfService getService() { + return fService; + } + + /** + * Returns the primary context the data is for. Additional qualifications + * may be held by derivative classes + */ + public IDMContext getContext() { + return fCtx; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.acmp.ICacheEntry#setMetaData(java.lang.Object) + */ + public void setMetaData(Object data) { + fMetaData = data; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.acmp.ICacheEntry#getMetaData() + */ + public Object getMetaData() { + return fMetaData; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.AbstractCache#reset() + */ + protected void reset() { + super.reset(); + + // Once we're invalid, there's no point in listening for events; we + // don't support going back to the valid state via a notification--too + // much work. A fresh asynchronous query is the only way to get back to + // the valid state + fService.getSession().removeServiceEventListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RequestCache#set(java.lang.Object, org.eclipse.core.runtime.IStatus) + */ + protected void set(long offset, int count, List data, IStatus status) { + super.set(offset, count, data, status); + + // Now that we are valid, listen for debug events to find out when we + // need to move ourselves to the invalid state + fService.getSession().addServiceEventListener(this, null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.acmp.BaseRequestCache#dispose() + */ + public void dispose() { + reset(); + } + + @DsfServiceEventHandler + public void resumedEventHandler(IDMEvent e) { + // We are extremely sensitive. *Any* debug event will cause us to lose + // confidence in our data. We should be more discriminating and react to + // specific events that we know may affect the data. E.g., there is no + // need to invalidate ourselves if a breakpoint creation event occurs. + reset(); + } + + public RequestMonitor getRequestMonitor() { + return null; // TODO: how to handle this??? + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/BaseRequestCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/BaseRequestCache.java new file mode 100644 index 0000000..75ea084 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/BaseRequestCache.java @@ -0,0 +1,112 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import org.eclipse.cdt.dsf.concurrent.ImmediateInDsfExecutor; +import org.eclipse.cdt.dsf.concurrent.RequestCache; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.IDsfService; +import org.eclipse.core.runtime.IStatus; + +/** + * Base EDC class for ACPM caches. See {@link RequestCache} + * @since 2.0 + */ +public abstract class BaseRequestCache extends RequestCache implements ICacheEntry { + + /** See {@link #getService()} */ + protected final IDsfService fService; + + /** See {@link #getContext()} */ + protected final IDMContext fCtx; + + /** See {@link #getMetaData()} */ + private Object fMetaData; + + /** + * Constructor + * + * @param service + * The DSF service that will provide the data + * @param ctx + * The primary context the data is for + */ + public BaseRequestCache(IDsfService service, IDMContext ctx) { + super(new ImmediateInDsfExecutor(service.getExecutor())); + fService = service; + fCtx = ctx; + } + + /** Returns the DSF service that provides the data */ + public IDsfService getService() { + return fService; + } + + /** + * Returns the primary context the data is for. Additional qualifications + * may be held by derivative classes + */ + public IDMContext getContext() { + return fCtx; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.acmp.ICacheEntry#setMetaData(java.lang.Object) + */ + public void setMetaData(Object data) { + fMetaData = data; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.acmp.ICacheEntry#getMetaData() + */ + public Object getMetaData() { + return fMetaData; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.acmp.ICacheEntry#dispose() + */ + public void dispose() { + if (isValid()) { + reset(); + } + } + + @DsfServiceEventHandler + public void resumedEventHandler(IDMEvent e) { + // The default behavior is to be extremely sensitive. *Any* debug event + // will cause us to lose confidence in our data. Subclasses should be + // more discriminating and react to specific events that we know may + // affect the data. E.g., there is no need to invalidate ourselves if a + // breakpoint creation event occurs. + if (isValid()) { + reset(); + } + } + + protected void set(V data, IStatus status) { + super.set(data, status); + + // Now that we are valid, listen for debug events to find out when we + // need to move ourselves to the invalid state + fService.getSession().addServiceEventListener(this, null); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.AbstractCache#reset() + */ + protected void reset() { + super.reset(); + + // Once we're invalid, there's no point in listening for events; we + // don't support going back to the valid state via a notification--too + // much work. A fresh asynchronous query is the only way to get back to + // the valid state + fService.getSession().removeServiceEventListener(this); + } + + public RequestMonitor getRequestMonitor() { + return fRm; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/FormatedExpressionValueRequestCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/FormatedExpressionValueRequestCache.java new file mode 100644 index 0000000..ecafb72 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/FormatedExpressionValueRequestCache.java @@ -0,0 +1,30 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData; + +/** + * An ACPM cache for {@link IFormattedValues#getFormattedExpressionValue(FormattedValueDMContext, DataRequestMonitor)} + * @since 2.0 + */ +public class FormatedExpressionValueRequestCache extends AbstractFormattedValuesRequestCache { + + public FormatedExpressionValueRequestCache(IFormattedValues service, FormattedValueDMContext ctx) { + super(service, ctx); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RequestCache#retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + protected void retrieve(final DataRequestMonitor rm) { + + ((IFormattedValues)fService).getFormattedExpressionValue((FormattedValueDMContext)fCtx, new DataRequestMonitor(fService.getExecutor(), rm) { + public void handleSuccess() { + rm.setData(getData()); + rm.done(); + } + }); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/GetRegistersRequestCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/GetRegistersRequestCache.java new file mode 100644 index 0000000..b69d355 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/GetRegistersRequestCache.java @@ -0,0 +1,24 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IRegisters; +import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext; + +/** + * An ACPM cache for {@link IRegisters#getRegisters(IDMContext, DataRequestMonitor) + * @since 2.0 + */ +public class GetRegistersRequestCache extends AbstractRegisterRequestCache { + + public GetRegistersRequestCache(IRegisters service, IDMContext ctx) { + super(service, ctx); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RequestCache#retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + protected void retrieve(DataRequestMonitor rm) { + ((IRegisters)fService).getRegisters(fCtx, rm); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/ICacheEntry.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/ICacheEntry.java new file mode 100644 index 0000000..2ea2483 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/ICacheEntry.java @@ -0,0 +1,52 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; + +/** + * EDC ACPM cache objects must implement this interface in order to be + * manageable by an ICacheManager. Some cache manager implementations need to + * attach meta data to the cache objects in order to track them and decide which + * ones should be discarded first. + * + * @since 2.0 + */ +public interface ICacheEntry { + /** + * Called by a cache manager to attach meta data for tracking purposes + * + * @param data + * the meta data + */ + void setMetaData(Object data); + + /** + * Called by a cache manager to retrieve the data it has previously attached + * via {@link #setMetaData(Object)} + * + * @return the meta data + */ + Object getMetaData(); + + /** + * Called by a cache manager when it discards a cache object in order to + * make room for more. The implementation should clear any data it has been + * storing from its source. + */ + void dispose(); + + /** + * Returns the RM the cache object passes to its derivative's retrieval + * method. Cache objects that are containers for other cache objects can + * return null. They are responsible for managing the lifetime of their own + * cache objects. We manage the lifetime of the collection as a whole. + */ + RequestMonitor getRequestMonitor(); + + + /** + * Returns the primary context the cache object is associated with + */ + IDMContext getContext(); +} + diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/MemoryRangeCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/MemoryRangeCache.java new file mode 100644 index 0000000..be41579 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/MemoryRangeCache.java @@ -0,0 +1,71 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; +import org.eclipse.cdt.dsf.debug.service.IMemory; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.debug.core.model.MemoryByte; + +/** + * An ACPM cache for + * {@link IMemory#getMemory(IMemoryDMContext, IAddress, long, int, int, DataRequestMonitor)} + * + * @since 2.0 + */ +public class MemoryRangeCache extends BaseRangeCache { + + /** See {@link #getAddress()} */ + final private IAddress fAddress; + + /** See {@link #getWordSize()} */ + final private int fWordSize; + + public MemoryRangeCache(IMemory service, IDMContext ctx, IAddress address, int wordSize) { + super(service, ctx); + fAddress = address; + fWordSize = wordSize; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RangeCache#retrieve(long, int, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + @Override + protected void retrieve(long offset, int count, final DataRequestMonitor> rm) { + ((IMemory)fService).getMemory((IMemoryDMContext)fCtx, fAddress, offset, fWordSize, count, new DataRequestMonitor(fService.getExecutor(), rm) { + public void handleSuccess() { + rm.setData(Arrays.asList(getData())); + rm.done(); + } + }); + } + + @DsfServiceEventHandler + public void resumedEventHandler(IDMEvent e) { + // TODO: be more discriminating instead instead of calling our super + // class for any event + super.resumedEventHandler(e); + } + + /** The base address range requests are relative to */ + public IAddress getAddress() { + return fAddress; + } + + /** The the size, in bytes, of an addressable item */ + public int getWordSize() { + return fWordSize; + } + + + public boolean wasCanceled() { + // TODO Auto-generated method stub + return false; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/RegisterGroupsRequestCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/RegisterGroupsRequestCache.java new file mode 100644 index 0000000..ee62b83 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/RegisterGroupsRequestCache.java @@ -0,0 +1,26 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IRegisters; +import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext; + +/** + * An ACPM cache for + * {@link IRegisters#getRegisters(IDMContext, DataRequestMonitor)} + * + * @since 2.0 + */ +public class RegisterGroupsRequestCache extends AbstractRegisterRequestCache { + + public RegisterGroupsRequestCache(IRegisters service, IDMContext ctx) { + super(service, ctx); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RequestCache#retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + protected void retrieve(DataRequestMonitor rm) { + ((IRegisters)fService).getRegisterGroups(fCtx, rm); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/RegistersByNameRequestCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/RegistersByNameRequestCache.java new file mode 100644 index 0000000..b29aab5 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/acpm/RegistersByNameRequestCache.java @@ -0,0 +1,63 @@ +package org.eclipse.cdt.debug.edc.acpm; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.debug.edc.services.DMContext; +import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IRegisters; +import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext; + +/** + * An ACPM cache of the collection of all available registers for the given + * context, indexed by name. The name is provided by TCF via the property + * {@link org.eclipse.tm.tcf.services.IRegisters#PROP_NAME} + * + * @since 2.0 + */ +public class RegistersByNameRequestCache extends AbstractRegisterRequestCache< Map > { + + public RegistersByNameRequestCache(IRegisters service, IDMContext ctx) { + super(service, ctx); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RequestCache#retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + protected void retrieve(final DataRequestMonitor< Map > rm) { + final Map registerMap = new HashMap(); + ((IRegisters)fService).getRegisterGroups(fCtx, new DataRequestMonitor(fService.getExecutor(), rm) { + public void handleSuccess() { + final List registers = new ArrayList(); + final IRegisterGroupDMContext[] groups = getData(); + final CountingRequestMonitor crm = new CountingRequestMonitor(fService.getExecutor(), rm) { + public void handleSuccess() { + for (IRegisterDMContext register : registers) { + String regname = (String)((DMContext)register).getProperties().get(org.eclipse.tm.tcf.services.IRegisters.PROP_NAME); + registerMap.put(regname, register); + } + rm.setData(registerMap); + rm.done(); + } + }; + crm.setDoneCount(groups.length); + for (IRegisterGroupDMContext group : groups) { + ((IRegisters)fService).getRegisters(group, new DataRequestMonitor(fService.getExecutor(), crm) { + public void handleSuccess() { + IRegisterDMContext[] regs = getData(); + for (IRegisterDMContext reg : regs) { + registers.add(reg); + } + crm.done(); + } + }); + } + } + }); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/AbstractDisassembler.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/AbstractDisassembler.java new file mode 100644 index 0000000..81ba6ad --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/AbstractDisassembler.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.disassembler; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; +import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext; +import org.eclipse.core.runtime.CoreException; + +/** + * Abstract disassembler that implements the platform neutral methods. + */ +public abstract class AbstractDisassembler implements IDisassembler { + + private final ITargetEnvironment targetEnvironment; + + /** + * Don't allow constructor without passing ITargetEnvironment + * @see org.eclipse.cdt.debug.edc.AbstractDisassembler#disassemblerAbstractDisassembler(ITargetEnvironment) + */ + @SuppressWarnings("unused") + private AbstractDisassembler() { targetEnvironment = null; } + + /** + * Since a disassembler is generally created within the implementor of + * {@link ITargetEnvironment#getDisassembler()}, this constructor together + * with the private default constructor forces the implementation to pass + * it's own "this" pointer for use in later disassembler processing. + * @since 2.0 + */ + protected AbstractDisassembler(ITargetEnvironment env) { + targetEnvironment = env; + } + + /** + * Returns the ITargetEnvironment used by the disassembler. + * @since 2.0 + */ + protected ITargetEnvironment getTargetEnvironment() { + return targetEnvironment; + } + + /** + * Translates the raw memory in the buffer into a list of disassembled instructions. + * + * @param startAddress the start address + * @param endAddress the end address + * @param codeBuffer the code buffer + * @param options the options, often target environment specific, that are used for disassembly + * @param dmc the disassembly context + * @return the list of disassembled instructions + * @throws CoreException the core exception + * @since 2.0 + */ + public List disassembleInstructions(IAddress startAddress, IAddress endAddress, + ByteBuffer codeBuffer, Map options, IDisassemblyDMContext dmc) + throws CoreException { + IDisassembledInstruction inst = null; + ArrayList result = new ArrayList(); + IAddress address = startAddress; + + while (codeBuffer.hasRemaining() && address.compareTo(endAddress) < 0) { + try { + inst = disassembleOneInstruction(address, codeBuffer, options, dmc); + result.add(inst); + + // next instruction address + // Note at this point the current position of code buffer should + // point to the next instruction. + address = address.add(inst.getSize()); + } catch (CodeBufferUnderflowException e) { + if (result.size() == 0) { + if (options.containsKey(IDisassemblerOptions.ADDRESS_IS_PC)) { + throwAnnotated(e, address); + } + throw e; + } + break; + } catch (CoreException e) { + throwAnnotated(e, address); + } + } + + return result; + } + + private void throwAnnotated(CoreException e, IAddress address) throws CoreException { + throw EDCDebugger.newCoreException("Fail to disassemble instruction at " + + address.toHexAddressString() + "\nCause: " + e.getLocalizedMessage(), e); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/AssemblyFormatter.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/AssemblyFormatter.java new file mode 100644 index 0000000..162cf76 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/AssemblyFormatter.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.disassembler; + +import java.nio.ByteBuffer; + +import org.eclipse.cdt.core.IAddress; + +public class AssemblyFormatter { + + private static final int ADDRESS_COLUMN_SIZE = 12; + private static final int CODE_BYTE_COLUMN_SIZE = 32; + protected static final int INST_NAME_COLUMN_SIZE = 10; + public static final char OPEN = '('; + public static final char CLOSE = ')'; + public static final char SEPARATOR = ','; + public static final char SCALE = ','; + public static final char PREFIX_IMMEDIATE = '$'; + public static final char PREFIX_REGISTER = '%'; + + public static String toHexString(IAddress addr, boolean show0x) { + // this gives "800000" + String ret = Integer.toHexString(addr.getValue().intValue()); + if (show0x) + ret = "0x" + ret; + + return ret; + } + + /** + * get hexString representation of a byte data.
    + * E.g. 0x12 => "12" or "0x12"
    + * 2 = > "02" or "0x02". + * + * @param b + * @param show0x + * @return + */ + public static String toHexString(byte b, boolean show0x) { + String s = Integer.toHexString(b & 0xff); + if (s.length() == 1) + // padding + s = "0" + s; + if (show0x) + s = "0x" + s; + + return s; + } + + public static String toHexString(long i, boolean show0x) { + String ret = Long.toHexString(i); + if (show0x) + ret = "0x" + ret; + + return ret; + } + public static String toHexString(int i, boolean show0x) { + String ret = Integer.toHexString(i); + if (show0x) + ret = "0x" + ret; + + return ret; + } + + public static String toHexString(short i, boolean show0x) { + String ret = Integer.toHexString(i & 0xffff); + if (show0x) + ret = "0x" + ret; + + return ret; + } + + public static String formatFarPointer(short segment, int offset) { + return "$" + toHexString(segment, true) + ",$" + toHexString(offset, true); + } + + /** + * Format address for displaying in format column. + */ + public static String formatForAddressColumn(IAddress addr) { + String addrStr = toHexString(addr, false); + + // Padding space at the end. + StringBuffer buf = new StringBuffer(addrStr).append(':'); + for (int i = 0; i < ADDRESS_COLUMN_SIZE - addrStr.length(); i++) + buf.append(' '); + + return buf.toString(); + } + + /** + * Format bytes for displaying in byte column. + * + * @param codeBuffer + * - code byte buffer. + * @param startPosition + * - position of the first byte in the code buffer. + * @param length + * - number of bytes to display. + * @return + */ + public static String formatForByteColumn(ByteBuffer codeBuffer, int startPosition, + int length) { + StringBuffer tmp = new StringBuffer(); + + codeBuffer.position(startPosition); + for (int i = 0; i < length; i++) { + byte b = codeBuffer.get(); + tmp.append(toHexString(b, false)).append(' '); + } + + int cnt = tmp.length(); + + // padding + for (int i = 0; i < CODE_BYTE_COLUMN_SIZE - cnt; i++) + tmp.append(' '); + + return tmp.toString(); + } + + public static String formatForCode(IAddress addr) { + return toHexString(addr, true); + } + + public static String formatImmediate(long imm) { + /* Not signed. */ + return PREFIX_IMMEDIATE + toHexString(imm, true); + } + + public static String formatImmediate(int imm) { + /* Not signed. */ + return PREFIX_IMMEDIATE + toHexString(imm, true); + } + + public static String formatDisplacement(int displacement) { + if (displacement < 0) + return "-" + toHexString(-displacement, true); // negative hex + else + return toHexString(displacement, true); // signed hex + } + + public static String formatOffset(int offset) { + // Offset is never negative. + return toHexString(offset, true); // signed hex + } + + public static String formatRegister(String regName, boolean fIndirectAddressing) { + String ret = ""; + if (fIndirectAddressing) + ret += OPEN; + + ret += PREFIX_REGISTER + regName; + + if (fIndirectAddressing) + ret += CLOSE; + + return ret; + } + + public static String instructionNameSizeSuffix(int size) { + return size == 8 ? "b" : (size == 16 ? "w" : "l"); + } + + public AssemblyFormatter() { + super(); + } + +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/CodeBufferUnderflowException.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/CodeBufferUnderflowException.java new file mode 100644 index 0000000..be4e7dc --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/CodeBufferUnderflowException.java @@ -0,0 +1,28 @@ +package org.eclipse.cdt.debug.edc.disassembler; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * Exists to help identify the precise CoreException being thrown by + * instruction parsers so that the disassemblers can perform error + * recovery more gracefully.
    Extends CoreException so that + * existing handlers can catch it without having to be modified. + * @since 2.0 + */ +public class CodeBufferUnderflowException extends CoreException { + private static final long serialVersionUID = 2725920360107613447L; + + /** + * Exists to help identify the precise CoreException being + * thrown by instruction parsers so that the disassemblers + * can perform error recovery more gracefully. + * @param t the original thrown object, for reference as necessary + */ + public CodeBufferUnderflowException(Throwable t) { + super(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, + " end of code buffer reached.", t)); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/DisassembledInstruction.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/DisassembledInstruction.java new file mode 100644 index 0000000..ae2528f --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/DisassembledInstruction.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.disassembler; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.IJumpToAddress; + +/** + * Class describing an instruction output from a disassembler. + */ +public class DisassembledInstruction implements IDisassembledInstruction { + // Address of the instruction + private IAddress address; + // size of instruction in 8-bit bytes + private int size; + // mnemonics, including instruction name & arguments. May include + // address and raw bytes, depending on disassembler options. + private String mnemonics; + // jump-to-address for a control-change instruction (branch, call, ret, + // etc.). + // Null for the other instructions. + private IJumpToAddress jumpToAddress; + + public DisassembledInstruction() { + address = null; + size = 0; + mnemonics = null; + jumpToAddress = null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.disassembler.IDisassembledInstruction#getAddress() + */ + public IAddress getAddress() { + return address; + } + + public void setAddress(IAddress address) { + this.address = address; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.disassembler.IDisassembledInstruction#isValid() + */ + public boolean isValid() { + return size > 0; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.disassembler.IDisassembledInstruction#getSize() + */ + public int getSize() { + return size; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.disassembler.IDisassembledInstruction#getMnemonics() + */ + public String getMnemonics() { + return mnemonics; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.disassembler.IDisassembledInstruction#getJumpToAddress() + */ + public IJumpToAddress getJumpToAddress() { + return jumpToAddress; + } + + public void setSize(int size) { + this.size = size; + } + + public void setMnemonics(String mnemonics) { + this.mnemonics = mnemonics; + } + + public void setJumpToAddress(IJumpToAddress jta) { + this.jumpToAddress = jta; + } + + @Override + public String toString() { + return "(length: " + size + ") " + Integer.toHexString(address.getValue().intValue()) + ": " + mnemonics + + (jumpToAddress != null ? " [BranchAddress: " + jumpToAddress.toString() + "]" : ""); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCInstruction.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCInstruction.java new file mode 100644 index 0000000..f864d84 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCInstruction.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.disassembler; + +import java.math.BigInteger; +import java.util.StringTokenizer; + +import org.eclipse.cdt.dsf.debug.service.AbstractInstruction; +import org.eclipse.cdt.dsf.debug.service.IInstruction; + +public class EDCInstruction extends AbstractInstruction { + + private final IDisassembledInstruction instruction; + private String functionName; + private int offset; + + public EDCInstruction(IDisassembledInstruction instruction) { + this.instruction = instruction; + functionName = null; + offset = 0; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.dsf.debug.service.IInstruction#getAdress() + */ + public BigInteger getAdress() { + return instruction.getAddress().getValue(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.dsf.debug.service.IInstruction#getArgs() + */ + public String getArgs() { + // It's assumed the disassembler does not put extras like address + // and raw bytes in the output. + String ret = null; + String asm = instruction.getMnemonics(); + StringTokenizer tzer = new StringTokenizer(asm); + if (tzer.countTokens() == 1) { // no arguments + return ret; + } else { + tzer.nextToken(); // skip the instruction name + ret = tzer.nextToken(); + while (tzer.hasMoreTokens()) + ret += " " + tzer.nextToken(); + } + + return ret; + } + + /** + * Sets the function name, if any, for this instruction.. + * + * @param functionName the new function name + * @since 2.0 + */ + public void setFunctionName(String functionName) { + this.functionName = functionName; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.dsf.debug.service.IInstruction#getFuntionName() + */ + public String getFuntionName() { + return functionName; + } + /** + * not a true override; the name is "misspelled" in {@link IInstruction} + * @since 2.0 + * @see org.eclipse.cdt.dsf.debug.service.IInstruction#getFuntionName() + */ + public String getFunctionName() { + return functionName; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.dsf.debug.service.IInstruction#getInstruction() + */ + public String getInstruction() { + // Hmm, this actually needs the whole instruction. + return instruction.getMnemonics(); + } + + /** + * Sets the offset for this instruction. + * + * @param offset the new offset + * @since 2.0 + */ + public void setOffset(int offset) { + this.offset = offset; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.dsf.debug.service.IInstruction#getOffset() + */ + public long getOffset() { + return offset; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.dsf.debug.service.IInstruction#getOpcode() + */ + public String getOpcode() { + // TODO Auto-generated method stub + return null; + } + + /** + * Needed for DisassemblyBackendDsf#insertDisassembly() ; + * for HEAD see the first reference; for CDT_7_0, see the second reference + * @see org.eclipse.cdt.dsf.debug.service.IInstruction#getSize() + * @see org.eclipse.cdt.dsf.debug.internal.provisional.service.IInstructionWithSize#getSize() + * @since 2.0 + */ + public Integer getSize() { + return instruction.getSize(); + } + + @Override + public String toString() { + return instruction.toString(); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCInstructionFunctionInfo.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCInstructionFunctionInfo.java new file mode 100644 index 0000000..8780d9b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCInstructionFunctionInfo.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.disassembler; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext; +import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.IScope; + + +/** + * Information for an instruction, line, or block that can be used + * when constructing EDCInstruction objects to collect and pass to + * DisassemblyBackendDsf for display in the disassembly view. + * @author kirk.beitz@nokia.com + * @since 2.0 + */ +public class EDCInstructionFunctionInfo { + private final String functionName; + private final IAddress functionStartAddress; + + /** + * simple constructor + * @param name function for the block this object represents + * @param address beginning of the function + */ + public EDCInstructionFunctionInfo(String name, IAddress address) { + functionName = name; + functionStartAddress = address; + } + + /** + * constructor for a block whose function may not be known + * @param module container of the item for which to find function/address info + * @param line source location from LNT for which to find function/address info + */ + public EDCInstructionFunctionInfo(IEDCModuleDMContext module, ILineEntry line) { + String name = null; + IAddress start = null; + IEDCSymbolReader reader = module.getSymbolReader(); + if (reader != null) { + IScope scope = reader.getModuleScope().getScopeAtAddress(line.getLowAddress()); + while (scope != null && !(scope instanceof IFunctionScope)) { + scope = scope.getParent(); + } + + if (scope != null) { + name = scope.getName(); + start = ((IFunctionScope)scope).getLowAddress(); + } + } + functionName = name; + functionStartAddress = start; + } + + /** + * @return function name for block, null if never established + */ + public String getFunctionName() { + return functionName; + } + + /** + * @return starting address of function, null if never established + */ + public IAddress getFunctionStartAddress() { + return functionStartAddress; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCMixedInstruction.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCMixedInstruction.java new file mode 100644 index 0000000..43a9d94 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/EDCMixedInstruction.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.disassembler; + +import org.eclipse.cdt.dsf.debug.service.IInstruction; +import org.eclipse.cdt.dsf.debug.service.IMixedInstruction; + +public class EDCMixedInstruction implements IMixedInstruction { + + private final String fileName; + private final int lineNumber; + private final IInstruction[] instructions; + + public EDCMixedInstruction(String fileName, int lineNumber, IInstruction[] instructions) { + this.fileName = fileName; + this.lineNumber = lineNumber; + this.instructions = instructions; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.dsf.debug.service.IMixedInstruction#getFileName() + */ + public String getFileName() { + return fileName; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.dsf.debug.service.IMixedInstruction#getInstructions() + */ + public IInstruction[] getInstructions() { + return instructions; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.dsf.debug.service.IMixedInstruction#getLineNumber() + */ + public int getLineNumber() { + return lineNumber; + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + + buf.append("Source File: ").append(fileName).append("\n"); + buf.append(" line #").append(lineNumber).append(":\n"); + for (IInstruction i : instructions) + buf.append("\t").append(i).append("\n"); + + return buf.toString(); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/IDisassembledInstruction.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/IDisassembledInstruction.java new file mode 100644 index 0000000..048dd06 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/IDisassembledInstruction.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.disassembler; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.IJumpToAddress; +import org.eclipse.cdt.debug.edc.JumpToAddress; + +public interface IDisassembledInstruction { + + public IAddress getAddress(); + + public boolean isValid(); + + public int getSize(); + + public String getMnemonics(); + + /** + * Get {@link JumpToAddress} of the instruction. Return null for non + * control-change instruction. + * + * @return + */ + public IJumpToAddress getJumpToAddress(); + +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/IDisassembler.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/IDisassembler.java new file mode 100644 index 0000000..32092c6 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/disassembler/IDisassembler.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.disassembler; + +import java.nio.ByteBuffer; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext; +import org.eclipse.core.runtime.CoreException; + +/** + * Generic interface for disassemblers. + * + */ +public interface IDisassembler { + + /** + * A known static value for assembly instruction parsers to use to + * indicate an instruction that cannot be parsed, and against which + * abstract/generic members of Disassembly services can compare. + * @since 2.0 + */ + public static final String INVALID_OPCODE = "invalid opcode"; + + /** + * Disassembler options that are common to all targets. Different targets + * may have its own disassembler options. + */ + public static interface IDisassemblerOptions { + /* + * Option key names. + */ + public final static String GET_BRANCH_ADDRESS = "GetBranchAddress"; + public final static String GET_MNEMONICS = "GetMnemonics"; + + // Following are sub-options when GetMnemonics is true. + // + /** + * Show address of the instruction in disassembler output. + */ + public final static String MNEMONICS_SHOW_ADDRESS = "ShowAddresses"; + /** + * Show original bytes of the instruction in disassembler output. + */ + public final static String MNEMONICS_SHOW_BYTES = "ShowBytes"; + /** + * Show symbol in the address in disassembler output. + */ + public final static String MNEMONICS_SHOW_SYMBOL = "ShowSymbol"; + + /** + * Indicates that the address being disassembled is the PC + * @since 2.0 + */ + public static final String ADDRESS_IS_PC = "AddressIsPC"; + } + + /** + * Disassemble one instruction at the beginning of the given byte array. + * + * @param address + * address of the code bytes + * @param code_bytes + * memory bytes containing instructions. + * @param options + * disassembler options. + * @param dmc + * for context specific needs of the implementor (may be null) + * @return a {@link IDisassembledInstruction} object, null if no valid + * instruction at the beginning of the code_bytes. + * @throws CoreException + * @since 2.0 + */ + public IDisassembledInstruction disassembleOneInstruction(IAddress address, ByteBuffer code_bytes, + Map options, IDisassemblyDMContext dmc) throws CoreException; + + /** + * Disassemble a block of memory. + * + * @param start_address + * address of the first byte in the "code_bytes" + * @param end_address + * address of the byte after the last byte that is disassembled. + * @param code_bytes + * memory bytes + * @param options + * disassembler options. + * @param dmc + * for context specific needs of the implementor (may be null) + * + * @return a list of {@link IDisassembledInstruction} objects. + * @throws CoreException + * @since 2.0 + */ + public List disassembleInstructions(IAddress start_address, IAddress end_address, + ByteBuffer code_bytes, Map options, IDisassemblyDMContext dmc) throws CoreException; +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractCompositeFormatProvider.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractCompositeFormatProvider.java new file mode 100644 index 0000000..607b555 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractCompositeFormatProvider.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.debug.edc.services.IEDCExpression; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.core.runtime.CoreException; + +/** + * An abstract class for formatting composite types. + */ +public abstract class AbstractCompositeFormatProvider extends AbstractVariableConverter implements ITypeContentProvider { + + /** + * The Class NameToFieldPath. + */ + protected static class NameToFieldPath { + + /** The name. */ + private String name; + + /** The field path. */ + private String fieldPath; + + /** + * Instantiates a new name to field path. + * + * @param name the name + * @param fieldPath the field path + */ + public NameToFieldPath(String name, String fieldPath) { + this.name = name; + this.fieldPath = fieldPath; + } + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the field path. + * + * @return the field path + */ + public String getFieldPath() { + return fieldPath; + } + } + + /** The name-to-field paths. */ + private final NameToFieldPath[] nameToFieldPaths; + + /** + * Instantiates a new abstract composite format provider. + * + * @param type the type + * @param forDetails is this used for the details pane + * @param nameToFieldPaths the name to field paths + */ + public AbstractCompositeFormatProvider(IType type, boolean forDetails, List nameToFieldPaths) { + super(type, forDetails); + this.nameToFieldPaths = nameToFieldPaths.toArray(new NameToFieldPath[nameToFieldPaths.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.formatter.ITypeContentProvider#getChildIterator(org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext) + */ + public Iterator getChildIterator(IExpressionDMContext variable) throws CoreException { + List childExpressions = getChildren(variable); + return childExpressions.iterator(); + } + + /** + * Gets the child count. + * + * @param variable the variable + * @return the child count + * @throws CoreException the core exception + * @since 2.0 + */ + public int getChildCount(IExpressionDMContext variable) throws CoreException { + List childExpressions = getChildren(variable); + return childExpressions.size(); + } + + /** + * Gets the children. + * + * @param variable the variable + * @return the children + * @throws CoreException the core exception + */ + protected List getChildren(IExpressionDMContext variable) throws CoreException { + List childExpressions = new ArrayList(); + for (NameToFieldPath nameToFieldPath : nameToFieldPaths) { + IExpressionDMContext createSubExpression = + FormatUtils.createSubExpression(variable, nameToFieldPath.getName(), + FormatUtils.getFieldAccessor(type) + nameToFieldPath.getFieldPath()); + if (createSubExpression != null) { + childExpressions.add(createSubExpression); + } + } + // now add all unmapped children + List allChildren = FormatUtils.getAllChildExpressions(variable); + for (IExpressionDMContext child : allChildren) { + String name = ((IEDCExpression) child).getName(); + if (!hasFieldPath(name)) + childExpressions.add(child); + } + return childExpressions; + } + + /** + * Checks for field path. + * + * @param fieldPath the field path + * @return true, if successful + */ + private boolean hasFieldPath(String fieldPath) { + for (NameToFieldPath nameToFieldPath : nameToFieldPaths) { + if (nameToFieldPath.getFieldPath().equals(fieldPath)) + return true; + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.formatter.AbstractVariableConverter#getDetailsValue(org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext) + */ + protected String getDetailsValue(IExpressionDMContext variable) throws CoreException { + return getValueString(variable); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.formatter.AbstractVariableConverter#getSummaryValue(org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext) + */ + protected String getSummaryValue(IExpressionDMContext variable) throws CoreException { + return getValueString(variable); + } + + /** + * Gets the value string. + * + * @param variable the variable + * @return the value string + * @throws CoreException the core exception + */ + protected String getValueString(IExpressionDMContext variable) throws CoreException { + IExpressions expressions = ((IEDCExpression) variable).getExpressionsService(); + if (expressions == null) + return ""; //$NON-NLS-1$ + + StringBuilder sb = new StringBuilder(); + List children = getChildren(variable); + int i = 0; + for (IExpressionDMContext child : children) { + IEDCExpression childExpression = (IEDCExpression) child; + if (i < nameToFieldPaths.length) + sb.append(nameToFieldPaths[i].getName()); + else + sb.append(childExpression.getName()); + sb.append("="); //$NON-NLS-1$ + sb.append(FormatUtils.getVariableValue(childExpression)); + sb.append(" "); //$NON-NLS-1$ + i++; + } + return sb.toString(); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractStringFormatter.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractStringFormatter.java new file mode 100644 index 0000000..5749848 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractStringFormatter.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.services.IEDCExpression; +import org.eclipse.cdt.debug.edc.symbols.IMemoryVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; + +/** + * Base class for string formatters. + */ +public abstract class AbstractStringFormatter implements IVariableFormatProvider { + + /** + * Converter handles char* and wchar_t* strings terminated by a null character. + */ + public class DefaultNullTerminatedStringConverter extends AbstractVariableConverter { + public DefaultNullTerminatedStringConverter(IType type, boolean forDetails) { + super(type, forDetails); + } + + + @Override + protected String getDetailsValue(IExpressionDMContext variable) throws CoreException { + return getValueString(variable); + } + + @Override + protected String getSummaryValue(IExpressionDMContext variable) throws CoreException { + return getValueString(variable); + } + + private String getValueString(IExpressionDMContext variable) throws CoreException { + IEDCExpression expressionDMC = (IEDCExpression) variable; + expressionDMC.evaluateExpression(); + IType baseType = TypeUtils.getBaseType(expressionDMC.getEvaluatedType()); + int size = baseType.getByteSize(); + + if (expressionDMC.getEvaluationError() != null) + return expressionDMC.getEvaluationError().getMessage(); + + // pointer living at null is not valid (e.g. inside a struct pointing to null) + IVariableLocation exprLoc = expressionDMC.getEvaluatedLocation(); + if (exprLoc instanceof IMemoryVariableLocation && ((IMemoryVariableLocation) exprLoc).getAddress().isZero()) + return "0"; + + int maximumLength = getMaximumLength(); + // limit to express char[] size if given + if (expressionDMC.getEvaluatedType() instanceof IArrayType) { + long boundLength = ((IArrayType)expressionDMC.getEvaluatedType()).getBound(0).getBoundCount(); + if (boundLength > 0) { + maximumLength = (int) Math.min(boundLength, maximumLength); + } + } + + Number value = expressionDMC.getEvaluatedValue(); + if (value == null) { + if (expressionDMC.getEvaluatedValueString() != null) { + // already a string + // TODO: proper formatting + return '"' + expressionDMC.getEvaluatedValueString() + '"'; + } + return null; + } + + IAddress address = FormatUtils.getPointerValue(value); + if (address == null) { + return value.toString(); // dunno + } + + // null pointer + if (address.isZero()) + return "0"; + + String formattedString = + FormatUtils.getFormattedNullTermString(variable, address, size, maximumLength); + return quoteString(formattedString); + } + + private String quoteString(String str) { + StringBuilder sb = new StringBuilder("\""); + sb.append(str); + sb.append('\"'); + return sb.toString(); + } + } + + /** + * Override to change the maximum string length to format. + * @return size in characters + */ + protected int getMaximumLength() { + IEclipsePreferences scope = InstanceScope.INSTANCE.getNode("org.eclipse.debug.ui"); + return scope.getInt("org.eclipse.debug.ui.max_detail_length", 256); + } + + public ITypeContentProvider getTypeContentProvider(IType type) { + return null; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractVariableConverter.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractVariableConverter.java new file mode 100644 index 0000000..12f86ba --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/AbstractVariableConverter.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.core.runtime.CoreException; + +/** + * Abstract class implementing IVariableValueConverter with summary and detail variants + */ +public abstract class AbstractVariableConverter implements IVariableValueConverter { + + protected IType type; + private boolean forDetails; + private int curValueLength; + + public AbstractVariableConverter(IType type, boolean forDetails) { + this.forDetails = forDetails; + this.type = type; + } + + protected abstract String getDetailsValue(IExpressionDMContext variable) throws CoreException; + + protected abstract String getSummaryValue(IExpressionDMContext variable) throws CoreException; + + public String getValue(IExpressionDMContext variable) throws CoreException { + if (forDetails) + return getDetailsValue(variable); + return getSummaryValue(variable); + } + + /** + * @since 2.0 + */ + public void setCurValueLength(int curValueLength) { + this.curValueLength = curValueLength; + } + + /** + * @since 2.0 + */ + public int getCurValueLength() { + return curValueLength; + } + + public boolean canEditValue() { + return false; // read-only implementation + } + + public String getEditableValue(IExpressionDMContext variable) throws CoreException { + return getValue(variable); // default - use same value + } + + public void setValue(IExpressionDMContext variable, String newValue) { + // read-only implementation + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultArrayFormatter.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultArrayFormatter.java new file mode 100644 index 0000000..dad0dae --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultArrayFormatter.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import java.util.List; + +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.IArrayDimensionType; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.services.IEDCExpression; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.core.runtime.CoreException; + +public class DefaultArrayFormatter implements IVariableFormatProvider { + + public class DefaultArrayConverter extends AbstractVariableConverter { + + private static final int STOP_LENGTH = 300; // stop adding items when string is this length + + public DefaultArrayConverter(IType type, boolean forDetails) { + super(type, forDetails); + } + + @Override + protected String getSummaryValue(IExpressionDMContext variable) throws CoreException { + IExpressions expressions = ((IEDCExpression) variable).getExpressionsService(); + if (expressions == null) + return ""; //$NON-NLS-1$ + StringBuilder sb = new StringBuilder("["); + List children = FormatUtils.getAllChildExpressions(variable); + boolean skip = true; + for (IExpressionDMContext child : children) { + if (skip) + skip = false; + else + sb.append(", "); + String customString = getCustomValueString(child, getCurValueLength() + sb.length()); + if (customString != null) { + sb.append('{'); + sb.append(customString); + sb.append('}'); + } + else { + IEDCExpression childExpression = (IEDCExpression) child; + sb.append(FormatUtils.getVariableValue(childExpression)); + } + if (getCurValueLength() + sb.length() > STOP_LENGTH) { + if (!children.get(children.size() - 1).equals(child)) + sb.append(", ..."); + break; + } + } + return sb.append(']').toString(); + } + + private String getCustomValueString(IExpressionDMContext variable, int curValueLength) throws CoreException { + IVariableValueConverter converter = FormatUtils.getCustomValueConverter(variable); + if (converter != null) { + if (converter instanceof AbstractVariableConverter) + ((AbstractVariableConverter) converter).setCurValueLength(curValueLength); + return converter.getValue(variable); + } + return null; + } + + @Override + protected String getDetailsValue(IExpressionDMContext variable) throws CoreException { + return getSummaryValue(variable); + } + + } + + public static boolean handlesType(IType type) { + IType unqualifiedType = FormatUtils.getUnqualifiedTypeRemovePointers(type); + return unqualifiedType instanceof IArrayType + || unqualifiedType instanceof IArrayDimensionType; + } + + public ITypeContentProvider getTypeContentProvider(IType type) { + return null; + } + + public IVariableValueConverter getDetailValueConverter(IType type) { + if (handlesType(type)) + return new DefaultArrayConverter(type, true); + return null; + } + + public IVariableValueConverter getVariableValueConverter(IType type) { + if (handlesType(type)) + return new DefaultArrayConverter(type, false); + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultCStringFormatter.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultCStringFormatter.java new file mode 100644 index 0000000..09bf72a --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultCStringFormatter.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import org.eclipse.cdt.debug.edc.internal.symbols.ConstType; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.IReferenceType; +import org.eclipse.cdt.debug.edc.internal.symbols.ITypedef; +import org.eclipse.cdt.debug.edc.internal.symbols.VolatileType; +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * Handle char* and wchar_t* strings (ignoring const, volatile, and typedefs to char type). + */ +public class DefaultCStringFormatter extends AbstractStringFormatter { + + public static boolean handlesType(IType type) { + if (type instanceof ICPPBasicType) { + ICPPBasicType basicType = (ICPPBasicType) type; + // NOTE: we may have neither signed nor unsigned set on a char*, and this is a "classic" string. + // We would like to explicitly ignore "unsigned char*", since that's normally a byte buffer -- + // but RVCT incorrectly sets this flag for some instances of "char*" in source. + boolean isCharString = /*!basicType.isUnsigned() &&*/ basicType.getBaseType() == ICPPBasicType.t_char; + boolean isWcharTString = basicType.getBaseType() == ICPPBasicType.t_wchar_t || basicType.getName().equals("wchar_t"); + return isCharString || isWcharTString; + } + return false; + } + + public ITypeContentProvider getTypeContentProvider(IType type) { + return null; + } + + public IVariableValueConverter getDetailValueConverter(IType type) { + IType basicType = getBasePointedType(type); + if (handlesType(basicType)) + return new DefaultNullTerminatedStringConverter(type, true); + + return null; + } + + public IVariableValueConverter getVariableValueConverter(IType type) { + IType basicType = getBasePointedType(type); + if (handlesType(basicType)) + return new DefaultNullTerminatedStringConverter(type, false); + + return null; + } + + + /** + * Get the basic unit type pointed to by a string (reducing, e.g., + * "const char *const" to "char"). Also, handle typedefs (e.g. "gchar") and + * references (char &) to char. + * @param type + * @return basic unit type or null if not a pointer to basic type + */ + protected IType getBasePointedType(IType type) { + // remove upper qualifiers + while (type instanceof ConstType || type instanceof VolatileType || type instanceof ITypedef || type instanceof IReferenceType) + type = type.getType(); + + // make sure it's a single pointer or a single-dimension array + if (type instanceof IPointerType) + type = type.getType(); + else if (type instanceof IArrayType && ((IArrayType) type).getBoundsCount() == 1) + type = type.getType(); + else + return null; + + // remove inner qualifiers + while (type instanceof ConstType || type instanceof VolatileType || type instanceof ITypedef || type instanceof IReferenceType) + type = type.getType(); + if (!(type instanceof ICPPBasicType)) + return null; + return type; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultCompositeFormatter.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultCompositeFormatter.java new file mode 100644 index 0000000..8d3ef44 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/DefaultCompositeFormatter.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import java.util.List; + +import org.eclipse.cdt.debug.edc.internal.symbols.ICompositeType; +import org.eclipse.cdt.debug.edc.services.IEDCExpression; +import org.eclipse.cdt.debug.edc.symbols.IMemoryVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.core.runtime.CoreException; + +public class DefaultCompositeFormatter implements IVariableFormatProvider { + + public class DefaultCompositeConverter extends AbstractVariableConverter { + + private static final int MAX_DEPTH = 1; // stop recursing at this depth + private static final int STOP_LENGTH = 300; // stop adding items when string is this length + + public DefaultCompositeConverter(IType type, boolean forDetails) { + super(type, forDetails); + } + + @Override + protected String getSummaryValue(IExpressionDMContext variable) throws CoreException { + StringBuilder sb = new StringBuilder(); + addVariableFields(null, sb, variable, 0); + if (sb.length() == 0) { + // if debug information does not include child information, + // return the already evaluated value + if (variable instanceof IEDCExpression) { + IEDCExpression variableEDMC = (IEDCExpression)variable; + return variableEDMC.getEvaluatedValueString(); + } + } + return sb.toString(); + } + + private boolean hasNullLocation(IExpressionDMContext variable) throws CoreException { + if (variable instanceof IEDCExpression) { + FormatUtils.evaluateExpression((IEDCExpression) variable); + IVariableLocation loc = ((IEDCExpression) variable).getEvaluatedLocation(); + if (loc instanceof IMemoryVariableLocation) { + if (((IMemoryVariableLocation) loc).getAddress().isZero()) { + return true; + } + } + } + return false; + } + + private void addVariableFields(String prefix, StringBuilder sb, IExpressionDMContext variable, int curDepth) throws CoreException { + // if at null, don't try + if (hasNullLocation(variable)) + return; + + if (prefix == null) + prefix = ""; //$NON-NLS-1$ + List childContexts = FormatUtils.getAllChildExpressions(variable); + for (IExpressionDMContext child : childContexts) { + IEDCExpression childExpression = (IEDCExpression) child; + + // if any child is at null, likely the struct is at null or crosses null, and is bad news + if (hasNullLocation(childExpression)) { + continue; + } + + IVariableValueConverter customConverter = + FormatUtils.getCustomValueConverter(child); + if (customConverter != null && + !(customConverter instanceof DefaultCompositeConverter)) { + sb.append(prefix); + sb.append(childExpression.getName()); + sb.append("="); //$NON-NLS-1$ + // for default array converter strings, don't surround in extra brackets + boolean isDefaultArrayConverter = + customConverter instanceof DefaultArrayFormatter.DefaultArrayConverter; + if (!isDefaultArrayConverter) + sb.append("{"); + if (customConverter instanceof AbstractVariableConverter) + ((AbstractVariableConverter) customConverter).setCurValueLength(getCurValueLength() + sb.length()); + sb.append(customConverter.getValue(child)); + if (!isDefaultArrayConverter) + sb.append("}"); + sb.append(" "); + } + else { + IType evaluatedType = childExpression.getEvaluatedType(); + IType unqualifiedType = FormatUtils.getUnqualifiedTypeRemovePointers(evaluatedType); + if (unqualifiedType instanceof ICompositeType) { + unqualifiedType = TypeUtils.getStrippedType(evaluatedType); + StringBuilder childPrefixSB = new StringBuilder(prefix); + String name = childExpression.getName(); + if (name.startsWith("*")) { + childPrefixSB.append('('); + childPrefixSB.append(name); + childPrefixSB.append(')'); + } else + childPrefixSB.append(name); + childPrefixSB.append(FormatUtils.getFieldAccessor(unqualifiedType)); + if (curDepth < MAX_DEPTH) + addVariableFields(childPrefixSB.toString(), sb, child, ++curDepth); + else { + addSimpleChild(prefix, sb, childExpression); + } + } + else { + addSimpleChild(prefix, sb, childExpression); + } + } + + if (getCurValueLength() + sb.length() > STOP_LENGTH) { + if (!childContexts.get(childContexts.size() - 1).equals(child)) + sb.append("... "); + break; + } + } + } + + private void addSimpleChild(String prefix, StringBuilder sb, IEDCExpression childExpression) { + IExpressions expressions = childExpression.getExpressionsService(); + if (expressions == null) + return; + + sb.append(prefix); + sb.append(childExpression.getName()); + sb.append("="); //$NON-NLS-1$ + sb.append(FormatUtils.getVariableValue(childExpression)); + sb.append(" "); //$NON-NLS-1$ + } + + @Override + protected String getDetailsValue(IExpressionDMContext variable) throws CoreException { + return getSummaryValue(variable); + } + } + + public static boolean handlesType(IType type) { + IType unqualifiedType = FormatUtils.getUnqualifiedTypeRemovePointers(type); + return unqualifiedType instanceof ICompositeType; + } + + public ITypeContentProvider getTypeContentProvider(IType type) { + return null; + } + + public IVariableValueConverter getDetailValueConverter(IType type) { + if (handlesType(type)) + return new DefaultCompositeConverter(type, true); + + return null; + } + + public IVariableValueConverter getVariableValueConverter(IType type) { + if (handlesType(type)) + return new DefaultCompositeConverter(type, false); + + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/EDCFormatterMessages.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/EDCFormatterMessages.java new file mode 100644 index 0000000..496c3ca --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/EDCFormatterMessages.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import org.eclipse.osgi.util.NLS; + +public class EDCFormatterMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.edc.formatter.EDCFormatterMessages"; //$NON-NLS-1$ + public static String FormatUtils_CannotReadMemory; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, EDCFormatterMessages.class); + } + + private EDCFormatterMessages() { + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/EDCFormatterMessages.properties b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/EDCFormatterMessages.properties new file mode 100644 index 0000000..d5480c9 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/EDCFormatterMessages.properties @@ -0,0 +1,11 @@ +############################################################################### +# Copyright (c) 2010 Nokia and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Nokia - Initial API and implementation +############################################################################### +FormatUtils_CannotReadMemory=Cannot read memory at 0x{0} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/FormatUtils.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/FormatUtils.java new file mode 100644 index 0000000..aeed5a6 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/FormatUtils.java @@ -0,0 +1,486 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import java.math.BigInteger; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.IArrayDimensionType; +import org.eclipse.cdt.debug.edc.internal.formatter.FormatExtensionManager; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Expressions; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Memory; +import org.eclipse.cdt.debug.edc.internal.symbols.ICompositeType; +import org.eclipse.cdt.debug.edc.internal.symbols.IInheritance; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.ITypedef; +import org.eclipse.cdt.debug.edc.services.IEDCExpression; +import org.eclipse.cdt.debug.edc.services.IEDCMemory; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.debug.core.model.MemoryByte; + +/** + * Utilities for generating formatters + * + * Use of non-api IType in this class is provisional. IType will later move to a public package. + */ +public class FormatUtils { + + /** The Constant CLASS. */ + private final static String CLASS = "class " ; //$NON-NLS-1$ + + /** The Constant STRUCT. */ + private final static String STRUCT = "struct "; //$NON-NLS-1$ + + /** + * Check type by name. + * + * @param type the type + * @param baseName the base name + * @return true, if successful + */ + public static boolean checkTypeByName(IType type, String baseName) { + if (type == null) + return false; + // we want to preserve typedefs to determine whether this is a type we support with a formatter + IType baseType = TypeUtils.getBaseTypePreservingTypedef(type); + + // check for someone making a typedef of what we're looking for + while (baseType != null && baseType instanceof ITypedef) { + if (baseType.getName().equals(baseName)) + return true; + baseType = TypeUtils.getBaseTypePreservingTypedef(baseType.getType()); + } + + if (baseType == null) + return false; + + return checkName(baseType.getName(), baseName); + } + + /** + * Check name. + * + * @param typeName the type name + * @param baseName the base name + * @return true, if successful + */ + public static boolean checkName(String typeName, String baseName) { + String checkName = typeName; + if (typeName.startsWith(CLASS)) + checkName = typeName.substring(CLASS.length()).trim(); + else if (typeName.startsWith(STRUCT)) + checkName = typeName.substring(STRUCT.length()).trim(); + return checkName.equals(baseName); + } + + + /** + * Check if the name of a class/struct, or one of the classes/structs it + * derives from, matches a given name. + * + * @param type type of class/struct + * @param name type name to match against + * @return true if class/struct or inherited class/struct matches name, + * or null if no match + */ + public static boolean checkClassOrInheritanceByName(IType type, String name) { + // strip off typedefs and type qualifiers, to look for classes and structs + type = TypeUtils.getBaseType(type); + + if (!(type instanceof ICompositeType)) + return false; + + ICompositeType composite = (ICompositeType)type; + + String baseName = composite.getBaseName(); + + if (baseName.equals(name)) + return true; + + // if base name ends with a template size (e.g., "<15>"), + // match ignoring the value in the braces + if (baseName.indexOf('<') != -1) //$NON-NLS-1$ + if (baseName.matches(name + "<.*>$")) //$NON-NLS-1$ + return true; + + // check classes and structs it derives from + for (IInheritance inheritance : composite.getInheritances()) { + if (checkClassOrInheritanceByName(inheritance.getType(), name)) + return true; + } + + return false; + } + + + /** + * Creates the sub expression. + * + * @param variable the variable + * @param name the name + * @param subExpressionStr the sub expression str + * @return the IExpressionDMContext for the sub expression. + */ + public static IExpressionDMContext createSubExpression(IExpressionDMContext variable, String name, String subExpressionStr) { + IEDCExpression parentExpr = (IEDCExpression) variable; + IExpressions expressions = parentExpr.getExpressionsService(); + if (expressions == null) + return null; + String expressionStr = parentExpr.getExpression() + subExpressionStr; + IEDCExpression subExpression = (IEDCExpression) expressions.createExpression(parentExpr, expressionStr); + subExpression.setName(name); + return subExpression; + } + + /** + * Gets the formatted string. + * + * @param variable the variable + * @param address the address + * @param length the length + * @param charSize the char size + * @return the formatted string + * @throws CoreException the core exception + */ + public static String getFormattedString(IExpressionDMContext variable, IAddress address, int length, int charSize) + throws CoreException { + IEDCExpression expression = (IEDCExpression) variable; + StackFrameDMC frame = (StackFrameDMC) expression.getFrame(); + IEDCMemory memory = frame.getEDCServicesTracker().getService(Memory.class); + + StringBuilder sb = new StringBuilder(); + ArrayList buffer = new ArrayList(); + IStatus status = memory.getMemory(frame.getExecutionDMC(), address, buffer, length * charSize, 1); + if (status.isOK()) { + for (int i = 0; i < length * charSize; i++) { + // make sure each byte is okay + if (!buffer.get(i).isReadable()) + throw EDCDebugger.newCoreException( + MessageFormat.format(EDCFormatterMessages.FormatUtils_CannotReadMemory, + address.add(i).getValue().toString(16))); + + char c = (char) (buffer.get(i).getValue() & 0xff); + if (charSize > 1) { + char c2 = (char) (buffer.get(++i).getValue() << 8); + c |= c2; + } + sb.append(c); + } + } + return sb.toString(); + } + + /** + * Gets the formatted null term string. + * + * @param variable the variable + * @param address the address + * @param charSize the char size + * @param maximumLength the maximum length + * @return the formatted null term string + * @throws CoreException the core exception + */ + public static String getFormattedNullTermString(IExpressionDMContext variable, + IAddress address, int charSize, + int maximumLength) throws CoreException { + IEDCExpression expression = (IEDCExpression) variable; + StackFrameDMC frame = (StackFrameDMC) expression.getFrame(); + IEDCMemory memory = frame.getEDCServicesTracker().getService(Memory.class); + + StringBuilder sb = new StringBuilder(); + ArrayList buffer = new ArrayList(64);// typical size of cache block + if (maximumLength == 0) + maximumLength = 16384; // somewhat arbitrary; if the user really wants more, the value can always be set higher + OUTER:while (maximumLength > 0) { + int amount = Math.min(maximumLength, 64);// typical size of cache block + IStatus status = memory.getMemory(frame.getExecutionDMC(), address, buffer, amount, charSize); + if (status.isOK()) { + // make sure each byte is okay + for (int i = 0; i < buffer.size() && maximumLength > 0; ++i, --maximumLength) { + if (!buffer.get(i).isReadable()) + { + if (i == 0) // partial memory read success + throw EDCDebugger.newCoreException( + MessageFormat.format(EDCFormatterMessages.FormatUtils_CannotReadMemory, + address.add(i).getValue().toString(16))); + maximumLength = 0; + break OUTER; + } + char c = (char) buffer.get(i).getValue(); + if (charSize > 1) { + char c2 = (char) (buffer.get(++i).getValue() << 8); + c |= c2; + } + if (c == '\0') + break OUTER; + sb.append(c); + address = address.add(charSize); + } + } else if (amount > 1) { + maximumLength = Math.min(maximumLength, 64) / 2; + } else { + // Error in reading memory, bail out. If we got more than one character, + // use ellipsis, else fail. + if (sb.length() == 0) + throw EDCDebugger.newCoreException( + MessageFormat.format(EDCFormatterMessages.FormatUtils_CannotReadMemory, + address.getValue().toString(16))); + maximumLength = 0; + break; + } + buffer.clear(); + } + if (maximumLength <= 0) + sb.append("..."); //$NON-NLS-1$ + + return sb.toString(); + } + + /** + * Find in collection by name. + * + * @param collection the collection + * @param name the name + * @return the i expression dm context + */ + public static IExpressionDMContext findInCollectionByName(Collection collection, String name) { + for (IExpressionDMContext context : collection) { + if (((IEDCExpression) context).getName().equals(name)) + return context; + } + + return null; + } + + /** + * Gets the all child expressions. + * + * @param variable the variable + * @return the all child expressions + */ + public static List getAllChildExpressions(IExpressionDMContext variable) { + + IEDCExpression variableDMC = (IEDCExpression) variable; + Expressions expressions = (Expressions) variableDMC.getExpressionsService(); + if (expressions == null) + return Collections.emptyList(); + + List kids = Arrays.asList( + expressions.getLogicalSubExpressions(variableDMC)); + return kids; + } + + /** + * Gets the field accessor. + * + * @param type the type + * @return the field accessor + */ + public static String getFieldAccessor(IType type) { + if (type instanceof IPointerType) + return "->"; //$NON-NLS-1$ + return "."; //$NON-NLS-1$ + } + + /** + * Gets the member value. + * + * @param variable the variable + * @param type the type + * @param memberName the member name + * @return the member value + */ + public static String getMemberValue(IExpressionDMContext variable, IType type, String memberName) { + return getMemberValue(variable, type, memberName, IExpressions.NATURAL_FORMAT); + } + + /** + * Gets the member value. + * + * @param variable the variable + * @param type the type + * @param memberName the member name + * @param format the format + * @return the member value + */ + public static String getMemberValue(IExpressionDMContext variable, IType type, String memberName, String format) { + IExpressions expressions = ((IEDCExpression)variable).getExpressionsService(); + if (expressions == null) + return ""; //$NON-NLS-1$ + IEDCExpression expression = + (IEDCExpression) expressions.createExpression(variable, variable.getExpression() + + FormatUtils.getFieldAccessor(type) + memberName); + FormattedValueDMContext fvc = expressions.getFormattedValueContext(expression, format); + return expression.getFormattedValue(fvc).getFormattedValue(); + } + + /** + * Gets the variable value. + * + * @param variable the variable + * @return the variable value + * @since 2.0 + */ + public static String getVariableValue(IExpressionDMContext variable) { + return getVariableValue(variable, IExpressions.NATURAL_FORMAT); + } + + /** + * Gets the variable value. + * + * @param variable the variable + * @param format the format + * @return the variable value + * @since 2.0 + */ + public static String getVariableValue(IExpressionDMContext variable, String format) { + IExpressions expressions = ((IEDCExpression)variable).getExpressionsService(); + FormattedValueDMContext fvc = + expressions.getFormattedValueContext(variable, format); + FormattedValueDMData formattedValue = ((IEDCExpression) variable).getFormattedValue(fvc); + return formattedValue.getFormattedValue(); + } + + /** + * Gets the unqualified type remove pointers. + * + * @param type the type + * @return the unqualified type remove pointers + */ + public static IType getUnqualifiedTypeRemovePointers(IType type) { + IType unqualifiedType = TypeUtils.getStrippedType(type); + while (unqualifiedType instanceof IPointerType) + unqualifiedType = TypeUtils.getStrippedType(unqualifiedType.getType()); + return unqualifiedType; + } + + /** + * Gets the custom value converter. + * + * @param variable the variable + * @return the custom value converter + */ + public static IVariableValueConverter getCustomValueConverter(IExpressionDMContext variable) { + IEDCExpression variableDMC = (IEDCExpression) variable; + variableDMC.evaluateExpression(); + IType type = TypeUtils.getUnRefStrippedType(variableDMC.getEvaluatedType()); + if (type instanceof IArrayDimensionType) + type = ((IArrayDimensionType)type).getArrayType(); + return FormatExtensionManager.instance().getVariableValueConverter(type); + } + + /** + * Get an address from an expression representing a pointer. + * @param value the evaluated value of an IEDCExpression + * @return the pointer address or null + */ + public static IAddress getPointerValue(Number value) { + IAddress address = null; + + if (value instanceof BigInteger) { + address = new Addr64((BigInteger) value); + } else { + address = new Addr32(value.longValue()); + } + return address; + } + + /** + * Gets the template type name. + * + * @param typeName the type name + * @param type the type + * @return the template type name + * @since 2.0 + */ + public static String getTemplateTypeName(String typeName, IType type) { + // TODO Fix this when type gives template information Bug 11443 + + ICompositeType composite = (ICompositeType) TypeUtils.getBaseType(type); + String baseName = composite.getBaseName(); + + Matcher m = Pattern.compile(typeName + "<(.+)>").matcher(baseName); + if (m.matches()) + return m.group(1); + + // check classes and structs it derives from + for (IInheritance inheritance : composite.getInheritances()) { + String templateTypeName = getTemplateTypeName(typeName, inheritance.getType()); + if (templateTypeName != null) + return templateTypeName; + } + + return null; + } + + /** + * Gets the formatted value. + * + * @param variable the variable + * @return the formatted value + * @throws CoreException the core exception + * @since 2.0 + */ + public static String getFormattedValue(IExpressionDMContext variable) throws CoreException { + IVariableValueConverter valueConverter = getCustomValueConverter(variable); + if (valueConverter != null) { + return valueConverter.getValue(variable); + } + else + return getVariableValue(variable); + } + + /** + * Gets the max number of children. + * + * @return the max number of children + * @since 2.0 + */ + public static int getMaxNumberOfChildren() { + return 200; // this seems like a good default + } + + /** + * Evaluates the expression and throws a CoreException if there is an evaluation error. + * + * @param expression the expression + * @throws CoreException the core exception + * @since 2.0 + */ + public static void evaluateExpression(IEDCExpression expression) throws CoreException { + expression.evaluateExpression(); + IStatus status = expression.getEvaluationError(); + if ((status != null && !status.isOK()) || expression.getEvaluatedValue() == null) { + Throwable t = status != null ? status.getException() : null; + throw EDCDebugger.newDebugException("Error evaluating expression: " + expression.getExpression(), t); + } + + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/ITypeContentProvider.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/ITypeContentProvider.java new file mode 100644 index 0000000..7daaa46 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/ITypeContentProvider.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import java.util.Iterator; + +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.core.runtime.CoreException; + + + +/** + * An interface describing structure for a type + */ +public interface ITypeContentProvider { + + /** + * Return an iterator starting at a start index generating the + * list of IExpressionDMContext for each of the direct children + * of the current object. + * @param variable IExpressionDMContext + * @return Iterator + * @throws CoreException on errors + */ + Iterator getChildIterator(IExpressionDMContext variable) throws CoreException; + + /** + * Return the number of children + * @param variable IExpressionDMContext + * @return int + * @throws CoreException on errors + * @since 2.0 + */ + int getChildCount(IExpressionDMContext variable) throws CoreException; +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/IVariableFormatProvider.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/IVariableFormatProvider.java new file mode 100644 index 0000000..367f318 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/IVariableFormatProvider.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * Interface for an extension providing custom formatting for variables + */ +public interface IVariableFormatProvider { + /** + * An optional structure to use for this type + * @param type IType + * @return ITypeContentProvider + */ + ITypeContentProvider getTypeContentProvider(IType type); + + /** + * An optional summary value to display in the value column for the current object. + * @param type IType + * @return IVariableValueConverter + */ + IVariableValueConverter getVariableValueConverter(IType type); + + /** + * An optional string to display in the detail pane when the variable is selected + * @param type IType + * @return IVariableValueConverter + */ + IVariableValueConverter getDetailValueConverter(IType type); +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/IVariableValueConverter.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/IVariableValueConverter.java new file mode 100644 index 0000000..7a8ece0 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/formatter/IVariableValueConverter.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.formatter; + +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.core.runtime.CoreException; + + +/** + * Interface for converting displayed values and optionally editing converted value + */ +public interface IVariableValueConverter { + /** + * Return the formatted value. + * @param variable IExpressionDMContext + * @return String + * @throws CoreException any error on getting the value. + */ + String getValue(IExpressionDMContext variable) throws CoreException; + + /** + * Whether the value is editable. + * If false, {@link #setValue(String)} and {@link #getEditableValue(IExpressionDMContext)} may fail. + * @return boolean + */ + boolean canEditValue(); + + /** + * Return the formatted value for editing. + * @param variable IExpressionDMContext + * @return String + * @throws CoreException any error on getting the value. + */ + String getEditableValue(IExpressionDMContext variable) throws CoreException; + + /** + * The value entered by the user to change the variable. + * @param variable IExpressionDMContext + * @param newValue String + * @throws CoreException any error on setting the value. + */ + void setValue(IExpressionDMContext variable, String newValue) throws CoreException; +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ByteBufferStreamBuffer.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ByteBufferStreamBuffer.java new file mode 100644 index 0000000..2a4c29a --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ByteBufferStreamBuffer.java @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal; + +import java.io.IOException; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; + +import org.eclipse.cdt.debug.edc.IStreamBuffer; + +/** + * This implementation of IStreamBuffer works on an existing ByteBuffer. + */ +public class ByteBufferStreamBuffer extends StreamBufferBase { + + private ByteBuffer buffer; + + + /** + * Wrap in-memory content. + * @param content + * @param order + */ + public ByteBufferStreamBuffer(ByteBuffer buffer) throws IOException { + super(buffer.order(), 0, buffer.capacity()); + this.buffer = buffer; + } + public ByteBufferStreamBuffer(ByteBuffer buffer, long position, long size) { + super(buffer.order(), position, size); + this.buffer = buffer; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.StreamBufferBase#fetchPage(byte[], int, int) + */ + @Override + protected void fetchPage(byte[] buffer, long sourceOffset, int count) { + if (sourceOffset > Integer.MAX_VALUE) + throw new BufferUnderflowException(); + this.buffer.position((int) sourceOffset); + this.buffer.get(buffer, 0, count); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.StreamBufferBase#createSubBuffer(long, long) + */ + @Override + protected IStreamBuffer createSubBuffer(long offset, long size) { + return new ByteBufferStreamBuffer(buffer, offset, size); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCApplication.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCApplication.java new file mode 100644 index 0000000..6920e72 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCApplication.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import org.eclipse.cdt.scripting.ScriptingPlugin; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.internal.core.IInternalDebugCoreConstants; +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; + +@SuppressWarnings("restriction") +public class EDCApplication implements IApplication { + + boolean running; + + public Object start(IApplicationContext context) throws Exception { + + running = true; + + IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(ScriptingPlugin.PLUGIN_ID); + prefs.putBoolean(ScriptingPlugin.SCRIPTING_ENABLED, true); + + prefs = InstanceScope.INSTANCE.getNode(DebugPlugin.getUniqueIdentifier()); + prefs.putBoolean(IInternalDebugCoreConstants.PREF_ENABLE_STATUS_HANDLERS, false); + + ScriptingPlugin.getBundleContext(); + + while (running) + { + Thread.sleep(1000); + } + + return null; + } + + public void stop() { + running = false; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCDebugPreferenceInitializer.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCDebugPreferenceInitializer.java new file mode 100644 index 0000000..5a78b25 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCDebugPreferenceInitializer.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import org.eclipse.cdt.debug.edc.internal.formatter.FormatExtensionManager; +import org.eclipse.cdt.debug.edc.internal.snapshot.Album; +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; + +public class EDCDebugPreferenceInitializer extends + AbstractPreferenceInitializer { + + @Override + public void initializeDefaultPreferences() { + IEclipsePreferences node = DefaultScope.INSTANCE.getNode(EDCDebugger.PLUGIN_ID); + node.putInt(Album.PREF_VARIABLE_CAPTURE_DEPTH, 5); + node.put(Album.PREF_CREATION_CONTROL, Album.CREATE_MANUAL); + node.putBoolean(FormatExtensionManager.VARIABLE_FORMATS_ENABLED, FormatExtensionManager.VARIABLE_FORMATS_ENABLED_DEFAULT); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCDebugger.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCDebugger.java new file mode 100644 index 0000000..5494bc0 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCDebugger.java @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import org.eclipse.cdt.debug.edc.ITCFServiceManager; +import org.eclipse.cdt.debug.edc.MessageLogger; +import org.eclipse.cdt.debug.edc.tcf.extension.services.ILogging; +import org.eclipse.cdt.debug.edc.tcf.extension.services.ISettings; +import org.eclipse.cdt.debug.edc.tcf.extension.services.LoggingProxy; +import org.eclipse.cdt.debug.edc.tcf.extension.services.SettingsProxy; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.eclipse.osgi.service.debug.DebugTrace; +import org.eclipse.tm.tcf.protocol.IChannel; +import org.eclipse.tm.tcf.protocol.Protocol; +import org.eclipse.tm.tcf.protocol.Protocol.ChannelOpenListener; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; + +/** + * The activator class controls the plug-in life cycle + */ + +public class EDCDebugger extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.cdt.debug.edc"; //$NON-NLS-1$ + + // The shared instance + private static EDCDebugger plugin; + + /** Platform facility used to trace. Lock {@link #traceLock} before accessing. */ + private volatile DebugTrace trace; + + /** Serializes access to {@link #trace} */ + private final String traceLock = new String("trace lock"); + + private ITCFServiceManager tcfServiceManager; + + private PersistentCache cache; + + /** This plugin, once activated */ + private BundleContext context; + + /** + * The constructor + */ + public EDCDebugger() { + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + this.context = context; + plugin = this; + + // Validate our plugin ID constant + if (!getBundle().getSymbolicName().equals(PLUGIN_ID)) { + throw new IllegalStateException("PLUGIN_ID constant is not correct"); //$NON-NLS-1$ + } + + EDCTrace.init(); + + installChannelListener(); + } + + private void installChannelListener() { + + Protocol.invokeLater(new Runnable() { + + public void run() { + Protocol.addChannelOpenListener(new ChannelOpenListener() { + + public void onChannelOpen(IChannel channel) { + // logging service + if (channel.getRemoteService(ILogging.NAME) != null) + channel.setServiceProxy(ILogging.class, new LoggingProxy(channel)); + // settings service + if (channel.getRemoteService(ISettings.NAME) != null) + channel.setServiceProxy(ISettings.class, new SettingsProxy(channel)); + // + } + }); + }; + }); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + if (cache != null) + cache.flushAll(); + plugin = null; + if (tcfServiceManager != null) + ((TCFServiceManager) tcfServiceManager).shutdown(); + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static EDCDebugger getDefault() { + return plugin; + } + + public static BundleContext getBundleContext() { + return getDefault().getBundle().getBundleContext(); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public DebugTrace getTrace() { + synchronized (traceLock) { + if (trace == null) { + if (context == null) { + return null; // Sorry, can't help. Bundle hasn't been activated yet + } + + ServiceTracker tracker = new ServiceTracker(context, DebugOptions.class.getName(), null); + tracker.open(); + DebugOptions debugOptions = (DebugOptions)tracker.getService(); + if (debugOptions != null) { + trace = debugOptions.newDebugTrace(getBundle().getSymbolicName()); + } + tracker.close(); + } + } + return trace; + } + + public ITCFServiceManager getServiceManager() { + if (tcfServiceManager == null) { + tcfServiceManager = new TCFServiceManager(); + } + return tcfServiceManager; + } + + /** + * Utility method for creating a CoreException object with this EDC plugin + * ID. + * + * @param msg + * - error message. + * @param e + * - cause exception, can be null. + * @return a {@link CoreException} object. + */ + public static CoreException newCoreException(String msg, Throwable t) { + if ((msg == null || msg.length() == 0) && t instanceof CoreException) + return new CoreException(((CoreException) t).getStatus()); + else + return new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, msg, t)); + } + + /** + * Utility method for creating a CoreException object with this EDC plugin + * ID. + * + * @param msg + * - error message. + * @return a {@link CoreException} object. + */ + public static CoreException newCoreException(String msg) { + return new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, msg)); + } + + /** + * Utility method for creating a DebugException object with this EDC plugin + * ID. + * + * @param msg + * - error message. + * @param e + * - cause exception, can be null. + * @return a {@link DebugException} object. + */ + public static DebugException newDebugException(String msg, Throwable t) { + if ((msg == null || msg.length() == 0) && t instanceof CoreException) + return new DebugException(((CoreException) t).getStatus()); + else + return new DebugException(new Status(IStatus.ERROR, PLUGIN_ID, msg, t)); + } + + /** + * Utility method for creating a DebugException object with this EDC plugin + * ID. + * + * @param msg + * - error message. + * @return a {@link DebugException} object. + */ + public static DebugException newDebugException(String msg) { + return new DebugException(new Status(IStatus.ERROR, PLUGIN_ID, msg)); + } + + public static MessageLogger getMessageLogger() { + return new MessageLogger() { + @Override + public String getPluginID() { + return PLUGIN_ID; + } + + @Override + public Plugin getPlugin() { + return plugin; + } + }; + } + + /** + * Returns the unique identifier of this plugin. + */ + public static String getUniqueIdentifier() { + return PLUGIN_ID; + } + + public static IStatus dsfRequestFailedStatus(String message, Throwable exception) { + return new Status(IStatus.ERROR, PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, message, exception); + } + + public PersistentCache getCache() { + if (cache == null) { + cache = new PersistentCache(getStateLocation().append("cached_data")); + } + return cache; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCTrace.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCTrace.java new file mode 100644 index 0000000..3bb5586 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/EDCTrace.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + * Freescale Semiconductor - Refactoring and improvements + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.service.debug.DebugTrace; + +/** + * Tracing of EDC code based on standard tracing mechanism in eclipse; + *
    see + *
    + * How do I use the Platform debug tracing facility? + */ +public class EDCTrace { + + // The various tracing options. DEBUG_TRACE is a master shut-on/off valve + public static final String DEBUG_TRACE = "/debug"; + public static final String RUN_CONTROL_TRACE = "/debug/runControl"; + public static final String STACK_TRACE = "/debug/stack"; + public static final String EXPRESSION_PARSE_TRACE = "/debug/expressionParse"; + public static final String SYMBOL_READER_TRACE = "/debug/symbolReader"; + public static final String SYMBOL_READER_VERBOSE_TRACE = "/debug/symbolReader/verbose"; + public static final String VARIABLE_VALUE_TRACE = "/debug/variableValue"; + public static final String BREAKPOINTS_TRACE = "/debug/breakpoints"; + public static final String MEMORY_TRACE = "/debug/memory"; + public static final String ACPM_TRACE = "/debug/acpm"; + public static final String PERSISTENT_CACHE_TRACE = "/debug/persistentCache"; + + // In order to minimize trace overhead when tracing is off, we check these + // "globals". They are set at plugin initialization time. Note that they do + // not preclude dynamic toggling of the trace options. Toggling would + // require dedicated GUI in any case. We would just have to have a pref + // change listener that toggles the values of these fields (note that they + // are not 'final'). + public static boolean DEBUG_TRACE_ON; + public static boolean RUN_CONTROL_TRACE_ON; + public static boolean STACK_TRACE_ON; + public static boolean EXPRESSION_PARSE_TRACE_ON; + public static boolean SYMBOL_READER_TRACE_ON; + public static boolean SYMBOL_READER_VERBOSE_TRACE_ON; + public static boolean VARIABLE_VALUE_TRACE_ON; + public static boolean BREAKPOINTS_TRACE_ON; + public static boolean MEMORY_TRACE_ON; + public static boolean ACPM_TRACE_ON; + public static boolean PERSISTENT_CACHE_TRACE_ON; + + /** + * Returns whether the specific tracing option is on. The answer is based on + * the real-time state of options as managed by the platform, whereas our + * XXXXX_ON static fields provide the answer based on the state of the + * options at plugin initialization time. Since we currently provide the + * user no way to toggle the options after launching Eclipse, use of this + * method is a heavy and unnecessary alternative to just checking the static + * field--thus the private visibility. + */ + private static boolean isOn(String option) { + return "true".equals(Platform.getDebugOption(EDCDebugger.PLUGIN_ID + option)); + } + + /** + * Sets up static booleans at plugin startup time for efficient trace checks. + */ + public static void init() { + if ("true".equals(Platform.getDebugOption(EDCDebugger.PLUGIN_ID + "/debug"))) { //$NON-NLS-1$//$NON-NLS-2$ + DEBUG_TRACE_ON = true; + RUN_CONTROL_TRACE_ON = isOn(EDCTrace.RUN_CONTROL_TRACE); + STACK_TRACE_ON = isOn(EDCTrace.STACK_TRACE); + EXPRESSION_PARSE_TRACE_ON = isOn(EDCTrace.EXPRESSION_PARSE_TRACE); + SYMBOL_READER_TRACE_ON = isOn(EDCTrace.SYMBOL_READER_TRACE); + SYMBOL_READER_VERBOSE_TRACE_ON = SYMBOL_READER_TRACE_ON && isOn(EDCTrace.SYMBOL_READER_VERBOSE_TRACE); + VARIABLE_VALUE_TRACE_ON = isOn(EDCTrace.VARIABLE_VALUE_TRACE); + BREAKPOINTS_TRACE_ON = isOn(EDCTrace.BREAKPOINTS_TRACE); + MEMORY_TRACE_ON = isOn(EDCTrace.MEMORY_TRACE); + ACPM_TRACE_ON = isOn(EDCTrace.ACPM_TRACE); + PERSISTENT_CACHE_TRACE_ON = isOn(EDCTrace.PERSISTENT_CACHE_TRACE); + } + } + + static class NullDebugTrace implements DebugTrace { + public void trace(String option, String message) {} + public void trace(String option, String message, Throwable error) {} + public void traceDumpStack(String option) {} + public void traceEntry(String option) {} + public void traceEntry(String option, Object methodArgument) {} + public void traceEntry(String option, Object[] methodArguments) {} + public void traceExit(String option) {} + public void traceExit(String option, Object result) {} + }; + + private static DebugTrace sTrace; + + public static String fixArg(Object argument) { + if (argument == null || sTrace instanceof NullDebugTrace) + return null; + return argument.toString().replaceAll("\\{", "[").replaceAll("\\}", "]"); + } + + public static String[] fixArgs(Object[] arguments) { + if (arguments == null || sTrace instanceof NullDebugTrace) + return null; + String[] args = new String[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + args[i] = fixArg(arguments[i]); + } + return args; + } + + public static DebugTrace getTrace() { + if (sTrace == null) { + EDCDebugger activator = EDCDebugger.getDefault(); + if (activator != null) { + sTrace = activator.getTrace(); + } + else + sTrace = new NullDebugTrace(); + } + return sTrace; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ExecutablesSourceContainer.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ExecutablesSourceContainer.java new file mode 100644 index 0000000..627df24 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ExecutablesSourceContainer.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import java.io.File; +import java.util.Collection; + +import org.eclipse.cdt.debug.core.executables.Executable; +import org.eclipse.cdt.debug.core.executables.ExecutablesManager; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.debug.core.sourcelookup.ISourceContainerType; +import org.eclipse.debug.core.sourcelookup.containers.AbstractSourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; + +public class ExecutablesSourceContainer extends AbstractSourceContainer { + + public static final String TYPE_ID = EDCDebugger.getUniqueIdentifier() + ".containerType.executables"; //$NON-NLS-1$ + + public Object[] findSourceElements(String name) throws CoreException { + IPath path = PathUtils.findExistingPathIfCaseSensitive(PathUtils.createPath(name)); + // Now looking for the file in executable view. + // + // Between the SDK and target, the exact directory and file capitalization may differ. + // + // Inject required initial slash so we can confidently use String#endsWith() without + // matching, e.g. "/path/to/program.exe" with "ram.exe". + // + String slashAndLowerFileName = File.separator + path.lastSegment().toLowerCase(); + String absoluteLowerPath = path.makeAbsolute().toOSString().toLowerCase(); + + // Note the 'wait=true' argument. We can wait now that this job does not lock the UI. + Collection executables = ExecutablesManager.getExecutablesManager().getExecutables(true); + for (Executable e : executables) { + String p = e.getPath().makeAbsolute().toOSString().toLowerCase(); + if (p.endsWith(absoluteLowerPath) || // stricter match first + p.endsWith(slashAndLowerFileName)) // then only check by name + { + return new LocalFileStorage[] { new LocalFileStorage(e.getPath().toFile()) }; + } + } + return new Object[]{}; + } + + public String getName() { + return "Executables"; + } + + public ISourceContainerType getType() { + return getSourceContainerType( TYPE_ID ); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/FileStreamBuffer.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/FileStreamBuffer.java new file mode 100644 index 0000000..9c76fd5 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/FileStreamBuffer.java @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.BufferUnderflowException; +import java.nio.ByteOrder; + +import org.eclipse.cdt.debug.edc.IStreamBuffer; + +/** + * This implementation of IStreamBuffer works on file content. + */ +public class FileStreamBuffer extends StreamBufferBase { + private final boolean DEBUG = false; + private RandomAccessFile file; + + + /** + * Wrap in-memory content. + * @param content + * @param order + */ + public FileStreamBuffer(RandomAccessFile file, ByteOrder order) throws IOException { + super(order, 0, file.length()); + this.file = file; + } + public FileStreamBuffer(RandomAccessFile file, ByteOrder order, long position, long size) { + super(order, position, size); + this.file = file; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.StreamBufferBase#fetchPage(byte[], int, int) + */ + @Override + protected void fetchPage(byte[] buffer, long sourceOffset, int count) { + try { + if (DEBUG) System.out.print("Reading "+ sourceOffset + " x "+ count + "... "); + file.seek(sourceOffset); + file.read(buffer, 0, count); + if (DEBUG) System.out.println("done"); + } catch (IOException e) { + BufferUnderflowException be = new BufferUnderflowException(); + be.initCause(e); + throw be; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.StreamBufferBase#createSubBuffer(long, long) + */ + @Override + protected IStreamBuffer createSubBuffer(long offset, long size) { + return new FileStreamBuffer(file, order, offset, size); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/HostOS.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/HostOS.java new file mode 100644 index 0000000..3d3d4f9 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/HostOS.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import java.io.File; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + + +/** + * Utilities used for portability between hosts. + */ +public class HostOS { + /** Is the host Windows? */ + public static boolean IS_WIN32 = File.separatorChar == '\\'; + /** Is the host some Unix variant? */ + public static boolean IS_UNIX = File.separatorChar == '/'; + /** Executable file extension */ + public static final String EXE_EXT = IS_WIN32 ? ".exe" : ""; + + /** + * Ensure that the executable name mentioned is canonical for the machine. + * This only affects Windows, currently, ensuring that an ".exe" is attached. + * @param executablePath + * @return updated path + */ + public static String canonicalizeExecutableName(String executable) { + if (IS_WIN32) { + IPath executablePath = new Path(executable); + String ext = executablePath.getFileExtension(); + if (ext == null) { + executable += EXE_EXT; + } + } + return executable; + } + + /** + * Scan the PATH variable and see if the given binary is visible on + * the PATH that will be used at runtime (with the default environment and overrides). + * @param pathValue the expected Path + * @param program + * @return IPath if program is on PATH, else null + */ + public static IPath findProgramOnPath(String program, String pathValue) { + + // be sure proper path/extension are present + program = HostOS.canonicalizeExecutableName(program); + + IPath path = null; + + IPath[] pathEntries = PathUtils.getPathEntries(pathValue); + for (IPath pathEntry : pathEntries) { + IPath testPath = pathEntry.append(program); + if (testPath.toFile().exists()) { + path = testPath; + break; + } + } + + return path; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/IMemoryAccess.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/IMemoryAccess.java new file mode 100644 index 0000000..658ca69 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/IMemoryAccess.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal; + +import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.debug.core.model.MemoryByte; + +/** + * @author Administrator + * @since 2.0 + * + */ +public interface IMemoryAccess { + + /** + * Retrieves the memory address values as shown at the Hex Pane Memory + * View. Every cell has 4 bytes. + * @param contextId string representing the context of for the memory + * @param memoryAddress The memory address to get its values. + * @param length the amount of memory to retrieve + * @return An array of memory bytes starting from the memory address given. + * @throws Exception Any exception is propagated to the caller. + */ + public MemoryByte[] getMemoryValues(final DsfSession session, + final IEDCExecutionDMC exe_dmc, final String memoryAddress, + final int length) + throws Exception; + + /** + * Changes the memory value for the given memory address for the length of the array + * @param contextId string representing the context of for the memory + * @param memoryAddress The memory address which content will be changed. + * @param newMemoryValue The new value of the memory address content. + * @return True if the change was successful. False if the value couldn't be changed. + * @throws Exception Any exception will be propagated to the caller. + */ + public boolean changeMemoryValue(final DsfSession session, + final IEDCExecutionDMC exe_dmc, final String memoryAddress, + final byte[] newMemoryValue) + throws Exception; +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/MemoryStreamBuffer.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/MemoryStreamBuffer.java new file mode 100644 index 0000000..9c581ec --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/MemoryStreamBuffer.java @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal; + +import java.nio.ByteOrder; + +import org.eclipse.cdt.debug.edc.IStreamBuffer; + +/** + * This implementation of IStreamBuffer works on memory content. + */ +public class MemoryStreamBuffer extends StreamBufferBase { + + private byte[] content; + + + /** + * Wrap in-memory content. + * @param content + * @param order + */ + public MemoryStreamBuffer(byte[] content, ByteOrder order) { + super(order, 0, content.length); + this.content = content; + } + public MemoryStreamBuffer(byte[] content, ByteOrder order, long position, long size) { + super(order, position, size); + this.content = content; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.StreamBufferBase#fetchPage(byte[], int, int) + */ + @Override + protected void fetchPage(byte[] buffer, long sourceOffset, int count) { + System.arraycopy(content, (int) sourceOffset, buffer, 0, count); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.StreamBufferBase#createSubBuffer(long, long) + */ + @Override + protected IStreamBuffer createSubBuffer(long offset, long size) { + return new MemoryStreamBuffer(content, order, offset, size); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/NumberFormatUtils.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/NumberFormatUtils.java new file mode 100644 index 0000000..17ff813 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/NumberFormatUtils.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; + +public class NumberFormatUtils { + + private static final String HEX_PREFIX = "0x"; //$NON-NLS-1$ + + private static final String OCTAL_PREFIX = "0"; //$NON-NLS-1$ + + private static final String BINARY_PREFIX = "0b"; //$NON-NLS-1$ + + private static final String SINGLE_QUOTE = "'"; //$NON-NLS-1$ + + private static final String DECIMAL_SUFFIX = " (Decimal)"; //$NON-NLS-1$ + + static public String toHexString(Number number) { + String str = null; + if (number instanceof Integer) + str = Integer.toHexString((Integer) number); + else if (number instanceof Long) + str = Long.toHexString((Long) number); + else if (number instanceof BigInteger) + str = ((BigInteger) number).toString(16); + else if (number instanceof Float) + str = Float.toHexString((Float) number); + else if (number instanceof Double) + str = Double.toHexString((Double) number); + if (str != null && !str.startsWith(HEX_PREFIX)) + return HEX_PREFIX + str; + return str; + } + + static public String toOctalString(Number number) { + String str = null; + if (number instanceof Integer) + str = Integer.toOctalString((Integer) number); + else if (number instanceof Long) + str = Long.toOctalString((Long) number); + else if (number instanceof BigInteger) + str = ((BigInteger) number).toString(8); + if (str != null && !str.startsWith(OCTAL_PREFIX)) + str = OCTAL_PREFIX + str; + if (str == null && (number instanceof Float || number instanceof Double)) + str = number.toString() + DECIMAL_SUFFIX; + return str; + } + + static public String asBinary(Number number) { + String str = null; + if (number instanceof Integer) + str = Integer.toBinaryString((Integer) number); + else if (number instanceof Long) + str = Long.toBinaryString((Long) number); + else if (number instanceof BigInteger) + str = ((BigInteger) number).toString(2); + if (str != null && !str.startsWith(BINARY_PREFIX)) + str = BINARY_PREFIX + str; + if (str == null && (number instanceof Float || number instanceof Double)) + str = number.toString() + DECIMAL_SUFFIX; + return str; + } + + static public String toCharString(Number number, IType valueType) { + int intValue = number.intValue(); + String charVal = null; + if (intValue < 128) { + switch ((char) intValue) { + case 0: + charVal = ("\\0"); //$NON-NLS-1$ + break; + case '\b': + charVal = ("\\b"); //$NON-NLS-1$ + break; + case '\f': + charVal = ("\\f"); //$NON-NLS-1$ + break; + case '\n': + charVal = ("\\n"); //$NON-NLS-1$ + break; + case '\r': + charVal = ("\\r"); //$NON-NLS-1$ + break; + case '\t': + charVal = ("\\t"); //$NON-NLS-1$ + break; + case '\'': + charVal = ("\\'"); //$NON-NLS-1$ + break; + case '\"': + charVal = ("\\\""); //$NON-NLS-1$ + break; + case '\\': + charVal = ("\\\\"); //$NON-NLS-1$ + break; + case 0xb: + charVal = ("\\v"); //$NON-NLS-1$ + break; + } + } + + // Show the numeric value (decimal for char, since it's short, and hex for wchar_t) + // then the character value. Note that at the system font may not be able to show + // all characters in the variables/expressions view, which is why we show the + // more meaningful numeric value before the possibly "boxy" character representation. + // + // Also, we assume wchar_t == Unicode. + boolean isWchart = (valueType instanceof ICPPBasicType + && ((ICPPBasicType) valueType).getBaseType() == ICPPBasicType.t_wchar_t) + || valueType.getName().equals("wchar_t"); //$NON-NLS-1$ + + StringBuilder info = new StringBuilder(); + + if (isWchart) { + info.append(HEX_PREFIX); + if (valueType.getByteSize() == 2) + info.append(String.format("%04X", intValue)); //$NON-NLS-1$ + else + info.append(String.format("%08X", intValue)); //$NON-NLS-1$ + info.append(" (L"); //$NON-NLS-1$ + } else { + info.append("" + intValue); //$NON-NLS-1$ + info.append(" ("); //$NON-NLS-1$ + } + + if (charVal == null) { + // treat chars as unsigned for getting the char representation + String fmt = "\\U%08X"; //$NON-NLS-1$ + switch (valueType.getByteSize()) { + case 1: + fmt = "\\%03o"; //$NON-NLS-1$ + intValue &= 0xff; break; + case 2: + fmt = "\\u%04X"; //$NON-NLS-1$ + intValue &= 0xffff; break; + case 4: + // note: may still be too large to be legal + fmt = "\\U%08X"; //$NON-NLS-1$ + intValue &= 0xffffffff; break; + } + + boolean gotRepr = false; + try { + if (!Character.isISOControl(intValue)) { + char[] chars = Character.toChars(intValue); + info.append(asStringQuoted(new String(chars))); + gotRepr = true; + } + } catch (IllegalArgumentException e) { + // some character values are negative or outside the UCS range; + // these throw exceptions + } + if (!gotRepr) { + info.append(asStringQuoted(String.format(fmt, intValue))); + } + } else { + info.append(asStringQuoted(charVal)); + } + info.append(')'); + + return info.toString(); + } + + static public String asStringQuoted(String val) { + StringBuilder sb = new StringBuilder(SINGLE_QUOTE); + sb.append(val); + sb.append(SINGLE_QUOTE); + return sb.toString(); + } + + static public BigInteger parseIntegerByFormat(String expressionValue, String formatId) { + int radix = 10; + if (IFormattedValues.HEX_FORMAT.equals(formatId)) { + if (expressionValue.startsWith(HEX_PREFIX)) + expressionValue = expressionValue.substring(HEX_PREFIX.length()); + radix = 16; + } else if (IFormattedValues.OCTAL_FORMAT.equals(formatId)) { + if (expressionValue.startsWith(OCTAL_PREFIX)) + expressionValue = expressionValue.substring(OCTAL_PREFIX.length()); + radix = 8; + } else if (IFormattedValues.BINARY_FORMAT.equals(formatId)) { + if (expressionValue.startsWith(BINARY_PREFIX)) + expressionValue = expressionValue.substring(BINARY_PREFIX.length()); + radix = 2; + } else if (IFormattedValues.NATURAL_FORMAT.equals(formatId)) { + if (expressionValue.startsWith(BINARY_PREFIX)) { + expressionValue = expressionValue.substring(BINARY_PREFIX.length()); + radix = 2; + } else if (expressionValue.startsWith(OCTAL_PREFIX)) { + expressionValue = expressionValue.substring(OCTAL_PREFIX.length()); + radix = 8; + } else if (expressionValue.startsWith(HEX_PREFIX)) { + expressionValue = expressionValue.substring(HEX_PREFIX.length()); + radix = 16; + } + // else, decimal + } + try { + return new BigInteger(expressionValue, radix); + } catch (NumberFormatException e) { + // just return null + } + + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/PathUtils.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/PathUtils.java new file mode 100644 index 0000000..31ec0f1 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/PathUtils.java @@ -0,0 +1,273 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * These utilities handle some common portability issues when dealing with + * (absolute) paths which may be in a format intended for another operating system. + * It also handles shortcomings in the org.eclipse.core.runtime.Path + * implementation, which is not able to construct a meaningful path from + * a Win32 path outside of Windows. + */ +public class PathUtils { + + /** + * Convert a variable constructed blindly for a Win32 environment into + * Unix-like syntax. This is typically used for PATH or lists + * of paths where ';' is the entry separator and '\' is the + * path component separator. + *

    + * NOTE: we assume that the entries in the + * path list are already legal Unix paths, but just with the + * wrong slash. + * @param env + * @return converted string + */ + public static String convertPathListToUnix(String env) { + if (env == null) return null; + env = env.replaceAll(";", ":"); // entry separators + env = env.replaceAll("\\\\", "/"); // path separators + return env; + } + + /** + * Convert a path constructed blindly for a Win32 environment into + * Unix-like syntax.

    + * NOTE: we assume that the path is already a legal Unix path, + * but just with the wrong slash. + * @param file + * @return converted string + */ + public static String convertPathToUnix(String file) { + if (file == null) return null; + // handle Windows slashes and canonicalize + file = file.replaceAll("\\\\", "/"); + return file; + } + + /** + * Convert a path which may be in Windows or Unix format to Windows format. + * NOTE: we assume that the path is already a legal path, + * but just with the wrong slash. + * @param file + * @return converted string + */ + public static String convertPathToWindows(String file) { + if (file == null) return null; + file = file.replaceAll("/", "\\\\"); + return file; + } + + /** + * Convert a path which may be in Windows or Unix format to Windows format. + * NOTE: we assume that the path is already a legal path, + * but just with the wrong slash. + * @param file + * @return converted string + */ + public static String convertPathToWindows(IPath path) { + return convertPathToWindows(path.toPortableString()); + } + + /** + * Convert a path which may be in the opposite slash format to the local slash format. + * NOTE: we assume that the path is already a legal path, + * but just with the wrong slash. + * @param file + * @return converted string + */ + public static String convertPathToNative(String path) { + if (path == null) return null; + if (HostOS.IS_UNIX) + return path.replaceAll("\\\\", "/"); + else + return path.replaceAll("/", "\\\\"); + } + + /** + * Create an IPath from a string which may be a Win32 path.

    + *

    + * ("new Path(...)" won't work in Unix when using a Win32 path: the backslash + * separator and the device notation are completely munged.) + * @param path + * @return converted string + */ + public static IPath createPath(String path) { + if (path == null) return null; + boolean hasWindowsSlashes = path.contains("\\"); + if (hasWindowsSlashes) { + // handle Windows slashes and canonicalize + path = path.replaceAll("\\\\", "/"); + } + + // also check for device or UNC + int idx = path.indexOf(":"); + if (idx > 0) { + String device = path.substring(0, idx + 1); + path = path.substring(idx + 1); + return new Path(path).setDevice(device); + } + else { + // Cygwin or UNC path + if (path.startsWith("//") && !hasWindowsSlashes) { + String network; + idx = path.indexOf("/", 2); + if (idx > 0) { + network = path.substring(0, idx); + path = path.substring(idx); + } else { + network = path; + path = ""; + } + return new Path(network, path).makeUNC(true); + } + } + + // fallthrough + return new Path(path); + } + + /** + * Get the PATH entries from the given path environment value or the + * system environment. + * @param pathValue the expected PATH/Path value, or null for the system value + * @return array of IPath, never null + */ + public static IPath[] getPathEntries(String pathValue) { + String pathVar = null; + if (pathValue != null) { + pathVar = pathValue; + } else { + if (HostOS.IS_WIN32) { + // canonical name, plus fallback below + pathVar = System.getenv("Path"); //$NON-NLS-1$ + } + if (pathVar == null) { + pathVar = System.getenv("PATH"); //$NON-NLS-1$ + } + } + + if (pathVar == null) + pathVar = ""; + + String pathSeparator = System.getProperty("path.separator"); + String[] pathEntries = pathVar.split(pathSeparator); + IPath[] paths = new IPath[pathEntries.length]; + for (int i = 0; i < pathEntries.length; i++) { + paths[i] = new Path(pathEntries[i]); + } + return paths; + } + + /** + * If the filesystem is case sensitive, locate the file on the filesystem + * on the given path, by ignoring case sensitivity differences. + * This is needed on case-preserving but not case-insensitive filesystems. + * @param path + * @return path pointing to existing file (possibly with different case in components) or + * original path if there is no match + */ + public static IPath findExistingPathIfCaseSensitive(IPath path) { + // case is insensitive already + if (HostOS.IS_WIN32) + return path; + + if (path == null || !path.isAbsolute()) + return path; + + File pathFile = path.toFile(); + if (pathFile.exists()) { + try { + return new Path(pathFile.getCanonicalPath()); + } catch (IOException e) { + // should not happen + return path; + } + } + + + // start with the assumption that the path is mostly correct except for the + // last N segments. + IPath goodPath = Path.ROOT; + if (path.getDevice() != null) + goodPath = goodPath.setDevice(path.getDevice()); + + // if bad drive or no root (?!), just skip + if (!goodPath.toFile().exists()) + return path; + + for (int seg = path.segmentCount(); seg > 0; seg--) { + final IPath prefix = path.uptoSegment(seg - 1); + + if (prefix.toFile().exists()) { + goodPath = prefix; + break; + } + } + + StringBuilder builder = new StringBuilder(); + + builder.append(goodPath.addTrailingSeparator().toOSString()); + + boolean failedLookup = false; + + for (int seg = goodPath.segmentCount(); seg < path.segmentCount(); seg++) { + final String segment = path.segment(seg); + + final String[] matches = { segment }; + + if (!failedLookup) { + File dir = new File(builder.toString()); + if (!new File(dir, matches[0]).exists()) { + // component has wrong case; find the first one matching case-insensitively + String[] names = dir.list(new FilenameFilter() { + + public boolean accept(File dir, String name) { + if (name.equalsIgnoreCase(segment)) { + matches[0] = name; + return true; + } + return false; + } + }); + + if (names.length == 0) { + // no matches! the rest of the path won't match either + failedLookup = true; + } + } + } + builder.append(matches[0]); + builder.append('/'); + } + + if (!path.hasTrailingSeparator() && builder.length() > 0 && builder.charAt(builder.length() - 1) == '/') { + builder.setLength(builder.length() - 1); + } + return new Path(builder.toString()); + } + + public static boolean isCaseSensitive() { + // Is the underlying file system case sensitive? + // This can actually be complex to determine and can even vary by volume + // but this is an OK general test for now. + if (HostOS.IS_UNIX) + return true; + return false; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/PersistentCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/PersistentCache.java new file mode 100644 index 0000000..4092cb6 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/PersistentCache.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IPath; + +public class PersistentCache { + + private class CacheEntry { + + private String identifier; + private long freshness; + private Serializable data; + private IPath location; + + public CacheEntry(String identifier, Serializable data, long freshness) { + this.identifier = identifier; + this.freshness = freshness; + this.data = data; + this.location = getDefaultLocation().append(Integer.toString(identifier.hashCode())).addFileExtension("txt");; + } + + public CacheEntry(ObjectInputStream ois) throws Exception { + this.identifier = (String) ois.readObject(); + this.freshness = (Long) ois.readObject(); + this.data = (Serializable) ois.readObject(); + this.location = getDefaultLocation().append(Integer.toString(identifier.hashCode())).addFileExtension("txt");; + } + + public IPath getLocation() { + return location; + } + + @SuppressWarnings("unchecked") + private T getData(Class expectedClass) { + if (expectedClass.isInstance(data)) + return (T) data; + else + return null; + } + + private long getFreshness() { + return freshness; + } + + private void flush() throws Exception { + File cacheFile = getLocation().toFile(); + if (!cacheFile.exists()) + { + cacheFile.getParentFile().mkdirs(); + cacheFile.createNewFile(); + } + FileOutputStream fos = new FileOutputStream(cacheFile); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(identifier); + oos.writeObject(freshness); + oos.writeObject(data); + fos.close(); + if (EDCTrace.PERSISTENT_CACHE_TRACE_ON) { + EDCTrace.getTrace().trace(null, "Cache flush: " + identifier + " data: " + data); + } + } + + public void delete() { + File cacheFile = getLocation().toFile(); + if (cacheFile.exists()) + { + cacheFile.delete(); + } + } + + } + + private Map caches = Collections.synchronizedMap(new HashMap()); + private IPath defaultLocation; + + public PersistentCache(IPath defaultLocation) { + this.defaultLocation = defaultLocation; + } + + public CacheEntry getCache(String identifier){ + CacheEntry result = caches.get(identifier); + return result; + } + + public boolean hasCachedData(String cacheIdentifier) { + return caches.containsKey(cacheIdentifier); + } + + synchronized public T getCachedData(String cacheIdentifier, T expectedClass, long freshness) { + @SuppressWarnings("unchecked") + T result = (T) getCachedData(cacheIdentifier, expectedClass.getClass(), freshness); + if (result == null) + { + putCachedData(cacheIdentifier, (Serializable) expectedClass, freshness); + result = expectedClass; + } + return result; + } + + synchronized public T getCachedData(String cacheIdentifier, Class expectedClass, long freshness) { + // freshness = 0; + CacheEntry cache = caches.get(cacheIdentifier); + + if (cache == null) + { + cache = loadCachedData(getDefaultLocation(), cacheIdentifier); + if (cache != null) + caches.put(cacheIdentifier, cache); + } + + if (cache != null) + { + long cachedFreshness = cache.getFreshness(); + T result = cache.getData(expectedClass); + if (cachedFreshness == freshness && result != null) + { + if (EDCTrace.PERSISTENT_CACHE_TRACE_ON) { + EDCTrace.getTrace().trace(null, "Cache get data: " + cacheIdentifier + " data: " + result); + } + return result; + } + else + { + if (EDCTrace.PERSISTENT_CACHE_TRACE_ON) { + EDCTrace.getTrace().trace(null, "Stale data. cachedFreshness: " + cachedFreshness + " freshness: " + result + " cache: " + cache); + } + caches.remove(cache); + cache.delete(); + } + } + + return null; + } + + private CacheEntry loadCachedData(IPath location, String cacheIdentifier) { + IPath flushPath = location.append(Integer.toString(cacheIdentifier.hashCode())).addFileExtension("txt"); + + if (flushPath.toFile().exists()) + { + try { + final ClassLoader classLoader = EDCDebugger.getDefault().getClass().getClassLoader(); + FileInputStream fis = new FileInputStream(flushPath.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) { + + @Override + protected Class resolveClass(ObjectStreamClass desc) + throws IOException, ClassNotFoundException { + String name = desc.getName(); + try { + return classLoader.loadClass(name); + } catch (ClassNotFoundException e) { + return super.resolveClass(desc); + } + }}; + return new CacheEntry(ois); + } catch (Exception e) {} + } + + return null; + } + + public void putCachedData(String cacheIdentifier, Serializable data, long freshness) + { + CacheEntry cache = new CacheEntry(cacheIdentifier, data, freshness); + caches.put(cacheIdentifier, cache); + if (EDCTrace.PERSISTENT_CACHE_TRACE_ON) { + EDCTrace.getTrace().trace(null, "Cache put data: " + cacheIdentifier + " data: " + data); + } + } + + public void flushAll() { + Collection allCaches = caches.values(); + for (CacheEntry entry : allCaches) { + try { + entry.flush(); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logException(e); + } + } + caches.clear(); + } + + public IPath getDefaultLocation() { + return defaultLocation; + } + + public void setDefaultLocation(IPath defaultLocation) { + this.defaultLocation = defaultLocation; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/StreamBufferBase.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/StreamBufferBase.java new file mode 100644 index 0000000..e12852d --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/StreamBufferBase.java @@ -0,0 +1,251 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal; + +import java.nio.BufferUnderflowException; +import java.nio.ByteOrder; + +import org.eclipse.cdt.debug.edc.IStreamBuffer; + +/** + * + */ +public abstract class StreamBufferBase implements IStreamBuffer { + /* must be a power of 2 */ + public static final int BUFFER_SIZE = 4096; + + protected ByteOrder order; + + // absolute + private long position; + // absolute + private long sourceCapacity; + + private byte[] buffer; + // absolute source position in buffer[0] + private long sourceOffset; + // absolute source position in buffer[buffer.length] + private long sourceLimit; + + // offset from source to position + private final long baseOffset; + + /** + * Create a buffer over some source content + * @param order native byte order of content + * @param baseOffset base offset from source to this buffer + * @param capacity total size of the source (from baseOffset) + */ + public StreamBufferBase(ByteOrder order, long baseOffset, long capacity) { + this.order = order; + this.baseOffset = baseOffset; + this.position = 0; + this.sourceCapacity = capacity; + + this.buffer = new byte[BUFFER_SIZE]; + this.sourceOffset = 0; + this.sourceLimit = 0; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return getClass().getSimpleName() + " pos="+position() + " of "+ capacity() + " base="+ baseOffset; //$NON-NLS-N$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * Fetch a page of content from the buffer. + * @param buffer the buffer + * @param sourceOffset absolute offset in original content + * @throws BufferUnderflowException + */ + protected abstract void fetchPage(byte[] buffer, long sourceOffset, int count); + + protected abstract IStreamBuffer createSubBuffer(long offset, long size); + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#wrapSubsection(int) + */ + public IStreamBuffer wrapSubsection(long size) { + long availableSize = capacity() - position(); + if (availableSize < size) + size = availableSize; + return createSubBuffer(position() + baseOffset, size); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#capacity() + */ + public long capacity() { + return sourceCapacity; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#hasRemaining() + */ + public boolean hasRemaining() { + return position < sourceCapacity; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#remaining() + */ + public long remaining() { + return sourceCapacity - position; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#position() + */ + public long position() { + return position; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#position(int) + */ + public IStreamBuffer position(long newPosition) { + if (newPosition < 0 || newPosition > sourceCapacity) + throw new IllegalArgumentException(newPosition + " not in 0.."+ sourceCapacity); + + this.position = newPosition; + return this; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#get(byte[], int, int) + */ + public IStreamBuffer get(byte[] dst, int offset, int length) { + // read page-by-page if possible + while (length > 0) { + if (needFetch()) + refetch(); + + int left = (int) Math.min(sourceLimit - position, length); + if (left > 0) { + System.arraycopy(buffer, (int) (position - sourceOffset), dst, offset, left); + offset += left; + position += left; + length -= left; + } else { + break; + } + } + return this; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#get(byte[]) + */ + public IStreamBuffer get(byte[] dst) { + return get(dst, 0, dst.length); + } + + /** + * Fill memory buffer from source + */ + protected void refetch() { + long newSourceOffset = position - (position & buffer.length - 1); + if (newSourceOffset < 0) + throw new BufferUnderflowException(); + if (newSourceOffset >= sourceCapacity) + throw new BufferUnderflowException(); + + int toFetch = (int) Math.min(sourceCapacity - newSourceOffset, buffer.length); + fetchPage(buffer, newSourceOffset + baseOffset, toFetch); + sourceOffset = newSourceOffset; + sourceLimit = sourceOffset + toFetch; + } + + protected final boolean needFetch() { + return (position < sourceOffset || position >= sourceLimit); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#get() + */ + public byte get() { + if (needFetch()) + refetch(); + + if (position < sourceCapacity) + return buffer[(int)((position++) - sourceOffset)]; + else + throw new BufferUnderflowException(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#getChar() + */ + public char getChar() { + return (char) getShort(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#getShort() + */ + public short getShort() { + int a = get() & 0xff; + int b = get() & 0xff; + if (order == ByteOrder.LITTLE_ENDIAN) + return (short) (a | (b << 8)); + else + return (short) (b | (a << 8)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#getInt() + */ + public int getInt() { + int a = getShort() & 0xffff; + int b = getShort() & 0xffff; + if (order == ByteOrder.LITTLE_ENDIAN) + return a | (b << 16); + else + return b | (a << 16); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IStreamBuffer#getLong() + */ + public long getLong() { + long a = getInt(); + long b = getInt(); + if (order == ByteOrder.LITTLE_ENDIAN) + return a | (b << 32); + else + return b | (a << 32); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.IStreamBuffer#skip(long) + */ + public IStreamBuffer skip(long amount) { + return position(position() + amount); + } + + public ByteOrder getOrder() { + return order; + } + public void setOrder(ByteOrder order) { + this.order = order; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/TCFServiceManager.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/TCFServiceManager.java new file mode 100644 index 0000000..d29e774 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/TCFServiceManager.java @@ -0,0 +1,618 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.cdt.debug.edc.ITCFAgentLauncher; +import org.eclipse.cdt.debug.edc.ITCFConnectionListener; +import org.eclipse.cdt.debug.edc.ITCFServiceManager; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Platform; +import org.eclipse.tm.tcf.core.AbstractPeer; +import org.eclipse.tm.tcf.protocol.IChannel; +import org.eclipse.tm.tcf.protocol.IChannel.IChannelListener; +import org.eclipse.tm.tcf.protocol.IPeer; +import org.eclipse.tm.tcf.protocol.IService; +import org.eclipse.tm.tcf.protocol.Protocol; +import org.eclipse.tm.tcf.services.ILocator; +import org.eclipse.tm.tcf.util.TCFTask; + +/** + * Utility class that provides access to TCF agents and services. It abstracts + * out the details of which agent provides the services, launching the agent if + * necessary, etc. + */ +public class TCFServiceManager implements ITCFServiceManager { + + /** + * The IP addresses of the local machine. Typically, there's at least two + * (the loopback address is one of them), but there can be more if there are + * multiple network adapters (physical or virtual). + * + *

    + * TODO: if you look at the TCF Java reference implementation, it updates + * its list every so often, as a system's network configuration can change + * during the life of a process. We should probably do that, too, though + * it's clearly an edge case. + */ + private static List localIPAddresses; + + private List tcfAgentLaunchers; + + private static final String EXTENSION_POINT_NAME = "tcfAgentLauncher"; + + private List launchedtcfAgentLaunchers; + + private ListenerList peerChannelListeners = new ListenerList(); + + static { + // Record local host IP addresses--not only numeric IP addresses but + // also hostnames if available. + try { + localIPAddresses = getLocalIPAddresses(); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError("Problem getting local IP addresses", e); //$NON-NLS-1$ + } + } + + public TCFServiceManager() { + // load TCFAgentLauncher extensions + tcfAgentLaunchers = new ArrayList(); + launchedtcfAgentLaunchers = new ArrayList(); + + IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EDCDebugger.PLUGIN_ID, EXTENSION_POINT_NAME); + IExtension[] extensions = extensionPoint.getExtensions(); + + for (IExtension extension : extensions) { + IConfigurationElement[] elements = extension.getConfigurationElements(); + IConfigurationElement element = elements[0]; + + boolean failed = false; + CoreException exc = null; + try { + Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$ + if (extObject instanceof ITCFAgentLauncher) { + tcfAgentLaunchers.add((ITCFAgentLauncher) extObject); + } else { + failed = true; + } + } catch (CoreException e) { + failed = true; + exc = e; + } + + if (failed) { + EDCDebugger.getMessageLogger().logError( + "Unable to load " + EXTENSION_POINT_NAME + " extension from " + extension.getContributor().getName(), exc); + } + } + + } + + /** + * Returns true if all the attributes in [attributesToMatch] appear + * identically in [attributes] (keys and respective values). Basically, is + * [attributesToMatch] a subset of [attributes]? + */ + public static boolean matchesAllAttributes(Map attributes, Map attributesToMatch) { + if (attributesToMatch.isEmpty()) + return false; + + for (String key : attributesToMatch.keySet()) { + if (!attributes.containsKey(key)) { + return false; + } + if (!attributesToMatch.get(key).equals(attributes.get(key))) { + return false; + } + } + + return true; + } + + /** + * Check if the given TCF peer is the LocalPeer defined in TCF. As that + * LocalPeer is not public, we check by its internal ID. It may not be + * forward compatible, but is there a better way ? + * + * @param p + * @return + */ + public static boolean isInternalLocalPeer(IPeer p) { + assert Protocol.isDispatchThread(); + return p.getID().equals("TCFLocal"); + } + + /** + * Find any registered TCF agent-launchers that will (should) produce a peer + * with the given attributes and that exposes the given service. The + * agent-launchers are registered through an EDC extension point. + * + * @param serviceName + * the required service + * @param attributesToMatch + * the required peer attributes + * @return zero or more agent-launchers that fit the bill + */ + public ITCFAgentLauncher[] findSuitableAgentLaunchers(final String serviceName, final Map attributesToMatch, boolean localAgentsOnly) { + List registeredPeerLabels = new ArrayList(); + List registeredAgents = new ArrayList(); + + // Find registered agents that meets our need and which can be launched. + + for (ITCFAgentLauncher descriptor : tcfAgentLaunchers) { + if (descriptor.getServiceNames().contains(serviceName) + && matchesAllAttributes(descriptor.getPeerAttributes(), attributesToMatch) + && descriptor.isLaunchable()) { + registeredPeerLabels.add(descriptor.getPeerName() + " (local registered non-started)"); + registeredAgents.add(descriptor); + } + } + return registeredAgents.toArray(new ITCFAgentLauncher[registeredAgents.size()]); + } + + public IPeer[] getRunningPeers(final String serviceName, final Map attributesToMatch, final boolean localAgentsOnly) throws CoreException { + // first find running peers with matching attributes + final List runningCandidates1 = new ArrayList(); + + Protocol.invokeAndWait(new Runnable() { + public void run() { + // This collection is only changed in TCF dispatcher thread. + // So don't worry about race condition. + Collection peers = Protocol.getLocator().getPeers().values(); + + for (IPeer p : peers) { + // Don't bother with internal local peer. + if (isInternalLocalPeer(p)) + continue; + + if (matchesAllAttributes(p.getAttributes(), attributesToMatch)) { + runningCandidates1.add(p); + } + } + } + }); + + // Now search the running candidates for the one that offers the + // required service. + + final List runningCandidates2 = new ArrayList(); + final List runningLocalAgentPorts = new ArrayList(); + + for (final IPeer peer : runningCandidates1) { + + // wait up to 3 seconds for the asynchronous task. + TCFTask task = new TCFTask(3000) { + public void run() { + final boolean isLocalAgent = isInLocalAgent(peer); + + /* + * If host has multiple IP addresses (e.g. 127.0.0.1 & + * 192.168.0.5), a local agent instance may be running on + * each of the addresses (see AgentServerTCP for more) but + * listening on the same port. In such case, we don't want + * to ask user to choose between those for local debug (it's + * annoying). So we'll just use first of them for local + * debug. Also note that different types of agents should + * not listen to the same port. + */ + if (isLocalAgent) { + String port = peer.getAttributes().get(IPeer.ATTR_IP_PORT); + if (port != null) { // TCP/IP peer + if (runningLocalAgentPorts.contains(port)) { + // a local agent on the same port already exists (it + // must be of the same agent type), skip this one. + done(this); + return; + } + else + runningLocalAgentPorts.add(port); + } + } + + IChannel ch = getChannelForPeer(peer); + if (ch != null) { + assert (ch.getState() == IChannel.STATE_OPEN); + if (null != ch.getRemoteService(serviceName)) { + // If the peer is on a local host, add it. If the + // peer is on another host, then whether we add + // it or not depends on the caller's wishes. + if (isLocalAgent || !localAgentsOnly) + runningCandidates2.add(peer); + } + done(this); + } else { + final IChannel channel = peer.openChannel(); + + IChannel.IChannelListener listener = new IChannel.IChannelListener() { + public void onChannelOpened() { + if (null != channel.getRemoteService(serviceName)) { + // If the peer is on this machine, add it. If the + // peer is on another machine, then whether we add + // it or not depends on the caller's wishes. + if (isLocalAgent || !localAgentsOnly) + runningCandidates2.add(peer); + } + + fireConnectionOpened(peer, channel); + + done(this); // argument is do-not-care + } + + public void onChannelClosed(Throwable error) { + fireConnectionClosed(peer, channel, error); + channel.removeChannelListener(this); + } + + public void congestionLevel(int level) { + } + }; + + channel.addChannelListener(listener); + } + } + }; + + try { + task.get(); + } catch (Exception e) { + // Failed to find nor open channel to the peer, it must be a + // stale peer (a peer that dies but not removed from the TCF + // framework. See + // rg.eclipse.tm.internal.tcf.services.local.LocatorService.refresh_timer()). + // Dispose it so that it won't get in the way + // when we try to auto-launch the agent again. + Protocol.invokeAndWait(new Runnable() { + public void run() { + try { + ((AbstractPeer) peer).dispose(); + } catch (AssertionError e) { + // we were wrong; it is disposed + } + } + }); + } + } + + return runningCandidates2.toArray(new IPeer[runningCandidates2.size()]); + } + + /** + * Determines whether the given peer is running in a local agent. We compare + * the IP address of the peer against the list of IP addresses for this + * machine (typically, there are at least two: the loopback address and the + * physical NIC). + */ + public static boolean isInLocalAgent(IPeer peer) { + assert Protocol.isDispatchThread(); + String ipHost = peer.getAttributes().get(IPeer.ATTR_IP_HOST); + return localIPAddresses.contains(ipHost); + } + + public IChannel findOrCreateChannelForPeer(final IPeer peer) throws CoreException { + IChannel channel = null; + + // First check if there is existing open channel to the peer. + // + channel = getChannelForPeer(peer); + if (channel != null) + return channel; + + // Then try to open a channel to the peer. + // + /* + * Following will cause deadlock if called in TCF dispatcher thread as + * it will wait for an TCF even to finish in the dispatcher thread. + */ + assert (!Protocol.isDispatchThread()); + + final WaitForResult waitForChannel = new WaitForResult(); + + Protocol.invokeAndWait(new Runnable() { + public void run() { + try { + final IChannel newChannel = peer.openChannel(); + newChannel.addChannelListener(new IChannelListener() { + + public void onChannelOpened() { + waitForChannel.setData(newChannel); + + fireConnectionOpened(peer, newChannel); + } + + public void onChannelClosed(Throwable error) { + waitForChannel.handleException(error); + fireConnectionClosed(peer, newChannel, error); + newChannel.removeChannelListener(this); + } + + public void congestionLevel(int level) { + } + }); + } + catch (Throwable exc) { + waitForChannel.handleException(exc); + } + } + }); + + try { + channel = waitForChannel.get(15, TimeUnit.SECONDS); + } catch (ExecutionException e) { + throw EDCDebugger.newCoreException("Failed to open channel for " + peer.getID(), e); + + } catch (Exception e) { + throw EDCDebugger.newCoreException("Time out getting open channel for peer.", e); + } + + return channel; + } + + /** + * Find existing open channel for the given peer. + * + * @param peer + * @return null if not found. + */ + public IChannel getChannelForPeer(final IPeer peer) { + + final IChannel[] ret = { null }; + + Protocol.invokeAndWait(new Runnable() { + public void run() { + String peerName = peer.getName(); + String peerID = peer.getID(); + + IChannel[] channels = Protocol.getOpenChannels(); + for (IChannel channel : channels) { + IPeer remotePeer = channel.getRemotePeer(); + if (remotePeer.getName().equals(peerName) && remotePeer.getID().equals(peerID)) { + ret[0] = channel; + return; + } + } + } + }); + + return ret[0]; + } + + /** + * Gets the service from the given TCF peer. + * + * @param peer + * TCF peer. + * @param serviceName + * the name of the service + * @return IService if the peer offers that service, null otherwise. + * @throws CoreException on error + */ + public IService getPeerService(final IPeer peer, final String serviceName) throws CoreException { + final WaitForResult waitForService = new WaitForResult(); + + final IChannel channel = findOrCreateChannelForPeer(peer); + + Protocol.invokeAndWait(new Runnable() { + public void run() { + try { + IService service = channel.getRemoteService(serviceName); + if (service == null) { + // If the service is unavailable, set a dummy service + // object so the delegating thread doesn't end up + // pointlessly waiting + service = new IService() { + public String getName() { + return null; + } + }; + } + waitForService.setData(service); + } catch (Exception e) { + waitForService.handleException(e); + } + } + }); + + try { + IService service = waitForService.get(); + // check for the dummy service object + return (service.getName() == null) ? null : service; + + } catch (Exception e) { + throw EDCDebugger.newCoreException("Fail to get TCF service [" + serviceName + "] from peer.", e); + } + } + + /** + * Invokes an agent-launcher and waits (a while) for an agent to be + * discovered that meets the given peer attributes + * + * @param descriptor + * @return + * @throws CoreException + */ + public IPeer launchAgent(final ITCFAgentLauncher descriptor, final Map peerAttrs) throws CoreException { + final WaitForResult waitForPeer = new WaitForResult() { + }; + + final ILocator.LocatorListener listener = new ILocator.LocatorListener() { + + public void peerRemoved(String id) { + } + + public void peerHeartBeat(String id) { + } + + public void peerChanged(IPeer peer) { + } + + public void peerAdded(IPeer peer) { + if (matchesAllAttributes(peer.getAttributes(), peerAttrs)) { + waitForPeer.setData(peer); + } + } + }; + + Protocol.invokeAndWait(new Runnable() { + public void run() { + // register ourselves as a listener + Protocol.getLocator().addListener(listener); + } + }); + + // launch the agent + + IPeer launchedPeer = null; + try { + // Launch the agent (if it's not already running) + try { + descriptor.launch(); + } catch (Exception e) { + throw EDCDebugger.newCoreException(MessageFormat.format("Failed to launch the TCF agent that hosts peer \"{0}\". Cause: {1}", + descriptor.getPeerName(), e.getLocalizedMessage()), e); + } + + // Wait for the Locator listener we registered above to be notified + // of the existence of the peer we're interested in + try { + launchedPeer = waitForPeer.get(); + } catch (Exception e) { + if (e.getCause() instanceof TimeoutException) { + throw EDCDebugger.newCoreException(MessageFormat.format("Timed out waiting for the launched TCF agent to make peer \"{0}\" available.", + descriptor.getPeerName()), null); + } + else { + throw EDCDebugger.newCoreException(MessageFormat.format("Error waiting for the launched TCF agent to make peer \"{0}\" available. Cause: {1}", + descriptor.getPeerName(), e.getLocalizedMessage()), e); + } + } + launchedtcfAgentLaunchers.add(descriptor); + } + finally { + Protocol.invokeAndWait(new Runnable() { + public void run() { + // unregister our listener + Protocol.getLocator().removeListener(listener); + } + }); + } + + + return launchedPeer; + } + + private static List getLocalIPAddresses() throws CoreException { + List ret = new ArrayList(); + + Enumeration e; + try { + e = NetworkInterface.getNetworkInterfaces(); + } catch (SocketException e1) { + throw EDCDebugger.newCoreException("Host is required to connect to a network but it isn't."); + } + + while (e.hasMoreElements()) { + NetworkInterface f = e.nextElement(); + Enumeration n = f.getInetAddresses(); + while (n.hasMoreElements()) { + InetAddress addr = n.nextElement(); + ret.add(addr.getHostAddress()); + } + } + + // Support agents who use hostnames instead of numeric IP addresses + try { + InetAddress localHost = InetAddress.getLocalHost(); + if (localHost != null) { + ret.add(localHost.getHostName()); + ret.add(localHost.getCanonicalHostName()); + } + } catch (UnknownHostException exc) { + EDCDebugger.getMessageLogger().logError("", exc); + } + + return ret; + } + + /** + * Shutdown. + */ + public void shutdown() { + // shutdown all agents that were launched by this manager + for (ITCFAgentLauncher desc : launchedtcfAgentLaunchers) { + try { + desc.shutdown(); + } catch (Exception e) { + } + } + launchedtcfAgentLaunchers.clear(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.ITCFServiceManager#addChannelPeerListener(org.eclipse.cdt.debug.edc.ITCFConnectionListener) + */ + public void addConnectionListener(ITCFConnectionListener listener) { + peerChannelListeners.add(listener); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.ITCFServiceManager#removeChannelPeerListener(org.eclipse.cdt.debug.edc.ITCFConnectionListener) + */ + public void removeConnectionListener(ITCFConnectionListener listener) { + peerChannelListeners.remove(listener); + } + + protected void fireConnectionOpened(final IPeer peer, final IChannel channel) { + Protocol.invokeAndWait(new Runnable() { + public void run() { + for (Object o : peerChannelListeners.getListeners()) { + try { + ((ITCFConnectionListener) o).peerChannelOpened(peer, channel); + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError("Exception thrown from connection listener", t); + } + } + } + }); + } + + protected void fireConnectionClosed(final IPeer peer, final IChannel channel, final Throwable exception) { + Protocol.invokeAndWait(new Runnable() { + public void run() { + for (Object o : peerChannelListeners.getListeners()) { + try { + ((ITCFConnectionListener) o).peerChannelClosed(peer, channel, exception); + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError("Exception thrown from connection listener", t); + } + } + } + }); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/WaitForResult.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/WaitForResult.java new file mode 100644 index 0000000..6b1dc41 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/WaitForResult.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class WaitForResult implements Future { + + public static final long DEFAULT_WAIT_TIMEOUT_SECONDS = 10; + public static final long WAIT_INTERVAL_MILLIS = 50; + private boolean running; + private boolean canceled; + private boolean done; + private V data; + private volatile Throwable exception; + + /* (non-Javadoc) + * @see java.util.concurrent.Future#cancel(boolean) + */ + public boolean cancel(boolean mayInterruptIfRunning) { + if (!running) + return false; + else { + canceled = true; + return true; + } + } + + /* (non-Javadoc) + * @see java.util.concurrent.Future#get() + */ + public V get() throws InterruptedException, ExecutionException { + try { + return get(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); + } catch (TimeoutException e) { + throw new ExecutionException(e); + } + } + + /* (non-Javadoc) + * @see java.util.concurrent.Future#get(long, java.util.concurrent.TimeUnit) + */ + public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + + long limitMillis = System.currentTimeMillis() + unit.toMillis(timeout); + running = true; + while (!canceled && (exception == null) && !hasResult()) { + Thread.sleep(WAIT_INTERVAL_MILLIS); + if (System.currentTimeMillis() > limitMillis) + throw new TimeoutException(); + } + done = true; + running = false; + + if (exception != null) + throw new ExecutionException(exception); + + return data; + } + + public void setData(V data) { + this.data = data; + } + + public V getData() { + return data; + } + + public boolean hasResult() { + return getData() != null; + } + + /* (non-Javadoc) + * @see java.util.concurrent.Future#isCancelled() + */ + public boolean isCancelled() { + return canceled; + } + + /* (non-Javadoc) + * @see java.util.concurrent.Future#isDone() + */ + public boolean isDone() { + return done; + } + + public void handleException(Throwable e) { + this.exception = e; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ZipFileUtils.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ZipFileUtils.java new file mode 100644 index 0000000..efd1a44 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/ZipFileUtils.java @@ -0,0 +1,347 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.eclipse.core.runtime.IProgressMonitor; + +import de.schlichtherle.io.ArchiveDetector; +import de.schlichtherle.io.ArchiveException; +import de.schlichtherle.io.DefaultArchiveDetector; +import de.schlichtherle.io.File; +import de.schlichtherle.io.FileInputStream; + + +/** + * Provides a convenience wrapper around TrueZip and java.util.zip for read/write access to zip archives. + * The API under java.util.zip does not provide ability to update individual entries in archives + * and hence can be cumbersome and slow to use so TrueZip is added to ease this pain. + *

    + * This wrapper also encapsulates the use of de.schlichtherle.io.File and only takes java.io.File + * as explicit arguments. When differentiating the two, only java.io.File must be explicit. + *

    + * For more information see https://truezip.dev.java.net/ + * + */ +public class ZipFileUtils { + + /** + * Delete a file from an archive + * @param fileName - File name relative path in the archive + * @param zipFile - The zip file on disk + * @param extensions - File extension of the zip format archive + * @return true on success + */ + public static boolean deleteFileFromZip(String fileName, java.io.File zipFile, String[] extensions){ + String archiveFileName = zipFile + File.separator + fileName; + + ArchiveDetector detector = getArchiveDetector(extensions); + + File file = null; + if (detector != null){ + file = new File(archiveFileName, detector); + } else { + file = new File(archiveFileName); + } + + boolean success = file.delete(); + + unmount(); + + return success; + } + + /** + * Delete a file from an archive + * @param fileName - File name relative path in the archive + * @param zipFile - File extension of the zip format archive + * @return true on success + * + * @see {@link deleteFileFromZip(String fileName, java.io.File zipFile, String[] extensions)} + */ + public static boolean deleteFileFromZip(String fileName, java.io.File zipFile) { + return deleteFileFromZip(fileName, zipFile, null); + } + + /** + * Copies a source file into a specified zip file. If the file exists it will be overwritten. + * @param src - The originating source to be copied + * @param zipFile - The destination for src + * @param extensions - File extension of the zip archive + * @return true on success + */ + public static boolean addFileToZip(java.io.File src, java.io.File zipFile, String[] extensions){ + + boolean success = false; + ArchiveDetector detector = getArchiveDetector(extensions); + + File toBeAddedFile = null; + + if (detector != null){ + toBeAddedFile = new File(src, detector); + success = toBeAddedFile.archiveCopyTo(new File(zipFile, toBeAddedFile.getName(), detector)); + } else { + toBeAddedFile = new File(src); + success = toBeAddedFile.archiveCopyTo(new File(zipFile, toBeAddedFile.getName())); + } + + unmount(); + + return success; + } + + /** + * Copies a source file into a specified zip file. If the file exists it will be overwritten. + * @param src - The originating source to be copied + * @param zipFile - The destination for src + * @return true on success + * + * @see {@link addFileToZip(java.io.File src, java.io.File zipFile, String[] extensions)} + */ + public static boolean addFileToZip(java.io.File srcFile, java.io.File zipFile) { + return addFileToZip(srcFile, zipFile, null); + } + + /** + * Copies source file(s) into a specified zip file. If the file exists it will be overwritten. + * @param src - The originating sources to be copied + * @param zipFile - The destination for src + * @param extensions - File extension of the zip archive + * @return true on success + */ + public static boolean addFilesToZip(java.io.File[] src, java.io.File zipFile, String[] extensions){ + + boolean success = false; + ArchiveDetector detector = getArchiveDetector(extensions); + + for (java.io.File currSrcFile : src) { + + try { + + File toBeAddedFile = null; + if (detector != null) { + + toBeAddedFile = new File(currSrcFile.getCanonicalFile(), + detector); + + success = toBeAddedFile.archiveCopyTo(new File(zipFile, + toBeAddedFile.getName(), detector)); + } else { + toBeAddedFile = new File(currSrcFile.getCanonicalFile()); + success = toBeAddedFile.archiveCopyTo(new File(zipFile, + toBeAddedFile.getName())); + } + + unmount(); + + } catch (ArchiveException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return success; + } + + /** + * Copies source file(s) into a specified zip file. If the file exists it will be overwritten. + * @param src - The originating source to be copied + * @param zipFile - The destination for src + * @return true on success + * + * @see ZipFileUtils#addFilesToZip(java.io.File[], java.io.File, String[]) + */ + public static boolean addFilesToZip(java.io.File[] src, java.io.File zipFile) { + return addFilesToZip(src, zipFile, null); + } + + /** + * TrueZip detects archive types by file extension and only has built in support for known types. + * If other file extensions are used that TrueZip does not have in it's default configuration + * it will complain that it does not recognize the archive type. Passing an array of extensions will + * allow TrueZip to recognize any arbitrary file extension as a zip archive. This only works for zip archvies. + * + * @param extensions - array of extension TrueZip should recognize as zip files. + * @return ArchiveDetector + */ + private static ArchiveDetector getArchiveDetector(String[] extensions){ + List zipFileExtensions = new ArrayList(); + ArchiveDetector detector = null; + if (extensions != null && extensions.length > 0){ + for (String ext : extensions){ + zipFileExtensions.add(ext); + zipFileExtensions.add(new de.schlichtherle.io.archive.zip.ZipDriver()); + } + + detector = new DefaultArchiveDetector(ArchiveDetector.NULL, + zipFileExtensions.toArray()); + } + + return detector; + } + + /** + * + * @param zipFileName + * @return + * @throws IOException + * + */ + public static List listZipContents(String zipFileName) throws IOException{ + List zipContents = new ArrayList(); + + ZipFile zipFile = new ZipFile(zipFileName); + Enumeration zipEntries = zipFile.entries(); + while (zipEntries.hasMoreElements()) { + zipContents.add(zipEntries.nextElement()); + } + + return zipContents; + } + + /** + * Get a java.io.BufferedInputStream for reading 'src' from the specified 'zipFile'. Clients should make sure to call {@link ZipFileUtils#unmount()} when reading is complete. + * @param zipFile - Archive to read + * @param src - File to open for reading in the zipFile + * @param extensions - Extensions for zip file used if not standard + * @return + */ + public static java.io.BufferedInputStream openFile(java.io.File zipFile, String src, String[] extensions){ + ArchiveDetector detector = getArchiveDetector(extensions); + String archiveFileName = zipFile + File.separator + src; + try { + File.setDefaultArchiveDetector(detector); + FileInputStream fs = new FileInputStream(archiveFileName); + java.io.BufferedInputStream stream = new java.io.BufferedInputStream(fs); + return stream; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + return null; + } + + /** + * Close all input and output streams. + * Equivalent to {@link File#umount(boolean, boolean, boolean, boolean) + */ + public static void unmount(){ + try { + File.umount(); + } catch (ArchiveException e) { + e.printStackTrace(); + } + } + + public static boolean createNewZip(java.io.File zipFileToCreate) { + boolean success = false; + if (zipFileToCreate.exists()){ + return true; + } + + if (!zipFileToCreate.getParentFile().exists()){ + zipFileToCreate.mkdirs(); + } + + File f = new File(zipFileToCreate); + + try { + success = f.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + unmount(); + } + + return success; + } + + /** + * Only unzips files in zip file not directories + * + * @param zipped + * file + * @param destPath + * Destination path + * @return Files that were unzipped + */ + public static List unzipFiles(java.io.File zippedfile, String destPath, IProgressMonitor monitor) + throws FileNotFoundException, IOException { + ZipFile zipFile = new ZipFile(zippedfile); + + Enumeration entries = zipFile.entries(); + List outputFiles = new ArrayList(); + File destinationFile = new File(destPath); + if (!destinationFile.exists()) { + destinationFile.mkdirs(); + } + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + File outputFile = new File(destinationFile, entry.getName()); + if (entry.isDirectory() && !outputFile.exists()) { + outputFile.mkdirs(); + continue; + } + + if (!outputFile.getParentFile().exists()) { + outputFile.getParentFile().mkdirs(); + } + + java.io.InputStream inputStream = zipFile.getInputStream(entry); + java.io.FileOutputStream outStream = new java.io.FileOutputStream(outputFile); + copyByteStream(inputStream, outStream); + + outputFiles.add(outputFile); + if (monitor != null) { + monitor.worked(1); + } + outStream.close(); + inputStream.close(); + } + zipFile.close(); + return outputFiles; + } + + public static void copyByteStream(java.io.InputStream in, java.io.OutputStream out) throws IOException { + if (in != null && out != null) { + java.io.BufferedInputStream inBuffered = new java.io.BufferedInputStream(in); + + int bufferSize = 1000; + byte[] buffer = new byte[bufferSize]; + + int readCount; + + java.io.BufferedOutputStream fout = new java.io.BufferedOutputStream(out); + + while ((readCount = inBuffered.read(buffer)) != -1) { + if (readCount < bufferSize) { + fout.write(buffer, 0, readCount); + } else { + fout.write(buffer); + } + } + fout.flush(); + fout.close(); + in.close(); + } + } + + + + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvalMessages.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvalMessages.java new file mode 100644 index 0000000..0f8eda1 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvalMessages.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine; + +import org.eclipse.osgi.util.NLS; + +public class ASTEvalMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages"; //$NON-NLS-1$ + + public static String DivideByZero; + public static String UnhandledTypeCode; + public static String UnhandledSize; + public static String UnsupportedStringOperation; + + public static String ASTEvaluationEngine_DidNotDetectType; + + public static String ASTInstructionCompiler_InvalidNumber; + + public static String ArraySubscript_ArrayHasNoBounds; + public static String ArraySubscript_CannotIndirectTemporary; + public static String ArraySubscript_ErrorDereferencingArray; + public static String ArraySubscript_MustSubscriptArray; + public static String ArraySubscript_ReadingPastEndOfString; + public static String ArraySubscript_SubscriptMustBeInteger; + + public static String EvaluateID_CannotResolveName; + public static String EvaluateID_NameHasNoLocation; + public static String EvaluateID_VariableNotFound; + + public static String FieldReference_InvalidPointerDeref; + public static String FieldReference_InvalidDotDeref; + public static String FieldReference_InvalidMember; + public static String FieldReference_AmbiguousMember; + public static String FieldReference_CannotDereferenceType; + public static String FieldReference_UnhandledOperandSize; + + public static String GetValue_TypePromotionError; + + public static String Instruction_CannotUseCompositeType; + public static String Instruction_EmptyStack; + public static String Instruction_UnhandledTypeCombination; + + public static String OperandValue_CannotGetAddress; + public static String OperandValue_CannotReadUnspecifiedType; + public static String OperandValue_CannotReadVoid; + public static String OperandValue_UnhandledType; + public static String OperandValue_VariableNoAddress; + + public static String OperatorAddrOf_RequiresVariable; + public static String OperatorAddrOf_NoRegister; + public static String OperatorAddrOf_NoBitField; + + public static String OperatorCast_CannotCastString; + + public static String OperatorIndirection_RequiresPointer; + public static String OperatorIndirection_NoBitField; + public static String OperatorIndirection_NoFunction; + public static String OperatorIndirection_UnhandledType; + + public static String OperatorMinus_NonPtrMinusPtr; + public static String OperatorPlus_PtrPlusPtr; + + public static String VariableWithValue_CannotLocateVariable; + public static String VariableWithValue_NoTwelveByteLongDouble; + public static String VariableWithValue_UnhandledType; + public static String VariableWithValue_UnknownLocation; + public static String VariableWithValue_VariableHasNoType; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, ASTEvalMessages.class); + } + + private ASTEvalMessages() { + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvalMessages.properties b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvalMessages.properties new file mode 100644 index 0000000..e7d930a --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvalMessages.properties @@ -0,0 +1,55 @@ +############################################################################### +# Copyright (c) 2010 Nokia and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Nokia - Initial API and implementation +############################################################################### +DivideByZero=divide by zero +ASTEvaluationEngine_DidNotDetectType=did not detect type +ASTInstructionCompiler_InvalidNumber=invalid number format +ArraySubscript_ArrayHasNoBounds=array type has no bounds +ArraySubscript_CannotIndirectTemporary=cannot indirect temporary +ArraySubscript_ErrorDereferencingArray=error dereferencing array +ArraySubscript_MustSubscriptArray=only arrays or pointers may be subscripted +ArraySubscript_ReadingPastEndOfString=reading past end of string +ArraySubscript_SubscriptMustBeInteger=subscript not an integral type +UnhandledSize=unhandled size {0} +EvaluateID_CannotResolveName=cannot resolve {0} +EvaluateID_NameHasNoLocation=no location found for {0} +EvaluateID_VariableNotFound=''{0}'' not found +FieldReference_InvalidPointerDeref=left operand of '->' not a pointer to a class, struct, or union +FieldReference_InvalidDotDeref=left operand of '.' not a class, struct, or union, or reference to one +FieldReference_InvalidMember=''{0}'' is an invalid class, struct, or union member +FieldReference_AmbiguousMember=''{0}'' matches 2 or more members (possibly inherited) of ''{1}'' +FieldReference_CannotDereferenceType=cannot dereference this type +FieldReference_UnhandledOperandSize=unhandled operand size +GetValue_TypePromotionError=internal error: type promotion failure +Instruction_CannotUseCompositeType=cannot use composite type in expression +Instruction_EmptyStack=empty stack +Instruction_UnhandledTypeCombination=unhandled type combination {0} and {1} +UnhandledTypeCode=unhandled type code +UnsupportedStringOperation=operation not supported on strings +OperandValue_CannotGetAddress=cannot get address of {0} +OperandValue_CannotReadUnspecifiedType=cannot read from unspecified type +OperandValue_CannotReadVoid=cannot read from void +OperandValue_UnhandledType=Unhandled type +OperandValue_VariableNoAddress=variable has no address +OperatorAddrOf_RequiresVariable=unary '&' requires a memory location +OperatorAddrOf_NoRegister=cannot get memory address of the variable because it is in register +OperatorAddrOf_NoBitField=cannot get memory address of a bit-field +OperatorCast_CannotCastString=cannot cast string literal +OperatorIndirection_RequiresPointer=unary '*' requires a pointer +OperatorIndirection_NoBitField=unary '*' cannot be applied to a bit-field +OperatorIndirection_NoFunction=cannot dereference a function pointer +OperatorIndirection_UnhandledType=unhandled type {0} +OperatorMinus_NonPtrMinusPtr=subtracting pointer from non-pointer +OperatorPlus_PtrPlusPtr=adding two pointers +VariableWithValue_CannotLocateVariable=Cannot locate variable +VariableWithValue_NoTwelveByteLongDouble=12-byte long double not implemented +VariableWithValue_UnhandledType=Unhandled type +VariableWithValue_UnknownLocation=unknown location +VariableWithValue_VariableHasNoType=Variable has no type diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvaluationEngine.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvaluationEngine.java new file mode 100644 index 0000000..b501681 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTEvaluationEngine.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTProblem; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.parser.ISourceCodeParser; +import org.eclipse.cdt.core.dom.parser.c.GCCScannerExtensionConfiguration; +import org.eclipse.cdt.core.dom.parser.cpp.GPPParserExtensionConfiguration; +import org.eclipse.cdt.core.parser.FileContent; +import org.eclipse.cdt.core.parser.IScanner; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IncludeFileContentProvider; +import org.eclipse.cdt.core.parser.NullLogService; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.ParserMode; +import org.eclipse.cdt.core.parser.ScannerInfo; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.InstructionSequence; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.Interpreter; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.symbols.TypeEngine; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser; +import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor; +import org.eclipse.core.runtime.CoreException; + +@SuppressWarnings("restriction") +public class ASTEvaluationEngine { + + public static final String UNKNOWN_TYPE = ""; //$NON-NLS-1$ + private final EDCServicesTracker tracker; + private final IDMContext context; + private final TypeEngine typeEngine; + + private static final Map compiledExpressionsCache = + Collections.synchronizedMap(new HashMap()); + + /** + * @param context + * @param tracker + * + */ + public ASTEvaluationEngine(EDCServicesTracker tracker, IDMContext context, TypeEngine typeEngine) { + this.tracker = tracker; + this.context = context; + this.typeEngine = typeEngine; + } + + public InstructionSequence getCompiledExpression(String expression) throws CoreException { + + // the creation and parsing of the AST can get expensive so we cache it for + // the given expression + InstructionSequence instructions = compiledExpressionsCache.get(expression); + if (instructions == null) { + FileContent reader = FileContent.create("", ("void* dummy_func() { return " + //$NON-NLS-1$ //$NON-NLS-2$ + expression + " ; }").toCharArray()); //$NON-NLS-1$ + IScannerInfo scannerInfo = new ScannerInfo(); // creates an empty scanner info + IScanner scanner = new CPreprocessor(reader, scannerInfo, ParserLanguage.CPP, new NullLogService(), GCCScannerExtensionConfiguration.getInstance(), IncludeFileContentProvider.getEmptyFilesProvider()); + ISourceCodeParser parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, new NullLogService(), GPPParserExtensionConfiguration.getInstance(), null); + IASTTranslationUnit ast = parser.parse(); + + ASTInstructionCompiler visitor = new ASTInstructionCompiler(expression); + ast.accept(visitor); + + if (visitor.hasErrors()) + throw EDCDebugger.newCoreException(visitor.getErrorMessage()); + + instructions = visitor.getInstructions(); + + // Remove NoOps + instructions.removeNoOps(); + + compiledExpressionsCache.put(expression, instructions); + } + + + // make a copy of the cached generic instruction sequence since we'll make + // context specific changes below (reduceCasts) + InstructionSequence sequence = new InstructionSequence(instructions); + + // Reduce (possibly internally generated) cast expressions to avoid + // taking the address of a register or bitfield. + sequence.reduceCasts(typeEngine); + + return sequence; + + } + + public Interpreter evaluateCompiledExpression(InstructionSequence expression) throws CoreException { + Interpreter interpreter = new Interpreter(tracker, context, typeEngine, expression); + interpreter.execute(); + return interpreter; + } + + /** + * Get the type engine + * @return + */ + public TypeEngine getTypeEngine() { + return typeEngine; + } + + + static private class ASTTypeVisitor extends ASTVisitor { + private IASTTypeId theType; + private String errorMessage; + + { + shouldVisitTypeIds = true; + shouldVisitProblems = true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTTypeId) + */ + @Override + public int visit(IASTTypeId typeId) { + theType = typeId; + return PROCESS_ABORT; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTProblem) + */ + @Override + public int visit(IASTProblem problem) { + errorMessage = problem.getMessage(); + return PROCESS_ABORT; + } + } + /** + * Parse the given type string and get the AST tree for it + * @param type + * @return IASTTypeId instance + * @throws CoreException + */ + public IASTTypeId getCompiledType(String type) throws CoreException { + + FileContent reader = FileContent.create("", ("void* dummy_func() { typeof(" + //$NON-NLS-1$ //$NON-NLS-2$ + type + ") x; }").toCharArray()); //$NON-NLS-1$ + IScannerInfo scannerInfo = new ScannerInfo(); // creates an empty scanner info + IScanner scanner = new CPreprocessor(reader, scannerInfo, ParserLanguage.CPP, new NullLogService(), GCCScannerExtensionConfiguration.getInstance(), IncludeFileContentProvider.getEmptyFilesProvider()); + ISourceCodeParser parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, new NullLogService(), GPPParserExtensionConfiguration.getInstance(), null); + IASTTranslationUnit ast = parser.parse(); + + ASTTypeVisitor visitor = new ASTTypeVisitor(); + ast.accept(visitor); + if (visitor.errorMessage != null) + throw EDCDebugger.newCoreException(visitor.errorMessage); + if (visitor.theType == null) + throw EDCDebugger.newCoreException(ASTEvalMessages.ASTEvaluationEngine_DidNotDetectType); + + return visitor.theType; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTInstructionCompiler.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTInstructionCompiler.java new file mode 100644 index 0000000..6b0d3fe --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/ASTInstructionCompiler.java @@ -0,0 +1,522 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine; + +import java.util.Stack; + +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; +import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; +import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTCastExpression; +import org.eclipse.cdt.core.dom.ast.IASTComment; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTFieldReference; +import org.eclipse.cdt.core.dom.ast.IASTIdExpression; +import org.eclipse.cdt.core.dom.ast.IASTInitializer; +import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; +import org.eclipse.cdt.core.dom.ast.IASTProblem; +import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.ArraySubscript; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.CompoundInstruction; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.EvaluateID; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.FieldReference; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.Instruction; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.InstructionSequence; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.NoOp; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorAddrOf; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorBinaryAnd; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorBinaryOr; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorBinaryXor; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorBitwiseNot; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorCast; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorCastValue; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorDivide; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorEquals; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorGreaterEqual; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorGreaterThan; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorIndirection; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorLessEqual; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorLessThan; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorLogicalAnd; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorLogicalNot; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorLogicalOr; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorMinus; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorModulo; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorMultiply; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorNotEquals; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorPlus; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorShiftLeft; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorShiftRight; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorUnaryMinus; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperatorUnaryPlus; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.PushBoolean; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.PushChar; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.PushDouble; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.PushFloat; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.PushLongOrBigInteger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.PushString; +import org.eclipse.cdt.debug.edc.symbols.TypeEngine; +import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; + +@SuppressWarnings("restriction") +public class ASTInstructionCompiler extends ASTVisitor { + + private final Stack stack; + private final InstructionSequence instructions; + private int counter; + private String errorMessage; + private boolean active = true; + + public ASTInstructionCompiler( String snippet) { + super(true); + stack = new Stack(); + instructions = new InstructionSequence(snippet); + } + + private void push(Instruction i) { + stack.push(i); + } + + private Instruction pop() { + return stack.pop(); + } + + /** + * Returns the instruction sequence generated by this AST instruction + * compiler + */ + public InstructionSequence getInstructions() { + return instructions; + } + + public boolean hasErrors() { + return errorMessage != null; + } + + public String getErrorMessage() { + return errorMessage; + } + + private boolean isActive() { + return active; + } + + private void storeInstruction() { + Instruction instruction = pop(); + counter++; + if (instruction instanceof CompoundInstruction) { + ((CompoundInstruction) instruction).setEnd(counter); + } + instructions.add(instruction); + } + + @Override + public int leave(IASTArrayModifier arrayModifier) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(arrayModifier)); } + return super.leave(arrayModifier); + } + + @SuppressWarnings("deprecation") // we're simply wrapping a deprecated method + @Override + public int leave(IASTComment comment) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(comment)); } + return super.leave(comment); + } + + @Override + public int leave(IASTDeclaration declaration) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(declaration)); } + return super.leave(declaration); + } + + @Override + public int leave(IASTDeclarator declarator) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(declarator)); } + return super.leave(declarator); + } + + @Override + public int leave(IASTDeclSpecifier declSpec) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(declSpec)); } + return super.leave(declSpec); + } + + @Override + public int leave(IASTEnumerator enumerator) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(enumerator)); } + return super.leave(enumerator); + } + + @Override + public int leave(IASTExpression expression) { + if (!isActive() || hasErrors()) + return PROCESS_CONTINUE; + storeInstruction(); + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(expression)); } + return super.leave(expression); + } + + @Override + public int leave(IASTInitializer initializer) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(initializer)); } + return super.leave(initializer); + } + + @Override + public int leave(IASTName name) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(name)); } + return super.leave(name); + } + + @Override + public int leave(IASTParameterDeclaration parameterDeclaration) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(parameterDeclaration)); } + return super.leave(parameterDeclaration); + } + + @Override + public int leave(IASTPointerOperator ptrOperator) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(ptrOperator)); } + return super.leave(ptrOperator); + } + + @Override + public int leave(IASTProblem problem) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(problem)); } + return super.leave(problem); + } + + @Override + public int leave(IASTStatement statement) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(statement)); } + return super.leave(statement); + } + + @Override + public int leave(IASTTranslationUnit tu) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(tu)); } + return super.leave(tu); + } + + @Override + public int leave(IASTTypeId typeId) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(typeId)); } + return super.leave(typeId); + } + + @Override + public int visit(IASTArrayModifier arrayModifier) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(arrayModifier)); } + return super.visit(arrayModifier); + } + + @SuppressWarnings("deprecation") // we're simply wrapping a deprecated method + @Override + public int visit(IASTComment comment) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(comment)); } + return super.visit(comment); + } + + @Override + public int visit(IASTDeclaration declaration) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(declaration)); } + return super.visit(declaration); + } + + @Override + public int visit(IASTDeclarator declarator) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(declarator)); } + return super.visit(declarator); + } + + @Override + public int visit(IASTDeclSpecifier declSpec) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(declSpec)); } + return super.visit(declSpec); + } + + @Override + public int visit(IASTEnumerator enumerator) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(enumerator)); } + return super.visit(enumerator); + } + + @Override + public int visit(IASTInitializer initializer) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(initializer)); } + return super.visit(initializer); + } + + @Override + public int visit(IASTParameterDeclaration parameterDeclaration) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg("visit: " + parameterDeclaration.getClass().getSimpleName())); } //$NON-NLS-1$ + return super.visit(parameterDeclaration); + } + + @Override + public int visit(IASTPointerOperator ptrOperator) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(ptrOperator)); } + return super.visit(ptrOperator); + } + + @Override + public int visit(IASTStatement statement) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(statement)); } + return super.visit(statement); + } + + @Override + public int visit(IASTTranslationUnit tu) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(tu)); } + return super.visit(tu); + } + + @Override + public int visit(IASTTypeId typeId) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(typeId)); } + return super.visit(typeId); + } + + @Override + public int visit(ASTAmbiguousNode astAmbiguousNode) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(astAmbiguousNode)); } + return super.visit(astAmbiguousNode); + } + + @Override + public int visit(IASTName name) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(name)); } + return super.visit(name); + } + + @Override + public int visit(IASTProblem problem) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(problem)); } + return super.visit(problem); + } + + @Override + public int visit(IASTExpression expression) { + if (EDCTrace.EXPRESSION_PARSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(expression)); } + + if (expression instanceof IASTLiteralExpression) { + visitLiteralExpression((IASTLiteralExpression) expression); + } else if (expression instanceof IASTBinaryExpression) { + visitBinaryExpression((IASTBinaryExpression) expression); + } else if (expression instanceof IASTUnaryExpression) { + visitUnaryExpression((IASTUnaryExpression) expression); + } else if (expression instanceof IASTIdExpression) { + visitIDExpression((IASTIdExpression) expression); + } else if (expression instanceof IASTArraySubscriptExpression) { + visitArraySubscriptExpression((IASTArraySubscriptExpression) expression); + } else if (expression instanceof IASTFieldReference) { + visitFieldReference((IASTFieldReference) expression); + } else if (expression instanceof IASTCastExpression) { + visitCastExpression((IASTCastExpression) expression); + } else + push(new NoOp(counter)); + + return super.visit(expression); + } + + private void visitIDExpression(IASTIdExpression expression) { + push(new EvaluateID(expression)); + } + + private void visitArraySubscriptExpression(IASTArraySubscriptExpression expression) { + push(new ArraySubscript(counter)); + } + + private void visitFieldReference(IASTFieldReference expression) { + push(new FieldReference(expression, counter)); + } + + private void visitCastExpression(IASTCastExpression expression) { + if (expression.getOperator() == ICPPASTCastExpression.op_reinterpret_cast) + push(new OperatorCastValue(counter, expression)); + else + push(new OperatorCast(counter, expression)); + } + + private void visitLiteralExpression(IASTLiteralExpression expression) { + int kind = expression.getKind(); + String value = new String(expression.getValue()); + switch (kind) { + case IASTLiteralExpression.lk_integer_constant: + try { + push(new PushLongOrBigInteger(value)); + } catch (NumberFormatException nfe) { + errorMessage = ASTEvalMessages.ASTInstructionCompiler_InvalidNumber; + } + break; + case IASTLiteralExpression.lk_float_constant: + // check for explicitly float constant + try { + if (value.toUpperCase().endsWith("F")) //$NON-NLS-1$ + push(new PushFloat(value)); + else + push(new PushDouble(value)); + } catch (NumberFormatException nfe) { + errorMessage = ASTEvalMessages.ASTInstructionCompiler_InvalidNumber; + } + break; + case IASTLiteralExpression.lk_char_constant: + try { + push(new PushChar(value)); + } catch (NumberFormatException nfe) { + errorMessage = ASTEvalMessages.ASTInstructionCompiler_InvalidNumber; + } + break; + case IASTLiteralExpression.lk_string_literal: + push(new PushString(value)); + break; + case IASTLiteralExpression.lk_false: + push(new PushBoolean(false)); + break; + case IASTLiteralExpression.lk_true: + push(new PushBoolean(true)); + break; + case IASTLiteralExpression.lk_this: + push(new EvaluateID("this")); //$NON-NLS-1$ + break; + default: + push(new NoOp(counter)); + } + } + + private void visitBinaryExpression(IASTBinaryExpression expression) { + int op = expression.getOperator(); + + switch (op) { + case IASTBinaryExpression.op_binaryAnd: + push(new OperatorBinaryAnd(counter)); + break; + + case IASTBinaryExpression.op_binaryOr: + push(new OperatorBinaryOr(counter)); + break; + + case IASTBinaryExpression.op_binaryXor: + push(new OperatorBinaryXor(counter)); + break; + + case IASTBinaryExpression.op_plus: + push(new OperatorPlus(counter)); + break; + + case IASTBinaryExpression.op_minus: + push(new OperatorMinus(counter)); + break; + + case IASTBinaryExpression.op_multiply: + push(new OperatorMultiply(counter)); + break; + + case IASTBinaryExpression.op_divide: + push(new OperatorDivide(counter)); + break; + + case IASTBinaryExpression.op_modulo: + push(new OperatorModulo(counter)); + break; + + case IASTBinaryExpression.op_shiftLeft: + push(new OperatorShiftLeft(counter)); + break; + + case IASTBinaryExpression.op_shiftRight: + push(new OperatorShiftRight(counter)); + break; + + case IASTBinaryExpression.op_equals: + push(new OperatorEquals(counter)); + break; + + case IASTBinaryExpression.op_notequals: + push(new OperatorNotEquals(counter)); + break; + + case IASTBinaryExpression.op_greaterEqual: + push(new OperatorGreaterEqual(counter)); + break; + + case IASTBinaryExpression.op_greaterThan: + push(new OperatorGreaterThan(counter)); + break; + + case IASTBinaryExpression.op_lessEqual: + push(new OperatorLessEqual(counter)); + break; + + case IASTBinaryExpression.op_lessThan: + push(new OperatorLessThan(counter)); + break; + + case IASTBinaryExpression.op_logicalAnd: + push(new OperatorLogicalAnd(counter)); + break; + + case IASTBinaryExpression.op_logicalOr: + push(new OperatorLogicalOr(counter)); + break; + + default: + push(new NoOp(counter)); + } + } + + private void visitUnaryExpression(IASTUnaryExpression expression) { + int op = expression.getOperator(); + + switch (op) { + case IASTUnaryExpression.op_minus: + push(new OperatorUnaryMinus(counter)); + break; + + case IASTUnaryExpression.op_not: + push(new OperatorLogicalNot(counter)); + break; + + case IASTUnaryExpression.op_plus: + push(new OperatorUnaryPlus(counter)); + break; + + case IASTUnaryExpression.op_tilde: + push(new OperatorBitwiseNot(counter)); + break; + + case IASTUnaryExpression.op_star: + push(new OperatorIndirection(counter)); + break; + + case IASTUnaryExpression.op_amper: + push(new OperatorAddrOf(counter)); + break; + + default: + push(new NoOp(counter)); + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/ArrayDimensionType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/ArrayDimensionType.java new file mode 100644 index 0000000..7897423 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/ArrayDimensionType.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.Type; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; + +// Internal expression type to hold all dimensions of a multidimensional array except the smallest. +// E.g., for "int a[6][7][8];", this type might hold info about "a[2]" or "a[2][4]", but not "a[2][4][3]". +public class ArrayDimensionType extends Type implements IArrayDimensionType { + + private final OperandValue value; // needed for scope, + // frame, services + // tracker, etc. + private final IArrayType arrayType; + private IVariableLocation location; + private int dimensionCount; // number of dimensions processed so far + + public ArrayDimensionType(String name, OperandValue value, IArrayType arrayType, IVariableLocation location) { + super(name, null, 0, null); + this.value = value; + this.arrayType = arrayType; + this.location = location; + this.dimensionCount = 1; + } + + public OperandValue getOperandValue() { + return this.value; + } + + public IArrayType getArrayType() { + return this.arrayType; + } + + public IVariableLocation getLocation() { + return this.location; + } + + public int getDimensionCount() { + return this.dimensionCount; + } + + public void addDimension(long subscript, long increase) { + this.name += "[" + subscript + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + this.location = location.addOffset(increase); + this.dimensionCount++; + } + + @Override + public IType getType() { + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/ArraySubscript.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/ArraySubscript.java new file mode 100644 index 0000000..f5971f5 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/ArraySubscript.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; +import java.text.MessageFormat; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.IAggregate; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.IBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.IEnumeration; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.ITypedef; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.debug.edc.symbols.VariableLocationFactory; +import org.eclipse.core.runtime.CoreException; + +/* + * Array subscript instruction + */ +public class ArraySubscript extends CompoundInstruction { + + /** + * Constructor for array subscript instruction + * + * @param expression + * - array subscript expression + * @param start + * - instruction start + */ + public ArraySubscript(int start) { + super(start); + } + + /** + * Resolve an array subscript expression + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + OperandValue subscriptOperand = popValue(); + OperandValue variableOperand = popValue(); + + long subscript = 0; + + if (subscriptOperand.isFloating()) + throw EDCDebugger.newCoreException(ASTEvalMessages.ArraySubscript_SubscriptMustBeInteger); + + subscript = subscriptOperand.getLongValue(); + + IType variableType = TypeUtils.getStrippedType(variableOperand.getValueType()); + + IArrayType arrayType; + IVariableLocation location = null; + IType arrayElementType; + int byteSize; + + if (variableType instanceof IArrayDimensionType) + arrayElementType = TypeUtils.getStrippedType(((IArrayDimensionType) variableType).getArrayType().getType()); + else + arrayElementType = TypeUtils.getStrippedType(variableType.getType()); + if (arrayElementType == null) + throw EDCDebugger.newCoreException(ASTEvalMessages.ArraySubscript_MustSubscriptArray); + + if (variableType instanceof IArrayType) + byteSize = variableType.getByteSize(); + else + byteSize = arrayElementType.getByteSize(); + + + IVariableLocation varLocation = variableOperand.getValueLocation(); + if (varLocation == null) { + // may be a string... + String stringValue = variableOperand.getStringValue(); + if (stringValue != null) { + if (subscript < stringValue.length()) { + pushNewValue(arrayElementType, (int) stringValue.charAt((int) subscript)); + } else if (subscript == stringValue.length()) { + pushNewValue(arrayElementType, 0); + } else { + throw EDCDebugger.newCoreException(ASTEvalMessages.ArraySubscript_ReadingPastEndOfString); + } + return; + } + throw EDCDebugger.newCoreException(ASTEvalMessages.ArraySubscript_CannotIndirectTemporary); + } + + // If the variable type is just a pointer, then add the pointer base type's size + // + // *(ptr+element) + if (variableType instanceof IPointerType) { + IPointerType pointerType = (IPointerType) variableType; + + // dereference ptr + BigInteger ptrValue = varLocation.readValue(pointerType.getByteSize()); + + // point into array + location = VariableLocationFactory.createMemoryVariableLocation( + fInterpreter.getServicesTracker(), fInterpreter.getContext(), + ptrValue.add(BigInteger.valueOf(byteSize * subscript))); + + // dereference to fetch offset + OperandValue op = new OperandValue(pointerType.getType()); + + op.setValueLocation(VariableLocationFactory.createMemoryVariableLocation( + fInterpreter.getServicesTracker(), fInterpreter.getContext(), + location.getAddress().getValue())); + + // read actual value + Number newValue = op.getValueByType(op.getValueType(), op.getValueLocation()); + op.setValue(newValue); + push(op); + + return; + + } + + // if the variable is an IArrayType, there are two cases: + // we're accessing a single element of a one dimensional array + // we're accessing an entire dimension of a multidimensional array + if (variableType instanceof IArrayType) { + + arrayType = (IArrayType) variableType; + + if (arrayType.getBoundsCount() == 0) { + throw EDCDebugger.newCoreException(ASTEvalMessages.ArraySubscript_ArrayHasNoBounds); + } + + // find the location of indexed 1st dimension element, or of entire + // dimension + location = varLocation.addOffset(arrayType.getBounds()[0].getElementCount() * byteSize + * subscript); + + if (arrayType.getBoundsCount() == 1) { + // we're accessing a single element of a one dimensional array + pushArrayElement(variableOperand, location, arrayElementType); + } else { + String name = variableOperand.getValueType().getName() + "[" + subscript + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + ArrayDimensionType arrayDimensionType = new ArrayDimensionType(name, variableOperand, arrayType, + location); + OperandValue opValue = new OperandValue(arrayDimensionType); + + opValue.setAddressValue(location); + opValue.setValueLocation(location); + push(opValue); + } + return; + } + + if (!(variableType instanceof IArrayDimensionType)) { + throw EDCDebugger.newCoreException(ASTEvalMessages.ArraySubscript_MustSubscriptArray); + } + + // if the variable is an ArrayDimensionType, there are two cases: + // we're accessing a single element of a multidimensional array + // we're accessing another entire dimension of a multidimensional array + ArrayDimensionType arrayDimension = (ArrayDimensionType) variableType; + arrayType = arrayDimension.getArrayType(); + arrayElementType = TypeUtils.getStrippedType(arrayType.getType()); + + byteSize = arrayElementType.getByteSize(); + if (arrayElementType instanceof ITypedef) { + byteSize = TypeUtils.getStrippedType(arrayElementType.getType()).getByteSize(); + } + + arrayDimension.addDimension(subscript, arrayType.getBound(arrayDimension.getDimensionCount()).getElementCount() + * byteSize * subscript); + location = arrayDimension.getLocation(); + + if (arrayDimension.getDimensionCount() >= arrayType.getBoundsCount()) { + // we're accessing a single element of a multidimensional array + pushArrayElement(arrayDimension.getOperandValue(), location, arrayElementType); + } else { + // we're accessing another entire dimension of a multidimensional + // array + variableOperand.setAddressValue(location); + variableOperand.setValueLocation(location); + push(variableOperand); + } + } + + private void pushArrayElement(OperandValue originalVariableValue, IVariableLocation location, IType arrayElementType) throws CoreException { + OperandValue varValue = new OperandValue(arrayElementType); + + varValue.setValueLocation(location); + + // for a lvalues (base arithmetic types, enums, and pointers), read the + // value and cast it to the right type + if (arrayElementType instanceof IBasicType || arrayElementType instanceof IEnumeration + || arrayElementType instanceof IPointerType) { + int byteSize = arrayElementType.getByteSize(); + + // TODO support 12-byte long double + if (byteSize != 1 && byteSize != 2 && byteSize != 4 && byteSize != 8) { + throw EDCDebugger.newCoreException(MessageFormat.format(ASTEvalMessages.UnhandledSize, byteSize)); + } + + // read the value pointed to + Number newValue = originalVariableValue.getValueByType(arrayElementType, location); + varValue.setValue(newValue); + push(varValue); + + } else if (arrayElementType instanceof IAggregate) { + // for aggregates, the address of the aggregate is the value + // returned + varValue.setAddressValue(location); + push(varValue); + + } else { + throw EDCDebugger.newCoreException(ASTEvalMessages.ArraySubscript_ErrorDereferencingArray); + } + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/BinaryLogicalOperator.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/BinaryLogicalOperator.java new file mode 100644 index 0000000..44911a5 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/BinaryLogicalOperator.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.core.runtime.CoreException; + +/* + * Binary logical operator, such as "<" + */ +public abstract class BinaryLogicalOperator extends CompoundInstruction { + + /** + * Constructor for a binary logical operator, such as "<" + * + * @param resultId - for assignment, variable ID of the result + * @param isAssignmentOperator - whether the result is assigned + * @param start - instruction start + */ + protected BinaryLogicalOperator(int resultId, boolean isAssignmentOperator, int start) { + super(start); + } + + /** + * Resolve a binary logical operator, such as "<" + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + OperandValue right = popValue(); + OperandValue left = popValue(); + + right = convertForPromotion(right); + left = convertForPromotion(left); + + int promotedType = getJavaBinaryPromotionType(right, left); + IType type = fInterpreter.getTypeEngine().getBooleanType(1); + + switch (promotedType) { + case T_String: + pushNewValue(type, getStringResult(GetValue.getStringValue(left), GetValue.getStringValue(right))); + break; + case T_double: + pushNewValue(type, getDoubleResult(GetValue.getDoubleValue(left), GetValue.getDoubleValue(right))); + break; + case T_float: + pushNewValue(type, getFloatResult(GetValue.getFloatValue(left), GetValue.getFloatValue(right))); + break; + case T_long: + pushNewValue(type, getLongResult(GetValue.getLongValue(left), GetValue.getLongValue(right))); + break; + case T_int: + pushNewValue(type, getIntResult(GetValue.getIntValue(left), GetValue.getIntValue(right))); + break; + case T_boolean: + pushNewValue(type, getBooleanResult(GetValue.getBooleanValue(left), GetValue.getBooleanValue(right))); + break; + case T_BigInt: + pushNewValue(type, getBigIntegerResult(GetValue.getBigIntegerValue(left), GetValue.getBigIntegerValue(right))); + break; + } + } + + /** + * Get boolean result of applying a binary logical operation to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return boolean result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract boolean getIntResult(int leftOperand, int rightOperand) throws CoreException; + + /** + * Get boolean result of applying a binary logical operation to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return boolean result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract boolean getLongResult(long leftOperand, long rightOperand) throws CoreException; + + /** + * Get boolean result of applying a binary logical operation to two + * BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @return boolean result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) + throws CoreException; + + /** + * Get boolean result of applying a binary logical operation to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return boolean result of the operation if possible, or an + * operation-specific default + */ + protected abstract boolean getFloatResult(float leftOperand, float rightOperand); + + /** + * Get boolean result of applying a binary logical operation to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return boolean result of the operation if possible, or an + * operation-specific default + */ + protected abstract boolean getDoubleResult(double leftOperand, double rightOperand); + + /** + * Get boolean result of applying a binary logical operation to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return boolean result of the operation if possible, or an + * operation-specific default + */ + protected abstract boolean getBooleanResult(boolean leftOperand, boolean rightOperand); + + /** + * Get boolean result of applying a binary logical operation to two strings + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return boolean result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract boolean getStringResult(String leftOperand, String rightOperand) throws CoreException; + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/BinaryOperator.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/BinaryOperator.java new file mode 100644 index 0000000..b289f63 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/BinaryOperator.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/* + * Binary arithmetic operator, such as "/" + */ +public abstract class BinaryOperator extends CompoundInstruction { + + /** + * Constructor for a binary arithmetic operator, such as "/" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected BinaryOperator(int resultId, boolean isAssignmentOperator, int start) { + super(start); + } + + /** + * Resolve a binary arithmetic operator, such as "/" + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + OperandValue right = popValue(); + OperandValue left = popValue(); + + right = convertForPromotion(right); + left = convertForPromotion(left); + + if (customHandleOperation(fInterpreter, left, right)) + return; + + int resultType = getJavaBinaryPromotionType(right, left); + IType type; + if (resultType == T_String) + type = left.getValueType(); + else + type = getBinaryPromotionType(right, left); + + // non-logical operations on booleans are int results + if ((type instanceof ICPPBasicType) && ((ICPPBasicType) type).getBaseType() == ICPPBasicType.t_bool) { + type = fInterpreter.getTypeEngine().getIntegerTypeFor(TypeUtils.BASIC_TYPE_INT, true); + } + + switch (resultType) { + case T_String: + pushNewValue(type, getStringResult(GetValue.getStringValue(left), GetValue.getStringValue(right))); + break; + case T_double: + pushNewValue(type, getDoubleResult(GetValue.getDoubleValue(left), GetValue.getDoubleValue(right))); + break; + case T_float: + pushNewValue(type, getFloatResult(GetValue.getFloatValue(left), GetValue.getFloatValue(right))); + break; + case T_long: + pushNewValue(type, getLongResult(GetValue.getLongValue(left), GetValue.getLongValue(right))); + break; + case T_int: + pushNewValue(type, getIntResult(GetValue.getIntValue(left), GetValue.getIntValue(right))); + break; + case T_boolean: + pushNewValue(type, getBooleanResult(GetValue.getBooleanValue(left), GetValue.getBooleanValue(right))); + break; + case T_BigInt: + pushNewValue(type, getBigIntegerResult(GetValue.getBigIntegerValue(left), GetValue.getBigIntegerValue(right), 8)); + break; + default: + throw EDCDebugger.newCoreException(ASTEvalMessages.UnhandledTypeCode + resultType); + } + } + + /** + * Handle type operation in a non-standard way + * @param fInterpreter + * @param left + * @param right + * @return true if handled + */ + protected boolean customHandleOperation(Interpreter fInterpreter, OperandValue left, OperandValue right) throws CoreException { + return false; + } + + /** + * Get int result of applying a binary operation to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return int result of the operation if possible, or an operation-specific + * default + * @throws CoreException + */ + protected abstract int getIntResult(int leftOperand, int rightOperand) throws CoreException; + + /** + * Get long result of applying a binary operation to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return long result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract long getLongResult(long leftOperand, long rightOperand) throws CoreException; + + /** + * Get BigInteger result of applying a binary operation to two longs + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return BigInteger result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException; + + /** + * Get float result of applying a binary operation to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return float result of the operation if possible, or an + * operation-specific default + */ + protected abstract float getFloatResult(float leftOperand, float rightOperand); + + /** + * Get double result of applying a binary operation to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return double result of the operation if possible, or an + * operation-specific default + */ + protected abstract double getDoubleResult(double leftOperand, double rightOperand); + + /** + * Get boolean result of applying a binary operation to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return boolean result of the operation if possible, or an + * operation-specific default + */ + protected abstract boolean getBooleanResult(boolean leftOperand, boolean rightOperand); + + /** + * Get string result of applying a binary operation to two strings. + * Default implementation throws. + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return string result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected String getStringResult(String leftOperand, String rightOperand) throws CoreException { + throw EDCDebugger.newCoreException(ASTEvalMessages.UnsupportedStringOperation); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/CompoundInstruction.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/CompoundInstruction.java new file mode 100644 index 0000000..720631d --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/CompoundInstruction.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +public abstract class CompoundInstruction extends Instruction { + + private int size; + + /** + * Constructor for a compound instruction + * + * @param start + * - instruction start + */ + protected CompoundInstruction(int start) { + size = -start; + } + + /** + * Set compound instruction end + * + * @param end + * - compound instruction end + */ + public void setEnd(int end) { + size += end; + } + + /** + * Get compound instruction size + * + * @return compound instruction size + */ + @Override + public int getSize() { + return size; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/EvaluateID.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/EvaluateID.java new file mode 100644 index 0000000..f9f97a3 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/EvaluateID.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.text.MessageFormat; +import java.util.List; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.dom.ast.IASTIdExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Symbols; +import org.eclipse.cdt.debug.edc.internal.symbols.InvalidVariableLocation; +import org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCModules; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.services.Stack.EnumeratorDMC; +import org.eclipse.cdt.debug.edc.services.Stack.IVariableEnumeratorContext; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.services.Stack.VariableDMC; +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.CoreException; + +public class EvaluateID extends SimpleInstruction { + + private String name; + private final ICPPASTQualifiedName qualifiedName; + + /** + * Constructor for ID (number + variable name) evaluate instruction + * + * @param idExpression + */ + public EvaluateID(IASTIdExpression idExpression) { + IASTName lookupName; + + if (idExpression.getName() instanceof ICPPASTQualifiedName) { + // the name has the form namespace::...::variable + qualifiedName = (ICPPASTQualifiedName) idExpression.getName(); + lookupName = qualifiedName.getLastName(); + } else { + lookupName = idExpression.getName(); + qualifiedName = null; + } + + name = new String(lookupName.getLookupKey()); + } + + /** + * Constructor for lookup of a specific literal name + * (presumably a local, like "this") + * + * @param name the literal name + */ + public EvaluateID(String name) { + this.name = name; + this.qualifiedName = null; + } + + /** + * Resolve a variable ID + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + + IDMContext context = getContext(); + + if (!(context instanceof StackFrameDMC)) + throw EDCDebugger.newCoreException(MessageFormat.format(ASTEvalMessages.EvaluateID_CannotResolveName, name)); + + StackFrameDMC frame = (StackFrameDMC) context; + EDCServicesTracker servicesTracker = frame.getEDCServicesTracker(); + IEDCModules modules = servicesTracker.getService(IEDCModules.class); + + // check by name for a variable or enumerator + IVariableEnumeratorContext variableOrEnumerator = frame.findVariableOrEnumeratorByName(name, qualifiedName != null ? qualifiedName.getRawSignature() : null, false); + VariableDMC variable = variableOrEnumerator instanceof VariableDMC ? + (VariableDMC)variableOrEnumerator : null; + EnumeratorDMC enumerator = variableOrEnumerator instanceof EnumeratorDMC ? + (EnumeratorDMC)variableOrEnumerator : null; + + // This may be called on debugger shutdown, in which case the "modules" + // service may have been shutdown. + if (variable != null && modules != null) { + IVariableLocation valueLocation = null; + ILocationProvider provider = variable.getVariable().getLocationProvider(); + IEDCModuleDMContext module = frame.getModule(); + if (module != null && provider != null) { + valueLocation = provider.getLocation(servicesTracker, frame, module.toLinkAddress(frame.getInstructionPtrAddress()), + TypeUtils.isConstType(variable.getVariable().getType())); + } + if (valueLocation == null) { + // unhandled + valueLocation = new InvalidVariableLocation(MessageFormat.format(ASTEvalMessages.EvaluateID_NameHasNoLocation, variable.getName())); + } + // create a VariableWithValue and push on the stack + VariableWithValue varWval = new VariableWithValue(servicesTracker, frame, variable.getVariable()); + varWval.setValueLocation(valueLocation); + push(varWval); + return; + } + + if (enumerator != null) { + // TODO: map IEnumerator to an IEnumeration and use the real type + pushNewValue(fInterpreter.getTypeEngine().getIntegerTypeOfSize(4, true), + enumerator.getEnumerator().getValue()); + return; + } + + // match against function names visible in the module + Symbols symbolsService = servicesTracker.getService(Symbols.class); + if (symbolsService != null) { + IEDCModuleDMContext module = frame.getModule(); + if (module != null) { + String searchName = name; + if (qualifiedName != null) + searchName = qualifiedName.getRawSignature(); + List addresses = symbolsService.getFunctionAddress(module, searchName); + if (addresses.size() > 0) { + pushNewValue(fInterpreter.getTypeEngine().getIntegerTypeOfSize(4, false), + addresses.get(0).getValue().longValue()); + return; + } + // show the whole qualified name in the exception message + name = searchName; + } + } + + // did not find a variable, enumerator, or function to match the expression + throw EDCDebugger.newCoreException( + MessageFormat.format(ASTEvalMessages.EvaluateID_VariableNotFound, name)); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/FieldReference.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/FieldReference.java new file mode 100644 index 0000000..fd3daa6 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/FieldReference.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.text.MessageFormat; + +import org.eclipse.cdt.core.dom.ast.IASTFieldReference; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.IAggregate; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICompositeType; +import org.eclipse.cdt.debug.edc.internal.symbols.IEnumeration; +import org.eclipse.cdt.debug.edc.internal.symbols.IField; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.IReferenceType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.debug.edc.symbols.VariableLocationFactory; +import org.eclipse.core.runtime.CoreException; + +/* + * Field reference instruction, such as "." or "->" + */ +public class FieldReference extends CompoundInstruction { + + private final IASTFieldReference refExpression; + + /** + * Constructor for field reference instruction + * + * @param expression + * - field reference expression + * @param start + * - instruction start + */ + public FieldReference(IASTFieldReference expression, int start) { + super(start); + this.refExpression = expression; + } + + /** + * Resolve a field reference operator, such as "." or "->" + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + // pop the structure variable at the start of the field references + OperandValue operand = popValue(); + + if (operand == null) + return; + + IType variableType = TypeUtils.getStrippedType(operand.getValueType()); + + IVariableLocation location = null; + boolean referenceType = variableType instanceof IReferenceType; + + if (refExpression.isPointerDereference()) { + // '->' operator requires a pointer type + boolean validPointerType = variableType instanceof IPointerType; + + if (!validPointerType) { + throw EDCDebugger.newCoreException(ASTEvalMessages.FieldReference_InvalidPointerDeref); + } + + IPointerType pointer = (IPointerType) variableType; + + IType pointedTo = pointer.getType(); + variableType = TypeUtils.getStrippedType(pointedTo); + } else if (referenceType) { + // '.' may be used with a reference "&" type + IReferenceType pointer = (IReferenceType) variableType; + + IType pointedTo = pointer.getType(); + variableType = TypeUtils.getStrippedType(pointedTo); + } + + if (!TypeUtils.isCompositeType(variableType)) { + throw EDCDebugger.newCoreException(ASTEvalMessages.FieldReference_InvalidDotDeref); + } + + // get the field/member + ICompositeType compositeType = (ICompositeType) variableType; + String fieldName = refExpression.getFieldName().toString(); + IField[] fields = compositeType.findFields(fieldName); + + if (fields == null) { + throw EDCDebugger.newCoreException( + MessageFormat.format(ASTEvalMessages.FieldReference_InvalidMember, fieldName)); + } + + if (fields.length > 1) { + throw EDCDebugger.newCoreException( + MessageFormat.format(ASTEvalMessages.FieldReference_AmbiguousMember, fieldName, + operand.getValueType().getName())); + } + + // type and address of the field + IField field = fields[0]; + IType typeOfField = field.getType(); + + if ( refExpression.isPointerDereference() + || (!refExpression.isPointerDereference() && referenceType)) { + // pointer with '->' operator, or reference with '.' + location = VariableLocationFactory.createMemoryVariableLocation( + fInterpreter.getServicesTracker(), fInterpreter.getContext(), + operand.getValue()); + } else { + // '.' operator + location = operand.getValueLocation(); + } + + location = location.addOffset(field.getFieldOffset()); + + OperandValue varValue = new OperandValue(typeOfField, field.getBitSize() > 0); + + typeOfField = TypeUtils.getStrippedType(typeOfField); + + // for lvalues (base arithmetic types, enums, and pointers), read the + // value and cast it to the right type + if ( typeOfField instanceof ICPPBasicType || typeOfField instanceof IPointerType + || typeOfField instanceof IEnumeration || typeOfField instanceof IReferenceType) { + int byteSize = typeOfField.getByteSize(); + + // TODO support 12-byte long double + if (byteSize != 1 && byteSize != 2 && byteSize != 4 && byteSize != 8 && + !(typeOfField instanceof IPointerType && byteSize == 0)) { + throw EDCDebugger.newCoreException(ASTEvalMessages.FieldReference_UnhandledOperandSize + byteSize); + } + + // read the value pointed to + Number newValue = varValue.getValueByType(typeOfField, location); + + // if this is a bit-field, then mask and/or extend the value + // appropriately + // Note: only unnamed bit-fields have a 0 bit size, so a named field + // with a 0 bit size is not a bit-field + if (field.getBitSize() > 0) { + int bitSize = field.getBitSize(); + int bitOffset = field.getBitOffset(); + boolean isSignedInt = false; + + if (typeOfField instanceof ICPPBasicType) + isSignedInt = ((ICPPBasicType) typeOfField).isSigned(); + else if (typeOfField instanceof IEnumeration) + isSignedInt = true; + + newValue = TypeUtils.extractBitField(newValue, byteSize, bitSize, bitOffset, isSignedInt); + } + varValue.setValue(newValue); + varValue.setValueLocation(location); + + } else if (typeOfField instanceof IAggregate) { + // for aggregates, the address of the aggregate is the value + // returned + varValue.setAddressValue(location); + varValue.setValueLocation(location); + + } else { + throw EDCDebugger.newCoreException(ASTEvalMessages.FieldReference_CannotDereferenceType); + } + + push(varValue); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/GetValue.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/GetValue.java new file mode 100644 index 0000000..fcaf336 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/GetValue.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.core.runtime.CoreException; + +/** + * Get the correct type of value from an object, converting if needed. + *

    + * All of these expect to be called with values no larger than their types (e.g. by {@link Instruction#convertForPromotion(Object)}) + * so we throw exceptions if not. + */ +public class GetValue { + + private static CoreException badType() { + return EDCDebugger.newCoreException(ASTEvalMessages.GetValue_TypePromotionError); + } + + /** + * Get the boolean value of an object + * + * @param value + * - possibly Boolean object + * @return boolean value of param, or false if param is not a Boolean object + */ + public static boolean getBooleanValue(OperandValue op) throws CoreException { + Number value = op.getValue(); + if (value instanceof BigInteger) + return ((BigInteger) value).signum() != 0 ? true : false; + return value.longValue() != 0; + } + + /** + * Get the integer value of an object + * + * @param value + * - possibly Integer, Short, or Byte object + * @return integer value of param, or 0 if param is not an integer object + */ + public static int getIntValue(OperandValue op) throws CoreException { + Number value = op.getValue(); + if (value instanceof Integer) + return (Integer) value; + if (value instanceof Short) + return new Integer((Short) value); + if (value instanceof Byte) + return new Integer((Byte) value); + throw badType(); + } + + /** + * Get the long value of an object + * + * @param value value with Long, Integer, Short, or Byte value + * @return long value of param, or 0 if param is not an integral object + */ + public static long getLongValue(OperandValue op) throws CoreException { + Number value = op.getValue(); + if (value instanceof Long) + return (Long) value; + if (value instanceof Integer) + return new Long((Integer) value); + if (value instanceof Short) + return new Long((Short) value); + if (value instanceof Byte) + return new Long((Byte) value); + throw badType(); + } + + /** + * Get the BigInteger value of an object + * + * @param value value with possibly BigInteger, Long, Integer, Short, Byte, or + * Character object + * @return BigInteger value of param, or 0 if param is not an integral + * object + */ + public static BigInteger getBigIntegerValue(OperandValue op) throws CoreException { + Number value = op.getValue(); + if (value instanceof BigInteger) + return (BigInteger) value; + if (value instanceof Long) + return new BigInteger(((Long) value).toString()); + if (value instanceof Integer) + return new BigInteger(((Integer) value).toString()); + if (value instanceof Short) + return new BigInteger(((Short) value).toString()); + if (value instanceof Byte) + return new BigInteger(new byte[] { (Byte) value }); + //if (value instanceof Character) + // return new BigInteger(new byte[] { (byte) Character.getNumericValue((Character) value) }); + throw badType(); + } + + /** + * Get the float value of an object + * + * @param value with possibly Float or integral (e.g., Long) object + * @return float value of param, or 0 if param is not a Float or integral + * object + */ + public static float getFloatValue(OperandValue op) throws CoreException { + Number value = op.getValue(); + if (value instanceof Float) + return (Float) value; + if (value instanceof Long) + return new Float((Long) value); + if (value instanceof Integer) + return new Float((Integer) value); + if (value instanceof Short) + return new Float((Short) value); + if (value instanceof Byte) + return new Float((Byte) value); + if (value instanceof BigInteger) + return new Float(((BigInteger) value).floatValue()); + throw badType(); + } + + /** + * Get the double value of an object + * + * @param value + * - possibly float (e.g., Double) or integral (e.g., Long) + * object + * @return double value of param, or 0 if param is not a float or integral + * object + */ + public static double getDoubleValue(OperandValue op) throws CoreException { + Number value = op.getValue(); + if (value instanceof Double) + return (Double) value; + if (value instanceof Float) + return new Double((Float) value); + if (value instanceof Long) + return new Double((Long) value); + if (value instanceof Integer) + return new Double((Integer) value); + if (value instanceof Short) + return new Double((Short) value); + if (value instanceof Byte) + return new Double((Byte) value); + if (value instanceof BigInteger) + return new Double(((BigInteger) value).doubleValue()); + throw badType(); + } + + /** + * Get the string value of an object + * + * @param value + * - String or Character object + * @return string value of String param, or quoted string for Character + * param + */ + public static String getStringValue(OperandValue value) throws CoreException { + if (value.getStringValue() != null) + return value.getStringValue(); + return "\"" + (char) (value.getValue().longValue()) + "\""; //$NON-NLS-1$ //$NON-NLS-2$ + //throw badType(); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/IArrayDimensionType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/IArrayDimensionType.java new file mode 100644 index 0000000..bf50556 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/IArrayDimensionType.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.cdt.debug.edc.internal.symbols.IAggregate; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; + +public interface IArrayDimensionType extends IAggregate { + + public IArrayType getArrayType(); + + public IVariableLocation getLocation(); + + public int getDimensionCount(); + + public void addDimension(long subscript, long increase); +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/IInvalidExpression.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/IInvalidExpression.java new file mode 100644 index 0000000..684b7ea --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/IInvalidExpression.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +/** + * Invalid expression + */ +public interface IInvalidExpression { + + /** + * Get message telling why the expression is invalid + * + * @return messsage + */ + public String getMessage(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/Instruction.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/Instruction.java new file mode 100644 index 0000000..87f5942 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/Instruction.java @@ -0,0 +1,521 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; +import java.text.MessageFormat; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICompositeType; +import org.eclipse.cdt.debug.edc.internal.symbols.IEnumeration; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.CoreException; + +public abstract class Instruction { + + protected static BigInteger Mask8Bytes = new BigInteger("ffffffffffffffff", 16); //$NON-NLS-1$ + + protected Interpreter fInterpreter; + + /** + * Get instruction size + * + * return instruction size + */ + public abstract int getSize(); + + /** + * Set instruction's fInterpreter + * + * @param interpreter + */ + public void setInterpreter(Interpreter interpreter) { + fInterpreter = interpreter; + } + + /** + * Stop the instruction fInterpreter + */ + public void stop() { + fInterpreter.stop(); + } + + /** + * Execute the instruction + * @throws CoreException + */ + public abstract void execute() throws CoreException; + + /** + * Get the instruction's context + * + * @return instruction fInterpreter context + */ + protected IDMContext getContext() { + return fInterpreter.getContext(); + } + + /** + * Jump to an instruction fInterpreter offset + * + * @param offset + * - fInterpreter offset + */ + protected void jump(int offset) { + fInterpreter.jump(offset); + } + + /** + * Push an object on the instruction stack + * + * @param op + */ + protected OperandValue push(OperandValue op) { + fInterpreter.push(op); + return op; + } + + /** + * Pop an object off the instruction stack + * + * @return object on the top of the stack + */ + protected OperandValue pop() { + return fInterpreter.pop(); + } + + /** + * Pop a value from the instruction stack + * + * @return current top of stack, if the stack is not empty, or + * null otherwise + * @throws CoreException + */ + protected OperandValue popValue() throws CoreException { + OperandValue value = null; + if (!fInterpreter.isEmpty()) + value = fInterpreter.pop(); + if (value == null) + throw EDCDebugger.newCoreException(ASTEvalMessages.Instruction_EmptyStack); + return value; + } + + /** + * Push a boolean on the instruction stack + * + * @param value + * - boolean value + */ + protected OperandValue pushNewValue(IType type, boolean value) { + OperandValue op = new OperandValue(value ? 1 : 0, type); + fInterpreter.push(op); + return op; + } + + + /** + * Push a number on the instruction stack + * + * @param value + * - number value + */ + protected OperandValue pushNewValue(IType type, Number value) { + OperandValue op = new OperandValue(value, type); + fInterpreter.push(op); + return op; + } + + /** + * Push a string on the instruction stack + * + * @param value + * - string value + */ + protected OperandValue pushNewValue(IType type, String value) { + OperandValue op = new OperandValue(value, type); + fInterpreter.push(op); + return op; + } + + /** + * Convert operands to types expected by getBinaryPromotionType() (e.g., + * VariableWithValue to its underlying Long) + * + * @param operand + * - original operand + * @return result operand type + * @throws CoreException if value cannot be fetched + */ + protected OperandValue convertForPromotion(OperandValue operand) throws CoreException { + IType type = getBasicType(operand.getValueType()); + if (type instanceof ICompositeType) { + throw EDCDebugger.newCoreException(ASTEvalMessages.Instruction_CannotUseCompositeType); + } + if (type instanceof IArrayType && operand.getValueLocation() != null) { + // take address as value + return new OperandValue(operand.getValueLocationAddress(), fInterpreter.getTypeEngine().getPointerSizeType()); + } + return operand; + } + + /** + * Get result binary operation type given types of the left and right + * operands, according to Java rules + * + * @param left + * - left operand + * @param right + * - right operand + * @return result T_ type + * @throws CoreException + */ + public int getJavaBinaryPromotionType(OperandValue left, OperandValue right) throws CoreException { + int leftType = getValueType(left); + int rightType = getValueType(right); + return fTypeTable[leftType][rightType]; + } + + /** + * Get result binary operation type given types of the left and right + * operands + * + * @param left + * - left operand T_ type + * @param right + * - right operand T_type + * @return result T_ type + */ + public int getBinaryPromotionType(int left, int right) { + return fTypeTable[left][right]; + } + + /** + * Get T_ type for a base Java type (e.g., Character or Boolean). + *

    + * This differs from the actual C type in that we pick the Java + * type that has the same size as the C type. I.e., "char" of size 1 + * becomes T_byte and "wchar_t" of size 4 becomes T_int. + * + * @param value + * - base Java type object + * @return corresponding T_ type, or T_undefined if value is not a base type + * @throws CoreException + */ + public int getValueType(OperandValue op) throws CoreException { + Number value = op.getValue(); + if (value == null) { + if (op.getStringValue() != null) + return T_String; + } + // respect Java types first, since C types can alias (e.g. int == long) + if (value instanceof Integer) + return T_int; + if (value instanceof Short) + return T_short; + if (value instanceof Byte) + return T_byte; + if (value instanceof Long) + return T_long; + if (value instanceof Float) + return T_float; + if (value instanceof Double) + return T_double; + if (value instanceof BigInteger) + return T_BigInt; + + return getJavaValueType(op.getValueType()); + } + + /** + * Get T_ type corresponding to the given C type. This is used for promotion. + * Note: in this interpretation, long long maps to T_BigInt. + * + * @param type the basic type + * @return corresponding T_ type, or T_undefined if value is not a base type + * @throws CoreException + */ + public int getCValueType(OperandValue op) throws CoreException { + if (op.getStringValue() != null) { + return T_String; + } + + IType type_ = getBasicType(op.getValueType()); + + if (!(type_ instanceof ICPPBasicType)) + return T_undefined; + + ICPPBasicType type = (ICPPBasicType) type_; + + switch (type.getBaseType()) { + case ICPPBasicType.t_bool: + return T_boolean; + case ICPPBasicType.t_char: + return T_char; + case ICPPBasicType.t_float: + return T_float; + case ICPPBasicType.t_double: + if (type.isLong()) + assert(false); // TODO; need long double type + return T_double; + case ICPPBasicType.t_int: + if (type.isLongLong()) + return T_BigInt; + if (type.isLong()) + return T_long; + if (type.isShort()) + return T_short; + return T_int; + case ICPPBasicType.t_unspecified: + return T_undefined; + case ICPPBasicType.t_void: + return T_void; + } + return T_undefined; + } + + /** + * Get result binary operation type given types of the left and right + * operands. This uses the C rules for type promotion. + * + * @param left + * - left type + * @param right + * - right type + * @return result type or null if an undefined promotion + */ + public IType getBinaryPromotionType(OperandValue leftOp, OperandValue rightOp) throws CoreException { + + int leftType = getCValueType(leftOp); + int rightType = getCValueType(rightOp); + int promoted = getBinaryPromotionType(leftType, rightType); + + if (promoted == T_null || promoted == T_undefined || promoted == T_void) + throw EDCDebugger.newCoreException(MessageFormat.format(ASTEvalMessages.Instruction_UnhandledTypeCombination, + leftOp.getValueType().getName(), rightOp.getValueType().getName())); + + // promoted type loses qualifier bits and enum-ness + if (leftType == promoted) + return getBasicType(leftOp.getValueType()); + if (rightType == promoted) + return getBasicType(rightOp.getValueType()); + + // we're here because the promoted type is bigger than either of the + // incoming types (e.g. short + float -> double) + + boolean isSigned = true; + + switch (promoted) { + case T_char: + return fInterpreter.getTypeEngine().getIntegerTypeFor(TypeUtils.BASIC_TYPE_CHAR, isSigned); + case T_short: + return fInterpreter.getTypeEngine().getIntegerTypeFor(TypeUtils.BASIC_TYPE_SHORT, isSigned); + case T_int: + return fInterpreter.getTypeEngine().getIntegerTypeFor(TypeUtils.BASIC_TYPE_INT, isSigned); + case T_long: + return fInterpreter.getTypeEngine().getIntegerTypeFor(TypeUtils.BASIC_TYPE_LONG, isSigned); + case T_float: + return fInterpreter.getTypeEngine().getFloatTypeOfSize(TypeUtils.BASIC_TYPE_FLOAT); + case T_double: + return fInterpreter.getTypeEngine().getFloatTypeOfSize(TypeUtils.BASIC_TYPE_DOUBLE); + // TODO: long double + + case T_byte: // should not happen + case T_null: // should not happen + case T_Object: // should not happen + case T_String: // should not happen + default: + assert(false); + throw EDCDebugger.newCoreException(ASTEvalMessages.UnhandledTypeCode + promoted); + } + } + + /** + * Get the stripped down basic type that promotion rules work with. + * Ignore const/volatile/... qualifiers, demote enums to ints, etc. + * @param type + * @return adjusted type + */ + private IType getBasicType(IType type) { + type = TypeUtils.getStrippedType(type); + if (type instanceof IEnumeration) { + // discover the appropriate integer to hold this + int byteSize = ((IEnumeration) type).getByteSize(); + type = fInterpreter.getTypeEngine().getIntegerTypeOfSize(byteSize, true); + } + return type; + } + + /** + * Get T_ type for a base Java type that can hold a given type + * (e.g., Character or Boolean). + *

    + * This differs from the actual C type in that we pick the Java + * type that has a compatible size as the C type. I.e., "char" of size 1 + * becomes T_byte and "wchar_t" of size 4 becomes T_int. (An actual + * target may have larger or smaller primitive types than Java.) + *

    + * Note: when we do unsigned math, we go up one type size in order to handle + * unsigned math properly. + * + * @param value + * - base Java type object + * @return corresponding T_ type, T_string, or T_undefined if value is not a base or string type + */ + public int getJavaValueType(IType type_) { + type_ = getBasicType(type_); + if (!(type_ instanceof ICPPBasicType)) { + if (type_ instanceof IArrayType && type_.getType() instanceof ICPPBasicType + && ((((ICPPBasicType) type_.getType()).getBaseType() == ICPPBasicType.t_char + || ((ICPPBasicType) type_.getType()).getBaseType() == ICPPBasicType.t_wchar_t))) { + return T_String; + } + return T_undefined; + } + + ICPPBasicType type = (ICPPBasicType) type_; + + switch (type.getBaseType()) { + case ICPPBasicType.t_bool: + return T_boolean; + case ICPPBasicType.t_char: + return T_char; + case ICPPBasicType.t_float: + return T_float; + case ICPPBasicType.t_double: + if (type.isLong()) + assert(false); // TODO + return T_double; + case ICPPBasicType.t_unspecified: + return T_undefined; + case ICPPBasicType.t_void: + return T_void; + case ICPPBasicType.t_int: + if (type.isLongLong()) { + if (type.getByteSize() > 8 || (type.getByteSize() == 8 && type.isUnsigned())) + return T_BigInt; // java long cannot handle unsigned 8-byte math + else + return T_long; + } + if (type.isLong()) { + if (type.getByteSize() > 8 || (type.getByteSize() == 8 && type.isUnsigned())) + return T_BigInt; // java long cannot handle unsigned 8-byte math + else + return T_long; + } + switch (type.getByteSize()) { + case 1: + if (type.isUnsigned()) + return T_short; + else + return T_byte; + case 2: + if (type.isUnsigned()) + return T_int; + else + return T_short; + case 4: + if (type.isUnsigned()) + return T_int; + else + return T_short; + } + if (type.isLong()) { + if (type.isUnsigned() && type.getByteSize() > 8) + return T_BigInt; + else + return T_long; + } + + + } + return T_undefined; + } + + static public final int T_undefined = 0; + static public final int T_Object = 1; + static public final int T_char = 2; + static public final int T_byte = 3; + static public final int T_short = 4; + static public final int T_boolean = 5; + static public final int T_void = 6; + static public final int T_long = 7; + static public final int T_double = 8; + static public final int T_float = 9; + static public final int T_int = 10; + static public final int T_String = 11; + static public final int T_null = 12; + static public final int T_BigInt = 13; + + private static final int[][] fTypeTable = { + // undefined object char byte short boolean void + /* undefined */ { T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, + // long double float int String null BigInteger + T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined}, + // undefined object char byte short boolean void + /* object */ { T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, + // long double float int String null BigInteger + T_undefined, T_undefined, T_undefined, T_undefined, T_String, T_undefined, T_undefined }, + // undefined object char byte short boolean void + /* char */ { T_undefined, T_undefined, T_int, T_int, T_int, T_undefined, T_undefined, + // long double float int String null BigInteger + T_long, T_double, T_float, T_int, T_String, T_undefined, T_BigInt }, + // undefined object char byte short boolean void + /* byte */ { T_undefined, T_undefined, T_int, T_int, T_int, T_undefined, T_undefined, + // long double float int String null BigInteger + T_long, T_double, T_float, T_int, T_String, T_undefined, T_BigInt }, + // undefined object char byte short boolean void + /* short */ { T_undefined, T_undefined, T_int, T_int, T_int, T_undefined, T_undefined, + // long double float int String null BigInteger + T_long, T_double, T_float, T_int, T_String, T_undefined, T_BigInt }, + // undefined object char byte short boolean void + /* boolean */ { T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_boolean, T_undefined, + // long double float int String null BigInteger + T_undefined, T_undefined, T_undefined, T_undefined, T_String, T_undefined, T_undefined }, + // undefined object char byte short boolean void + /* void */ { T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, + // long double float int String null BigInteger + T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined }, + // undefined object char byte short boolean void + /* long */ { T_undefined, T_undefined, T_long, T_long, T_long, T_undefined, T_undefined, + // long double float int String null BigInteger + T_long, T_double, T_float, T_long, T_String, T_undefined, T_BigInt }, + // undefined object char byte short boolean void + /* double */ { T_undefined, T_undefined, T_double, T_double, T_double, T_undefined, T_undefined, + // long double float int String null BigInteger + T_double, T_double, T_double, T_double, T_String, T_undefined, T_double }, + // undefined object char byte short boolean void + /* float */ { T_undefined, T_undefined, T_float, T_float, T_float, T_undefined, T_undefined, + // long double float int String null BigInteger + T_float, T_double, T_float, T_float, T_String, T_undefined, T_float }, + // undefined object char byte short boolean void + /* int */ { T_undefined, T_undefined, T_int, T_int, T_int, T_undefined, T_undefined, + // long double float int String null BigInteger + T_long, T_double, T_float, T_int, T_String, T_undefined, T_BigInt }, + // undefined object char byte short boolean void + /* String */ { T_undefined, T_String, T_String, T_String, T_String, T_String, T_undefined, + // long double float int String null BigInteger + T_String, T_String, T_String, T_String, T_String, T_String, T_undefined }, + // undefined object char byte short boolean void + /* null */ { T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, T_undefined, + // long double float int String null BigInteger + T_undefined, T_undefined, T_undefined, T_undefined, T_String, T_undefined, T_undefined }, + // undefined object char byte short boolean void + /* BigInteger */{ T_undefined, T_undefined, T_BigInt, T_BigInt, T_BigInt, T_undefined, T_undefined, + // long double float int String null BigInteger + T_BigInt, T_double, T_float, T_BigInt, T_undefined, T_undefined, T_BigInt }, + }; + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/InstructionSequence.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/InstructionSequence.java new file mode 100644 index 0000000..e417b20 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/InstructionSequence.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeEngine; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/** + * Instruction sequence + */ +public class InstructionSequence { + + private List fInstructions; + /** + * A collection of error messages (String) that occurred while + * creating this expression + */ + private List fErrors; + private String fSnippet; + private CoreException fException; + + /** + * Constructor for an instruction sequence + * + * @param snippet + * - expression the instruction sequence represents + */ + public InstructionSequence(String snippet) { + fInstructions = new ArrayList(10); + fErrors = new ArrayList(); + fSnippet = snippet; + } + + /** + * Copy constructor + * + * @param original - the instance to copy + */ + public InstructionSequence(InstructionSequence original) { + fInstructions = new ArrayList(Arrays.asList(original.getInstructions())); + fErrors = new ArrayList(Arrays.asList(original.getErrorMessages())); + fSnippet = original.getSnippet(); + fException = original.getException(); + } + + /** + * Get the runtime exception that occurred while evaluating this expression + * + * @param runtime + * exception, or null if no exception occurred + */ + public CoreException getException() { + return fException; + } + + /** + * @see ICompiledExpression#getSnippet() + */ + public String getSnippet() { + return fSnippet; + } + + /** + * Adds the given error to the list of errors that occurred while compiling + * this instruction sequence + */ + public void addError(String error) { + fErrors.add(error); + } + + /** + * @see ICompiledExpression#hasErrors() + */ + public boolean hasErrors() { + return !fErrors.isEmpty(); + } + + /** + * @see org.eclipse.jdt.debug.eval.ICompiledExpression#getErrorMessages() + */ + public String[] getErrorMessages() { + return fErrors.toArray(new String[fErrors.size()]); + } + + /** + * Get the array of instructions + * + * return array of instructions, or an empty array + */ + public Instruction[] getInstructions() { + int size = fInstructions.size(); + Instruction[] instructions = new Instruction[size]; + if (size > 0) { + fInstructions.toArray(instructions); + } + return instructions; + } + + /** + * Get the instruction at the given address + * + * @param address + * - address of instruction + * @return instruction at the address + */ + public Instruction getInstruction(int address) { + return fInstructions.get(address); + } + + /** + * Add the given instruction to the end of the list + * + * @param instruction + * - instruction to add + */ + public void add(Instruction instruction) { + fInstructions.add(instruction); + } + + /** + * Get the index of an instruction + * + * @param instruction + * - instruction to find + * @return index of instruction, or -1 if the instruction does not exist + */ + public int indexOf(Instruction instruction) { + return fInstructions.indexOf(instruction); + } + + /** + * Tell whether the instruction sequence is empty + * + * @return true if the instruction sequence is empty, and false otherwise + */ + public boolean isEmpty() { + return fInstructions.isEmpty(); + } + + /** + * Insert the instruction at the given index. If the index is less than 0 or + * greater than the current instruction count, the instruction is added at + * the end of the sequence. + * + * Instructs the instructions to update their program counters. + */ + public void insert(Instruction instruction, int index) { + fInstructions.add(index, instruction); + } + + /** + * Get the instruction at the given address + * + * @param address + * - instruction address + * @return instruction at the given address + */ + public Instruction get(int address) { + return fInstructions.get(address); + } + + /** + * Get the index of the last instruction in the sequence + * + * @return size of the instruction sequence - 1 + */ + public int getEnd() { + return fInstructions.size() - 1; + } + + /** + * Remove no-ops from the instruction list + */ + public void removeNoOps() { + for (Iterator iter = fInstructions.iterator(); iter.hasNext(); ) { + if (iter.next() instanceof NoOp) { + iter.remove(); + } + } + } + + /** + * Fixup instructions like: *(*)& + *

    + * We want to avoid getting the address of a register or bitfield and + * causing an error, so just make a synthetic "cast value" operator here. + *

    + * If there is a concern about incorrectly avoiding an error here -- + * "if the variable is in a register, then this should fail" -- I argue that + * the user doesn't necessarily know it's in a register at compile time, and + * we should try harder to allow evaluating such an expression. Asking him to + * modify and rebuild his code so the variable will be in memory is a bit draconian. + * @param typeEngine + */ + public void reduceCasts(TypeEngine typeEngine) { + boolean anyChanges = false; + for (int i = 0; i < fInstructions.size(); i++) { + Instruction inst = fInstructions.get(i); + if ((inst instanceof OperatorAddrOf) && i + 1 < fInstructions.size()) { + Instruction inst2 = fInstructions.get(i + 1); + if (inst2 instanceof OperatorCast && i + 2 < fInstructions.size()) { + Instruction inst3 = fInstructions.get(i + 2); + if (inst3 instanceof OperatorIndirection) { + // see if it's a pointer or array + IType castType = null; + try { + castType = TypeUtils.getStrippedType(((OperatorCast) inst2).getCastType(typeEngine)); + } catch (CoreException e) { + // ignore + continue; + } + if (castType instanceof IPointerType || castType instanceof IArrayType) { + OperatorCastValue cv = new OperatorCastValue(inst.getSize(), castType.getType()); + fInstructions.set(i, cv); + fInstructions.set(i + 1, new NoOp(inst2.getSize())); + fInstructions.set(i + 2, new NoOp(inst3.getSize())); + anyChanges = true; + } + } + } else if (inst2 instanceof OperatorCastValue) { + // see if it's a pointer or array + IType castType; + try { + castType = TypeUtils.getStrippedType(((OperatorCastValue)inst2).getCastType(typeEngine)); + } catch (CoreException e) { + // ignore + continue; + } + if (castType instanceof IPointerType || castType instanceof IArrayType) { + OperatorCastValue cv = new OperatorCastValue(inst.getSize(), castType.getType()); + fInstructions.set(i, cv); + fInstructions.set(i + 1, new NoOp(inst2.getSize())); + anyChanges = true; + } + } + } + } + if (anyChanges) { + removeNoOps(); + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/Interpreter.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/Interpreter.java new file mode 100644 index 0000000..4ceae01 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/Interpreter.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.util.EmptyStackException; +import java.util.Stack; + +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.symbols.TypeEngine; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.CoreException; + +public class Interpreter { + private final Instruction[] instructions; + private int instructionCounter; + private final IDMContext context; + private Stack stack; + private OperandValue lastValue; + + private boolean fStopped = false; + private final EDCServicesTracker tracker; + private final TypeEngine typeEngine; + + /** + * Constructor for fInterpreter + * @param context + * @param instructionSequence + * - instruction sequence to execute + * @param context + * - instruction context + */ + public Interpreter(EDCServicesTracker tracker, IDMContext context, + TypeEngine typeEngine, + InstructionSequence instructionSequence) { + this.tracker = tracker; + this.context = context; + this.typeEngine = typeEngine; + this.instructions = instructionSequence.getInstructions(); + } + + public EDCServicesTracker getServicesTracker() { + return tracker; + } + + /** + * Execute an instruction sequence + * + * @throws CoreException + */ + public void execute() throws CoreException { + reset(); + while (instructionCounter < instructions.length && !fStopped) { + Instruction instruction = instructions[instructionCounter++]; + synchronized(instruction) + { + Interpreter old = instruction.fInterpreter; + instruction.setInterpreter(this); + instruction.execute(); + instruction.setInterpreter(old); + } + } + } + + /** + * Stop the fInterpreter + */ + public void stop() { + fStopped = true; + } + + /** + * Reset the fInterpreter + */ + private void reset() { + stack = new Stack(); + instructionCounter = 0; + } + + /** + * Jump to a relative instruction counter offset + * + * @param offset + * - offset from the current instruction counter + */ + public void jump(int offset) { + instructionCounter += offset; + } + + /** + * Push an object on the stack. Disables garbage collection for any interim + * object pushed onto the stack. Objects are released after the evaluation + * completes. + * + * @param object + */ + public void push(OperandValue object) { + stack.push(object); + } + + /** + * Tell whether the stack is empty + * + * @return true if the stack is empty, and false otherwise + */ + public boolean isEmpty() { + return stack.isEmpty(); + } + + /** + * Peek at the top object of the stack + * + * @return object on the top of the stack + */ + public OperandValue peek() { + return stack.peek(); + } + + /** + * Pop an object off of the stack + * + * @return object on the top of the stack + */ + public OperandValue pop() throws EmptyStackException { + return stack.pop(); + } + + /** + * Get the context for the fInterpreter + * + * @return fInterpreter context + */ + public IDMContext getContext() { + return context; + } + + /** + * Get current instruction result + * + * @return current top of stack, or the last stack value if the stack is + * null or empty + */ + public OperandValue getResult() { + if (stack == null || stack.isEmpty()) { + return lastValue; + } + OperandValue top = stack.peek(); + return top; + } + + public TypeEngine getTypeEngine() { + return typeEngine; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/NoOp.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/NoOp.java new file mode 100644 index 0000000..e706b7e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/NoOp.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.core.runtime.CoreException; + +/* + * No-op instruction + */ +public class NoOp extends CompoundInstruction { + + /** + * Constructor for no-op instruction + * + * @param start + * - instruction start + */ + public NoOp(int start) { + super(start); + } + + /** + * Resolve a no-op instruction + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperandValue.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperandValue.java new file mode 100644 index 0000000..56af32c --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperandValue.java @@ -0,0 +1,409 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; +import java.text.MessageFormat; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.IAggregate; +import org.eclipse.cdt.debug.edc.internal.symbols.IBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.IEnumeration; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.IQualifierType; +import org.eclipse.cdt.debug.edc.internal.symbols.IReferenceType; +import org.eclipse.cdt.debug.edc.internal.symbols.TypedefType; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.symbols.IEnumerator; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.debug.edc.symbols.VariableLocationFactory; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.CoreException; + +/** + * This is the basic unit of work when evaluating expressions. It carries + * a type and a number. Subclasses like {@link VariableWithValue} may hold + * additional information, like a specific variable and a location. + */ +public class OperandValue { + + protected IVariableLocation valueLocation; + + protected Number value; + protected String stringValue; + protected IType type; + protected boolean isBitField; + + + public OperandValue(IType type) { + this(type, false); + } + + public OperandValue(IType type, boolean isBitField) { + this.type = type; + this.isBitField = isBitField; + } + + // operand order switched so we don't accidentally invoke isBitField variant with Boolean + public OperandValue(Number value, IType type) { + this.type = type; + this.value = value; + } + + public OperandValue(String string, IType type) { + this(type, false); + this.stringValue = string; + } + + /** + * @return the type + */ + public IType getValueType() { + return type; + } + + public IVariableLocation getValueLocation() { + return valueLocation; + } + + public void setValueLocation(IVariableLocation valueLocation) { + this.valueLocation = valueLocation; + } + + public Number getValueLocationAddress() throws CoreException { + IVariableLocation location = getValueLocation(); + if (location == null) + throw EDCDebugger.newCoreException(ASTEvalMessages.OperandValue_VariableNoAddress); + return getLocationAddress(location); + } + + public Number getValueByType(IType varType, IVariableLocation location) + throws CoreException { + Number result; + + if (varType != null) { + if (varType instanceof ICPPBasicType) + result = getBasicTypeValue(varType, location); + else if (varType instanceof IPointerType) + result = getBasicTypeValue(varType, location); + else if (varType instanceof IReferenceType) { + result = getBasicTypeValue(varType, location); + + // use result as the location of the referenced variable's value + if (location != null && location.getContext() != null && location.getServicesTracker() != null) { + IDMContext context = location.getContext(); + EDCServicesTracker servicesTracker = location.getServicesTracker(); + IType pointedTo = TypeUtils.getStrippedType(varType).getType(); + if (pointedTo instanceof ICPPBasicType || pointedTo instanceof IPointerType || + pointedTo instanceof IEnumeration) { + IVariableLocation newLocation = VariableLocationFactory.createMemoryVariableLocation(servicesTracker, context, result); + setValueLocation(newLocation); + result = getBasicTypeValue(pointedTo, newLocation); + } + } + } else if (varType instanceof IAggregate) + result = getAggregateTypeValue((IAggregate) varType, location); + else if (varType instanceof IQualifierType || varType instanceof TypedefType) + result = getValueByType(varType.getType(), location); + else if (varType instanceof IEnumeration) + result = getBasicTypeValue(varType, location); + else { + assert false; + throw EDCDebugger.newCoreException(ASTEvalMessages.VariableWithValue_UnhandledType + varType.getName()); + } + } else { + throw EDCDebugger.newCoreException(ASTEvalMessages.VariableWithValue_VariableHasNoType); + } + return result; + } + + public Number getValue() throws CoreException { + return value; + } + + public void setValue(Number value) { + this.value = value; + } + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + public void setAddressValue(IVariableLocation location) throws CoreException { + setValue(getLocationAddress(location)); + } + + protected Number getLocationAddress(IVariableLocation location) throws CoreException { + IAddress addr = location.getAddress(); + if (addr == null) + throw EDCDebugger.newCoreException( + MessageFormat.format(ASTEvalMessages.OperandValue_CannotGetAddress, location.getLocationName())); + return addr.getValue(); + } + + private Number getAggregateTypeValue(IAggregate varType, IVariableLocation location) + throws CoreException { + // assumes that an array, class, struct, or union is always located in + // memory, not in a register + return getLocationAddress(location); + } + + private Number getBasicTypeValue(IType varType, IVariableLocation location) + throws CoreException { + if (EDCTrace.VARIABLE_VALUE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { varType, location })); } + Number result = null; + try { + result = doGetBasicTypeValue(varType, location); + return result; + } finally { + if (EDCTrace.VARIABLE_VALUE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(result)); } + } + } + + private Number doGetBasicTypeValue(IType varType, IVariableLocation location) throws CoreException { + + Number result = null; + int varSize = varType.getByteSize(); + + // get characteristics of the type + int basicType = IBasicType.t_unspecified; + boolean isSigned = false; + boolean isShort = false; + boolean isLong = false; + boolean isLongLong = false; + boolean isComplex = false; + + if (varType instanceof IBasicType) { + IBasicType type = (IBasicType) varType; + basicType = type.getBaseType(); + + if (basicType == ICPPBasicType.t_void) + throw EDCDebugger.newCoreException(ASTEvalMessages.OperandValue_CannotReadVoid); + if (basicType == ICPPBasicType.t_unspecified) + throw EDCDebugger.newCoreException(ASTEvalMessages.OperandValue_CannotReadUnspecifiedType); + + isSigned = type.isSigned(); + isShort = type.isShort(); + isLong = type.isLong(); + + if (varType instanceof ICPPBasicType) { + ICPPBasicType cppType = (ICPPBasicType) varType; + isLongLong = cppType.isLongLong(); + isComplex = cppType.isComplex(); + } + } else if (varType instanceof IPointerType) { + // treat pointer as an unsigned int + basicType = IBasicType.t_int; + } else if (varType instanceof IEnumerator){ + // treat enumerator as a signed int + basicType = IBasicType.t_int; + isSigned = true; + } else { + // treat unknown type as an unsigned int + basicType = IBasicType.t_int; + isSigned = false; + } + + // if variable's size is 0, use its default size + if (varSize == 0) { + varSize = getDefaultSize(varType, basicType, isShort, isLong, isLongLong, isComplex); + } + + // all other locations + IVariableLocation varLocation = location; + BigInteger varValue = null; + + if (varLocation != null) { + varValue = varLocation.readValue(varSize); + } else { + throw EDCDebugger.newCoreException(ASTEvalMessages.VariableWithValue_UnknownLocation); + } + + switch (basicType) { + case IBasicType.t_float: + case IBasicType.t_double: + if (varSize == 4) { + result = Float.intBitsToFloat(varValue.intValue()); + } else if (varSize == 8) { + result = Double.longBitsToDouble(varValue.longValue()); + } else { + // TODO: support 12-byte long double read from register + throw EDCDebugger.newCoreException(ASTEvalMessages.VariableWithValue_NoTwelveByteLongDouble); + } + break; + + case ICPPBasicType.t_bool: + case ICPPBasicType.t_wchar_t: + case IBasicType.t_char: + case IBasicType.t_int: + case IBasicType.t_void: + if (isSigned) { + // as needed, mask the value and sign-extend + if (varSize == 4) { + result = new Integer(varValue.intValue()); + } else if (varSize == 2) { + int intResult = varValue.intValue() & 0xffff; + if ((intResult & 0x00008000) != 0) + intResult |= 0xffff0000; + result = new Integer(intResult); + } else if (varSize == 1) { + int intResult = varValue.intValue() & 0xff; + if ((intResult & 0x00000080) != 0) + intResult |= 0xffffff00; + result = new Integer(intResult); + } else { + // assume an 8-byte long is the default + result = new Long(varValue.longValue()); + } + } else { + if (varSize == 4) { + result = new Long(varValue.longValue() & 0xffffffffL); // keep it unsigned + } else if (varSize == 2) { + result = new Integer(varValue.intValue() & 0xffff); + } else if (varSize == 1) { + result = new Integer(varValue.intValue() & 0xff); + } else { + // assume an 8-byte long is the default + result = new Long(varValue.longValue()); + } + } + break; + + case IBasicType.t_unspecified: + default: + assert false; + throw EDCDebugger.newCoreException(ASTEvalMessages.OperandValue_UnhandledType); + } + return result; + } + + private int getDefaultSize(IType varType, int basicType, boolean isShort, + boolean isLong, boolean isLongLong, boolean isComplex) { + int varSize = 0; + + // debug info should never claim something is zero size any more + /* + Object retrievedSize = null; + ITargetEnvironment targetEnvironmentService = servicesTracker.getService(ITargetEnvironment.class); + if (targetEnvironmentService != null) { + Map sizes = targetEnvironmentService.getBasicTypeSizes(); + + switch(basicType) { + case IBasicType.t_char: + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_CHAR); + break; + case IBasicType.t_int: + if (isShort) { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_SHORT); + } else if (isLongLong) { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_LONG_LONG); + } else if (isLong) { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_LONG); + } else { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_INT); + } + break; + case IBasicType.t_float: + if (isComplex) { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_FLOAT_COMPLEX); + } else { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_FLOAT); + } + break; + case IBasicType.t_double: + if (isComplex) { + if (isLong) { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_LONG_DOUBLE_COMPLEX); + } else { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_DOUBLE_COMPLEX); + } + } else { + if (isLong) { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_LONG_DOUBLE); + } else { + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_DOUBLE); + } + } + break; + case ICPPBasicType.t_bool: + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_BOOL); + break; + case ICPPBasicType.t_wchar_t: + retrievedSize = sizes.get(TypeUtils.BASIC_TYPE_WCHAR_T); + break; + default: + retrievedSize = 1; + } + } + if (retrievedSize != null) + varSize = (Integer) retrievedSize; + */ + + varSize = 1; + return varSize; + } + + /** + * Get the operand value as a long + * @return long + * @throws CoreException + */ + public long getLongValue() throws CoreException { + return getValue().longValue(); + } + + /** + * @return + */ + public boolean isFloating() { + return value instanceof Float || value instanceof Double; + } + + + public boolean isBitField() { + return isBitField; + } + + /** + * Get the value as a BigInteger + * @return value or 0 if not a number + */ + public BigInteger getBigIntValue() throws CoreException { + BigInteger bigIntVal; + if (getValue() == null) + return BigInteger.ZERO; + if (value instanceof BigInteger) + bigIntVal = (BigInteger) value; + else + bigIntVal = BigInteger.valueOf(value.longValue()); + return bigIntVal; + } + + public OperandValue copyWithType(IType otherType) { + OperandValue value = new OperandValue(otherType); + value.value = this.value; + value.stringValue = this.stringValue; + value.valueLocation = this.valueLocation; + return value; + } + +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorAddrOf.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorAddrOf.java new file mode 100644 index 0000000..9644e54 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorAddrOf.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.PointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.RegisterVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.core.runtime.CoreException; + +/* + * Unary address of operation "&" + */ +public class OperatorAddrOf extends CompoundInstruction { + + /** + * Constructor for address of operation "&" + * + * @param start + * - instruction start + */ + public OperatorAddrOf(int start) { + super(start); + } + + /** + * Resolve an address of operation "&" + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + OperandValue operand = popValue(); + + // only allow address of an lvalue + if (operand.getValueLocation() == null) { + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorAddrOf_RequiresVariable); + } + + IType subType = operand.getValueType(); + + // do not allow a variable that is in a register + if (operand.getValueLocation() instanceof RegisterVariableLocation) { + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorAddrOf_NoRegister); + } + + // do not allow a bit-field + if (operand.isBitField()) { + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorAddrOf_NoBitField); + } + + PointerType pointer = new PointerType(); + pointer.setType(subType); + + OperandValue addr = new OperandValue(pointer); + addr.setValueLocation(operand.getValueLocation()); + addr.setValue(operand.getValueLocationAddress()); + push(addr); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryAnd.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryAnd.java new file mode 100644 index 0000000..91a8e83 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryAnd.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary AND operation "&" + */ +public class OperatorBinaryAnd extends BinaryOperator { + + /** + * Constructor for a binary AND operation "&" + * + * @param start + * - instruction start + */ + public OperatorBinaryAnd(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary AND operation "&" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorBinaryAnd(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get int result of applying binary AND "&" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand & rightOperand + * @throws CoreException + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand & rightOperand; + } + + /** + * Get long result of applying binary AND "&" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand & rightOperand + * @throws CoreException + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand & rightOperand; + } + + /** + * Get BigInteger result of applying binary AND "&" to two BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return leftOperand & rightOperand + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + return leftOperand.and(rightOperand); + } + + /** + * Get float result of applying binary AND "&" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return 0 + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return 0; + } + + /** + * Get double result of applying binary AND "&" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return 0 + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return 0; + } + + /** + * Get boolean result of applying binary AND "&" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return leftOperand & rightOperand + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return leftOperand & rightOperand; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryOr.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryOr.java new file mode 100644 index 0000000..74c8f21 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryOr.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary OR operation "|" + */ +public class OperatorBinaryOr extends BinaryOperator { + + /** + * Constructor for a binary OR operation "|" + * + * @param start + * - instruction start + */ + public OperatorBinaryOr(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary OR operation "|" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorBinaryOr(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get int result of applying binary OR "|" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand | rightOperand + * @throws CoreException + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand | rightOperand; + } + + /** + * Get long result of applying binary OR "|" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand | rightOperand + * @throws CoreException + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand | rightOperand; + } + + /** + * Get BigInteger result of applying binary OR "|" to two BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return leftOperand | rightOperand + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + return leftOperand.or(rightOperand); + } + + /** + * Get float result of applying binary OR "|" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return 0 + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return 0; + } + + /** + * Get double result of applying binary OR "|" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return 0 + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return 0; + } + + /** + * Get boolean result of applying binary OR "|" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return leftOperand | rightOperand + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return leftOperand | rightOperand; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryXor.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryXor.java new file mode 100644 index 0000000..6cfbd77 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBinaryXor.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary XOR operation "^" + */ +public class OperatorBinaryXor extends BinaryOperator { + + /** + * Constructor for a binary XOR operation "^" + * + * @param start + * - instruction start + */ + public OperatorBinaryXor(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary XOR operation "^" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorBinaryXor(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get int result of applying binary XOR "^" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand ^ rightOperand + * @throws CoreException + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand ^ rightOperand; + } + + /** + * Get long result of applying binary XOR "^" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand ^ rightOperand + * @throws CoreException + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand ^ rightOperand; + } + + /** + * Get BigInteger result of applying binary XOR "^" to two BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return leftOperand ^ rightOperand + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + return leftOperand.xor(rightOperand); + } + + /** + * Get float result of applying binary XOR "^" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return 0 + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return 0; + } + + /** + * Get double result of applying binary XOR "^" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return 0 + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return 0; + } + + /** + * Get boolean result of applying binary XOR "^" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return leftOperand ^ rightOperand + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return leftOperand ^ rightOperand; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBitwiseNot.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBitwiseNot.java new file mode 100644 index 0000000..553bbc7 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorBitwiseNot.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.core.runtime.CoreException; + +/* + * Unary bit-wise NOT operation "~" + */ +public class OperatorBitwiseNot extends UnaryOperator { + + /** + * Constructor for a unary bit-wise NOT operation "~" + * + * @param start + * - instruction start + */ + public OperatorBitwiseNot(int start) { + super(start); + } + + /** + * Constructor for a unary bit-wise NOT operation "~" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + public OperatorBitwiseNot(int resultId, boolean isAssignmentOperator, int start) { + super(start); + } + + /** + * Get int result of applying unary bit-wise NOT "~" to an int + * + * @param operand + * - int operand + * @return ~operand + * @throws CoreException + */ + @Override + protected int getIntResult(int operand) throws CoreException { + return ~operand; + } + + /** + * Get long result of applying unary bit-wise NOT "~" to a long + * + * @param operand + * - long operand + * @return ~operand + * @throws CoreException + */ + @Override + protected long getLongResult(long operand) throws CoreException { + return ~operand; + } + + /** + * Get BigInteger result of applying unary bit-wise NOT "~" to a BigInteger + * + * @param operand + * - BigInteger operand + * @param length + * - length in bytes of result + * @return ~operand + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger operand, int length) throws CoreException { + return operand.not(); + } + + /** + * Get float result of applying unary bit-wise NOT "~" to a float + * + * @param operand + * - float operand + * @return 0 + */ + @Override + protected float getFloatResult(float operand) { + return 0; + } + + /** + * Get double result of applying unary bit-wise NOT "~" to a double + * + * @param operand + * - double operand + * @return 0 + */ + @Override + protected double getDoubleResult(double operand) { + return 0; + } + + /** + * Get boolean result of applying unary bit-wise NOT "~" to a boolean + * + * @param operand + * - boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean operand) { + return false; + } + + /** + * Get string result of applying unary bit-wise NOT "~" to a string + * + * @param operand + * - string operand + * @return null + * @throws CoreException + */ + @Override + protected String getStringResult(String operand) throws CoreException { + throw EDCDebugger.newCoreException(ASTEvalMessages.UnsupportedStringOperation); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorCast.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorCast.java new file mode 100644 index 0000000..6d3880b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorCast.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.core.dom.ast.IASTCastExpression; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeEngine; +import org.eclipse.core.runtime.CoreException; + +/** + * + */ +public class OperatorCast extends CompoundInstruction { + + private final IASTCastExpression castExpr; + private IType castType; + + public OperatorCast(int start, IASTCastExpression castExpr) { + super(start); + this.castExpr = castExpr; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.Instruction#execute() + */ + @Override + public void execute() throws CoreException { + OperandValue value = fInterpreter.pop(); + if (value.getStringValue() != null) + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorCast_CannotCastString); + + castType = getCastType(fInterpreter.getTypeEngine()); + + IVariableLocation location = value.getValueLocation(); + + OperandValue castValue = new OperandValue(castType); + Number origValue = value.getValue(); + Number castedValue = origValue; + + if (castType instanceof ICPPBasicType) { + ICPPBasicType cppType = (ICPPBasicType) castType; + // when casting to primtive integral type, reduce or zero/sign extend + if (cppType.getBaseType() == ICPPBasicType.t_char || + cppType.getBaseType() == ICPPBasicType.t_int || + cppType.getBaseType() == ICPPBasicType.t_wchar_t || + cppType.getBaseType() == ICPPBasicType.t_bool) { + switch (cppType.getByteSize()) { + case 1: + if (cppType.isSigned()) + castedValue = origValue.byteValue(); + else + castedValue = origValue.byteValue() & 0xff; + break; + case 2: + if (cppType.isSigned()) + castedValue = origValue.shortValue(); + else + castedValue = origValue.shortValue() & 0xfffff; + break; + case 4: + if (cppType.isSigned()) + castedValue = origValue.intValue(); + else + castedValue = origValue.intValue() & 0xffffffffL; + break; + case 8: + if (cppType.isSigned()) + castedValue = BigInteger.valueOf(origValue.longValue()); + else + castedValue = BigInteger.valueOf(origValue.longValue()).and(Mask8Bytes); + break; + } + } else if (cppType.getBaseType() == ICPPBasicType.t_float || + cppType.getBaseType() == ICPPBasicType.t_double) { + // and be sure integers promoted to floats, if needed + switch (cppType.getByteSize()) { + case 4: + castedValue = Float.valueOf(origValue.longValue()); + break; + case 8: + case 12: + castedValue = Double.valueOf(origValue.longValue()); + break; + } + } + } + + castValue.setValue(castedValue); + castValue.setValueLocation(location); + + fInterpreter.push(castValue); + } + + /** + * @return + * @throws CoreException + */ + public IType getCastType(TypeEngine typeEngine) throws CoreException { + if (castType == null) { + IASTTypeId typeId = castExpr.getTypeId(); + castType = typeEngine.getTypeForTypeId(typeId); + } + return castType; + } + + public IASTCastExpression getCastExpr() { + return castExpr; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorCastValue.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorCastValue.java new file mode 100644 index 0000000..fd09ba5 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorCastValue.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.cdt.core.dom.ast.IASTCastExpression; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.ValueVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeEngine; +import org.eclipse.core.runtime.CoreException; + +/** + * This operator directly casts the value of an expression without going through + * "*(type*)&expr". + */ +public class OperatorCastValue extends CompoundInstruction { + private IASTCastExpression castExpr; + private IType castType; + + public OperatorCastValue(int start, IType castType) { + super(start); + this.castType = castType; + } + + public OperatorCastValue(int start, IASTCastExpression castExpr) { + super(start); + this.castExpr = castExpr; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.Instruction#execute() + */ + @Override + public void execute() throws CoreException { + OperandValue value = fInterpreter.pop(); + if (value.getStringValue() != null) + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorCast_CannotCastString); + + castType = getCastType(fInterpreter.getTypeEngine()); + + IVariableLocation location = value.getValueLocation(); + OperandValue castValue = new OperandValue(castType); + + if (location == null) + location = new ValueVariableLocation(value.getBigIntValue()); + + Number castedValue = castValue.getValueByType(castType, location); + + castValue.setValue(castedValue); + castValue.setValueLocation(location); + + fInterpreter.push(castValue); + } + + public IType getCastType(TypeEngine typeEngine) throws CoreException { + if (castType == null) { + IASTTypeId typeId = castExpr.getTypeId(); + castType = typeEngine.getTypeForTypeId(typeId); + } + return castType; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorDivide.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorDivide.java new file mode 100644 index 0000000..091ae94 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorDivide.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.core.runtime.CoreException; + +/* + * Binary divide operation "/" + */ +public class OperatorDivide extends BinaryOperator { + + /** + * Constructor for a binary divide operation "/" + * + * @param start + * - instruction start + */ + public OperatorDivide(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary divide operation "/" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorDivide(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get int result of applying binary divide "/" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand / rightOperand + * @throws CoreException + * if rightOperand is 0 + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + if (rightOperand == 0) + throw EDCDebugger.newCoreException(ASTEvalMessages.DivideByZero); + else + return leftOperand / rightOperand; + } + + /** + * Get long result of applying binary divide "/" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand / rightOperand + * @throws CoreException + * if rightOperand is 0 + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + if (rightOperand == 0) + throw EDCDebugger.newCoreException(ASTEvalMessages.DivideByZero); + else + return leftOperand / rightOperand; + } + + /** + * Get BigInteger result of applying binary divide "/" to two BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return leftOperand / rightOperand + * @throws CoreException + * if rightOperand is 0 + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + if (rightOperand.equals(BigInteger.ZERO)) + throw EDCDebugger.newCoreException(ASTEvalMessages.DivideByZero); + else + return leftOperand.divide(rightOperand); + } + + /** + * Get float result of applying binary divide "/" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return leftOperand / rightOperand + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return leftOperand / rightOperand; + } + + /** + * Get double result of applying binary divide "/" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return leftOperand / rightOperand + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand / rightOperand; + } + + /** + * Get boolean result of applying binary divide "/" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorEquals.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorEquals.java new file mode 100644 index 0000000..f524b01 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorEquals.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary equals operation "==" + */ +public class OperatorEquals extends BinaryLogicalOperator { + + /** + * Constructor for a binary equals operation "==" + * + * @param start + * - instruction start + */ + public OperatorEquals(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary equals operation "==" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorEquals(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get boolean result of comparing two ints with equals "==" + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return true if leftOperand == rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand == rightOperand; + } + + /** + * Get boolean result of comparing two longs with equals "==" + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return true if leftOperand == rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand == rightOperand; + } + + /** + * Get boolean result of comparing two BigIntegers with equals "==" + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @return true if leftOperand == rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) throws CoreException { + return leftOperand.equals(rightOperand); + } + + /** + * Get boolean result of comparing two floats with equals "==" + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return true if leftOperand == rightOperand, + * and false otherwise + */ + @Override + protected boolean getFloatResult(float leftOperand, float rightOperand) { + return leftOperand == rightOperand; + } + + /** + * Get boolean result of comparing two doubles with equals "==" + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return true if leftOperand == rightOperand, + * and false otherwise + */ + @Override + protected boolean getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand == rightOperand; + } + + /** + * Get boolean result of comparing two booleans with equals "==" + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return true if leftOperand == rightOperand, + * and false otherwise + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return leftOperand == rightOperand; + } + + /** + * Get boolean result of comparing two strings with equals "==" + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return true if leftOperand == rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand, String rightOperand) throws CoreException { + return leftOperand.equals(rightOperand); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorGreaterEqual.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorGreaterEqual.java new file mode 100644 index 0000000..20c9626 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorGreaterEqual.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary greater or equal operation ">=" + */ +public class OperatorGreaterEqual extends BinaryLogicalOperator { + + /** + * Constructor for a binary greater or equal operation ">=" + * + * @param start + * - instruction start + */ + public OperatorGreaterEqual(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary greater or equal operation ">=" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorGreaterEqual(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get boolean result of comparing two ints with greater or equal ">=" + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return true if leftOperand >= rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand >= rightOperand; + } + + /** + * Get boolean result of comparing two longs with greater or equal ">=" + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return true if leftOperand >= rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand >= rightOperand; + } + + /** + * Get boolean result of comparing two BigIntegers with greater or equal + * ">=" + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @return true if leftOperand >= rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) throws CoreException { + return leftOperand.compareTo(rightOperand) >= 0; + } + + /** + * Get boolean result of comparing two floats with greater or equal ">=" + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return true if leftOperand >= rightOperand, + * and false otherwise + */ + @Override + protected boolean getFloatResult(float leftOperand, float rightOperand) { + return leftOperand >= rightOperand; + } + + /** + * Get boolean result of comparing two doubles with greater or equal ">=" + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return true if leftOperand >= rightOperand, + * and false otherwise + */ + @Override + protected boolean getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand >= rightOperand; + } + + /** + * Get boolean result of comparing two booleans with greater or equal ">=" + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } + + /** + * Get boolean result of comparing two strings with greater or equal ">=" + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return true if leftOperand >= rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand, String rightOperand) throws CoreException { + return leftOperand.compareTo(rightOperand) >= 0; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorGreaterThan.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorGreaterThan.java new file mode 100644 index 0000000..2da911e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorGreaterThan.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary greater than operation ">" + */ +public class OperatorGreaterThan extends BinaryLogicalOperator { + + /** + * Constructor for a binary greater than operation ">" + * + * @param start + * - instruction start + */ + public OperatorGreaterThan(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary greater than operation ">" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorGreaterThan(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get boolean result of comparing two ints with greater than ">" + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return true if leftOperand > rightOperand, and + * false otherwise + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand > rightOperand; + } + + /** + * Get boolean result of comparing two longs with greater than ">" + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return true if leftOperand > rightOperand, and + * false otherwise + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand > rightOperand; + } + + /** + * Get boolean result of comparing two BigIntegers with greater than ">" + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @return true if leftOperand > rightOperand, and + * false otherwise + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) throws CoreException { + return leftOperand.compareTo(rightOperand) > 0; + } + + /** + * Get boolean result of comparing two floats with greater than ">" + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return true if leftOperand > rightOperand, and + * false otherwise + */ + @Override + protected boolean getFloatResult(float leftOperand, float rightOperand) { + return leftOperand > rightOperand; + } + + /** + * Get boolean result of comparing two doubles with greater than ">" + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return true if leftOperand > rightOperand, and + * false otherwise + */ + @Override + protected boolean getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand > rightOperand; + } + + /** + * Get boolean result of comparing two booleans with greater than ">" + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } + + /** + * Get boolean result of comparing two longs with greater than ">" + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return true if leftOperand > rightOperand, and + * false otherwise + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand, String rightOperand) throws CoreException { + return leftOperand.compareTo(rightOperand) > 0; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorIndirection.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorIndirection.java new file mode 100644 index 0000000..124e7ad --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorIndirection.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.text.MessageFormat; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.IAggregate; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.IEnumeration; +import org.eclipse.cdt.debug.edc.internal.symbols.IField; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.ISubroutineType; +import org.eclipse.cdt.debug.edc.symbols.IMemoryVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.debug.edc.symbols.VariableLocationFactory; +import org.eclipse.core.runtime.CoreException; + +/* + * Unary indirection operation "*" + */ +public class OperatorIndirection extends CompoundInstruction { + + /** + * Constructor for a unary indirection operation "*" + * + * @param start + * - instruction start + */ + public OperatorIndirection(int start) { + super(start); + } + + /** + * Resolve a unary indirection expression + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + OperandValue operand = popValue(); + + IType opType = TypeUtils.getUnRefStrippedType(operand.getValueType()); + + if (operand.getStringValue() != null) { + // read first char of a string constant + pushNewValue(opType.getType(), (int) operand.getStringValue().charAt(0)); + return; + } + + if (!TypeUtils.isPointerType(opType)) { + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorIndirection_RequiresPointer); + } + + IPointerType pointer = (IPointerType) opType; + IType pointedTo = pointer.getType(); + IType unqualifiedPointedTo = TypeUtils.getStrippedType(pointedTo); + + // do not allow a pointer to a bit-field + if ((unqualifiedPointedTo instanceof IField) && (((IField) unqualifiedPointedTo).getBitSize() != 0)) { + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorIndirection_NoBitField); + } + + OperandValue opValue = new OperandValue(unqualifiedPointedTo); + + // for a lvalues (base arithmetic types, enums, and pointers), read the + // value and cast it to the right type + IMemoryVariableLocation location = VariableLocationFactory.createMemoryVariableLocation( + fInterpreter.getServicesTracker(), fInterpreter.getContext(), + operand.getValue()); + + if (unqualifiedPointedTo instanceof ICPPBasicType || unqualifiedPointedTo instanceof IPointerType + || unqualifiedPointedTo instanceof IEnumeration) { + int byteSize = unqualifiedPointedTo.getByteSize(); + + // treat ICPPBasicType of byte size 0 as a void pointer (size 4) + if (unqualifiedPointedTo instanceof ICPPBasicType && byteSize == 0) + byteSize = 4; + + if (byteSize != 1 && byteSize != 2 && byteSize != 4 && byteSize != 8) { + throw EDCDebugger.newCoreException(MessageFormat.format(ASTEvalMessages.UnhandledSize, byteSize)); + } + + // read the value pointed to + Number newValue = operand.getValueByType(unqualifiedPointedTo, location); + opValue.setValue(newValue); + opValue.setValueLocation(location); + push(opValue); + + } else if (unqualifiedPointedTo instanceof IAggregate) { + // for aggregates, the address of the aggregate is the value + // returned + opValue.setAddressValue(location); + opValue.setValueLocation(location); + push(opValue); + + } else { + if (unqualifiedPointedTo instanceof ISubroutineType) + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorIndirection_NoFunction); + else + throw EDCDebugger.newCoreException(MessageFormat.format(ASTEvalMessages.OperatorIndirection_UnhandledType, + unqualifiedPointedTo != null ? unqualifiedPointedTo.getName() : "null")); + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLessEqual.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLessEqual.java new file mode 100644 index 0000000..42f4674 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLessEqual.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary less or equal operation "<=" + */ +public class OperatorLessEqual extends BinaryLogicalOperator { + + /** + * Constructor for a binary less or equal operation "<=" + * + * @param start + * - instruction start + */ + public OperatorLessEqual(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary less or equal operation "<=" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorLessEqual(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get boolean result of comparing two ints with less or equal "<=" + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return true if leftOperand <= rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand <= rightOperand; + } + + /** + * Get boolean result of comparing two longs with less or equal "<=" + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return true if leftOperand <= rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand <= rightOperand; + } + + /** + * Get boolean result of comparing two BigIntegers with less or equal "<=" + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @return true if leftOperand <= rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) throws CoreException { + return leftOperand.compareTo(rightOperand) <= 0; + } + + /** + * Get boolean result of comparing two floats with less or equal "<=" + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return true if leftOperand <= rightOperand, + * and false otherwise + */ + @Override + protected boolean getFloatResult(float leftOperand, float rightOperand) { + return leftOperand <= rightOperand; + } + + /** + * Get boolean result of comparing two doubles with less or equal "<=" + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return true if leftOperand <= rightOperand, + * and false otherwise + */ + @Override + protected boolean getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand <= rightOperand; + } + + /** + * Get boolean result of comparing two booleans with less or equal "<=" + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } + + /** + * Get boolean result of comparing two strings with less or equal "<=" + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return true if leftOperand <= rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand, String rightOperand) throws CoreException { + return leftOperand.compareTo(rightOperand) <= 0; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLessThan.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLessThan.java new file mode 100644 index 0000000..36bf245 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLessThan.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary less than operation "<" + */ +public class OperatorLessThan extends BinaryLogicalOperator { + +/** + * Constructor for a binary less than operation "<" + * + * @param start - instruction start + */ + public OperatorLessThan(int start) { + this(0, false, start); + } + +/** + * Constructor for a binary less than operation "<" + * + * @param resultId - for assignment, variable ID of the result + * @param isAssignmentOperator - whether the result is assigned + * @param start - instruction start + */ + protected OperatorLessThan(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + +/** + * Get boolean result of comparing two ints with less than "<" + * + * @param leftOperand - left int operand + * @param rightOperand - right int operand + * @return true if leftOperand < rightOperand, and false otherwise + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand < rightOperand; + } + +/** + * Get boolean result of comparing two longs with less than "<" + * + * @param leftOperand - left long operand + * @param rightOperand - right long operand + * @return true if leftOperand < rightOperand, and false otherwise + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand < rightOperand; + } + +/** + * Get boolean result of comparing two BigIntegers with less than "<" + * + * @param leftOperand - left BigInteger operand + * @param rightOperand - right BigInteger operand + * @return true if leftOperand < rightOperand, and false otherwise + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) throws CoreException { + return leftOperand.compareTo(rightOperand) < 0; + } + +/** + * Get boolean result of comparing two floats with less than "<" + * + * @param leftOperand - left float operand + * @param rightOperand - right float operand + * @return true if leftOperand < rightOperand, and false otherwise + */ + @Override + protected boolean getFloatResult(float leftOperand, float rightOperand) { + return leftOperand < rightOperand; + } + +/** + * Get boolean result of comparing two doubles with less than "<" + * + * @param leftOperand - left double operand + * @param rightOperand - right double operand + * @return true if leftOperand < rightOperand, and false otherwise + */ + @Override + protected boolean getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand < rightOperand; + } + +/** + * Get boolean result of comparing two longs with less than "<" + * + * @param leftOperand - left long operand + * @param rightOperand - right long operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } + +/** + * Get boolean result of comparing two strings with less than "<" + * + * @param leftOperand - left string operand + * @param rightOperand - right string operand + * @return true if leftOperand < rightOperand, and false otherwise + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand, String rightOperand) throws CoreException { + return leftOperand.compareTo(rightOperand) < 0; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalAnd.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalAnd.java new file mode 100644 index 0000000..ddbae53 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalAnd.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary logical AND operation "&&" + */ +public class OperatorLogicalAnd extends BinaryLogicalOperator { + + /** + * Constructor for a binary logical AND operation "&&" + * + * @param start + * - instruction start + */ + public OperatorLogicalAnd(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary logical AND operation "&&" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorLogicalAnd(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get boolean result of comparing two ints with logical AND "&&" + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand, int rightOperand) throws CoreException { + // as bools + return (leftOperand != 0) && (rightOperand != 0); + } + + /** + * Get boolean result of comparing two longs with logical AND "&&" + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand, long rightOperand) throws CoreException { + // as bools + return (leftOperand != 0) && (rightOperand != 0); + } + + /** + * Get boolean result of comparing two BigIntegers with logical AND "&&" + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) throws CoreException { + // as bools + return (leftOperand.signum() != 0) && (rightOperand.signum() != 0); + } + + /** + * Get boolean result of comparing two floats with logical AND "&&" + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return false + */ + @Override + protected boolean getFloatResult(float leftOperand, float rightOperand) { + // as bools + return (leftOperand != 0) && (rightOperand != 0); + } + + /** + * Get boolean result of comparing two doubles with logical AND "&&" + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return false + */ + @Override + protected boolean getDoubleResult(double leftOperand, double rightOperand) { + // as bools + return (leftOperand != 0) && (rightOperand != 0); + } + + /** + * Get boolean result of comparing two booleans with logical AND "&&" + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return true if leftOperand && rightOperand is + * true, and false otherwise + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return leftOperand && rightOperand; + } + + /** + * Get boolean result of comparing two strings with logical AND "&&" + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand, String rightOperand) throws CoreException { + return true; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalNot.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalNot.java new file mode 100644 index 0000000..000a315 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalNot.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Unary logical NOT operation "!" + */ +public class OperatorLogicalNot extends UnaryLogicalOperator { + + /** + * Constructor for a unary logical NOT operation "!" + * + * @param start + * - instruction start + */ + public OperatorLogicalNot(int start) { + super(start); + } + + /** + * Get boolean result of applying logical NOT "!" to an int + * + * @param operand + * - int operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand) throws CoreException { + // as bool + return leftOperand == 0; + } + + /** + * Get boolean result of applying logical NOT "!" to a long + * + * @param operand + * - long operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand) throws CoreException { + // as bool + return leftOperand == 0; + } + + /** + * Get boolean result of applying logical NOT "!" to a BigInteger + * + * @param operand + * - BigInteger operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand) throws CoreException { + // as bool + return leftOperand.signum() == 0; + } + + /** + * Get boolean result of applying logical NOT "!" to a float + * + * @param operand + * - float operand + * @return false + */ + @Override + protected boolean getFloatResult(float leftOperand) { + // as bool + return leftOperand == 0; + } + + /** + * Get boolean result of applying logical NOT "!" to a double + * + * @param operand + * - double operand + * @return false + */ + @Override + protected boolean getDoubleResult(double leftOperand) { + // as bool + return leftOperand == 0; + } + + /** + * Get boolean result of applying logical NOT "!" to a boolean + * + * @param operand + * - boolean operand + * @return !operand + */ + @Override + protected boolean getBooleanResult(boolean leftOperand) { + return !leftOperand; + } + + /** + * Get boolean result of applying logical NOT "!" to a string + * + * @param operand + * - string operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand) throws CoreException { + // not of address + return false; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalOr.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalOr.java new file mode 100644 index 0000000..4d97b43 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorLogicalOr.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary logical OR operation "||" + */ +public class OperatorLogicalOr extends BinaryLogicalOperator { + + /** + * Constructor for a binary logical OR operation "||" + * + * @param start + * - instruction start + */ + public OperatorLogicalOr(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary logical OR operation "||" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorLogicalOr(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get boolean result of comparing two ints with logical OR "||" + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand, int rightOperand) throws CoreException { + // as bools + return (leftOperand != 0) || (rightOperand != 0); + } + + /** + * Get boolean result of comparing two longs with logical OR "||" + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand, long rightOperand) throws CoreException { + // as bools + return (leftOperand != 0) || (rightOperand != 0); + } + + /** + * Get boolean result of comparing two BigIntegers with logical OR "||" + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) throws CoreException { + // as bools + return (leftOperand.signum() != 0) || (rightOperand.signum() != 0); + } + + /** + * Get boolean result of comparing two floats with logical OR "||" + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return false + */ + @Override + protected boolean getFloatResult(float leftOperand, float rightOperand) { + // as bools + return (leftOperand != 0) || (rightOperand != 0); + + } + + /** + * Get boolean result of comparing two doubles with logical OR "||" + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return false + */ + @Override + protected boolean getDoubleResult(double leftOperand, double rightOperand) { + // as bools + return (leftOperand != 0) || (rightOperand != 0); + } + + /** + * Get boolean result of comparing two booleans with logical OR "||" + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return true if leftOperand || rightOperand is + * true, and false otherwise + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return leftOperand || rightOperand; + } + + /** + * Get boolean result of comparing two strings with logical OR "||" + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return false + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand, String rightOperand) throws CoreException { + // address or + return true; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorMinus.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorMinus.java new file mode 100644 index 0000000..e1b999e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorMinus.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/* + * Binary minus operation "-" + */ +public class OperatorMinus extends BinaryOperator { + + /** + * Constructor for a binary minus operation "-" + * + * @param start + * - instruction start + */ + public OperatorMinus(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary minus operation "-" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorMinus(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.BinaryOperator#customHandleOperation(org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperandValue, org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperandValue) + */ + @Override + protected boolean customHandleOperation(Interpreter fInterpreter, + OperandValue left, OperandValue right) throws CoreException { + IType rightType = null; + IType leftType = null; + + boolean isLeftPointer = false; + leftType = TypeUtils.getStrippedType(left.getValueType()); + isLeftPointer = leftType instanceof IPointerType || leftType instanceof IArrayType; + + boolean isRightPointer = false; + rightType = TypeUtils.getStrippedType(right.getValueType()); + isRightPointer = rightType instanceof IPointerType || rightType instanceof IArrayType; + + // no pointer operands + if (!isLeftPointer && !isRightPointer) { + return false; + } + + // only pointer is on the right + if (!isLeftPointer && isRightPointer) { + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorMinus_NonPtrMinusPtr); + } + + // ignore strings + if (getValueType(left) == T_String && getValueType(right) == T_String) + return false; + + BigInteger bigIntAddress = left.getBigIntValue(); + + BigInteger aggregateSize; + if (leftType instanceof IPointerType) + aggregateSize = BigInteger.valueOf(leftType.getByteSize()); + else + aggregateSize = BigInteger.valueOf(TypeUtils.getStrippedType(leftType.getType()) + .getByteSize()); + + if (!isRightPointer) { + right = convertForPromotion(right); + } + + BigInteger subtractAmount = right.getBigIntValue(); + + if (!isRightPointer) + subtractAmount = subtractAmount.multiply(aggregateSize); + + bigIntAddress = bigIntAddress.subtract(subtractAmount); + + // if both are pointers, subtract, then divide by size of what's pointed + // to + if (isRightPointer && aggregateSize.longValue() != 0) + bigIntAddress = bigIntAddress.divide(aggregateSize); + + if (isRightPointer) + pushNewValue(left.getValueType(), bigIntAddress); + else + pushNewValue(fInterpreter.getTypeEngine().getPointerSizeType(), bigIntAddress); + + return true; + } + + /** + * Get int result of applying binary minus "-" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand - rightOperand + * @throws CoreException + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand - rightOperand; + } + + /** + * Get long result of applying binary minus "-" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand - rightOperand + * @throws CoreException + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand - rightOperand; + } + + /** + * Get BigInteger result of applying binary minus "-" to two BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return leftOperand - rightOperand, truncated + * to 8 bytes + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + return leftOperand.subtract(rightOperand).and(Instruction.Mask8Bytes); + } + + /** + * Get float result of applying binary minus "-" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return leftOperand - rightOperand + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return leftOperand - rightOperand; + } + + /** + * Get double result of applying binary minus "-" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return leftOperand - rightOperand + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand - rightOperand; + } + + /** + * Get boolean result of applying binary minus "-" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorModulo.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorModulo.java new file mode 100644 index 0000000..85b96ef --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorModulo.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.core.runtime.CoreException; + +/* + * Binary modulo operation "%" + */ +public class OperatorModulo extends BinaryOperator { + + /** + * Constructor for a binary modulo operation "%" + * + * @param start + * - instruction start + */ + public OperatorModulo(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary modulo operation "%" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorModulo(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get int result of applying binary modulo "%" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand % rightOperand + * @throws CoreException + * if rightOperand is 0 + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + if (rightOperand == 0) + throw EDCDebugger.newCoreException(ASTEvalMessages.DivideByZero); + else + return leftOperand % rightOperand; + } + + /** + * Get long result of applying binary modulo "%" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand % rightOperand + * @throws CoreException + * if rightOperand is 0 + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + if (rightOperand == 0) + throw EDCDebugger.newCoreException(ASTEvalMessages.DivideByZero); + else + return leftOperand % rightOperand; + } + + /** + * Get BigInteger result of applying binary modulo "%" to two BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return leftOperand % rightOperand + * @throws CoreException + * if rightOperand is 0 + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + if (rightOperand.equals(BigInteger.ZERO)) + throw EDCDebugger.newCoreException(ASTEvalMessages.DivideByZero); + else + return leftOperand.mod(rightOperand); + } + + /** + * Get float result of applying binary modulo "%" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return 0 + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return leftOperand % rightOperand; + } + + /** + * Get double result of applying binary modulo "%" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return 0 + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand % rightOperand; + } + + /** + * Get boolean result of applying binary modulo "%" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorMultiply.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorMultiply.java new file mode 100644 index 0000000..40cb543 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorMultiply.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary multiply operation "*" + */ +public class OperatorMultiply extends BinaryOperator { + + /** + * Constructor for a binary multiply operation "*" + * + * @param start + * - instruction start + */ + public OperatorMultiply(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary multiply operation "*" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorMultiply(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get int result of applying binary multiply "*" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand * rightOperand + * @throws CoreException + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand * rightOperand; + } + + /** + * Get long result of applying binary multiply "*" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand * rightOperand + * @throws CoreException + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand * rightOperand; + } + + /** + * Get BigInteger result of applying binary multiply "*" to two BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return leftOperand * rightOperand, truncated + * to 8 bytes + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + return leftOperand.multiply(rightOperand).and(Instruction.Mask8Bytes); + } + + /** + * Get float result of applying binary multiply "*" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return leftOperand * rightOperand + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return leftOperand * rightOperand; + } + + /** + * Get double result of applying binary multiply "*" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return leftOperand * rightOperand + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand * rightOperand; + } + + /** + * Get boolean result of applying binary multiply "*" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorNotEquals.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorNotEquals.java new file mode 100644 index 0000000..748e7eb --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorNotEquals.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary not equals operation "!=" + */ +public class OperatorNotEquals extends BinaryLogicalOperator { + + /** + * Constructor for a binary not equals operation "!=" + * + * @param start + * - instruction start + */ + public OperatorNotEquals(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary not equals operation "!=" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorNotEquals(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get boolean result of comparing two ints with not equals "!=" + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return true if leftOperand != rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand != rightOperand; + } + + /** + * Get boolean result of comparing two longs with not equals "!=" + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return true if leftOperand != rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand != rightOperand; + } + + /** + * Get boolean result of comparing two BigIntegers with not equals "!=" + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @return true if leftOperand != rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand) throws CoreException { + return !leftOperand.equals(rightOperand); + } + + /** + * Get boolean result of comparing two floats with not equals "!=" + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return true if leftOperand != rightOperand, + * and false otherwise + */ + @Override + protected boolean getFloatResult(float leftOperand, float rightOperand) { + return leftOperand != rightOperand; + } + + /** + * Get boolean result of comparing two doubles with not equals "!=" + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return true if leftOperand != rightOperand, + * and false otherwise + */ + @Override + protected boolean getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand != rightOperand; + } + + /** + * Get boolean result of comparing two booleans with not equals "!=" + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return true if leftOperand != rightOperand, + * and false otherwise + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return leftOperand != rightOperand; + } + + /** + * Get boolean result of comparing two strings with not equals "!=" + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return true if leftOperand != rightOperand, + * and false otherwise + * @throws CoreException + */ + @Override + protected boolean getStringResult(String leftOperand, String rightOperand) throws CoreException { + return !leftOperand.equals(rightOperand); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorPlus.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorPlus.java new file mode 100644 index 0000000..0fe52cb --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorPlus.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/* + * Binary add operation "+" + */ +public class OperatorPlus extends BinaryOperator { + + /** + * Constructor for a binary add operation "+" + * + * @param start + * - instruction start + */ + public OperatorPlus(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary add operation "+" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorPlus(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.BinaryOperator#customHandleOperation(org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperandValue, org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperandValue) + */ + @Override + protected boolean customHandleOperation(Interpreter fInterpreter, + OperandValue left, OperandValue right) throws CoreException { + IType rightType = null; + IType leftType = null; + + boolean isLeftPointer = false; + leftType = TypeUtils.getStrippedType(left.getValueType()); + isLeftPointer = leftType instanceof IPointerType || leftType instanceof IArrayType; + + boolean isRightPointer = false; + rightType = TypeUtils.getStrippedType(right.getValueType()); + isRightPointer = rightType instanceof IPointerType || rightType instanceof IArrayType; + + // zero pointer operands + if (!isLeftPointer && !isRightPointer) { + return false; + } + + // two pointer operands + if (isLeftPointer && isRightPointer) { + // allow for strings... + if (getValueType(left) == T_String && getValueType(right) == T_String) + return false; + throw EDCDebugger.newCoreException(ASTEvalMessages.OperatorPlus_PtrPlusPtr); + } + + // get the non-pointer on the left + if (isRightPointer) { + OperandValue temp = right; + right = left; + left = temp; + temp = right; + right = left; + left = temp; + IType tempType = rightType; + rightType = leftType; + leftType = tempType; + } + + // convert the left address to BigInteger + BigInteger bigIntAddress = left.getBigIntValue(); + + BigInteger aggregateSize = BigInteger.ZERO; + if (leftType instanceof IPointerType) + aggregateSize = BigInteger.valueOf(leftType.getByteSize()); + else + aggregateSize = BigInteger.valueOf(TypeUtils.getStrippedType(leftType.getType()) + .getByteSize()); + BigInteger addAmount = aggregateSize; + + right = convertForPromotion(right); + + addAmount = addAmount.multiply(right.getBigIntValue()); + + bigIntAddress = bigIntAddress.add(addAmount); + + pushNewValue(left.getValueType(), bigIntAddress); + + return true; + } + + /** + * Get int result of applying binary plus "+" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand + rightOperand + * @throws CoreException + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand + rightOperand; + } + + /** + * Get long result of applying binary plus "+" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand + rightOperand + * @throws CoreException + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand + rightOperand; + } + + /** + * Get BigInteger result of applying binary plus "+" to two BigIntegers + * + * @param leftOperand + * - BigInteger long operand + * @param rightOperand + * - BigInteger long operand + * @param length + * - length in bytes of result + * @return leftOperand + rightOperand, truncated + * to 8 bytes + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + return leftOperand.add(rightOperand).and(Instruction.Mask8Bytes); + } + + /** + * Get float result of applying binary plus "+" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return leftOperand + rightOperand + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return leftOperand + rightOperand; + } + + /** + * Get double result of applying binary plus "+" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return leftOperand + rightOperand + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return leftOperand + rightOperand; + } + + /** + * Get boolean result of applying binary plus "+" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } + + /** + * Get string result of applying binary plus "+" to two strings + * + * @param leftOperand + * - left string operand + * @param rightOperand + * - right string operand + * @return leftOperand + rightOperand + * @throws CoreException + */ + @Override + protected String getStringResult(String leftOperand, String rightOperand) throws CoreException { + return leftOperand + rightOperand; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorShiftLeft.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorShiftLeft.java new file mode 100644 index 0000000..c61b040 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorShiftLeft.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary shift left operation "<<" + */ +public class OperatorShiftLeft extends BinaryOperator { + + /** + * Constructor for a binary shift left operation "<<" + * + * @param start - instruction start + */ + public OperatorShiftLeft(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary shift left operation "<<" + * + * @param resultId - for assignment, variable ID of the result + * @param isAssignmentOperator - whether the result is assigned + * @param start - instruction start + */ + protected OperatorShiftLeft(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get int result of applying binary shift left "<<" to two ints + * + * @param leftOperand - left int operand + * @param rightOperand - right int operand + * @return leftOperand << rightOperand + * @throws CoreException + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand << rightOperand; + } + + /** + * Get long result of applying binary shift left "<<" to two longs + * + * @param leftOperand - left long operand + * @param rightOperand - right long operand + * @return leftOperand << rightOperand + * @throws CoreException + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand << rightOperand; + } + + /** + * Get BigInteger result of applying binary shift left "<<" to two BigIntegers + * + * @param leftOperand - left BigInteger operand + * @param rightOperand - right BigInteger operand + * @param length - length in bytes of result + * @return leftOperand << rightOperand, truncated to 8 bytes + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + return leftOperand.shiftLeft(rightOperand.intValue()).and(Instruction.Mask8Bytes); + } + + /** + * Get float result of applying binary shift left "<<" to two floats + * + * @param leftOperand - left float operand + * @param rightOperand - right float operand + * @return 0 + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return 0; + } + + /** + * Get double result of applying binary shift left "<<" to two doubles + * + * @param leftOperand - left double operand + * @param rightOperand - right double operand + * @return 0 + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return 0; + } + + /** + * Get boolean result of applying binary shift left "<<" to two booleans + * + * @param leftOperand - left boolean operand + * @param rightOperand - right boolean operand + * @return boolean + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorShiftRight.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorShiftRight.java new file mode 100644 index 0000000..8f36735 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorShiftRight.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.CoreException; + +/* + * Binary shift right operation ">>" + */ +public class OperatorShiftRight extends BinaryOperator { + + /** + * Constructor for a binary shift right operation ">>" + * + * @param start + * - instruction start + */ + public OperatorShiftRight(int start) { + this(0, false, start); + } + + /** + * Constructor for a binary shift right operation ">>" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + protected OperatorShiftRight(int resultId, boolean isAssignmentOperator, int start) { + super(resultId, isAssignmentOperator, start); + } + + /** + * Get int result of applying binary shift right ">>" to two ints + * + * @param leftOperand + * - left int operand + * @param rightOperand + * - right int operand + * @return leftOperand >> rightOperand + * @throws CoreException + */ + @Override + protected int getIntResult(int leftOperand, int rightOperand) throws CoreException { + return leftOperand >> rightOperand; + } + + /** + * Get long result of applying binary shift right ">>" to two longs + * + * @param leftOperand + * - left long operand + * @param rightOperand + * - right long operand + * @return leftOperand >> rightOperand + * @throws CoreException + */ + @Override + protected long getLongResult(long leftOperand, long rightOperand) throws CoreException { + return leftOperand >> rightOperand; + } + + /** + * Get BigInteger result of applying binary shift right ">>" to two + * BigIntegers + * + * @param leftOperand + * - left BigInteger operand + * @param rightOperand + * - right BigInteger operand + * @param length + * - length in bytes of result + * @return leftOperand >> rightOperand + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger leftOperand, BigInteger rightOperand, int length) + throws CoreException { + return leftOperand.shiftRight(rightOperand.intValue()); + } + + /** + * Get float result of applying binary shift right ">>" to two floats + * + * @param leftOperand + * - left float operand + * @param rightOperand + * - right float operand + * @return 0 + */ + @Override + protected float getFloatResult(float leftOperand, float rightOperand) { + return 0; + } + + /** + * Get double result of applying binary shift right ">>" to two doubles + * + * @param leftOperand + * - left double operand + * @param rightOperand + * - right double operand + * @return 0 + */ + @Override + protected double getDoubleResult(double leftOperand, double rightOperand) { + return 0; + } + + /** + * Get boolean result of applying binary shift right ">>" to two booleans + * + * @param leftOperand + * - left boolean operand + * @param rightOperand + * - right boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean leftOperand, boolean rightOperand) { + return false; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorUnaryMinus.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorUnaryMinus.java new file mode 100644 index 0000000..14c5e39 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorUnaryMinus.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.core.runtime.CoreException; + +/* + * Unary minus operation "-" + */ +public class OperatorUnaryMinus extends UnaryOperator { + + /** + * Constructor for a unary minus operation "-" + * + * @param start + * - instruction start + */ + public OperatorUnaryMinus(int start) { + super(start); + } + + /** + * Constructor for a unary minus operation "-" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + public OperatorUnaryMinus(int resultId, boolean isAssignmentOperator, int start) { + super(start); + } + + /** + * Get int result of applying unary minus "-" to an int + * + * @param operand + * - int operand + * @return -operand + * @throws CoreException + */ + @Override + protected int getIntResult(int operand) throws CoreException { + return -operand; + } + + /** + * Get long result of applying unary minus "-" to a long + * + * @param operand + * - long operand + * @return -operand + * @throws CoreException + */ + @Override + protected long getLongResult(long operand) throws CoreException { + return -operand; + } + + /** + * Get BigInteger result of applying unary minus "-" to a BigInteger + * + * @param operand + * - BigInteger operand + * @param length + * - length in bytes of result + * @return -operand + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger operand, int length) throws CoreException { + return operand.negate(); + } + + /** + * Get float result of applying unary minus "-" to a float + * + * @param operand + * - float operand + * @return -operand + */ + @Override + protected float getFloatResult(float operand) { + return -operand; + } + + /** + * Get double result of applying unary minus "-" to a double + * + * @param operand + * - double operand + * @return -operand + */ + @Override + protected double getDoubleResult(double operand) { + return -operand; + } + + /** + * Get boolean result of applying unary minus "-" to a boolean + * + * @param operand + * - boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean operand) { + return false; + } + + /** + * Get string result of applying unary minus "-" to a string + * + * @param operand + * - string operand + * @return null + * @throws CoreException + */ + @Override + protected String getStringResult(String operand) throws CoreException { + throw EDCDebugger.newCoreException(ASTEvalMessages.UnsupportedStringOperation); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorUnaryPlus.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorUnaryPlus.java new file mode 100644 index 0000000..295ff1d --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/OperatorUnaryPlus.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.core.runtime.CoreException; + +/* + * Unary plus operation "+" + */ +public class OperatorUnaryPlus extends UnaryOperator { + + /** + * Constructor for unary plus operator "+" + * + * @param start + */ + public OperatorUnaryPlus(int start) { + super(start); + } + + /** + * Constructor for a unary plus operation "+" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + public OperatorUnaryPlus(int resultId, boolean isAssignmentOperator, int start) { + super(start); + } + + /** + * Get int result of applying unary plus "+" to an int + * + * @param operand + * - int operand + * @return operand + * @throws CoreException + */ + @Override + protected int getIntResult(int operand) throws CoreException { + return operand; + } + + /** + * Get long result of applying unary plus "+" to a long + * + * @param operand + * - long operand + * @return operand + * @throws CoreException + */ + @Override + protected long getLongResult(long operand) throws CoreException { + return operand; + } + + /** + * Get BigInteger result of applying unary plus "+" to a BigInteger + * + * @param operand + * - BigInteger operand + * @param length + * - length in bytes of result + * @return operand + * @throws CoreException + */ + @Override + protected BigInteger getBigIntegerResult(BigInteger operand, int length) throws CoreException { + return operand; + } + + /** + * Get float result of applying unary plus "+" to a float + * + * @param operand + * - float operand + * @return operand + */ + @Override + protected float getFloatResult(float operand) { + return operand; + } + + /** + * Get double result of applying unary plus "+" to a double + * + * @param operand + * - double operand + * @return operand + */ + @Override + protected double getDoubleResult(double operand) { + return operand; + } + + /** + * Get boolean result of applying unary plus "+" to a boolean + * + * @param operand + * - boolean operand + * @return false + */ + @Override + protected boolean getBooleanResult(boolean operand) { + return false; + } + + /** + * Get string result of applying unary plus "+" to a string + * + * @param operand + * - string operand + * @return null + * @throws CoreException + */ + @Override + protected String getStringResult(String operand) throws CoreException { + throw EDCDebugger.newCoreException(ASTEvalMessages.UnsupportedStringOperation); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushBoolean.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushBoolean.java new file mode 100644 index 0000000..5db6420 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushBoolean.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.core.runtime.CoreException; + +/* + * Push a boolean on the instruction stack + */ +public class PushBoolean extends SimpleInstruction { + private boolean fValue; + + /** + * Constructor for pushing a boolean on the stack + * + * @param value + * - boolean value + */ + public PushBoolean(boolean value) { + fValue = value; + } + + /** + * Execute pushing a boolean on the stack + * + * @throws CoreException + */ + @Override + public void execute() { + pushNewValue(fInterpreter.getTypeEngine().getBooleanType(4), fValue); + } + + /** + * Show a boolean value as a string + * + * @return string version of a boolean + */ + @Override + public String toString() { + return Boolean.toString(fValue); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushChar.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushChar.java new file mode 100644 index 0000000..e043669 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushChar.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/* + * Push a character on the instruction stack + * + * Note: if the character does not fit in a byte, it is represented by the low 4 bytes of a Java long */ +public class PushChar extends SimpleInstruction { + + static private final char BELL = '\u0007'; + static private final char VERTICAL_TAB = '\u000B'; + + // character value + private long fValue; + // is wchar_t? + private boolean isWide; + // if true, the value is multiple characters (e.g. 'AB' or 'CWIE') + private boolean multiChar; + + /** + * Constructor for pushing a char on the stack + * + * @param value + * - char value + */ + public PushChar(char value) { + fValue = (short) value; + } + + /** + * Constructor for pushing a char on the stack + * + * @param value + * - string value of form 'X' to convert to char X + * @throws NumberFormatException + */ + public PushChar(String value) throws NumberFormatException { + parseCharValue(value); + } + + /** + * Execute pushing a char on the stack + * + * @throws CoreException + */ + @Override + public void execute() { + if (multiChar) { + pushNewValue(fInterpreter.getTypeEngine().getIntegerTypeOfSize(4, false), fValue); + return; + } + + if (!isWide) { + // TODO: truncate to size of this type + pushNewValue(fInterpreter.getTypeEngine().getCharacterType( + fInterpreter.getTypeEngine().getTypeSize(TypeUtils.BASIC_TYPE_CHAR)), fValue); + } else { + pushNewValue(fInterpreter.getTypeEngine().getCharacterType( + fInterpreter.getTypeEngine().getTypeSize(TypeUtils.BASIC_TYPE_WCHAR_T)), fValue); + } + } + + /** + * Show a char value as a string + * + * @return string version of a char + */ + @Override + public String toString() { + if (fValue < 65536) + return "" + ((char) fValue); //$NON-NLS-1$ + char[] surrogate = { (char)(fValue >> 16), (char)(fValue & 0xffff) }; + return new String(surrogate); + } + + /** + * Convert string value of form 'X' to char X. This may be either a single + * character (char or wchar_t) or a multi-character constant, which is treated + * as an integer. + * + * @param value + * - string of form 'X' + * @throws NumberFormatException + */ + private void parseCharValue(String value) throws NumberFormatException { + if (value.startsWith("L")) { //$NON-NLS-1$ + isWide = true; + value = value.substring(1); + } + if (value.length() < 3 || value.charAt(0) != '\'' || !value.endsWith("'")) //$NON-NLS-1$ + throw new NumberFormatException(); + + value = value.substring(1, value.length() - 1); + + if (value.startsWith("\\u")) { //$NON-NLS-1$ + // hex representation + if (value.length() < 3) + throw new NumberFormatException(); + + fValue = Long.parseLong(value.substring(2), 16); + return; + } + + // escape character + if (value.startsWith("\\")) { //$NON-NLS-1$ + if (value.length() < 2) + throw new NumberFormatException(); + + if (value.charAt(1) >= '0' && value.charAt(1) <= '7') { + // octal representation + if (value.length() > 4) + throw new NumberFormatException(); + + fValue = Long.parseLong(value.substring(1), 8); + return; + } + + if (value.length() > 2) + throw new NumberFormatException(); + + switch (value.charAt(1)) { + case 'n': + fValue = '\n'; break; + case 't': + fValue = '\t'; break; + case 'v': + fValue = VERTICAL_TAB; break; + case 'b': + fValue = '\b'; break; + case 'r': + fValue = '\r'; break; + case 'f': + fValue = '\f'; break; + case 'a': + fValue = BELL; break; + case '\\': + fValue = '\\'; break; + case '?': + fValue = '?'; break; + case '\'': + fValue = '\''; break; + case '"': + fValue = '"'; break; + default: + fValue = value.charAt(1); break; + } + return; + } + + multiChar = (value.length() > 1); + + fValue = 0; + for (int i = 0; i < value.length(); i++) { + fValue = (fValue << 8) + value.charAt(i); + } + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushDouble.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushDouble.java new file mode 100644 index 0000000..161481e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushDouble.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/* + * Push a double value on the instruction stack + */ +public class PushDouble extends SimpleInstruction { + + private double fValue; + private boolean isLong; + + /** + * Constructor for pushing a double value on the stack + * + * @param value + * - double value + */ + public PushDouble(double value) { + fValue = value; + } + + /** + * Constructor for pushing a double value on the stack + * + * @param value + * - string version of a double + * @throws NumberFormatException + */ + public PushDouble(String value) throws NumberFormatException { + if (value.toLowerCase().endsWith("l")) { //$NON-NLS-1$ + isLong = true; + value = value.substring(0, value.length() - 1); + } + fValue = Double.valueOf(value).doubleValue(); + } + + /** + * Execute pushing a double value on the stack + * + * @throws CoreException + */ + @Override + public void execute() { + int size; + if (isLong) { + size = fInterpreter.getTypeEngine().getTypeSize(TypeUtils.BASIC_TYPE_LONG_DOUBLE); + pushNewValue(fInterpreter.getTypeEngine().getBasicType(ICPPBasicType.t_double, ICPPBasicType.IS_LONG, size), fValue); + } + else { + size = fInterpreter.getTypeEngine().getTypeSize(TypeUtils.BASIC_TYPE_DOUBLE); + pushNewValue(fInterpreter.getTypeEngine().getBasicType(ICPPBasicType.t_double, 0, size), fValue); + } + + } + + /** + * Show a double value as a string + * + * @return string version of a double + */ + @Override + public String toString() { + return Double.toString(fValue); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushFloat.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushFloat.java new file mode 100644 index 0000000..8e441f3 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushFloat.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.core.runtime.CoreException; + +/* + * Push a float on the instruction stack + */ +public class PushFloat extends SimpleInstruction { + + private float fValue; + + /** + * Constructor for pushing a float on the stack + * + * @param value + * - float value + */ + public PushFloat(float value) { + fValue = value; + } + + /** + * Constructor for pushing a float on the stack + * + * @param value + * - string version of a float + * @throws NumberFormatException + */ + public PushFloat(String value) throws NumberFormatException { + fValue = Float.valueOf(value).floatValue(); + } + + /** + * Execute pushing a float on the stack + * + * @throws CoreException + */ + @Override + public void execute() { + pushNewValue(fInterpreter.getTypeEngine().getFloatTypeOfSize(4), fValue); + } + + /** + * Show a float value as a string + * + * @return string version of a float + */ + @Override + public String toString() { + return Float.toString(fValue); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushLongOrBigInteger.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushLongOrBigInteger.java new file mode 100644 index 0000000..494f210 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushLongOrBigInteger.java @@ -0,0 +1,347 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/* + * Push a long on the instruction stack + */ +public class PushLongOrBigInteger extends SimpleInstruction { + + // if true, suffix had 'u' + private boolean isUnsigned; + // if true, suffix had 'l' (but not 'll') + private boolean isLong; + // if true, suffix had 'll' (but not 'l') + private boolean isLongLong; + + // if true, the original number was a hex or octal string + private boolean isHexOrOctal; + + // if not null, a big integer + private BigInteger fBigInteger; + // otherwise, this is the value + private long fLong; + private IType type; + + /** + * Constructor for pushing a long on the stack + * + * @param value + * - long value + */ + public PushLongOrBigInteger(long value) { + isLong = true; + fLong = value; + } + + /** + * Constructor for pushing a long on the stack + * + * @param value + * - string version of a long + * @throws NumberFormatException + */ + public PushLongOrBigInteger(String value) throws NumberFormatException { + parseLongOrBigInteger(value); + } + + /** + */ + public long getLong() { + return fLong; + } + + /** + * Execute pushing a long on the stack + * + * @throws CoreException + */ + @Override + public void execute() { + Number number = fBigInteger; + if (number == null) + number = fLong; + + // TODO: Handle 8-byte long and >8-byte long long + + int intSize = fInterpreter.getTypeEngine().getTypeSize(TypeUtils.BASIC_TYPE_INT); + int longSize = fInterpreter.getTypeEngine().getTypeSize(TypeUtils.BASIC_TYPE_LONG); + int longLongSize = fInterpreter.getTypeEngine().getTypeSize(TypeUtils.BASIC_TYPE_LONG_LONG); + + // promote constant type based on the size of C/C++ int, long, and long long types. + // this cannot be done at parse time because the type engine is not known then + correctIntegerType(intSize * 8, longSize * 8, longLongSize * 8); + + if (type == null) { + int flags = isLongLong ? ICPPBasicType.IS_LONG_LONG : isLong ? ICPPBasicType.IS_LONG : 0; + + if (isUnsigned) + flags |= ICPPBasicType.IS_UNSIGNED; + else + flags |= ICPPBasicType.IS_SIGNED; + + int size; + if (isLongLong) + size = longLongSize; + else if (isLong) + size = longSize; + else + size = intSize; + + type = fInterpreter.getTypeEngine().getBasicType(ICPPBasicType.t_int, flags, size); + } + + pushNewValue(type, number); + } + + /** + * Fix type of constant based on C++ promotion rules, which depend on the size of + * int, long, and long long types. + * + * @param intBitSize + * @param longBitSize + * @param longLongBitSize + */ + private void correctIntegerType(int intBitSize, int longBitSize, int longLongBitSize) { + if ( fBigInteger == null + // check if it fits in signed long (but maybe not an unsigned int) + && ( (fLong >= 0 && (fLong >> (intBitSize - 1)) == 0) + || (fLong < 0 && (fLong >> (intBitSize - 1)) < -1))) + return; + + // at execute() time, isUnsigned means explicit unsigned, isLong means explicit long, + // and isLongLong means explicit long long + if (fBigInteger == null) { + // it fits in a 64-bit signed Java long + if (isUnsigned) { + // explicit unsigned decimal, hex, or octal constant + if (isLong) { + // explicit unsigned long may change to unsigned long long + if ((fLong >> longBitSize) > 0) { + isLong = false; + isLongLong = true; + } + } else if (!isLongLong) { + // not declared long long - may be int, long, or long long + if ((fLong >> (intBitSize - 1)) <= 1) { + // fits in an unsigned int + } else if ((fLong >> (longBitSize - 1)) <= 1) { + // fits in an unsigned long + isLong = true; + } else { + // fits in an unsigned longLong + isLongLong = true; + } + } + } else { + // signed decimal, hex, or octal constant + if (!isHexOrOctal) { + // decimal constant + if (!isLong && !isLongLong){ + // signed decimal constant, not declared long or long long + if ( (fLong >= 0 && (fLong >> (longBitSize - 1)) == 0) + || (fLong < 0 && (fLong >> (longBitSize - 1)) < -1)) { + // fits in signed long + isLong = true; + } else { + // fits in signed long long + isLongLong = true; + } + } else if (isLong) { + // explicit long may change to long long + if (!( (fLong >= 0 && (fLong >> (longLongBitSize - 1)) == 0) + || (fLong < 0 && (fLong >> (longLongBitSize - 1)) < -1))) { + isLong = false; + isLongLong = true; + } + } + } else { + // hex or octal constant + if (!isLong && !isLongLong){ + // signed hex or octal constant, not declared long or long long + // may be int, unsigned int, long, unsigned long, long long, or unsigned long long + if (fLong >> (intBitSize - 1) == 1) { + // fits in unsigned int + isUnsigned = true; + } else if ( (fLong >= 0 && (fLong >> (longBitSize - 1)) == 0) + || (fLong < 0 && (fLong >> (longBitSize - 1)) < -1)) { + // fits in signed long + isLong = true; + } else if (fLong >> (longBitSize - 1) == 1) { + // fits in unsigned long + isLong = true; + isUnsigned = true; + } else if ( (fLong >= 0 && (fLong >> (longLongBitSize - 1)) == 0) + || (fLong < 0 && (fLong >> (longLongBitSize - 1)) < -1)) { + // fits in signed long long + isLongLong = true; + } else { + // fits in unsigned long long + isLongLong = true; + isUnsigned = true; + } + } else if (isLong) { + // explicit long hex or octal may change to unsigned long, long long, or unsigned long long + if ( (fLong >= 0 && (fLong >> (longBitSize - 1)) == 0) + || (fLong < 0 && (fLong >> (longBitSize - 1)) < -1)) { + // fits in signed long + } else if (fLong >> (longBitSize - 1) == 1) { + // fits in unsigned long + isUnsigned = true; + } else if ( (fLong >= 0 && (fLong >> (longLongBitSize - 1)) == 0) + || (fLong < 0 && (fLong >> (longLongBitSize - 1)) < -1)) { + // fits in signed long long + isLong = false; + isLongLong = true; + } else { + // fits in unsigned long long + isLong = false; + isLongLong = true; + isUnsigned = true; + } + } else { + // explicit long long may change to unsigned long long + if (fLong >> (longLongBitSize - 1) > 0) + isUnsigned = true; + } + } + } + } else { + // BigInteger, which does not fit in a Java long + isLongLong = true; + isLong = false; + if (!isUnsigned) { + // signed decimal, hex, or octal long long constant + if (isHexOrOctal) { + // for hex or octal constant, long long may change to unsigned long long + if (fBigInteger.bitLength() > (longLongBitSize - 1)) + isUnsigned = true; + } + } + } + } + + /** + * Show a long or BigInteger value as a string + * + * @return string version of a long or BigInteger + */ + @Override + public String toString() { + if (isLong) + return Long.toString(fLong); + else + return fBigInteger.toString(); + } + + /** + * Convert a string to a long or BigInteger + * + * @param value + * - string version of a long + * @throws NumberFormatException + */ + public void parseLongOrBigInteger(String value) throws NumberFormatException { + isUnsigned = false; + isHexOrOctal = false; + + String val = value.toLowerCase(); + int length = value.length(); + + if (val.endsWith("ull") || val.endsWith("llu")) { //$NON-NLS-1$ //$NON-NLS-2$ + isUnsigned = true; + isLongLong = true; + isLong = false; + val = val.substring(0, val.length() - 3); + length -= 3; + } else if (val.endsWith("ll")) { //$NON-NLS-1$ + isLong = false; + isLongLong = true; + val = val.substring(0, val.length() - 2); + length -= 2; + } else if (val.endsWith("ul") || val.endsWith("lu")) { //$NON-NLS-1$ //$NON-NLS-2$ + isUnsigned = true; + isLong = true; + val = val.substring(0, val.length() - 2); + length -= 2; + } else if (val.endsWith("l")) { //$NON-NLS-1$ + isLong = true; + val = val.substring(0, val.length() - 1); + length -= 1; + } else if (val.endsWith("u")) { //$NON-NLS-1$ + isUnsigned = true; + val = val.substring(0, val.length() - 1); + length -= 1; + } + + // if conversion to BigInteger fails, the string is invalid + // if after BigInteger conversion, Long conversion fails, the value is + // too large or small + if (val.startsWith("0x")) { //$NON-NLS-1$ + isHexOrOctal = true; + try { + fLong = Long.valueOf(val.substring(2), 16); + } catch (NumberFormatException nfe) { + fBigInteger = new BigInteger(val.substring(2), 16); + fBigInteger.and(Instruction.Mask8Bytes); + return; + } + length -= 2; + } else if (length > 1 && val.startsWith("0")) { //$NON-NLS-1$ + isHexOrOctal = true; + + try { + fLong = Long.valueOf(val.substring(1), 8); + } catch (NumberFormatException nfe) { + fBigInteger = new BigInteger(val.substring(1), 8); + fBigInteger.and(Instruction.Mask8Bytes); + return; + } + length -= 1; + } else { + + try { + fLong = Long.valueOf(val); + } catch (NumberFormatException nfe) { + fBigInteger = new BigInteger(val); + fBigInteger.and(Instruction.Mask8Bytes); + return; + } + } + + if (length == 0) { + fLong = 0; + return; + } + + if (isUnsigned) { + if (fBigInteger != null) { + if (fBigInteger.bitLength() < 64) { + // unsigned will fit in a Java long + fLong = fBigInteger.longValue(); + fBigInteger = null; + return; + } + // keep it a BigInteger + // TODO: Allow bigger than 8 bytes + fBigInteger.and(Instruction.Mask8Bytes); + } + } + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushString.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushString.java new file mode 100644 index 0000000..c5d0a33 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/PushString.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/* + * Push a string on the instruction stack + */ +public class PushString extends SimpleInstruction { + + private String fValue; + private boolean isWide; + private IType stringType; + + /** + * Constructor for pushing a string on the stack + * + * @param value + * - string value in format "..." or L"..." + */ + public PushString(String value) { + if (value.startsWith("L")) { //$NON-NLS-1$ + isWide = true; + value = value.substring(1); + } + + fValue = value.substring(1, value.length() - 1); + } + + /** + * Execute pushing a string on the stack + * + * @throws CoreException + */ + @Override + public void execute() { + if (stringType == null) { + int size = fInterpreter.getTypeEngine().getTypeSize(isWide ? TypeUtils.BASIC_TYPE_WCHAR_T : TypeUtils.BASIC_TYPE_CHAR); + IType charType = fInterpreter.getTypeEngine().getBasicType(ICPPBasicType.t_char, 0, size); + stringType = fInterpreter.getTypeEngine().getCharArrayType(charType, fValue.length() + 1); + } + pushNewValue(stringType, fValue); + } + + /** + * Show a string value + * + * @return string + */ + @Override + public String toString() { + return fValue; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/SimpleInstruction.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/SimpleInstruction.java new file mode 100644 index 0000000..aa08a80 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/SimpleInstruction.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +public abstract class SimpleInstruction extends Instruction { + + /** + * Constructor for a simple instruction + */ + protected SimpleInstruction() { + super(); + } + + /** + * Get simple instruction size + * + * @return 1 + */ + @Override + public int getSize() { + return 1; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/UnaryLogicalOperator.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/UnaryLogicalOperator.java new file mode 100644 index 0000000..1552729 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/UnaryLogicalOperator.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.core.runtime.CoreException; + +/* + * Unary logical operator, such as "!" + */ +public abstract class UnaryLogicalOperator extends CompoundInstruction { + + /** + * Constructor for a unary logical operator, such as "!" + * + * @param start + * - instruction start + */ + public UnaryLogicalOperator(int start) { + super(start); + } + + /** + * Constructor for a unary logical operator, such as "!" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + public UnaryLogicalOperator(int resultId, boolean isAssignmentOperator, int start) { + super(start); + } + + /** + * Resolve a unary logical expression + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + OperandValue operand = popValue(); + + operand = convertForPromotion(operand); + + // change chars/shorts to int, etc. + int resultType = getJavaBinaryPromotionType(operand, operand); + IType type = fInterpreter.getTypeEngine().getBooleanType(1); + + switch (resultType) { + case T_String: + pushNewValue(type, getStringResult(GetValue.getStringValue(operand))); + break; + case T_double: + pushNewValue(type, getDoubleResult(GetValue.getDoubleValue(operand))); + break; + case T_float: + pushNewValue(type, getFloatResult(GetValue.getFloatValue(operand))); + break; + case T_long: + pushNewValue(type, getLongResult(GetValue.getLongValue(operand))); + break; + case T_int: + pushNewValue(type, getIntResult(GetValue.getIntValue(operand))); + break; + case T_boolean: + pushNewValue(type, getBooleanResult(GetValue.getBooleanValue(operand))); + break; + case T_BigInt: + pushNewValue(type, getBigIntegerResult(GetValue.getBigIntegerValue(operand))); + break; + default: + throw EDCDebugger.newCoreException(ASTEvalMessages.UnhandledTypeCode + resultType); + + } + } + + /** + * Get boolean result of applying a unary logical operation to an int + * + * @param operand + * - int operand + * @return boolean result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract boolean getIntResult(int operand) throws CoreException; + + /** + * Get boolean result of applying a unary logical operation to a long + * + * @param operand + * - long operand + * @return boolean result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract boolean getLongResult(long operand) throws CoreException; + + /** + * Get boolean result of applying a unary logical operation to a BigInteger + * + * @param operand + * - BigInteger operand + * @return boolean result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract boolean getBigIntegerResult(BigInteger operand) throws CoreException; + + /** + * Get boolean result of applying a unary logical operation to a float + * + * @param operand + * - float operand + * @return boolean result of the operation if possible, or an + * operation-specific default + */ + protected abstract boolean getFloatResult(float operand); + + /** + * Get boolean result of applying a unary logical operation to a double + * + * @param operand + * - double operand + * @return boolean result of the operation if possible, or an + * operation-specific default + */ + protected abstract boolean getDoubleResult(double operand); + + /** + * Get boolean result of applying a unary logical operation to a boolean + * + * @param operand + * - boolean operand + * @return boolean result of the operation if possible, or an + * operation-specific default + */ + protected abstract boolean getBooleanResult(boolean operand); + + /** + * Get boolean result of applying a unary logical operation to a string + * + * @param operand + * - string operand + * @return boolean result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract boolean getStringResult(String operand) throws CoreException; + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/UnaryOperator.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/UnaryOperator.java new file mode 100644 index 0000000..ebe5ba0 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/UnaryOperator.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +/* + * Unary arithmetic operator, such as "~" + */ +public abstract class UnaryOperator extends CompoundInstruction { + + /** + * Constructor for a unary arithmetic operator, such as "~" + * + * @param start + * - instruction start + */ + public UnaryOperator(int start) { + super(start); + } + + /** + * Constructor for a unary arithmetic operator, such as "~" + * + * @param resultId + * - for assignment, variable ID of the result + * @param isAssignmentOperator + * - whether the result is assigned + * @param start + * - instruction start + */ + public UnaryOperator(int resultId, boolean isAssignmentOperator, int start) { + super(start); + } + + /** + * Resolve a unary arithmetic expression + * + * @throws CoreException + */ + @Override + public void execute() throws CoreException { + OperandValue operand = popValue(); + + operand = convertForPromotion(operand); + + // change chars/shorts to int, etc. + + int resultType = getJavaBinaryPromotionType(operand, operand); + IType type = getBinaryPromotionType(operand, operand); + + // non-logical operations on booleans are int results + if ((type instanceof ICPPBasicType) && ((ICPPBasicType) type).getBaseType() == ICPPBasicType.t_bool) { + type = fInterpreter.getTypeEngine().getIntegerTypeFor(TypeUtils.BASIC_TYPE_INT, true); + } + + switch (resultType) { + case T_String: + pushNewValue(type, getStringResult(GetValue.getStringValue(operand))); + break; + case T_double: + pushNewValue(type, getDoubleResult(GetValue.getDoubleValue(operand))); + break; + case T_float: + pushNewValue(type, getFloatResult(GetValue.getFloatValue(operand))); + break; + case T_long: + pushNewValue(type, getLongResult(GetValue.getLongValue(operand))); + break; + case T_int: + pushNewValue(type, getIntResult(GetValue.getIntValue(operand))); + break; + case T_boolean: + pushNewValue(type, getBooleanResult(GetValue.getBooleanValue(operand))); + break; + default: + throw EDCDebugger.newCoreException(ASTEvalMessages.UnhandledTypeCode + resultType); + } + } + + /** + * Get int result of applying a unary operation to an int + * + * @param operand + * - int operand + * @return int result of the operation if possible, or an operation-specific + * default + * @throws CoreException + */ + protected abstract int getIntResult(int operand) throws CoreException; + + /** + * Get long result of applying a unary operation to a long + * + * @param operand + * - long operand + * @return long result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract long getLongResult(long operand) throws CoreException; + + /** + * Get BigInteger result of applying a unary operation to a BigInteger + * + * @param operand + * - long operand + * @param length + * - length in bytes of the result + * @return long result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract BigInteger getBigIntegerResult(BigInteger operand, int length) throws CoreException; + + /** + * Get float result of applying a unary operation to a float + * + * @param operand + * - float operand + * @return float result of the operation if possible, or an + * operation-specific default + */ + protected abstract float getFloatResult(float operand); + + /** + * Get double result of applying a unary operation to a double + * + * @param operand + * - double operand + * @return double result of the operation if possible, or an + * operation-specific default + */ + protected abstract double getDoubleResult(double operand); + + /** + * Get boolean result of applying a unary operation to a boolean + * + * @param operand + * - boolean operand + * @return boolean result of the operation if possible, or an + * operation-specific default + */ + protected abstract boolean getBooleanResult(boolean operand); + + /** + * Get string result of applying a unary operation to a string + * + * @param operand + * - string operand + * @return string result of the operation if possible, or an + * operation-specific default + * @throws CoreException + */ + protected abstract String getStringResult(String operand) throws CoreException; + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/VariableWithValue.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/VariableWithValue.java new file mode 100644 index 0000000..61fe7f4 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/eval/ast/engine/instructions/VariableWithValue.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions; + + +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages; +import org.eclipse.cdt.debug.edc.internal.symbols.InvalidVariableLocation; +import org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariable; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.core.runtime.CoreException; + +public class VariableWithValue extends OperandValue { + final IVariable variable; + private final EDCServicesTracker servicesTracker; + private final StackFrameDMC frame; + + public VariableWithValue(EDCServicesTracker servicesTracker, StackFrameDMC frame, IVariable variable) { + this(servicesTracker, frame, variable, false); + } + + public VariableWithValue(EDCServicesTracker servicesTracker, StackFrameDMC frame, IVariable variable, + boolean isBitField) { + super(variable.getType(), isBitField); + this.servicesTracker = servicesTracker; + this.frame = frame; + this.variable = variable; + } + + public VariableWithValue(EDCServicesTracker servicesTracker, StackFrameDMC frame, IVariable variable, IType otherType) { + super(otherType, false); + this.servicesTracker = servicesTracker; + this.frame = frame; + this.variable = variable; + } + /** + * @return the servicesTracker + */ + public EDCServicesTracker getServicesTracker() { + return servicesTracker; + } + /** + * @return the frame + */ + public StackFrameDMC getFrame() { + return frame; + } + public IVariable getVariable() { + return variable; + } + + public Number getValue() throws CoreException { + if (value == null) { + IVariableLocation location = getValueLocation(); + IType varType = type; + if (varType != null) { + value = getValueByType(varType, location); + } else { + assert false; + } + } + return value; + } + + public IVariableLocation getValueLocation() { + if (valueLocation == null) { + ILocationProvider provider = variable.getLocationProvider(); + if (provider == null) { + // ERROR + valueLocation = new InvalidVariableLocation(ASTEvalMessages.VariableWithValue_CannotLocateVariable); + return valueLocation; + } + IEDCModuleDMContext module = frame.getModule(); + valueLocation = provider.getLocation(servicesTracker, frame, module.toLinkAddress(frame.getInstructionPtrAddress()), + TypeUtils.isConstType(variable.getType())); + if (valueLocation == null) { + // unhandled + valueLocation = new InvalidVariableLocation(ASTEvalMessages.VariableWithValue_CannotLocateVariable); + } + } + return valueLocation; + } + + public OperandValue copyWithType(IType otherType) { + OperandValue value = new VariableWithValue(servicesTracker, frame, variable, otherType); + value.stringValue = this.stringValue; + value.valueLocation = this.valueLocation; + return value; + } + + public void setType(IType type) { + this.type = type; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/FormatExtensionManager.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/FormatExtensionManager.java new file mode 100644 index 0000000..f18648f --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/FormatExtensionManager.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.formatter; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.cdt.debug.edc.formatter.ITypeContentProvider; +import org.eclipse.cdt.debug.edc.formatter.IVariableFormatProvider; +import org.eclipse.cdt.debug.edc.formatter.IVariableValueConverter; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; + +/** + * Manages format extensions + */ +public class FormatExtensionManager implements IVariableFormatManager { + + // Preferences + public static final String VARIABLE_FORMATS_ENABLED = "variable_formats_enabled"; + public static final boolean VARIABLE_FORMATS_ENABLED_DEFAULT = true; + + /** + * A chooser implementation that always defers to any formatter that is not one of the default formatters + */ + private static final class DefaultFormatProviderChooser implements IVariableFormatProviderChooser { + private static final String DEFAULT_COMPOSITE = + "org.eclipse.cdt.debug.edc.formatter.default.composite"; //$NON-NLS-1$ + private static final String DEFAULT_ARRAY = + "org.eclipse.cdt.debug.edc.formatter.default.array"; //$NON-NLS-1$ + + public String chooseDetailValueConverter(IType type, Collection ids) { + return chooseAnyBeforeDefault(ids); + } + + public String chooseTypeContentProvider(IType type, Collection ids) { + return chooseAnyBeforeDefault(ids); + } + + public String chooseVariableValueConverter(IType type, Collection ids) { + return chooseAnyBeforeDefault(ids); + } + + private String chooseAnyBeforeDefault(Collection ids) { + if (ids.size() > 1) { + for (String id : ids) { + if (!id.equals(DEFAULT_COMPOSITE) && !id.equals(DEFAULT_ARRAY)) + return id; + } + } + else if (ids.size() == 1) + return ids.iterator().next(); + + return null; + } + } + + public class FormatProviderExtension { + private String label; + private IVariableFormatProvider formatProvider; + + public FormatProviderExtension(String label, IVariableFormatProvider formatProvider) { + this.label = label; + this.formatProvider = formatProvider; + } + + public String getLabel() { + return label; + } + + public IVariableFormatProvider getFormatProvider() { + return formatProvider; + } + } + + private static IVariableFormatManager instance = + new FormatExtensionManager(new DefaultFormatProviderChooser()); + + private Map formatProviders; + private IVariableFormatProviderChooser chooser; + private boolean enabled = FormatExtensionManager.VARIABLE_FORMATS_ENABLED_DEFAULT; + + public static IVariableFormatManager instance() { + return instance; + } + + private FormatExtensionManager(IVariableFormatProviderChooser chooser) { + readProviders(); + setFormatProviderChooser(chooser); + IEclipsePreferences scope = InstanceScope.INSTANCE.getNode(EDCDebugger.PLUGIN_ID); + enabled = scope.getBoolean(VARIABLE_FORMATS_ENABLED, FormatExtensionManager.VARIABLE_FORMATS_ENABLED_DEFAULT); + } + + private void readProviders() { + if (formatProviders != null) + return; + IConfigurationElement[] elements = + Platform.getExtensionRegistry().getConfigurationElementsFor(EDCDebugger.PLUGIN_ID + ".variableFormatProvider"); //$NON-NLS-1$ + for (IConfigurationElement element : elements) { + try { + String id = element.getAttribute("id"); //$NON-NLS-1$ + String label = element.getAttribute("label"); //$NON-NLS-1$ + IVariableFormatProvider formatProvider = + (IVariableFormatProvider) element.createExecutableExtension("class"); //$NON-NLS-1$ + if (formatProviders == null) + formatProviders = new HashMap(); + formatProviders.put(id, new FormatProviderExtension(label, formatProvider)); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError("Could not create formatting extension", e); + } + } + } + + private interface Getter { + T get(IVariableFormatProvider fp, IType type); + String choose(IType type, Collection ids); + } + + private T getProvider(IType type, Getter getter) { + if (!enabled) + return null; + Map providers = new HashMap(); + for (Entry entry : formatProviders.entrySet()) { + IVariableFormatProvider fp = entry.getValue().getFormatProvider(); + T t = getter.get(fp, type); + if (t != null) + providers.put(entry.getKey(), t); + } + String id = getter.choose(type, providers.keySet()); + return providers.get(id); + } + + + public ITypeContentProvider getTypeContentProvider(IType type) { + return getProvider(type, new Getter() { + public ITypeContentProvider get(IVariableFormatProvider fp, IType type) { + return fp.getTypeContentProvider(type); + } + public String choose(IType type, Collection ids) { + return chooser.chooseTypeContentProvider(type, ids); + } + }); + } + + public IVariableValueConverter getVariableValueConverter(IType type) { + return getProvider(type, new Getter() { + public IVariableValueConverter get(IVariableFormatProvider fp, IType type) { + return fp.getVariableValueConverter(type); + } + public String choose(IType type, Collection ids) { + return chooser.chooseVariableValueConverter(type, ids); + } + }); + } + + public IVariableValueConverter getDetailValueConverter(IType type) { + return getProvider(type, new Getter() { + public IVariableValueConverter get(IVariableFormatProvider fp, IType type) { + return fp.getDetailValueConverter(type); + } + public String choose(IType type, Collection ids) { + return chooser.chooseDetailValueConverter(type, ids); + } + }); + } + + public void setFormatProviderChooser(IVariableFormatProviderChooser chooser) { + this.chooser = chooser; + } + + public String[] getVariableFormatProviderIds() { + Set keySet = formatProviders.keySet(); + return keySet.toArray(new String[keySet.size()]); + } + + public String getFormatProviderLabel(String id) { + return formatProviders.get(id).getLabel(); + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isEnabled() { + return enabled; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/IVariableFormatManager.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/IVariableFormatManager.java new file mode 100644 index 0000000..2f6640c --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/IVariableFormatManager.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.formatter; + +import org.eclipse.cdt.debug.edc.formatter.IVariableFormatProvider; + +/** + * An interface to the variable format provider manager singleton + */ +public interface IVariableFormatManager extends IVariableFormatProvider { + + void setFormatProviderChooser(IVariableFormatProviderChooser chooser); + + String[] getVariableFormatProviderIds(); + + String getFormatProviderLabel(String id); + + void setEnabled(boolean enabled); + + boolean isEnabled(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/IVariableFormatProviderChooser.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/IVariableFormatProviderChooser.java new file mode 100644 index 0000000..9047349 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/formatter/IVariableFormatProviderChooser.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.formatter; + +import java.util.Collection; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * An object that allows choosing between format providers + */ +public interface IVariableFormatProviderChooser { + + String chooseTypeContentProvider(IType type, Collection ids); + + String chooseVariableValueConverter(IType type, Collection ids); + + String chooseDetailValueConverter(IType type, Collection ids); +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/CSourceLookup.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/CSourceLookup.java new file mode 100644 index 0000000..4973671 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/CSourceLookup.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.launch; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.service.ISourceLookup; +import org.eclipse.cdt.dsf.service.AbstractDsfService; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.osgi.framework.BundleContext; + +/** + * ISourceLookup service implementation based on the CDT CSourceLookupDirector. + * Supports multiple source lookup directors. + */ +public class CSourceLookup extends AbstractDsfService implements ISourceLookup { + + private final Map> directors = new HashMap>(); + + public CSourceLookup(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return EDCDebugger.getBundleContext(); + } + + public void addSourceLookupDirector(ISourceLookupDMContext ctx, CSourceLookupDirector director) { + List directorsInContext = directors.get(ctx); + if (directorsInContext == null) + directorsInContext = new ArrayList(); + directorsInContext.add(director); + directors.put(ctx, directorsInContext); + } + + public CSourceLookupDirector[] getSourceLookupDirectors(ISourceLookupDMContext ctx) { + List directorList = directors.get(ctx); + return directorList.toArray(new CSourceLookupDirector[directorList.size()]); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(final RequestMonitor requestMonitor) { + // Register this service + register(new String[] { CSourceLookup.class.getName(), ISourceLookup.class.getName() }, + new Hashtable()); + + requestMonitor.done(); + } + + @Override + public void shutdown(final RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } + + public void getDebuggerPath(ISourceLookupDMContext sourceLookupCtx, Object source, + final DataRequestMonitor rm) { + if (!(source instanceof String)) { + // In future if needed other elements such as URIs could be + // supported. + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, + "Only string source element is supported", null)); //$NON-NLS-1$); + rm.done(); + return; + } + final String sourceString = (String) source; + + if (!directors.containsKey(sourceLookupCtx)) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, + "No source director configured for given context", null)); //$NON-NLS-1$); + rm.done(); + return; + } + final CSourceLookupDirector[] director = getSourceLookupDirectors(sourceLookupCtx); + + new Job("Lookup Debugger Path") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + + rm.setData(sourceString); + + for (CSourceLookupDirector cSourceLookupDirector : director) { + IPath debuggerPath = cSourceLookupDirector.getCompilationPath(sourceString); + if (debuggerPath != null) { + rm.setData(debuggerPath.toString()); + break; + } + } + rm.done(); + + return Status.OK_STATUS; + } + }.schedule(); + + } + + public void getSource(ISourceLookupDMContext sourceLookupCtx, final String debuggerPath, + final DataRequestMonitor rm) { + if (!directors.containsKey(sourceLookupCtx)) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, + "No source director configured for given context", null)); //$NON-NLS-1$); + rm.done(); + return; + } + final CSourceLookupDirector[] director = getSourceLookupDirectors(sourceLookupCtx); + + new Job("Lookup Source") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + Object[] sources; + try { + for (CSourceLookupDirector cSourceLookupDirector : director) { + sources = cSourceLookupDirector.findSourceElements(debuggerPath); + if (sources == null || sources.length == 0) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, + IDsfStatusConstants.REQUEST_FAILED, "No sources found", null)); //$NON-NLS-1$); + } else { + rm.setData(sources[0]); + break; + } + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, + "Source lookup failed", e)); //$NON-NLS-1$); + } finally { + rm.done(); + } + + return Status.OK_STATUS; + } + }.schedule(); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/ServicesLaunchSequence.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/ServicesLaunchSequence.java new file mode 100644 index 0000000..eeaeeec --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/ServicesLaunchSequence.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.launch; + +import org.eclipse.cdt.debug.edc.internal.services.dsf.BreakpointAttributeTranslator; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Breakpoints; +import org.eclipse.cdt.debug.edc.internal.services.dsf.INoop; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules; +import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Snapshots; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Symbols; +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator2; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints; +import org.eclipse.cdt.dsf.debug.service.IDisassembly; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IMemory; +import org.eclipse.cdt.dsf.debug.service.IModules; +import org.eclipse.cdt.dsf.debug.service.IProcesses; +import org.eclipse.cdt.dsf.debug.service.IRegisters; +import org.eclipse.cdt.dsf.debug.service.IRunControl; +import org.eclipse.cdt.dsf.debug.service.ISourceLookup; +import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack; +import org.eclipse.cdt.dsf.debug.service.ISymbols; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IProgressMonitor; + +public class ServicesLaunchSequence extends Sequence { + + Step[] fSteps = new Step[] { + /* + * create this service as the first one as it's needed when + * constructing/initializing other services. + */ + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(ITargetEnvironment.class, session, launch).initialize( + requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(IProcesses.class, session).initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + runControlService = (RunControl) launch.getServiceFactory().createService(IRunControl.class, session); + runControlService.initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(IMemory.class, session).initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + Modules modules = (Modules) launch.getServiceFactory().createService(IModules.class, session); + modules.initialize(requestMonitor); + modules.setSourceLocator(launch.getExecutableLocator()); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(IStack.class, session).initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + Symbols symbols = (Symbols) launch.getServiceFactory().createService(ISymbols.class, session); + symbols.initialize(requestMonitor); + symbols.setSourceLocator(launch.getSourceLocator()); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(IExpressions.class, session).initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + sourceLookup = (CSourceLookup) launch.getServiceFactory().createService(ISourceLookup.class, session); + sourceLookup.initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + ISourceLookupDMContext sourceLookupDmc = runControlService.getRootDMC(); + sourceLookup.addSourceLookupDirector(sourceLookupDmc, (CSourceLookupDirector) launch.getSourceLocator()); + requestMonitor.done(); + } + }, + + new Step() { + @Override + public void execute(final RequestMonitor requestMonitor) { + Breakpoints breakpoints = (Breakpoints) launch.getServiceFactory().createService(IBreakpoints.class, + session); + breakpoints.initialize(new RequestMonitor(getExecutor(), requestMonitor)); + breakpoints.setSourceLocator(launch.getSourceLocator()); + } + }, + + new Step() { + @Override + public void execute(final RequestMonitor requestMonitor) { + final BreakpointsMediator2 bpmService = new BreakpointsMediator2(session, new BreakpointAttributeTranslator( + session)); + bpmService.initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(IRegisters.class, session).initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(IDisassembly.class, session).initialize(requestMonitor); + } + }, + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(Snapshots.class, session).initialize( + requestMonitor); + } + }, + + // Used for testing + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + launch.getServiceFactory().createService(INoop.class, session).initialize(requestMonitor); + } + }}; + + DsfSession session; + EDCLaunch launch; + RunControl runControlService; + CSourceLookup sourceLookup; + + public ServicesLaunchSequence(DsfSession session, EDCLaunch launch, IProgressMonitor pm) { + super(session.getExecutor(), pm, "Initializing debugger services", "Aborting debugger services initialization"); + this.session = session; + this.launch = launch; + } + + @Override + public Step[] getSteps() { + return fSteps; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/ShutdownSequence.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/ShutdownSequence.java new file mode 100644 index 0000000..44ba7f8 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/ShutdownSequence.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.launch; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.services.dsf.INoop; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Snapshots; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Symbols; +import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator2; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints; +import org.eclipse.cdt.dsf.debug.service.IDisassembly; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IMemory; +import org.eclipse.cdt.dsf.debug.service.IModules; +import org.eclipse.cdt.dsf.debug.service.IProcesses; +import org.eclipse.cdt.dsf.debug.service.IRegisters; +import org.eclipse.cdt.dsf.debug.service.IRunControl; +import org.eclipse.cdt.dsf.debug.service.ISourceLookup; +import org.eclipse.cdt.dsf.debug.service.IStack; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.IDsfService; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +public class ShutdownSequence extends Sequence { + + String sessionId; + + String applicationName; + + String debugModelId; + + DsfServicesTracker tracker; + + public ShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) { + super(executor, requestMonitor); + this.sessionId = sessionId; + } + + @Override + public Step[] getSteps() { + return steps; + } + + private final Step[] steps = new Step[] { + + new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + assert EDCDebugger.getDefault().getBundle().getBundleContext() != null; + tracker = new DsfServicesTracker(EDCDebugger.getDefault().getBundle().getBundleContext(), sessionId); + requestMonitor.done(); + } + + @Override + public void rollBack(RequestMonitor requestMonitor) { + tracker.dispose(); + tracker = null; + requestMonitor.done(); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(Snapshots.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IDisassembly.class, requestMonitor); + } + }, new Step() { + // Call this to make sure breakpoints are removed. + // Do this before we shutdown other services to ensure + // breakpoints can be removed. + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(BreakpointsMediator2.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IRegisters.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IBreakpoints.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(ISourceLookup.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IExpressions.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IStack.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IModules.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IMemory.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IRunControl.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(IProcesses.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(ITargetEnvironment.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(Symbols.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + shutdownService(INoop.class, requestMonitor); + } + }, new Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + tracker.dispose(); + tracker = null; + requestMonitor.done(); + } + } }; + + private void shutdownService(Class clazz, final RequestMonitor requestMonitor) { + IDsfService service = (IDsfService) tracker.getService(clazz); + if (service != null) { + service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleCompleted() { + if (!isSuccess()) { + + } + requestMonitor.done(); + } + }); + } else { + requestMonitor + .setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "AbstractEDCService '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ + requestMonitor.done(); + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/SnapshotLaunch.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/SnapshotLaunch.java new file mode 100644 index 0000000..91864d6 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/SnapshotLaunch.java @@ -0,0 +1,14 @@ +package org.eclipse.cdt.debug.edc.internal.launch; + +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.ISourceLocator; + +public class SnapshotLaunch extends EDCLaunch { + + public SnapshotLaunch(ILaunchConfiguration launchConfiguration, String mode, + ISourceLocator locator, String ownerID) { + super(launchConfiguration, mode, locator, ownerID); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/SnapshotLaunchDelegate.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/SnapshotLaunchDelegate.java new file mode 100644 index 0000000..9a7366a --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/launch/SnapshotLaunchDelegate.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.launch; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.snapshot.Album; +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.cdt.debug.edc.launch.EDCLaunchDelegate; +import org.eclipse.cdt.debug.edc.launch.IEDCLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.debug.service.IDsfDebugServicesFactory; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; + +public class SnapshotLaunchDelegate extends EDCLaunchDelegate { + + public final static String SNAPSHOT_DEBUG_MODEL_ID = "org.eclipse.cdt.debug.edc.internal.snapshot"; //$NON-NLS-1$ + private Album album; + private ILaunchConfiguration proxyLaunchConfig; + + @Override + public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) + throws CoreException { + String albumLocation = configuration.getAttribute(IEDCLaunchConfigurationConstants.ATTR_ALBUM_FILE, ""); + IPath albumPath = new Path(albumLocation); + album = Album.getAlbumByLocation(albumPath); + if (album == null || !album.isLoaded()) { + if (album == null) { + album = new Album(); + } + album.setLocation(albumPath); + try { + album.loadAlbum(false); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + return false; + } + } + ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); + String launchID = album.getLaunchTypeID(); + ILaunchConfigurationType launchType = lm.getLaunchConfigurationType(launchID); + if (launchType == null) { + throw new CoreException(new Status(Status.ERROR, EDCDebugger.PLUGIN_ID, "Can't launch this snapshot because the required debugger is not installed: " + launchID)); + } + proxyLaunchConfig = findExistingLaunchForAlbum(albumLocation); + if (proxyLaunchConfig == null) { + String lcName = lm.generateLaunchConfigurationName(album.getDisplayName()); + ILaunchConfigurationWorkingCopy proxyLaunchConfigWC = launchType.newInstance(null, lcName); + + proxyLaunchConfigWC.setAttributes(album.getLaunchProperties()); + proxyLaunchConfigWC.setAttribute(IEDCLaunchConfigurationConstants.ATTR_ALBUM_FILE, configuration + .getAttribute(IEDCLaunchConfigurationConstants.ATTR_ALBUM_FILE, "")); + proxyLaunchConfig = proxyLaunchConfigWC.doSave(); + } + + Job launchJob = new Job("Launching " + configuration.getName()) { + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + proxyLaunchConfig.launch(ILaunchManager.DEBUG_MODE, new NullProgressMonitor(), false, true); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + return Status.CANCEL_STATUS; + } + return Status.OK_STATUS; + } + }; + launchJob.schedule(); + return false; + } + + private ILaunchConfiguration findExistingLaunchForAlbum(String albumLocation) { + ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); + ILaunchConfigurationType launchType = lm.getLaunchConfigurationType(album.getLaunchTypeID()); + + try { + ILaunchConfiguration[] configurations = lm.getLaunchConfigurations(launchType); + for (ILaunchConfiguration configuration : configurations) { + if (albumLocation.equals(configuration.getAttribute(IEDCLaunchConfigurationConstants.ATTR_ALBUM_FILE, + ""))) + return configuration; + } + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + return null; + } + + @Override + public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) + throws CoreException { + proxyLaunchConfig.launch(mode, new NullProgressMonitor(), false, true); + } + + @Override + public String getDebugModelID() { + return SNAPSHOT_DEBUG_MODEL_ID; + } + + @Override + protected Sequence getLiveLaunchSequence(DsfExecutor executor, EDCLaunch launch, IProgressMonitor pm) { + return null; + } + + @Override + protected IDsfDebugServicesFactory newServiceFactory() { + return null; + } + + @Override + protected String getPluginID() { + return EDCDebugger.getUniqueIdentifier(); + } + + @Override + protected boolean isSameTarget(EDCLaunch existingLaunch, + ILaunchConfiguration configuration, String mode) { + return false; + } + + @Override + public EDCLaunch createLaunch(ILaunchConfiguration configuration, + String mode) { + return new SnapshotLaunch(configuration, mode, null, getDebugModelID()); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/BreakpointAttributeTranslator.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/BreakpointAttributeTranslator.java new file mode 100644 index 0000000..0b7119b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/BreakpointAttributeTranslator.java @@ -0,0 +1,459 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.ModuleDMC; +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; +import org.eclipse.cdt.debug.edc.symbols.ILineEntryProvider.ILineAddresses; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator2; +import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator2.BreakpointEventType; +import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator2.ITargetBreakpointInfo; +import org.eclipse.cdt.dsf.debug.service.IBreakpointAttributeTranslator2; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IBreakpoint; + +public class BreakpointAttributeTranslator implements IBreakpointAttributeTranslator2 { + + private DsfServicesTracker dsfServicesTracker; + private DsfSession dsfSession; + private ITargetEnvironment targetEnvService; + + public BreakpointAttributeTranslator(DsfSession dsfSession) { + super(); + this.dsfSession = dsfSession; + + dsfServicesTracker = new DsfServicesTracker(EDCDebugger.getDefault().getBundle().getBundleContext(), dsfSession.getId()); + targetEnvService = dsfServicesTracker.getService(ITargetEnvironment.class); + assert targetEnvService != null; + } + + public boolean canUpdateAttributes(IBreakpointDMContext bp, Map delta) { + /* + * This method decides whether we need to re-install the breakpoint + * based on the attributes change (refer to caller in + * BreakpointsMediator). For EDC, following changed attributes justify + * re-installation. + */ + // Check if there is any modified attribute + if (delta == null || delta.size() == 0) + return true; + + // Check the "critical" attributes + // TODO: threadID change + if (delta.containsKey(IMarker.LINE_NUMBER) // Line number + || delta.containsKey(IBreakpoint.ENABLED) // EDC don't handle enable/disable. TODO: ask ITargetEnvironment service if it can handle it. + || delta.containsKey(ICLineBreakpoint.FUNCTION) // Function name + || delta.containsKey(ICLineBreakpoint.ADDRESS) // Absolute address + || delta.containsKey(ICWatchpoint.EXPRESSION) // Watchpoint expression + || delta.containsKey(ICWatchpoint.READ) // Watchpoint type + || delta.containsKey(ICWatchpoint.WRITE)) { // Watchpoint type + return false; + } + + // for other attrs (ICBreakpoint.INSTALL_COUNT, ICBreakpoint.IGNORE_COUNT, + // ICBreakpoint.CONDITION, etc), we can update by just copying. + return true; + } + + public void dispose() { + if (dsfServicesTracker != null) + dsfServicesTracker.dispose(); + dsfSession = null; + } + + public List> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) + throws CoreException { + // The breakpoint mediator allows for multiple target-side breakpoints + // to be created for each IDE breakpoint. But the API is not good enough. + + // obsolete + List> retVal = new ArrayList>(1); + return retVal; + } + + public void initialize(BreakpointsMediator2 mediator) { + + } + + public boolean supportsBreakpoint(IBreakpoint bp) { + // We support only CDT breakpoints. + return bp instanceof ICBreakpoint; + } + + public void updateBreakpointStatus(IBreakpoint bp) { + // obsolet, do nothing. + } + + public void updateBreakpointsStatus(Map> bpsInfo, + BreakpointEventType eventType) { + for (IBreakpoint bp : bpsInfo.keySet()) { + if (! (bp instanceof ICBreakpoint)) // not C breakpoints, bail out. + return; + + final ICBreakpoint icbp = (ICBreakpoint) bp; + + Map targetBpPerContext = bpsInfo.get(bp); + + switch (eventType) { + case ADDED: { + int installCountTotal = 0; + for (ITargetBreakpointInfo[] tbpInfos : targetBpPerContext.values()) { + // For each BpTargetDMContext, we increment the installCount for each + // target BP that has been successfully installed. + int installCountPerContext = 0; + for (ITargetBreakpointInfo tbp : tbpInfos) { + if (tbp.getTargetBreakpoint() != null) + installCountPerContext++; + } + installCountTotal += installCountPerContext; + } + + for (int i=0; i < installCountTotal; i++) + try { + // this will eventually carried out in a workbench runnable. + icbp.incrementInstallCount(); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().log(e.getStatus()); + } + break; + } + case MODIFIED: + break; + + case REMOVED: { + int removeCountTotal = 0; + for (ITargetBreakpointInfo[] tbpInfos : targetBpPerContext.values()) { + // For each BpTargetDMContext, we decrement the installCount for each + // target BP that we tried to remove, even if the removal failed. That's + // because I've not seen a way to tell platform that removal fails + // and the BP should be kept in UI. + removeCountTotal += tbpInfos.length; + } + + for (int i=0; i < removeCountTotal; i++) + try { + if (icbp.isRegistered()) // not deleted in UI + icbp.decrementInstallCount(); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().log(e.getStatus()); + } + break; + } + } + } + } + + public Map convertAttributes(Map platformBPAttrDelta) { + // For EDC, we don't need any conversion yet....11/08/09. + return new HashMap(platformBPAttrDelta); + } + + public void resolveBreakpoint(IBreakpointsTargetDMContext context, IBreakpoint breakpoint, + final Map attributes, final DataRequestMonitor>> drm) { + + final List> targetBPAttrs = new ArrayList>(1); + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, + "Resolving breakpoint " + EDCTrace.fixArg(breakpoint) + " in context " + EDCTrace.fixArg(context)); } + + if (dsfSession == null) { + // already disposed + drm.setData(targetBPAttrs); + drm.done(); + if (EDCTrace.BREAKPOINTS_TRACE_ON) {EDCTrace.getTrace().traceExit(null, "null session");} + return; + } + + Map oneBPAttr; + + final ModuleDMC module = (ModuleDMC) context; + + String bpType = (String)attributes.get(Breakpoints.BREAKPOINT_SUBTYPE); + + if (bpType.equals(Breakpoints.ADDRESS_BREAKPOINT)) { + String addr = (String)attributes.get(ICLineBreakpoint.ADDRESS); + // This is hex string with "0x". + assert addr != null; + + oneBPAttr = new HashMap(attributes); + String s = addr.toLowerCase().startsWith("0x") ? addr.substring(2) : addr; + oneBPAttr.put(Breakpoints.RUNTIME_ADDRESS, s); + targetBPAttrs.add(oneBPAttr); + + drm.setData(targetBPAttrs); + drm.done(); + } + else if (bpType.equals(Breakpoints.FUNCTION_BREAKPOINT)) { + String function = (String) attributes.get(ICLineBreakpoint.FUNCTION); + assert (function != null && function.length() > 0); + + // the point is a symbol + Symbols symService = dsfServicesTracker.getService(Symbols.class); + List addrs = symService.getFunctionAddress(module, function); + for (IAddress a : addrs) { + oneBPAttr = new HashMap(attributes); + oneBPAttr.put(Breakpoints.RUNTIME_ADDRESS, a.toString(16)); + + targetBPAttrs.add(oneBPAttr); + } + + drm.setData(targetBPAttrs); + drm.done(); + } + else { + assert bpType.equals(Breakpoints.LINE_BREAKPOINT); + + final String bpFile = (String) attributes.get(ICBreakpoint.SOURCE_HANDLE); + final Integer line = (Integer) attributes.get(IMarker.LINE_NUMBER); + + final IExecutionDMContext exe_dmc = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); + + final ICBreakpoint icBP = (ICBreakpoint)breakpoint; + + assert exe_dmc != null : "ExecutionDMContext is unknown in resolveBreakpoint()."; + + Modules modulesService = dsfServicesTracker.getService(Modules.class); + ISymbolDMContext sym_dmc = DMContexts.getAncestorOfType(context, ISymbolDMContext.class); + + String compileFile = EDCLaunch.getLaunchForSession(dsfSession.getId()).getCompilationPath(bpFile); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, + "BP file: " + bpFile + " Compile file: " + compileFile); } + + /* + * Look for code lines within five lines above and below the line in + * question as we don't want to move a breakpoint too far. + */ + modulesService.findClosestLineWithCode(sym_dmc, compileFile, line, 5, + new DataRequestMonitor(dsfSession.getExecutor(), drm) { + + @Override + protected void handleCompleted() { + if (! isSuccess()) { + drm.setStatus(getStatus()); + drm.done(); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, + "findClosestLineWithCode failed: " + drm.getStatus()); } + return; + } + + ILineAddresses codeLine = getData(); + + /* + * there could be multiple address ranges for the same + * source line. e.g. for templates or inlined functions. if + * so, we need only set a breakpoint on the first location + */ + IAddress[] addresses = codeLine.getAddress(); + if (addresses.length > 0) { + IAddress address = addresses[0]; + for (int i = 1; i < addresses.length; i++) + if (addresses[i].getValue().longValue() < address.getValue().longValue()) + address = addresses[i]; + Map targetAttr = new HashMap(attributes); + targetAttr.put(Breakpoints.RUNTIME_ADDRESS, address.toString(16)); + targetBPAttrs.add(targetAttr); + } + + drm.setData(targetBPAttrs); + + int actualCodeLine = codeLine.getLineNumber(); + + if (actualCodeLine == line) + drm.done(); + else { + // breakpoint is resolved to a different line (the closest code line). + // If there is no user breakpoint at that line, we move the breakpoint there. + // Otherwise just mark this breakpoint as unresolved. + // + final int newLine = actualCodeLine; + + /** + * Move the breakpoint to the actual code line. + * + * Should we run following code in another thread ? Seems yes according to comment in + * BreakpointsMediator2.startTrackingBreakpoints(). But that way we'll run into this + * problem: + * 11 // blank line + * 12 // blank line + * 13 i = 2; + * set bp at line 11 & 12, start debugger, we'll get two resolved breakpoints on line 13 + * (check in Breakpoints view). + * + * To fix that issue, I just run this in DSF executor thread. I don't see any problem + * in my test......... 01/03/11 + */ + if (null == findUserBreakpointAt(bpFile, newLine)) { + // After we change the line number attribute, a breakpoint-change + // notification will come from platform through BreakpointsMediator2, + // resulting in installation of the changed bp and removal of the + // original bp. + try { + icBP.getMarker().setAttribute(IMarker.LINE_NUMBER, newLine); + } catch (CoreException e) { + // When will this happen ? ignore. + } + + // At this point the "drm" contains a valid list of "targetBPAttrs", namely + // we treat this BP as resolved. This is needed for such moved-BP to work + // on debugger start. + drm.done(); + } + else { + targetBPAttrs.clear(); // mark the BP as unresolved by clearing the list. + drm.done(); + } + } + } + }); + } + if (EDCTrace.BREAKPOINTS_TRACE_ON) {EDCTrace.getTrace().traceExit(null);} + } + + public Map getAllBreakpointAttributes(IBreakpoint platformBP, boolean bpManagerEnabled) + throws CoreException { + // Check that the marker exists and retrieve its attributes. + // Due to accepted race conditions, the breakpoint marker may become + // null while this method is being invoked. In this case throw an exception + // and let the caller handle it. + IMarker marker = platformBP.getMarker(); + if (marker == null || !marker.exists()) { + throw new DebugException(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, DebugException.REQUEST_FAILED, + "Breakpoint marker does not exist", null)); + } + // Suppress cast warning: platform is still on Java 1.3 + Map platformBpAttrs = marker.getAttributes(); + + // Just make a copy of the platform attributes. + // Add conversion or addition when needed. + Map attrs = new HashMap(platformBpAttrs); + + if (platformBP instanceof ICWatchpoint) { + attrs.put(Breakpoints.BREAKPOINT_TYPE, Breakpoints.WATCHPOINT); + /* + * Related Attributes attributes.get(ICWatchpoint.EXPRESSION)); + * attributes.get(ICWatchpoint.READ)); + * attributes.get(ICWatchpoint.WRITE)); + */ + } else if (platformBP instanceof ICLineBreakpoint) { + attrs.put(Breakpoints.BREAKPOINT_TYPE, Breakpoints.BREAKPOINT); + + String file = (String) attrs.get(ICBreakpoint.SOURCE_HANDLE); + String address = (String) attrs.get(ICLineBreakpoint.ADDRESS); + String function = (String) attrs.get(ICLineBreakpoint.FUNCTION); + Integer line = (Integer) attrs.get(IMarker.LINE_NUMBER); + + if (address != null && address.length() > 0) + attrs.put(Breakpoints.BREAKPOINT_SUBTYPE, Breakpoints.ADDRESS_BREAKPOINT); + else if (function != null && function.length() > 0) + attrs.put(Breakpoints.BREAKPOINT_SUBTYPE, Breakpoints.FUNCTION_BREAKPOINT); + else { + assert file != null && file.length() > 0 && line != null; + attrs.put(Breakpoints.BREAKPOINT_SUBTYPE, Breakpoints.LINE_BREAKPOINT); + } + /* + * Related attributes: String + * attributes.get(ICBreakpoint.SOURCE_HANDLE)); Int + * attributes.get(IMarker.LINE_NUMBER)); String + * attributes.get(ICLineBreakpoint.FUNCTION)); String + * attributes.get(ICLineBreakpoint.ADDRESS)); + */ + } else { + // catchpoint? + } + + /* + * Common fields attributes.get(ICBreakpoint.CONDITION)); + * attributes.get(ICBreakpoint.IGNORE_COUNT)); + * attributes.get(ICBreakpoint.INSTALL_COUNT)); + * attributes.get(ICBreakpoint.ENABLED)); + * attributes.get(ATTR_THREAD_ID)); // TODO: check: gdb specific ? + */ + + // If the breakpoint manager is disabled, override the enabled + // attribute. + if (!bpManagerEnabled) { + attrs.put(IBreakpoint.ENABLED, false); + } + + return attrs; + } + + public boolean canUpdateAttributes(IBreakpoint bp, IBreakpointsTargetDMContext context, Map attrDelta) { + // no special handling needed for EDC yet. + return canUpdateAttributes(null, attrDelta); + } + + /** + * Find the CDT line breakpoint that exists at the given line of the + * given file. + * + * @param bpFile + * @param bpLine + * @return IBreakpoint if found, null otherwise. + */ + static private IBreakpoint findUserBreakpointAt( + String bpFile, int bpLine) { + IBreakpoint[] platformBPs = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(); + for (IBreakpoint pbp : platformBPs) { + if (pbp instanceof ICLineBreakpoint) { + // Check that the marker exists and retrieve its attributes. + // Due to accepted race conditions, the breakpoint marker may become + // null while this method is being invoked. In this case throw an exception + // and let the caller handle it. + IMarker marker = pbp.getMarker(); + if (marker == null || !marker.exists()) + continue; + + // Suppress cast warning: platform is still on Java 1.3 + try { + Map attrs = marker.getAttributes(); + + String file = (String) attrs.get(ICBreakpoint.SOURCE_HANDLE); + Integer line = (Integer) attrs.get(IMarker.LINE_NUMBER); + + if (bpFile.equals(file) && bpLine == line) + return pbp; + } + catch (Exception e) { + // ignore + } + } + } + + return null; + } +} + \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Breakpoints.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Breakpoints.java new file mode 100644 index 0000000..abfe6c0 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Breakpoints.java @@ -0,0 +1,1207 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.IllegalFormatException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.ModuleDMC; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.ModuleLoadedEvent; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.ModuleUnloadedEvent; +import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC; +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.debug.edc.services.DMContext; +import org.eclipse.cdt.debug.edc.services.IDSFServiceUsingTCF; +import org.eclipse.cdt.debug.edc.services.IEDCDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCExpression; +import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; +import org.eclipse.cdt.debug.edc.services.Stack; +import org.eclipse.cdt.debug.edc.tcf.extension.ProtocolConstants.IModuleProperty; +import org.eclipse.cdt.debug.internal.core.breakpoints.BreakpointProblems; +import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator2; +import org.eclipse.cdt.dsf.debug.service.IBreakpointAttributeTranslator; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.cdt.dsf.debug.service.IModules.ModuleLoadedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IModules.ModuleUnloadedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.tm.tcf.protocol.IService; +import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.protocol.Protocol; +import org.eclipse.tm.tcf.services.IBreakpoints.DoneCommand; + +public class Breakpoints extends AbstractEDCService implements IBreakpoints, IDSFServiceUsingTCF { + + /** + * Breakpoint attributes markers used in the map parameters of + * insert/updateBreakpoint(). All are optional with the possible exception + * of TYPE. It is the responsibility of the + * {@link IBreakpointAttributeTranslator} to ensure that the set of + * attributes provided is sufficient to create/update a valid breakpoint on + * the back-end. + */ + public static final String PREFIX = "org.eclipse.cdt.debug.edc.breakpoint"; //$NON-NLS-1$ + + // Our own attribute keys. + // + /** + * Breakpoint type: value is string. + */ + public static final String BREAKPOINT_TYPE = PREFIX + ".type"; //$NON-NLS-1$ + // type values: + public static final String BREAKPOINT = "breakpoint"; //$NON-NLS-1$ + public static final String WATCHPOINT = "watchpoint"; //$NON-NLS-1$ + public static final String CATCHPOINT = "catchpoint"; //$NON-NLS-1$ + + /** + * breakponint sub-type: value is string. + */ + public static final String BREAKPOINT_SUBTYPE = PREFIX + ".subtype"; //$NON-NLS-1$ + // sub-type values: + public static final String LINE_BREAKPOINT = "line_bp"; //$NON-NLS-1$ + public static final String FUNCTION_BREAKPOINT = "function_bp"; //$NON-NLS-1$ + public static final String ADDRESS_BREAKPOINT = "address_bp"; //$NON-NLS-1$ + + /** + * breakpoint runtime address: value is hex string with no preceding "0x". + */ + public static final String RUNTIME_ADDRESS = PREFIX + ".runtime_addr"; + + // Error messages + static final String NULL_STRING = ""; //$NON-NLS-1$ + static final String UNKNOWN_EXECUTION_CONTEXT = "Unknown execution context"; //$NON-NLS-1$ + static final String UNKNOWN_BREAKPOINT_CONTEXT = "Unknown breakpoint context"; //$NON-NLS-1$ + static final String UNKNOWN_BREAKPOINT_TYPE = "Unknown breakpoint type"; //$NON-NLS-1$ + static final String UNKNOWN_BREAKPOINT = "Unknown breakpoint"; //$NON-NLS-1$ + static final String BREAKPOINT_INSERTION_FAILURE = "Breakpoint insertion failure"; //$NON-NLS-1$ + static final String WATCHPOINT_INSERTION_FAILURE = "Watchpoint insertion failure"; //$NON-NLS-1$ + static final String INVALID_CONDITION = "Invalid condition"; //$NON-NLS-1$ + + // User breakpoints (those from the IDE) currently installed. + private final Map userBreakpoints = new HashMap(); + + /** + * Internal temporary breakpoints set by debugger for stepping. + */ + private final List tempBreakpoints = new ArrayList(); + + private org.eclipse.tm.tcf.services.IBreakpoints tcfBreakpointService; + + // Module in which startup breakpoint is installed for the debug session. + private Map startupBreakpointModule = new HashMap(); + + private ISourceLocator sourceLocator; + + private Map fBreakpointMarkers = new HashMap(); + + static private long nextBreakpointID = 1; + + // ///////////////////////////////////////////////////////////////////////// + // Breakpoint Events + // ///////////////////////////////////////////////////////////////////////// + + public class BreakpointsChangedEvent extends AbstractDMEvent implements + IBreakpointsChangedEvent { + private IBreakpointDMContext[] eventBreakpoints; + + public BreakpointsChangedEvent(IBreakpointDMContext bp) { + super(DMContexts.getAncestorOfType(bp, IBreakpointsTargetDMContext.class)); + eventBreakpoints = new IBreakpointDMContext[] { bp }; + } + + public IBreakpointDMContext[] getBreakpoints() { + return eventBreakpoints; + } + } + + public class BreakpointAddedEvent extends BreakpointsChangedEvent implements IBreakpointsAddedEvent { + public BreakpointAddedEvent(IBreakpointDMContext context) { + super(context); + } + } + + public class BreakpointUpdatedEvent extends BreakpointsChangedEvent implements IBreakpointsUpdatedEvent { + public BreakpointUpdatedEvent(IBreakpointDMContext context) { + super(context); + } + } + + public class BreakpointRemovedEvent extends BreakpointsChangedEvent implements IBreakpointsRemovedEvent { + public BreakpointRemovedEvent(IBreakpointDMContext context) { + super(context); + } + } + + // ///////////////////////////////////////////////////////////////////////// + // IBreakpointDMContext + // ///////////////////////////////////////////////////////////////////////// + @Immutable + public static final class BreakpointDMContext extends DMContext implements IBreakpointDMContext { + public BreakpointDMContext(String sessionID, IDMContext[] parents, long id) { + super(sessionID, parents, Long.toString(id)); + } + + @Override + public String toString() { + return "BreakpointDMContext [id=" + getID() + "]"; + } + } + + public class BreakpointDMData implements IBreakpointDMData { + + private final long id; // internal ID. + private final IBreakpointDMContext context; + private final IAddress[] addresses; + private final byte[] originalInstruction; + private Map properties; + private int hitCount; + + public BreakpointDMData(long id, IBreakpointDMContext context, IAddress[] addresses, + Map properties) { + super(); + this.id = id; + this.context = context; + this.addresses = addresses; + this.originalInstruction = null; + this.properties = new HashMap(properties); // make a copy + } + + public BreakpointDMData(long id, IBreakpointDMContext context, IAddress[] addresses, + byte[] fOriginalInstruction, Map properties) { + super(); + this.id = id; + this.context = context; + this.addresses = addresses; + this.originalInstruction = fOriginalInstruction; + this.properties = new HashMap(properties); + } + + public IAddress[] getAddresses() { + return addresses; + } + + public String getBreakpointType() { + return (String) properties.get(BREAKPOINT_TYPE); + } + + public String getCondition() { + return (String) properties.get(ICBreakpoint.CONDITION); + } + + public String getExpression() { + return (String) properties.get(ICWatchpoint.EXPRESSION); + } + + public String getFileName() { + return (String) properties.get(ICBreakpoint.SOURCE_HANDLE); + } + + public String getFunctionName() { + return (String) properties.get(ICLineBreakpoint.FUNCTION); + } + + public int getIgnoreCount() { + return (Integer) properties.get(ICBreakpoint.IGNORE_COUNT); + } + + public int getLineNumber() { + return (Integer) properties.get(IMarker.LINE_NUMBER); + } + + public boolean isEnabled() { + return (Boolean) properties.get(IBreakpoint.ENABLED); + } + + public long getID() { + return id; + } + + public byte[] getOriginalInstruction() { + return originalInstruction; + } + + /** + * @return reference to properties map of the bp. + */ + public Map getProperties() { + return properties; + } + + public IBreakpointDMContext getContext() { + return context; + } + + public void setProperties(Map props) { + properties = new HashMap(props); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getOuterType().hashCode(); + result = prime * result + (int) (id ^ (id >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BreakpointDMData other = (BreakpointDMData) obj; + if (!getOuterType().equals(other.getOuterType())) + return false; + if (id != other.id) + return false; + return true; + } + + private Breakpoints getOuterType() { + return Breakpoints.this; + } + + @Override + public String toString() { + String s = getFileName(); + if (s == null) // address breakpoint + s = getAddresses()[0].toHexAddressString(); + else { + if (getFunctionName() != null) + s += ": " + getFunctionName(); + else + s += ":line " + getLineNumber(); + } + return "Breakpoint@" + s; + } + + public void incrementHitCount() { + hitCount++; + } + + public int getHitCount() + { + return hitCount; + } + } + + public Breakpoints(DsfSession session) { + super(session, new String[] { IBreakpoints.class.getName(), Breakpoints.class.getName() }); + } + + @Override + public void initialize(final RequestMonitor rm) { + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + // Register as event listener. + getSession().addServiceEventListener(Breakpoints.this, null); + rm.done(); + } + }); + } + + public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor drm) { + if (!userBreakpoints.containsKey(dmc)) { + drm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, UNKNOWN_BREAKPOINT)); + } else + drm.setData(userBreakpoints.get(dmc)); + + drm.done(); + } + + public void getBreakpoints(IBreakpointsTargetDMContext context, DataRequestMonitor drm) { + Set breakpointIDs = userBreakpoints.keySet(); + drm.setData(breakpointIDs.toArray(new IBreakpointDMContext[breakpointIDs.size()])); + drm.done(); + } + + /** + * Find breakpoint, either user-set or debugger internal temporary one, at + * the given address. + * + * @param addr + * - absolute runtime address. + * @return null if not found. + */ + public BreakpointDMData findBreakpoint(IAddress addr) { + BreakpointDMData bp = findUserBreakpoint(addr); + if (bp == null) + bp = findTempBreakpoint(addr); + return bp; + } + + /** + * Find user breakpoint at the given address. + * + * @param addr + * - absolute runtime address. + * @return null if not found. + */ + public BreakpointDMData findUserBreakpoint(IAddress addr) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, "Find user breakpoint at " + addr.toHexAddressString()); } + + for (BreakpointDMData bp : userBreakpoints.values()) + if (bp.getAddresses()[0].equals(addr)) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(bp.toString())); } + return bp; + } + + if (EDCTrace.BREAKPOINTS_TRACE_ON) {EDCTrace.getTrace().traceExit(null, "not found.");} + return null; + } + + /** + * Find a temporary breakpoint at the given address. + * + * @param addr + * - absolute runtime address. + * @return null if not found. + */ + public BreakpointDMData findTempBreakpoint(IAddress addr) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, "Find temp breakpoint at " + addr.toHexAddressString()); } + + for (BreakpointDMData bp : tempBreakpoints) { + if (bp.getAddresses()[0].equals(addr)) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(bp.toString())); } + return bp; + } + } + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null, "not found."); } + return null; + } + + /** + * Remove software breakpoints inserted in memory by debugger from the given + * memory buffer starting from given address. + * + * @param startAddr + * start address of the memory data. + * @param memBuffer + * a buffer containing data from memory. Its content will be + * changed by this method if a breakpoint falls in the address + * range. + */ + public void removeBreakpointFromMemoryBuffer(IAddress startAddr, MemoryByte[] memBuffer) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, "remove bp in memory area:" + startAddr.toHexAddressString() + "," + memBuffer.length); } + + // If the breakpoint is actually set by TCF agent, we have to assume + // that the TCF agent would do this breakpoint removing for us as + // we have no idea how the agent set the breakpoint (e.g. is it software + // breakpoint ? if yes, what breakpoint instruction is used ?) + // + if (usesTCFBreakpointService()) + return; + + for (BreakpointDMData edcBp : userBreakpoints.values()) { + // TODO: bail out if the bp is not software breakpoint. + + IAddress bpAddr = edcBp.getAddresses()[0]; + int bpOffset = (int) startAddr.distanceTo(bpAddr).longValue(); + if (bpOffset >= 0 && bpOffset < memBuffer.length) { + // the breakpoint falls in the buffer. Restore the original + // instruction. + byte[] orgInst = edcBp.getOriginalInstruction(); + for (int i = 0; i < orgInst.length && i + bpOffset < memBuffer.length; i++) { + memBuffer[bpOffset + i].setValue(orgInst[i]); + } + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, "breakpoint removed at offset " + bpOffset); } + } + } + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, + DataRequestMonitor drm) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { attributes })); } + + // Validate the context + if (context == null) { + drm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_EXECUTION_CONTEXT, + null)); + drm.done(); + return; + } + + // Validate the breakpoint type + String type = (String) attributes.get(BREAKPOINT_TYPE); + if (type == null) { + drm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, + null)); + drm.done(); + return; + } + + // And go... + if (type.equals(BREAKPOINT)) { + addBreakpoint(context, attributes, drm); + } else if (type.equals(WATCHPOINT)) { + drm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, + "Watchpoint is not supported yet.", null)); + drm.done(); + } else { + drm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, + null)); + drm.done(); + } + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * Set one target breakpoint. + * + * @param context + * @param attributes + * attributes for the target breakpoint. For EDC, it must contain + * the RUNTIME_ADDRESS attribute. + * @param drm + */ + private void addBreakpoint(final IBreakpointsTargetDMContext context, final Map attributes, + final DataRequestMonitor drm) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { attributes })); } + + IExecutionDMContext exe_dmc = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); + String bpAddr = (String)attributes.get(RUNTIME_ADDRESS); + + assert exe_dmc != null : "ExecutionDMContext is unknown in addBreakpoint()."; + assert bpAddr != null; + + createBreakpoint(exe_dmc, new Addr64(bpAddr, 16), attributes, new DataRequestMonitor( + getExecutor(), drm) { + + @Override + protected void handleSuccess() { + final BreakpointDMData bpd = getData(); + + enableBreakpoint(bpd, new RequestMonitor(getExecutor(), drm) { + + @Override + protected void handleSuccess() { + IBreakpointDMContext bp_dmc = bpd.getContext(); + drm.setData(bp_dmc); + + // Remember this in our global list. + userBreakpoints.put(bp_dmc, bpd); + + drm.done(); + } + }); + } + }); + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + public ISourceLocator getSourceLocator() { + return sourceLocator; + } + + public void setSourceLocator(ISourceLocator sourceLocator) { + this.sourceLocator = sourceLocator; + } + + /** + * Set temporary breakpoint at given address. This is for cases such as + * stepping and initial startup breakpoint (aka entry breakpoint).
    + * If a user or temporary breakpoint already exists at the address, no + * temporary breakpoint will be set. + * + * @param context + * @param address + * @param rm + */ + public void setTempBreakpoint(final IExecutionDMContext context, final IAddress address, final RequestMonitor rm) { + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, "set temp breakpoint at " + address.toHexAddressString()); } + + // If a breakpoint (user-set or temp) exists at the address, we are + // done. + if (findBreakpoint(address) != null) { + rm.done(); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null, "A breakpoint exists at " + address.toHexAddressString()); } + return; + } + + createBreakpoint(context, address, new HashMap(), new DataRequestMonitor( + getExecutor(), rm) { + @Override + protected void handleSuccess() { + final BreakpointDMData bp_data = getData(); + + enableBreakpoint(bp_data, new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + // Remember this in our list. + tempBreakpoints.add(bp_data); + rm.done(); + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg("A temp breakpoint successfully set at " + address.toHexAddressString())); } + } + }); + } + }); + } + + /** + * Remove all temporary breakpoints set so far. + * + * @param rm + */ + public void removeAllTempBreakpoints(final RequestMonitor rm) { + + int numTempBps = tempBreakpoints.size(); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, "remove " + numTempBps + " temp breakpoint" + ((numTempBps == 1)?"":"s") + "."); } + + if (numTempBps == 0) { + rm.done(); + return; + } + + CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + tempBreakpoints.clear(); + } + super.handleCompleted(); + } + }; + + crm.setDoneCount(tempBreakpoints.size()); + + for (BreakpointDMData bp : tempBreakpoints) + disableBreakpoint(bp, crm); + } + + private void createBreakpoint(final IExecutionDMContext exeDMC, final IAddress address, final Map props, + final DataRequestMonitor drm) { + + asyncExec(new Runnable() { + public void run() { + final long id = getNewBreakpointID(); + final IBreakpointDMContext bp_dmc = new BreakpointDMContext(getSession().getId(), new IDMContext[] { exeDMC }, + id); + final IAddress[] bp_addrs = new IAddress[] { address }; + final Map properties = new HashMap(props); + + if (usesTCFBreakpointService()) { + properties.put(org.eclipse.tm.tcf.services.IBreakpoints.PROP_ID, Long.toString(id)); + properties.put(org.eclipse.tm.tcf.services.IBreakpoints.PROP_ENABLED, true); + properties.put(org.eclipse.tm.tcf.services.IBreakpoints.PROP_TYPE, + org.eclipse.tm.tcf.services.IBreakpoints.TYPE_AUTO); + properties.put(org.eclipse.tm.tcf.services.IBreakpoints.PROP_LOCATION, address.toString()); + + + // Pass "contexts" for which the BP is supposed to work. + // NOTE: EDC extension to TCF: + // TCF only define "IBreakpoints.PROP_CONTEXTIDS" as a array of IDs. + // In EDC, it's required the first element in the array be IBreakpointsTargetDMContext + // which is usually (but not always) a process. This makes EDC backward compatible with + // some existing TCF agents. + IBreakpointsTargetDMContext bpTargetDMC = DMContexts.getAncestorOfType(exeDMC, IBreakpointsTargetDMContext.class); + // pass "exeDMC" as a context if it's different from bpTargetDMC, say, if "exeDMC" is a thread and + // the "bpTargetDMC" is the owner process. This allows for thread-specific BP if agent supports it. + String[] contexts; + if (! exeDMC.equals(bpTargetDMC)) + contexts = new String[] {((IEDCDMContext)bpTargetDMC).getID(), ((IEDCDMContext)exeDMC).getID()}; + else + contexts = new String[] {((IEDCDMContext)bpTargetDMC).getID()}; + properties.put(org.eclipse.tm.tcf.services.IBreakpoints.PROP_CONTEXTIDS, contexts); + + getTargetEnvironmentService().updateBreakpointProperties(exeDMC, address, properties); + + drm.setData(new BreakpointDMData(id, bp_dmc, bp_addrs, properties)); + drm.done(); + } else { // generic software breakpoint + final byte[] bpInstruction = getTargetEnvironmentService().getBreakpointInstruction(exeDMC, address); + final int inst_size = bpInstruction.length; + + Memory memoryService = getService(Memory.class); + IMemoryDMContext mem_dmc = DMContexts.getAncestorOfType(exeDMC, IMemoryDMContext.class); + + memoryService.getMemory(mem_dmc, address, 0, 1, inst_size, new DataRequestMonitor( + getExecutor(), drm) { + @Override + protected void handleSuccess() { + MemoryByte[] org_inst = getData(); + final byte[] org_inst_bytes = new byte[org_inst.length]; + for (int i = 0; i < org_inst.length; i++) { + // make sure each byte is okay + if (!org_inst[i].isReadable()) { + drm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, + ("Cannot read memory at 0x" + address.add(i).getValue().toString(16)), + null)); + drm.done(); + return; + } + org_inst_bytes[i] = org_inst[i].getValue(); + } + + drm.setData(new BreakpointDMData(id, bp_dmc, bp_addrs, org_inst_bytes, properties)); + drm.done(); + } + }); + } + } + + }, drm); + + } + + /** + * Install the breakpoint in the target process. + * + * @param bp + * @param rm + */ + public void enableBreakpoint(final BreakpointDMData bp, final RequestMonitor rm) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(bp)); } + + if (usesTCFBreakpointService()) { + Protocol.invokeLater(new Runnable() { + public void run() { + tcfBreakpointService.add(bp.getProperties(), new DoneCommand() { + + public void doneCommand(IToken token, Exception error) { + if (error != null) { + // Make sure "done()" is called for the rm. + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, + "TCF agent fails to install " + bp + " because:\n" + + error.getLocalizedMessage(), error)); + rm.done(); + } else { + getSession().dispatchEvent(new BreakpointAddedEvent(bp.getContext()), + new Hashtable(bp.getProperties())); + + rm.done(); + } + } + }); + } + }); + } else { + IAddress bp_addr = bp.getAddresses()[0]; + IExecutionDMContext exe_dmc = DMContexts.getAncestorOfType(bp.getContext(), IExecutionDMContext.class); + byte[] bpInstruction = getTargetEnvironmentService().getBreakpointInstruction(exe_dmc, bp_addr); + + Memory memoryService = getService(Memory.class); + IMemoryDMContext mem_dmc = DMContexts.getAncestorOfType(bp.getContext(), IMemoryDMContext.class); + + memoryService.setMemory(mem_dmc, bp_addr, 0, 1, bpInstruction.length, bpInstruction, rm); + getSession().dispatchEvent(new BreakpointAddedEvent(bp.getContext()), + new Hashtable(bp.getProperties())); + } + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + private synchronized long getNewBreakpointID() { + return nextBreakpointID++; + } + + public void removeBreakpoint(final IBreakpointDMContext dmc, RequestMonitor rm) { + // Remove user breakpoint. + // + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { dmc })); } + + if (!(dmc instanceof BreakpointDMContext)) { + // not our breakpoint, should not happen + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, "Unrecognized breakpoint context.")); + rm.done(); + return; + } + + if (!userBreakpoints.containsKey(dmc)) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, UNKNOWN_BREAKPOINT)); + rm.done(); + return; + } + + disableBreakpoint(userBreakpoints.get(dmc), new RequestMonitor(getExecutor(), rm) { + + @Override + protected void handleSuccess() { + // Remove it from our record. + userBreakpoints.remove(dmc); + + super.handleSuccess(); + } + }); + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * Remove the breakpoint from the target process. + * + * @param bp + * @param rm + */ + public void disableBreakpoint(final BreakpointDMData bp, final RequestMonitor rm) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { bp })); } + + if (!usesTCFBreakpointService()) { + final Memory memoryService = getService(Memory.class); + IMemoryDMContext mem_dmc = DMContexts.getAncestorOfType(bp.getContext(), IMemoryDMContext.class); + byte[] orgInst = bp.getOriginalInstruction(); + memoryService.setMemory(mem_dmc, bp.getAddresses()[0], 0, 1, orgInst.length, orgInst, rm); + } else { + Protocol.invokeLater(new Runnable() { + public void run() { + Map properties = bp.getProperties(); + String id = (String) properties.get(org.eclipse.tm.tcf.services.IBreakpoints.PROP_ID); + tcfBreakpointService.remove(new String[] { id }, new DoneCommand() { + + public void doneCommand(IToken token, Exception error) { + rm.done(); + } + }); + } + }); + } + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + public void updateBreakpoint(IBreakpointDMContext dmc, Map delta, RequestMonitor rm) { + /* + * For EDC, we don't need to do any update on non-significant attribute + * change, e.g. change of Install_count, ignore_count. For significant + * change, the breakpoint will just be re-installed. + * See canUpdateAttributes(). + */ + BreakpointDMData bp = userBreakpoints.get(dmc); + if (bp == null) + assert false : "Fail to find BreakpointDMData linked with the IBreakpointDMContext:" + dmc; + else { + Map existingProps = bp.getProperties(); + for (String key : delta.keySet()) + existingProps.put(key, delta.get(key)); + } + rm.done(); + } + + public boolean usesTCFBreakpointService() { + return tcfBreakpointService != null; + } + + public void tcfServiceReady(IService service) { + tcfBreakpointService = (org.eclipse.tm.tcf.services.IBreakpoints) service; + } + + @DsfServiceEventHandler + public void eventHandler_installBreakpointsForModule(ModuleLoadedDMEvent e) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { e })); } + + // A new module (including main exe) is loaded. Install breakpoints for + // it. + ModuleLoadedEvent event = (ModuleLoadedEvent) e; + final IExecutionDMContext executionDMC = event.getExecutionDMC(); + final ModuleDMC module = (ModuleDMC) e.getLoadedModuleContext(); + BreakpointsMediator2 bm = getService(BreakpointsMediator2.class); + if (bm == null) { + EDCDebugger.getMessageLogger().logError("Fail to get BreakpointsMediator service to install breakpoints for loaded module "+module, null); + assert false; + return; + } + + final boolean requireResume = requireResume(module); + + IBreakpointsTargetDMContext bt_dmc = DMContexts.getAncestorOfType(module, IBreakpointsTargetDMContext.class); + bm.startTrackingBreakpoints(bt_dmc, new RequestMonitor(getExecutor(), null) { + + @Override + protected void handleCompleted() { + if (!isSuccess()) { + // do we want to display a dialog for user ? + // No, as it's expected not all breakpoints can be resolved + // in the module. + + // Form readable message and log it. + IStatus status = getStatus(); + String msg = MessageFormat.format( + "Failed to install some breakpoints in the module [{0}]. Errors: \n", module.getName()); + if (status.isMultiStatus()) { + for (IStatus s : ((MultiStatus) status).getChildren()) + msg += s.getMessage() + "\n"; + } else + msg += status.getMessage(); + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, msg); } + } + + // We should do these regardless of whether installing + // breakpoints succeeded or not. + setStartupBreakpoint(module, new RequestMonitor(getExecutor(), null) { + + @Override + protected void handleCompleted() { + // do this regardless of status of installing entry + // breakpoint + // as it's expected the startup bp not resolvable in all + // modules. + // + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, "resume process after module load event ..."); } + if (requireResume) + ((ExecutionDMC) executionDMC).resume(new RequestMonitor(getExecutor(), null)); + } + }); + } + }); + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * Check if resume is required after handling load/unload of the given module. + * + * @param module + * @return + */ + private boolean requireResume(ModuleDMC module) { + boolean requireResume = true; + Object propvalue = module.getProperties().get(IModuleProperty.PROP_RESUME); + if (propvalue != null) + if (propvalue instanceof Boolean) + requireResume = (Boolean) propvalue; + + return requireResume; + } + + /** + * Set breakpoint at startup point specified by user. + * + * @param module + * @param rm + */ + protected void setStartupBreakpoint(ModuleDMC module, RequestMonitor rm) { + EDCLaunch launch = EDCLaunch.getLaunchForSession(getSession().getId()); + ILaunchConfiguration launchConfig = launch.getLaunchConfiguration(); + if (startupBreakpointModule.get(launchConfig) != null) { + // already set in a module for this launch configuration, no need to try it for any other module + rm.done(); + return; + } + + String startupStopAt = launch.getStartupStopAtPoint(); + // Is this even requested by user ? + if (startupStopAt == null) { + rm.done(); + return; + } + + // Ask target environment whether it wants us to try installing + // startup breakpoint in the module. + ITargetEnvironment te = getTargetEnvironmentService(); + if (! te.needStartupBreakpointInExecutable(module.getName())) { + rm.done(); + return; + } + + IAddress iaddr = null; + long address = 0; + + // Check if the point is absolute runtime address. + // + try { + // first check if it's decimal number + address = Long.parseLong(startupStopAt); + } catch (NumberFormatException e) { + // then check if it's hex + if (startupStopAt.toLowerCase().startsWith("0x")) { + try { + address = Long.parseLong(startupStopAt.substring(2), 16); + } catch (IllegalFormatException e1) { + // ignore + } + } + } + + if (address != 0) { + iaddr = new Addr32(address); + + // Assume it is a link-time address first. Run-time addresses are not predictable across launches. + IAddress runAddr = module.toRuntimeAddress(iaddr); + if (module.containsAddress(runAddr)) { + iaddr = runAddr; + } else { + // Try for a runtime address. + if (!module.containsAddress(iaddr)) { + // address not in the module, don't bother. + // This is to ensure the address breakpoint is installed + // after the container module is loaded. + iaddr = null; + } + } + } else { + // the point is a symbol + Symbols symService = getService(Symbols.class); + List addrs = symService.getFunctionAddress(module, startupStopAt); + + if (addrs.size() > 0) + // just choose the first one + iaddr = addrs.get(0); + } + + if (iaddr == null) { + EDCDebugger.getMessageLogger().logError( + "Could not resolve startup breakpoint: "+ startupStopAt, null); + rm.done(); + } else { + // The breakpoint is resolved in the module. + startupBreakpointModule.put(launchConfig, module); + + IExecutionDMContext exe_dmc = DMContexts.getAncestorOfType(module, IExecutionDMContext.class); + setTempBreakpoint(exe_dmc, iaddr, rm); + } + } + + @DsfServiceEventHandler + public void eventHandler_uninstallBreakpointsForModule(ModuleUnloadedDMEvent e) { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { e.getClass().getName(), e })); } + + // An existing module (including main exe) is unloaded. Uninstall + // breakpoints for it. + ModuleUnloadedEvent event = (ModuleUnloadedEvent) e; + final ExecutionDMC executionDMC = (ExecutionDMC)event.getExecutionDMC(); + final ModuleDMC module = (ModuleDMC) e.getUnloadedModuleContext(); + + /* + * If module containing startup break is unloaded, mark the startup + * break as gone so that we can reinstall it the next time the module is + * loaded again in the same debug session. + */ + if (startupBreakpointModule != null && + startupBreakpointModule.equals(module)) + startupBreakpointModule = null; + + final boolean requireResume = requireResume(module); + + BreakpointsMediator2 bm = getService(BreakpointsMediator2.class); + IBreakpointsTargetDMContext bt_dmc = DMContexts.getAncestorOfType(e.getUnloadedModuleContext(), + IBreakpointsTargetDMContext.class); + bm.stopTrackingBreakpoints(bt_dmc, new RequestMonitor(getExecutor(), null) { + @Override + protected void handleFailure() { + // super will just log the error. + super.handleFailure(); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, "uninstalling breakpoints failed"); } + } + + @Override + protected void handleSuccess() { + super.handleSuccess(); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, "breakpoints uninstalled and resume process..."); } + if (requireResume) + executionDMC.resume(new RequestMonitor(getExecutor(), null)); + } + }); + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + protected void addBreakpointProblemMarker(final ICBreakpoint breakpoint, final String description, final int severity) { + if (! (breakpoint instanceof ICLineBreakpoint)) + return; + + new Job("Add Breakpoint Problem Marker") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + // If we have already have a problem marker on this breakpoint + // we should remove it first. + IMarker marker = fBreakpointMarkers.remove(breakpoint); + if (marker != null) { + try { + marker.delete(); + } catch (CoreException e) { + } + } + + ICLineBreakpoint lineBreakpoint = (ICLineBreakpoint) breakpoint; + try { + // Locate the workspace resource via the breakpoint marker + IMarker breakpoint_marker = lineBreakpoint.getMarker(); + IResource resource = breakpoint_marker.getResource(); + + // Add a problem marker to the resource + IMarker problem_marker = resource.createMarker(BreakpointProblems.BREAKPOINT_PROBLEM_MARKER_ID); + int line_number = lineBreakpoint.getLineNumber(); + problem_marker.setAttribute(IMarker.LOCATION, String.valueOf(line_number)); + problem_marker.setAttribute(IMarker.MESSAGE, description); + problem_marker.setAttribute(IMarker.SEVERITY, severity); + problem_marker.setAttribute(IMarker.LINE_NUMBER, line_number); + + // And save the baby + fBreakpointMarkers.put(breakpoint, problem_marker); + } catch (CoreException e) { + } + + return Status.OK_STATUS; + } + }.schedule(); + } + + protected void removeBreakpointProblemMarker(final ICBreakpoint breakpoint) { + + final IMarker marker = fBreakpointMarkers.remove(breakpoint); + if (marker == null) + return; + + new Job("Remove Breakpoint Problem Marker") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + marker.delete(); + } catch (CoreException e) { + } + + return Status.OK_STATUS; + } + }.schedule(); + } + + /** + * Evaluate condition of given breakpoint, if any. + * + * @param context + * execution context in which to evaluate the condition. + * @param bp + * the breakpoint. + * @param drm + * DataRequestMonitor that contains result indicating whether + * to stop execution of debugged program. The result value is + * true if
    + * 1. the breakpoint has no condition, or
    + * 2. the breakpoint condition is invalid in syntax, or
    + * 3. the breakpoint condition cannot be resolved, or
    + * 4. the breakpoint condition is true.
    + * Otherwise the result in the drm is false. + * + */ + public void evaluateBreakpointCondition(IExecutionDMContext context, final BreakpointDMData bp, final DataRequestMonitor drm) { + final String expr = bp.getCondition(); + if (expr == null || expr.length() == 0) { + bp.incrementHitCount(); + drm.setData(bp.getHitCount() > bp.getIgnoreCount()); + drm.done(); + return; + } + + Stack stackService = getService(Stack.class); + + stackService.getTopFrame(context, new DataRequestMonitor(getExecutor(), drm) { + + @Override + protected void handleCompleted() { + if (!isSuccess()) { // fail to get frame, namely cannot + // evaluate the condition + bp.incrementHitCount(); + drm.setData(bp.getHitCount() > bp.getIgnoreCount()); + drm.done(); + } else { + Expressions exprService = getService(Expressions.class); + IEDCExpression expression = (IEDCExpression) exprService.createExpression(getData(), expr); + FormattedValueDMContext fvc = exprService.getFormattedValueContext(expression, + IFormattedValues.NATURAL_FORMAT); + FormattedValueDMData value = expression.getFormattedValue(fvc); + /* + * honor the breakpoint if the condition is true or + * invalid. + */ + String vstr = value.getFormattedValue(); + if (! vstr.equals("true") && ! vstr.equals("false")) //$NON-NLS-1$ //$NON-NLS-2$ + reportBreakpointProblem(bp.getContext(), "Breakpoint condition failed to resolve to boolean: " + vstr); + else // remove any problem marker + reportBreakpointProblem(bp.getContext(), ""); + + if (!vstr.equals("false")) + { + bp.incrementHitCount(); + drm.setData(bp.getHitCount() > bp.getIgnoreCount()); + } + else + drm.setData(false); //$NON-NLS-1$ + + drm.done(); + } + } + }); + } + + /** + * Report breakpoint problem in breakpoint marker. + * + * @param targetBP + * @param description - empty string indicates removing problem marker. + */ + protected void reportBreakpointProblem(IBreakpointDMContext targetBP, String description) { + BreakpointsMediator2 bmService = getService(BreakpointsMediator2.class); + if (bmService == null) { + assert false; + return; + } + IBreakpoint platformBP = bmService.getPlatformBreakpoint(null, targetBP); + if (platformBP == null) + return; + + if (description.length() > 0) + addBreakpointProblemMarker((ICBreakpoint)platformBP, description, IMarker.SEVERITY_WARNING); + else + removeBreakpointProblemMarker((ICBreakpoint)platformBP); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/EDCServicesMessages.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/EDCServicesMessages.java new file mode 100644 index 0000000..1a90b90 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/EDCServicesMessages.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import org.eclipse.osgi.util.NLS; + +public class EDCServicesMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.edc.internal.services.dsf.EDCServicesMessages"; //$NON-NLS-1$ + + public static String Expressions_CannotCastOutsideFrame; + + public static String Expressions_CannotModifyCompositeValue; + + public static String Expressions_CannotParseExpression; + + public static String Expressions_ErrorInVariableFormatter; + + public static String Expressions_ExpressionNoLocation; + + public static String Expressions_SyntaxError; + + public static String Disassembly_CannotReadMemoryAt; + + public static String Disassembly_NoDisassemblerYet; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, EDCServicesMessages.class); + } + + private EDCServicesMessages() { + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/EDCServicesMessages.properties b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/EDCServicesMessages.properties new file mode 100644 index 0000000..7618d6e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/EDCServicesMessages.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2009, 2010 Nokia and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Nokia - Initial API and implementation +############################################################################### +Expressions_CannotCastOutsideFrame=cannot cast expressions outside stack frame +Expressions_CannotModifyCompositeValue=Cannot modify the value of a composite type +Expressions_CannotParseExpression=cannot parse expression +Expressions_SyntaxError=syntax error +Expressions_ErrorInVariableFormatter=Error in variable formatter: +Expressions_ExpressionNoLocation=expression has no location +Disassembly_CannotReadMemoryAt=Cannot read memory at {0} (length {1}) +Disassembly_NoDisassemblerYet=No disassembler is available yet. diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Expressions.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Expressions.java new file mode 100644 index 0000000..5e1a6ca --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Expressions.java @@ -0,0 +1,1428 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.debug.edc.MemoryUtils; +import org.eclipse.cdt.debug.edc.formatter.ITypeContentProvider; +import org.eclipse.cdt.debug.edc.formatter.IVariableValueConverter; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.internal.NumberFormatUtils; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvaluationEngine; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.IArrayDimensionType; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.InstructionSequence; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.Interpreter; +import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions.OperandValue; +import org.eclipse.cdt.debug.edc.internal.formatter.FormatExtensionManager; +import org.eclipse.cdt.debug.edc.internal.symbols.IAggregate; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICompositeType; +import org.eclipse.cdt.debug.edc.internal.symbols.IEnumeration; +import org.eclipse.cdt.debug.edc.internal.symbols.IField; +import org.eclipse.cdt.debug.edc.internal.symbols.IInheritance; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.IReferenceType; +import org.eclipse.cdt.debug.edc.internal.symbols.ISubroutineType; +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.debug.edc.services.DMContext; +import org.eclipse.cdt.debug.edc.services.IEDCDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCExpression; +import org.eclipse.cdt.debug.edc.services.IEDCExpressions; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.symbols.IEnumerator; +import org.eclipse.cdt.debug.edc.symbols.IInvalidVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.AbstractDMContext; +import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions2; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; +import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +public class Expressions extends AbstractEDCService implements IEDCExpressions { + + public abstract class BaseEDCExpressionDMC extends DMContext implements IEDCExpression { + protected String expression; + private InstructionSequence parsedExpression; + private final ASTEvaluationEngine engine; + private final StackFrameDMC frame; + protected Number value; + protected IStatus valueError; + private IVariableLocation valueLocation; + private IType valueType; + private boolean hasChildren = false; + private String valueString; + + public BaseEDCExpressionDMC(IDMContext parent, String expression, String name) { + super(Expressions.this, new IDMContext[] { parent }, name, ((IEDCDMContext)parent).getID() + "." + name); //$NON-NLS-1$ + this.expression = expression; + this.frame = DMContexts.getAncestorOfType(parent, StackFrameDMC.class); + engine = new ASTEvaluationEngine(getEDCServicesTracker(), frame, frame.getTypeEngine()); + } + + public BaseEDCExpressionDMC(IDMContext parent, String expression) { + this(parent, expression, expression); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.services.DMContext#toString() + */ + @Override + public String toString() { + return getExpression(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getFrame() + */ + public IFrameDMContext getFrame() { + return frame; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getExpression() + */ + public String getExpression() { + return expression; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#evaluateExpression() + */ + public synchronized void evaluateExpression() { + if (value != null || valueError != null) + return; + + String expression = getExpression(); + + if (parsedExpression == null) { + try { + parsedExpression = engine.getCompiledExpression(expression); + } catch (CoreException e) { + value = null; + valueError = e.getStatus(); + valueLocation = null; + valueType = null; + return; + } + } + + if (parsedExpression.getInstructions().length == 0) { + value = null; + valueError = new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, + EDCServicesMessages.Expressions_SyntaxError); + valueLocation = null; + valueType = null; + return; + } + + Interpreter interpreter; + try { + interpreter = engine.evaluateCompiledExpression(parsedExpression); + } catch (CoreException e) { + value = null; + valueError = e.getStatus(); + valueLocation = null; + valueType = null; + return; + } + + OperandValue variableValue = interpreter.getResult(); + if (variableValue == null) { + value = null; + valueError = null; + valueLocation = null; + valueType = null; + return; + } + + valueLocation = variableValue.getValueLocation(); + valueType = variableValue.getValueType(); + try { + value = variableValue.getValue(); + valueString = variableValue.getStringValue(); + } catch (CoreException e1) { + value = null; + valueError = e1.getStatus(); + return; + } + + // for a structured type or array, return the location and note + // that it has children + if (valueType instanceof IAggregate && valueLocation != null) { + // TODO + try { + value = variableValue.getValueLocationAddress(); + } catch (CoreException e) { + value = null; + valueError = e.getStatus(); + } + if (!(value instanceof IInvalidVariableLocation)) + hasChildren = true; + } + + // if the location evaluates to NotLive, the types and values do + // not matter + if (valueLocation instanceof IInvalidVariableLocation) { + value = null; + valueError = new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, + ((IInvalidVariableLocation) valueLocation).getMessage()); + valueLocation = null; //$NON-NLS-1$ + return; + } + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getFormattedValue(org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext) + */ + public FormattedValueDMData getFormattedValue(FormattedValueDMContext dmc) { + if (EDCTrace.VARIABLE_VALUE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(dmc)); } + evaluateExpression(); + String result = ""; //$NON-NLS-1$ + + if (valueError != null) { + result = valueError.getMessage(); + } else if (value != null) { + result = value.toString(); + + IType unqualifiedType = TypeUtils.getUnRefStrippedType(valueType); + + String temp = null; + String formatID = dmc.getFormatID(); + + // the non-natural formats have expected representations in other + // parts of DSF, so be strict about what we return + if (formatID.equals(IFormattedValues.HEX_FORMAT)) { + temp = NumberFormatUtils.toHexString(value); + } else if (formatID.equals(IFormattedValues.OCTAL_FORMAT)) { + temp = NumberFormatUtils.toOctalString(value); + } else if (formatID.equals(IFormattedValues.BINARY_FORMAT)) { + temp = NumberFormatUtils.asBinary(value); + } else if (formatID.equals(IFormattedValues.NATURAL_FORMAT)) { + // convert non-integer types to original representation + if (unqualifiedType instanceof ICPPBasicType) { + ICPPBasicType basicType = (ICPPBasicType) unqualifiedType; + switch (basicType.getBaseType()) { + case ICPPBasicType.t_char: + temp = NumberFormatUtils.toCharString(value, valueType); + break; + case ICPPBasicType.t_wchar_t: + temp = NumberFormatUtils.toCharString(value, valueType); + break; + case ICPPBasicType.t_bool: + temp = Boolean.toString(value.longValue() != 0); + break; + default: + // account for other debug formats + if (basicType.getName().equals("wchar_t")) { //$NON-NLS-1$ + temp = NumberFormatUtils.toCharString(value, valueType); + } + break; + } + } else if (unqualifiedType instanceof IAggregate || unqualifiedType instanceof IPointerType) { + // show addresses for aggregates and pointers as hex in natural format + temp = NumberFormatUtils.toHexString(value); + } + + // TODO: add type suffix if the value cannot fit in + // the ordinary range of the base type. + // E.g., for an unsigned int, 0xFFFFFFFF should usually be 0xFFFFFFFFU, + // and for a long double, 1.E1000 should be 1.E1000L. + /* + // apply required integer and float suffixes + IType unqualifiedType = TypeUtils.getStrippedType(valueType); + if (unqualifiedType instanceof ICPPBasicType) { + ICPPBasicType basicType = (ICPPBasicType) unqualifiedType; + + if (basicType.getBaseType() == ICPPBasicType.t_float) { + //result += "F"; // no + } else if (basicType.getBaseType() == ICPPBasicType.t_double) { + if (basicType.isLong() AND actual value does not fit in a double) + result += "L"; + } else if (basicType.getBaseType() == ICPPBasicType.t_int) { + if (basicType.isUnsigned() AND actual value does not fit in a signed int) + result += "U"; + if (basicType.isLongLong() AND actual value does not fit in a signed int) + result += "LL"; + else if (basicType.isLong() AND actual value does not fit in a signed int) + result += "L"; + } + } + */ + + // for an enumerator, return the name, if any + if (unqualifiedType instanceof IEnumeration) { + long enumeratorValue = value.longValue(); + + IEnumerator enumerator = ((IEnumeration) unqualifiedType).getEnumeratorByValue(enumeratorValue); + if (enumerator != null) { + if (temp == null) + temp = result; + + temp = enumerator.getName() + " [" + temp + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + if (temp != null) + result = temp; + + // otherwise, leave value as is + + + } + if (EDCTrace.VARIABLE_VALUE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(result)); } + return new FormattedValueDMData(result); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getValueLocation() + */ + public IVariableLocation getValueLocation() { + evaluateExpression(); + return getEvaluatedLocation(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.services.IEDCExpression#getEvaluationError() + */ + public IStatus getEvaluationError() { + return valueError; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getEvaluatedValue() + */ + public Number getEvaluatedValue() { + return value; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.services.IEDCExpression#getEvaluatedValueString() + */ + public String getEvaluatedValueString() { + if (valueError != null) + return valueError.getMessage(); + + if (valueString != null) + return valueString; + + valueString = value != null ? value.toString() : ""; //$NON-NLS-1$ + return valueString; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.services.IEDCExpression#setEvaluatedValueString(java.lang.String) + */ + public void setEvaluatedValueString(String string) { + this.valueString = string; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#setEvaluatedValue(java.lang.Object) + */ + public void setEvaluatedValue(Number value) { + this.value = value; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getEvaluatedLocation() + */ + public IVariableLocation getEvaluatedLocation() { + return valueLocation; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getEvaluatedType() + */ + public IType getEvaluatedType() { + return valueType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getTypeName() + */ + public String getTypeName() { + evaluateExpression(); + if (valueType == null) + if (valueError != null) + return ""; //$NON-NLS-1$ + else + return ASTEvaluationEngine.UNKNOWN_TYPE; + return engine.getTypeEngine().getTypeName(valueType); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#hasChildren() + */ + public boolean hasChildren() { + return this.hasChildren; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getService() + */ + public Expressions getExpressionsService() { + return Expressions.this; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.services.IEDCExpression#getExecutor() + */ + public Executor getExecutor() { + return getSession().getExecutor(); + } + + } + + /** A basic expression. */ + private class ExpressionDMC extends BaseEDCExpressionDMC { + + public ExpressionDMC(IDMContext parent, String expression) { + super(parent, expression); + } + + + public ExpressionDMC(IDMContext parent, String expression, String name) { + super(parent, expression, name); + } + + /** + * There is no casting on a vanilla expression. + * @return null + */ + public CastInfo getCastInfo() { + return null; + } + + + } + + /** A casted or array-displayed expression. */ + private class CastedExpressionDMC extends BaseEDCExpressionDMC implements ICastedExpressionDMContext { + + private final CastInfo castInfo; + /** if non-null, interpret result as this type rather than the raw expression's type */ + private IType castType = null; + private IStatus castError; + + public CastedExpressionDMC(IEDCExpression exprDMC, String expression, String name, CastInfo castInfo) { + super(exprDMC, name); + this.castInfo = castInfo; + + String castType = castInfo.getTypeString(); + + String castExpression = expression; + + // If changing type, assume it's reinterpret_cast<>. + // Once we support RTTI, this should be dynamic_cast<> when casting + // class pointers to class pointers. + if (castType != null) { + if (castInfo.getArrayCount() > 0) { + castType += "[]"; //$NON-NLS-1$ + // Force non-pointer expressions to be pointers. + exprDMC.evaluateExpression(); + IType exprType = TypeUtils.getStrippedType(exprDMC.getEvaluatedType()); + if (exprType != null) { + if (!(exprType instanceof IPointerType || exprType instanceof IArrayType)) { + expression = "&" + expression; //$NON-NLS-1$ + } + } + } + castExpression = "reinterpret_cast<" + castType +">(" + expression + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } else if (castInfo.getArrayCount() > 0) { + // For arrays, be sure the OperatorSubscript accepts the base type. + // Force non-pointer expressions to be pointers. + exprDMC.evaluateExpression(); + IType exprType = TypeUtils.getStrippedType(exprDMC.getEvaluatedType()); + if (exprType != null) { + if (!(exprType instanceof IPointerType || exprType instanceof IArrayType)) { + // cast to pointer if not already one (cast to array is not valid C/C++ but we support it) + castExpression = "(" + exprDMC.getTypeName() + "[])&" + expression; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + this.expression = castExpression; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#evaluateExpression() + */ + public void evaluateExpression() { + if (castError != null) { + return; + } + + super.evaluateExpression(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCExpression#getEvaluatedType() + */ + public IType getEvaluatedType() { + if (castType != null) + return castType; + return super.getEvaluatedType(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.IExpressions2.ICastedExpressionDMContext#getCastInfo() + */ + public CastInfo getCastInfo() { + return castInfo; + } + } + + public class ExpressionData implements IExpressionDMData { + + private final IEDCExpression dmc; + private String typeName = ""; + + public ExpressionData(IEDCExpression dmc) { + this.dmc = dmc; + if (dmc != null) + this.typeName = dmc.getTypeName(); + } + + public BasicType getBasicType() { + BasicType basicType = BasicType.unknown; + if (dmc == null) + return basicType; + + IType type = dmc.getEvaluatedType(); + type = TypeUtils.getStrippedType(type); + if (type instanceof IArrayType) { + basicType = BasicType.array; + } + else if (type instanceof IBasicType) { + basicType = BasicType.basic; + } + else if (type instanceof ICompositeType) { + basicType = BasicType.composite; + } + else if (type instanceof IEnumeration) { + basicType = BasicType.enumeration; + } + else if (type instanceof IPointerType) { + basicType = BasicType.pointer; + } + else if (type instanceof ISubroutineType) { + basicType = BasicType.function; + } + return basicType; + } + + public String getEncoding() { + return null; + } + + public Map getEnumerations() { + return null; + } + + public String getName() { + if (dmc != null) + return dmc.getName(); + else + return ""; //$NON-NLS-1$ + } + + public IRegisterDMContext getRegister() { + return null; + } + + public String getTypeId() { + return TYPEID_INTEGER; + } + + public String getTypeName() { + return typeName; + } + + } + + protected static class InvalidContextExpressionDMC extends AbstractDMContext implements IExpressionDMContext { + private final String expression; + + public InvalidContextExpressionDMC(String sessionId, String expr, IDMContext parent) { + super(sessionId, new IDMContext[] { parent }); + expression = expr; + } + + @Override + public boolean equals(Object other) { + return super.baseEquals(other) && expression == null ? ((InvalidContextExpressionDMC) other) + .getExpression() == null : expression.equals(((InvalidContextExpressionDMC) other).getExpression()); + } + + @Override + public int hashCode() { + return expression == null ? super.baseHashCode() : super.baseHashCode() ^ expression.hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".invalid_expr[" + expression + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public String getExpression() { + return expression; + } + } + + public class ExpressionDMAddress implements IExpressionDMLocation { + + private final IVariableLocation valueLocation; + + public ExpressionDMAddress(IExpressionDMContext exprContext) { + if (exprContext instanceof IEDCExpression) + valueLocation = ((IEDCExpression) exprContext).getValueLocation(); + else + valueLocation = null; + } + + public IAddress getAddress() { + if (valueLocation != null) { + IAddress address = valueLocation.getAddress(); + if (address != null) + return address; + } + return new Addr64(BigInteger.ZERO); + } + + public int getSize() { + return 4; + } + + public String getLocation() { + if (valueLocation instanceof IInvalidVariableLocation) { + return ((IInvalidVariableLocation)valueLocation).getMessage(); + } + if (valueLocation == null) + return ""; //$NON-NLS-1$ + return valueLocation.getLocationName(); + } + + } + + public Expressions(DsfSession session) { + super(session, new String[] { IExpressions.class.getName(), Expressions.class.getName(), IExpressions2.class.getName() }); + } + + public boolean canWriteExpression(IEDCExpression expressionDMC) { + EDCLaunch launch = EDCLaunch.getLaunchForSession(getSession().getId()); + if (launch.isSnapshotLaunch()) + return false; + IVariableValueConverter converter = getCustomValueConverter(expressionDMC); + if (converter != null) + return converter.canEditValue(); + + return !isComposite(expressionDMC); + } + + public void canWriteExpression(IExpressionDMContext exprContext, DataRequestMonitor rm) { + IEDCExpression expressionDMC = (IEDCExpression) exprContext; + rm.setData(canWriteExpression(expressionDMC)); + rm.done(); + } + + private boolean isComposite(IEDCExpression expressionDMC) { + IType exprType = TypeUtils.getStrippedType(expressionDMC.getEvaluatedType()); + return exprType instanceof ICompositeType; + } + + public IExpressionDMContext createExpression(IDMContext context, String expression) { + StackFrameDMC frameDmc = DMContexts.getAncestorOfType(context, StackFrameDMC.class); + + if (frameDmc != null) { + return new ExpressionDMC(frameDmc, expression); + } + return new InvalidContextExpressionDMC(getSession().getId(), expression, context); + } + + class CastInfoCachedData { + + private CastInfo info; + + private IType type; + private IStatus error; + private StackFrameDMC frameDmc; + + public CastInfoCachedData(ExpressionDMC exprDMC, CastInfo info) { + this.info = info; + this.frameDmc = DMContexts.getAncestorOfType(exprDMC, StackFrameDMC.class); + } + + public String getTypeString() { + return info.getTypeString(); + } + + public int getArrayStartIndex() { + return info.getArrayStartIndex(); + } + + public int getArrayCount() { + return info.getArrayCount(); + } + + /** + * Get the compiled type + * @return the type + */ + public IType getType() { + if (info.getTypeString() == null) + return null; + + if (type == null && error == null) { + if (frameDmc != null) { + ASTEvaluationEngine engine = new ASTEvaluationEngine(getEDCServicesTracker(), frameDmc, frameDmc.getTypeEngine()); + try { + IASTTypeId typeId = engine.getCompiledType(info.getTypeString()); + type = engine.getTypeEngine().getTypeForTypeId(typeId); + } catch (CoreException e) { + error = e.getStatus(); + } + } else { + error = EDCDebugger.dsfRequestFailedStatus(EDCServicesMessages.Expressions_CannotCastOutsideFrame, null); + } + } + return type; + } + + /** + * @return the error + */ + public IStatus getError() { + if (type == null && error == null) { + getType(); + } + return error; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.IExpressions2#createCastedExpression(org.eclipse.cdt.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.cdt.dsf.debug.service.IExpressions2.ICastedExpressionDMContext) + */ + public ICastedExpressionDMContext createCastedExpression(IExpressionDMContext exprDMC, + CastInfo castInfo) { + + // then apply the casting stuff + if (exprDMC instanceof IEDCExpression) { + CastedExpressionDMC castedDMC = new CastedExpressionDMC((IEDCExpression) exprDMC, + exprDMC.getExpression(), ((IEDCExpression) exprDMC).getName(), castInfo); + return castedDMC; + } else { + assert false; + return null; + } + } + + /* + public void createCastedExpression(IDMContext context, String expression, + ICastedExpressionDMContext castDMC, IArrayCastedExpressionDMContext arrayCastDMC, + DataRequestMonitor rm) { + + // create an ordinary expression... + IExpressionDMContext exprDMC = createExpression(context, expression); + + // then apply the casting stuff + if (exprDMC instanceof ExpressionDMC + && (castDMC == null || castDMC instanceof CastedExpressionDMContext) + && (arrayCastDMC == null || arrayCastDMC instanceof ArrayCastedExpressionDMContext)) { + ExpressionDMC expressionDMC = ((ExpressionDMC) exprDMC); + if (castDMC != null) + expressionDMC.setCastToType((CastedExpressionDMContext) castDMC); + if (arrayCastDMC != null) + expressionDMC.setArrayCast((ArrayCastedExpressionDMContext) arrayCastDMC); + rm.setData(expressionDMC); + rm.done(); + } else { + assert false; + rm.setStatus(EDCDebugger.dsfRequestFailedStatus("unexpected cast information", null)); + rm.done(); + } + } + */ + + public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm) { + rm.setData(new IEDCExpression[0]); + rm.done(); + } + + public void getExpressionAddressData(final IExpressionDMContext exprContext, final DataRequestMonitor rm) { + asyncExec(new Runnable() { + public void run() { + if (exprContext instanceof IEDCExpression) + rm.setData(new ExpressionDMAddress(exprContext)); + else + rm.setData(new ExpressionDMAddress(null)); + rm.done(); + } + }, rm); + } + + public void getExpressionData(final IExpressionDMContext exprContext, final DataRequestMonitor rm) { + asyncExec(new Runnable() { + public void run() { + if (exprContext instanceof IEDCExpression) + rm.setData(new ExpressionData((IEDCExpression) exprContext)); + else + rm.setData(new ExpressionData(null)); + rm.done(); + } + }, rm); + } + + public void getSubExpressionCount(final IExpressionDMContext exprContext, final DataRequestMonitor rm) { + asyncExec(new Runnable() { + public void run() { + // handle array casts + CastInfo cast = null; + if (exprContext instanceof IEDCExpression && (cast = ((IEDCExpression) exprContext).getCastInfo()) != null) { + if (cast.getArrayCount() > 0) { + if (((IEDCExpression)exprContext).getEvaluationError() != null) { + rm.setData(0); + rm.done(); + return; + } + rm.setData(cast.getArrayCount()); + rm.done(); + return; + } + } + + if (!(exprContext instanceof IEDCExpression)) { + rm.setData(0); + rm.done(); + return; + } + + IEDCExpression expr = (IEDCExpression) exprContext; + + // if expression has no evaluated value, then it has not yet been evaluated + if (expr.getEvaluatedValue() == null && expr.getEvaluatedValueString() != null) { + expr.evaluateExpression(); + } + + IType exprType = TypeUtils.getStrippedType(expr.getEvaluatedType()); + + // to expand it, it must either be a pointer, a reference to an aggregate, + // or an aggregate + boolean pointerType = exprType instanceof IPointerType; + boolean referenceType = exprType instanceof IReferenceType; + IType pointedTo = null; + if (referenceType) + pointedTo = TypeUtils.getStrippedType(((IReferenceType) exprType).getType()); + + if (!(exprType instanceof IAggregate) && !pointerType && + !(referenceType && (pointedTo instanceof IAggregate || pointedTo instanceof IPointerType))) { + rm.setData(0); + rm.done(); + return; + } + + ITypeContentProvider customProvider = + FormatExtensionManager.instance().getTypeContentProvider(exprType); + if (customProvider != null) { + try { + rm.setData(customProvider.getChildCount(expr)); + rm.done(); + return; + } catch (Throwable e) { + } + } + + // TODO: maybe cache these subexpressions; they are just requested again in #getSubExpressions() + getSubExpressions(exprContext, new DataRequestMonitor( + getExecutor(), rm) { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.RequestMonitor#handleSuccess() + */ + @Override + protected void handleSuccess() { + rm.setData(getData().length); + rm.done(); + } + }); + } + }, rm); + } + + public void getSubExpressions(final IExpressionDMContext exprContext, final DataRequestMonitor rm) { + asyncExec(new Runnable() { + public void run() { + if (!(exprContext instanceof IEDCExpression) || ((IEDCExpression) exprContext).getFrame() == null) { + rm.setData(new IEDCExpression[0]); + rm.done(); + return; + } + + IEDCExpression expr = (IEDCExpression) exprContext; + + // if expression has no evaluated value, then it has not yet been evaluated + if (expr.getEvaluatedValue() == null && expr.getEvaluatedValueString() != null) { + expr.evaluateExpression(); + } + + StackFrameDMC frame = (StackFrameDMC) expr.getFrame(); + IType exprType = TypeUtils.getStrippedType(expr.getEvaluatedType()); + + // if casted to an array, convert thusly + CastInfo castInfo = expr.getCastInfo(); + if (castInfo != null && castInfo.getArrayCount() > 0) { + try { + exprType = frame.getTypeEngine().convertToArrayType(exprType, castInfo.getArrayCount()); + } catch (CoreException e) { + rm.setStatus(e.getStatus()); + rm.done(); + return; + } + } + + + // to expand it, it must either be a pointer, a reference to an aggregate, + // or an aggregate + boolean pointerType = exprType instanceof IPointerType; + boolean referenceType = exprType instanceof IReferenceType; + IType pointedTo = null; + if (referenceType) { + pointedTo = TypeUtils.getStrippedType(((IReferenceType) exprType).getType()); + exprType = pointedTo; + } + + if (!(exprType instanceof IAggregate) && !pointerType && + !(referenceType && (pointedTo instanceof IAggregate || pointedTo instanceof IPointerType))) { + rm.setData(new IEDCExpression[0]); + rm.done(); + return; + } + + ITypeContentProvider customProvider = + FormatExtensionManager.instance().getTypeContentProvider(exprType); + if (customProvider != null) { + getSubExpressions(expr, frame, exprType, customProvider, rm); + } + else + getSubExpressions(expr, rm); + } + }, rm); + } + + public void getSubExpressions(final IExpressionDMContext exprContext, final int startIndex_, final int length_, + final DataRequestMonitor rm) { + asyncExec(new Runnable() { + public void run() { + getSubExpressions(exprContext, new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + IExpressionDMContext[] allExprs = getData(); + if (startIndex_ == 0 && length_ >= allExprs.length) { + rm.setData(allExprs); + rm.done(); + } else { + int startIndex = startIndex_, length = length_; + if (startIndex > allExprs.length) { + startIndex = allExprs.length; + length = 0; + } else if (startIndex + length > allExprs.length) { + length = allExprs.length - startIndex; + if (length < 0) + length = 0; + } + + IExpressionDMContext[] result = new IExpressionDMContext[length]; + System.arraycopy(allExprs, startIndex, result, 0, length); + rm.setData(result); + rm.done(); + } + } + }); + } + }, rm); + } + + private void getSubExpressions(final IEDCExpression expr, final StackFrameDMC frame, + final IType exprType, final ITypeContentProvider customProvider, + final DataRequestMonitor rm) { + + List children = new ArrayList(); + Iterator childIterator; + try { + childIterator = customProvider.getChildIterator(expr); + while (childIterator.hasNext() && !rm.isCanceled()) { + children.add(childIterator.next()); + } + rm.setData(children.toArray(new IExpressionDMContext[children.size()])); + rm.done(); + } catch (CoreException e) { + // Checked exception. But we don't want to pass the error up as it + // would make the variable (say, a structure) not expandable on UI. + // Just resort to the normal formatting. + getSubExpressions(expr, rm); + } catch (Throwable e) { + // unexpected error. log it. + EDCDebugger.getMessageLogger().logError( + EDCServicesMessages.Expressions_ErrorInVariableFormatter + customProvider.getClass().getName(), e); + + // default to normal formatting + getSubExpressions(expr, rm); + } + } + + private void getSubExpressions(final IEDCExpression expr, + final DataRequestMonitor rm) { + rm.setData(getLogicalSubExpressions(expr)); + rm.done(); + } + + /** + * Get the logical subexpressions for the given expression context. We want + * to skip unnecessary nodes, e.g., a pointer to a composite, and directly + * show the object contents. + * @param expr the expression from which to start + * @return array of children + */ + public IEDCExpression[] getLogicalSubExpressions(IEDCExpression expr) { + + IType exprType = TypeUtils.getUnRefStrippedType(expr.getEvaluatedType()); + + // cast to array? + CastInfo castInfo = expr.getCastInfo(); + if (castInfo != null && castInfo.getArrayCount() > 0) { + + String exprName = expr.getExpression(); + + // in case of casts, need to resolve that before dereferencing, so be safe + if (exprName.contains("(")) //$NON-NLS-1$ + exprName = '(' + exprName + ')'; + + long lowerBound = castInfo.getArrayStartIndex(); + long count = castInfo.getArrayCount(); + + List arrayChildren = new ArrayList(); + for (int i = 0; i < count; i++) { + String arrayElement = "[" + (i + lowerBound) + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + IEDCExpression newExpr = new ExpressionDMC(expr.getFrame(), (exprName + arrayElement), + expr.getName() + arrayElement); + IEDCExpression exprChild = newExpr; //$NON-NLS-1$ //$NON-NLS-2$ + if (exprChild != null) { + arrayChildren.add(exprChild); + } + } + + return arrayChildren.toArray(new IEDCExpression[arrayChildren.size()]); + } + + if (exprType instanceof IPointerType) { + // automatically dereference a pointer + String exprName = expr.getExpression(); + IType typePointedTo = TypeUtils.getStrippedType(exprType.getType()); + + // If expression name already starts with "&" (e.g. "&struct"), indirect it first + boolean indirected = false; + + IEDCExpression exprChild; + + if (exprName.startsWith("&")) { //$NON-NLS-1$ + exprName = exprName.substring(1); + IEDCExpression newExpr = new ExpressionDMC(expr.getFrame(), exprName); + exprChild = newExpr; + indirected = true; + } + else { + // avoid dereferencing void pointer + if (typePointedTo instanceof ICPPBasicType + && ((ICPPBasicType) typePointedTo).getBaseType() == ICPPBasicType.t_void) { + return new IEDCExpression[0]; + } + + // do not dereference null either + if (expr.getEvaluatedValue() != null && expr.getEvaluatedValue().intValue() == 0) + return new IEDCExpression[0]; + IEDCExpression newExpr = new ExpressionDMC(expr.getFrame(), ("*" + exprName), "*" + expr.getName()); //$NON-NLS-1$ //$NON-NLS-2$ + + // a pointer type has one child + exprChild = newExpr; //$NON-NLS-1$ + } + + return doGetLogicalSubExpressions(exprChild, typePointedTo, indirected); + } + else if (exprType instanceof IReferenceType) { + // and bypass a reference + + IType typePointedTo = TypeUtils.getStrippedType(exprType.getType()); + return doGetLogicalSubExpressions(expr, typePointedTo, false); + }else { + // normal aggregate, just do it + return doGetLogicalSubExpressions(expr, exprType, false); + } + + } + + /** + * Get the logical subexpressions for the given expression context and string + * @param expr the expression from which to start + * @param exprType the type in which to consider the expression + * @param indirected if true, the expression was already indirected, as opposed to what the expression says + * @return + */ + private IEDCExpression[] doGetLogicalSubExpressions(IEDCExpression expr, IType exprType, boolean indirected) { + ArrayList exprList = new ArrayList(); + IEDCExpression exprChild; + + String expression = expr.getExpression(); + + // in case of casts, need to resolve that before dereferencing, so be safe + if (expression.contains("(")) //$NON-NLS-1$ + expression = '(' + expression + ')'; + + /* + // cast to array? + CastInfo castInfo = expr.getCastInfo(); + if (castInfo != null && castInfo.getArrayCount() > 0) { + long lowerBound = castInfo.getArrayStartIndex(); + long count = castInfo.getArrayCount(); + for (int i = 0; i < count; i++) { + exprChild = createDerivedExpression(expr, exprName + "[" + (i + lowerBound) + "]"); //$NON-NLS-1$ //$NON-NLS-2$ + if (exprChild != null) { + exprList.add(exprChild); + } + } + + } + else*/ if (exprType instanceof ICompositeType) { + // an artifact of following a pointer to a structure is that the + // name starts with '*' + if (expression.startsWith("*")) { //$NON-NLS-1$ + if (expression.startsWith("**")) + expression = "(" + expression.substring(1) + ")->"; //$NON-NLS-1$ + else + expression = expression.substring(1) + "->"; //$NON-NLS-1$ + } else { + expression = expression + '.'; //$NON-NLS-1$ + } + + // for each field, evaluate an expression, then shorten the name + ICompositeType compositeType = (ICompositeType) exprType; + + for (IField field : compositeType.getFields()) { + String fieldName = field.getName(); + if (fieldName.length() == 0) { + // This makes an invalid expression + // The debug info provider should have filtered out or renamed such fields + assert false; + continue; + } + exprChild = new ExpressionDMC(expr.getFrame(), expression + fieldName, fieldName); + if (exprChild != null) { + exprList.add(exprChild); + } + } + + for (IInheritance inherited : compositeType.getInheritances()) { + String inheritedName = inherited.getName(); + if (inheritedName.length() == 0) { + // This makes an invalid expression + // The debug info provider should have filtered out or renamed such fields + assert false; // couldn't this be the case for an anonymous member, like a union? + } else if (!inheritedName.contains("<")) { + exprChild = new ExpressionDMC(expr.getFrame(), expression + inheritedName, inheritedName); + if (exprChild != null) { + exprList.add(exprChild); + } + } else { + IType inheritedType = inherited.getType(); + if (inheritedType instanceof ICompositeType) { + for (IField field : ((ICompositeType)inheritedType).getFields()) { + String fieldName = field.getName(); + if (fieldName.length() == 0) { + // This makes an invalid expression + // The debug info provider should have filtered out or renamed such fields + assert false; + continue; + } + exprChild = new ExpressionDMC(expr.getFrame(), expression + fieldName, fieldName); + if (exprChild != null) { + exprList.add(exprChild); + } + } + } + } + } + + } + else if (exprType instanceof IArrayType) { + IArrayType arrayType = (IArrayType) exprType; + + if (arrayType.getBoundsCount() > 0) { + long lowerBound = expr.getCastInfo() != null && expr.getCastInfo().getArrayCount() > 0 + ? expr.getCastInfo().getArrayStartIndex() : 0; + long upperBound = arrayType.getBound(0).getBoundCount(); + if (upperBound == 0) + upperBound = 1; + for (int i = 0; i < upperBound; i++) { + String arrayElementName = "[" + (i + lowerBound) + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + IEDCExpression newExpr = new ExpressionDMC(expr.getFrame(), expression + arrayElementName, + expr.getName() + arrayElementName); + exprChild = newExpr; + if (exprChild != null) { + exprList.add(exprChild); + } + } + } + } + else if (exprType instanceof IArrayDimensionType) { + IArrayDimensionType arrayDimensionType = (IArrayDimensionType) exprType; + IArrayType arrayType = arrayDimensionType.getArrayType(); + + if (arrayType.getBoundsCount() > arrayDimensionType.getDimensionCount()) { + long lowerBound = expr.getCastInfo() != null && expr.getCastInfo().getArrayCount() > 0 + ? expr.getCastInfo().getArrayStartIndex() : 0; + long upperBound = arrayType.getBound(arrayDimensionType.getDimensionCount()).getBoundCount(); + for (int i = 0; i < upperBound; i++) { + String arrayElement = "[" + (i + lowerBound) + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + IEDCExpression newExpr = new ExpressionDMC(expr.getFrame(), expression + arrayElement, + expr.getName() + arrayElement); + exprChild = newExpr; + if (exprChild != null) { + exprList.add(exprChild); + } + } + } + } + else { + // nothing interesting + exprList.add(expr); + } + + return exprList.toArray(new IEDCExpression[exprList.size()]); + } + + @Immutable + private static class ExpressionChangedDMEvent extends AbstractDMEvent implements IExpressionChangedDMEvent { + ExpressionChangedDMEvent(IExpressionDMContext expression) { + super(expression); + } + } + + public void writeExpression(final IExpressionDMContext exprContext, final String expressionValue, final String formatId, final RequestMonitor rm) { + + asyncExec(new Runnable() { + public void run() { + IEDCExpression expressionDMC = (IEDCExpression) exprContext; + if (isComposite(expressionDMC)) { + rm.setStatus(EDCDebugger.dsfRequestFailedStatus(EDCServicesMessages.Expressions_CannotModifyCompositeValue, null)); + rm.done(); + return; + } + + IType exprType = TypeUtils.getStrippedType(expressionDMC.getEvaluatedType()); + + // first try to get value by format as BigInteger + Number number = NumberFormatUtils.parseIntegerByFormat(expressionValue, formatId); + if (number == null) { + IEDCExpression temp = (IEDCExpression) createExpression(expressionDMC.getFrame(), expressionValue); + temp.evaluateExpression(); + number = temp.getEvaluatedValue(); + + if (number == null) { + rm.setStatus(EDCDebugger.dsfRequestFailedStatus(EDCServicesMessages.Expressions_CannotParseExpression, null)); + rm.done(); + return; + } + } + + BigInteger value = null; + try { + value = MemoryUtils.convertValueToMemory(exprType, number); + } catch (CoreException e) { + rm.setStatus(e.getStatus()); + rm.done(); + return; + } + + IVariableLocation variableLocation = expressionDMC.getValueLocation(); + if (variableLocation == null) { + rm.setStatus(EDCDebugger.dsfRequestFailedStatus(EDCServicesMessages.Expressions_ExpressionNoLocation, null)); + rm.done(); + return; + } + + try { + variableLocation.writeValue(exprType.getByteSize(), value); + getSession().dispatchEvent(new ExpressionChangedDMEvent(exprContext), getProperties()); + } catch (CoreException e) { + rm.setStatus(e.getStatus()); + } + + rm.done(); + } + }, rm); + + } + + public void getAvailableFormats(IFormattedDataDMContext formattedDataContext, DataRequestMonitor rm) { + rm.setData(new String[] { IFormattedValues.NATURAL_FORMAT, IFormattedValues.DECIMAL_FORMAT, + IFormattedValues.HEX_FORMAT, IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT }); + rm.done(); + } + + public void getFormattedExpressionValue(final FormattedValueDMContext formattedDataContext, + final DataRequestMonitor rm) { + asyncExec(new Runnable() { + public void run() { + try { + rm.setData(getFormattedExpressionValue(formattedDataContext)); + rm.done(); + } catch (CoreException ce) { + rm.setStatus(ce.getStatus()); + rm.done(); + return; + } + } + }, rm); + } + + public String getExpressionValueString(IExpressionDMContext expression, String format) throws CoreException { + FormattedValueDMContext formattedDataContext = getFormattedValueContext(expression, format); + FormattedValueDMData formattedValue = getFormattedExpressionValue(formattedDataContext); + + return formattedValue != null ? formattedValue.getFormattedValue() : ""; + } + + public FormattedValueDMData getFormattedExpressionValue(FormattedValueDMContext formattedDataContext) throws CoreException { + IDMContext idmContext = formattedDataContext.getParents()[0]; + FormattedValueDMData formattedValue = null; + IEDCExpression exprDMC = null; + + if (idmContext instanceof IEDCExpression) { + exprDMC = (IEDCExpression) formattedDataContext.getParents()[0]; + + exprDMC.evaluateExpression(); + + if (exprDMC != null && exprDMC.getEvaluationError() != null) { + throw new CoreException(exprDMC.getEvaluationError()); + } + + formattedValue = exprDMC.getFormattedValue(formattedDataContext); // must call this to get type + + if (formattedDataContext.getFormatID().equals(IFormattedValues.NATURAL_FORMAT)) + { + IVariableValueConverter customConverter = getCustomValueConverter(exprDMC); + if (customConverter != null) { + FormattedValueDMData customFormattedValue = null; + try { + customFormattedValue = new FormattedValueDMData(customConverter.getValue(exprDMC)); + formattedValue = customFormattedValue; + } + catch (Throwable t) { + // CoreExeception will just propagate out, so this is for + // other unexpected errors, usually bug in the formatter. Log it + // so that user will be able to see and report the bug. + // Meanwhile, default to normal formatting so that user won't see + // such error in Variable UI. + EDCDebugger.getMessageLogger().logError( + EDCServicesMessages.Expressions_ErrorInVariableFormatter + customConverter.getClass().getName(), t); + } + } + } + } else + formattedValue = new FormattedValueDMData(""); //$NON-NLS-1$ + + return formattedValue; + } + + private IVariableValueConverter getCustomValueConverter(IEDCExpression exprDMC) { + IType exprType = TypeUtils.getUnRefStrippedType(exprDMC.getEvaluatedType()); + return FormatExtensionManager.instance().getVariableValueConverter(exprType); + } + + public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext formattedDataContext, + String formatId) { + return new FormattedValueDMContext(this, formattedDataContext, formatId); + } + + public void getModelData(IDMContext context, DataRequestMonitor rm) { + } + + public String getExpressionValue(IExpressionDMContext expression) + { + final StringBuffer holder = new StringBuffer(); + FormattedValueDMContext formattedValueContext = getFormattedValueContext(expression, IFormattedValues.NATURAL_FORMAT); + getFormattedExpressionValue(formattedValueContext, new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleSuccess() { + holder.append(this.getData().getFormattedValue()); + } + + @Override + protected void handleFailure() { + // RequestMonitor would by default log any error if it's not explicitly + // handled. But we don't want to log those expected errors (checked exceptions) + // in such case as creating snapshot. Hence this dummy handler...02/17/10 + + // DO nothing. + } + + + }); + return holder.toString(); + } + + public void loadExpressionValues(IExpressionDMContext expression, int depth) + { + loadExpressionValues(expression, new Integer[] {depth}); + } + + private void loadExpressionValues(IExpressionDMContext expression, final Integer[] depth) + { + getExpressionValue(expression); + if (depth[0] > 0) + { + getSubExpressions(expression, new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { + + @Override + protected void handleSuccess() { + depth[0] = depth[0] - 1; + IExpressions.IExpressionDMContext[] subExpressions = getData(); + for (IExpressionDMContext iExpressionDMContext : subExpressions) { + loadExpressionValues(iExpressionDMContext, depth); + } + }}); + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/INoop.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/INoop.java new file mode 100644 index 0000000..0d48b35 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/INoop.java @@ -0,0 +1,36 @@ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import org.eclipse.cdt.debug.edc.services.IEDCService; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; + +/** + * A dummy DSF service used for testing. + */ +public interface INoop extends IEDCService { + /** Simply sticks a boolean in the given RM */ + void noop(IDMContext whatever, DataRequestMonitor rm); + + /** + * Simply sticks a boolean in the given RM after 10 seconds have elapsed. + * The sleep is not done on the DSF executor thread, of course + */ + void longNoop(IDMContext whatever, DataRequestMonitor rm); + + /** + * This service simply loops for [duration] seconds, asking for the service + * tracker every second and trying to use it to get a service. It's used in + * a shutdown test to validate that threads in the EDC thread pool are given + * a chance to complete before the DSF session moves forward with its + * shutdown. If session shutdown didn't wait, then this service would end up + * encountering either a null pointer exception or an exception due to the + * attempted use of a disposed tracker. + * + * @param duration + * the number of seconds to loop + * @param rm + * not used but included for consistency + */ + void longNoopUsingServiceTracker(int duration, RequestMonitor rm); +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/LineEntryMapper.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/LineEntryMapper.java new file mode 100644 index 0000000..932041d --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/LineEntryMapper.java @@ -0,0 +1,144 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.EDCAddressRange; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.ILineEntryProvider; +import org.eclipse.cdt.debug.edc.symbols.IModuleLineEntryProvider; +import org.eclipse.cdt.dsf.debug.service.IModules.AddressRange; +import org.eclipse.core.runtime.IPath; + +/** + * Utilities for mapping source to addresses and vice versa. + */ +public class LineEntryMapper { + + private static final int toEOF = -1; + + /** + * Get the link-time address ranges starting at the given source location. + * There may be more than one, e.g., in template expansions, static functions + * declared in headers, inlined functions, etc. Or, of course, someone may + * declare multiple functions on one line. + * @path sourceFile the absolute path to the source file + * @param line the line number (1-based) + * @return the unmodifiable list of link-time addresses which start at the given line, possibly empty, + * will be null if the source file is not used by this module. + */ + public static Collection getAddressRangesAtSource( + IModuleLineEntryProvider moduleLineEntryProvider, + IPath sourceFile, + int line) { + Collection range = getAddressRangesAtSource(moduleLineEntryProvider, sourceFile, line, line); + if (range != null && range.isEmpty()) { + range = getAddressRangesAtSource(moduleLineEntryProvider, sourceFile, line, toEOF); + } + return range; + } + + /** + * The public version of this function acts as a wrapper, allowing the original algorithm + * to try all fileProviders first, and if that fails, to try to find the next line. + * The use case in the original case is to be precise about inline/template situations. + * The use case in the new version of the call is to set a breakpoint on first available line + * in case the user has chosen to set a breakpoint on a line without LNT information. + * @path sourceFile the absolute path to the source file + * @param startLine the line number (1-based) + * @param endLine the line number (1-based) + * @return the unmodifiable list of link-time addresses which start at the given line, possibly empty, + * will be null if the source file is not used by this module. + */ + private static Collection getAddressRangesAtSource( + IModuleLineEntryProvider moduleLineEntryProvider, + IPath sourceFile, + int startLine, + int endLine) { + Collection fileProviders = + moduleLineEntryProvider.getLineEntryProvidersForFile(sourceFile); + if (fileProviders.isEmpty()) + return null; + + int lastColumn = -1; + IPath lastFile = null; + int bestLine = endLine; + + List addrRanges = null; + for (ILineEntryProvider fileProvider : fileProviders) { + + Collection entries = fileProvider.getLineEntriesForLines(sourceFile, startLine, endLine); + if (addrRanges == null && !entries.isEmpty()) + addrRanges = new ArrayList(); + + for (ILineEntry entry : entries) { + + int entryLine = entry.getLineNumber(); + + if (entryLine < bestLine && addrRanges != null) { + addrRanges.clear(); + bestLine = entryLine; + } + else if (bestLine == toEOF) { + bestLine = entryLine; + } + else if (entryLine > bestLine) { + break; // assume entries sorted; go onto the next fileProvider + } + // else (entryLine == bestLine) // implied + + /* + * when there is more than one line mapping for the source line, + * see if it makes sense to merge the line entries into the same + * address range, or keep different address ranges. examples of + * when this might happen are when there are multiple logical + * code segments for the same source line, but in different + * columns. in this case it makes sense to merge these into one + * address range. for templates and inline functions however, + * the column will be the same. for these cases it makes sense + * to keep the address ranges separate. + */ + IPath entryPath = entry.getFilePath(); + int entryColumn = entry.getColumnNumber(); + if (addrRanges != null) + { + if (addrRanges.isEmpty() || !entryPath.equals(lastFile) || lastColumn == entryColumn) { + addrRanges.add(new EDCAddressRange(entry.getLowAddress(), entry.getHighAddress())); + } else { + EDCAddressRange range = addrRanges.remove(addrRanges.size() - 1); + range.setEndAddress(entry.getHighAddress()); + addrRanges.add(range); + } + } + lastColumn = entryColumn; + lastFile = entryPath; + } + } + + if (addrRanges == null) + return Collections.emptyList(); + + List returnRanges = addrRanges; + return Collections.unmodifiableCollection(returnRanges); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Memory.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Memory.java new file mode 100644 index 0000000..5c0dffa --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Memory.java @@ -0,0 +1,471 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.debug.edc.services.IDSFServiceUsingTCF; +import org.eclipse.cdt.debug.edc.services.IEDCDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC; +import org.eclipse.cdt.debug.edc.services.IEDCMemory; +import org.eclipse.cdt.debug.edc.snapshot.IAlbum; +import org.eclipse.cdt.debug.edc.snapshot.ISnapshotContributor; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.ICachingService; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.cdt.dsf.debug.service.IMemory; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.tm.tcf.protocol.IService; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +public class Memory extends AbstractEDCService implements IEDCMemory, ICachingService, ISnapshotContributor, + IDSFServiceUsingTCF { + + private org.eclipse.tm.tcf.services.IMemory tcfMemoryService; + private Map memoryCaches; + private long tcfTimeout; + + private class MemoryChangedEvent extends AbstractDMEvent implements IMemoryChangedEvent { + IAddress[] addresses; + + public MemoryChangedEvent(IMemoryDMContext context, IAddress[] addresses) { + super(context); + this.addresses = addresses; + } + + public IAddress[] getAddresses() { + return addresses; + } + } + + public Memory(DsfSession session) { + super(session, new String[] { IEDCMemory.class.getName(), IMemory.class.getName(), Memory.class.getName(), + ISnapshotContributor.class.getName() }); + setTCFTimeout(15 * 1000); // Fifteen seconds + } + + private MemoryCache getMemoryCache(IMemoryDMContext memoryDMC) { + assert memoryDMC instanceof IEDCDMContext; + MemoryCache cache = memoryCaches.get(((IEDCDMContext) memoryDMC).getID()); + if (cache == null) { + cache = new MemoryCache(getTargetEnvironmentService().getMemoryCacheMinimumBlockSize()); + memoryCaches.put(((IEDCDMContext) memoryDMC).getID(), cache); + } + return cache; + } + + @Override + protected void doInitialize(RequestMonitor requestMonitor) { + super.doInitialize(requestMonitor); + + // create memory cache + memoryCaches = new HashMap(); + + getSession().addServiceEventListener(this, null); + } + + public MemoryByte[] getMemory(final IMemoryDMContext context, final IAddress address, final long offset, + final int word_size, final int count) throws CoreException { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { address.toHexAddressString(), offset, word_size, count })); } + + // Validate the context + if (context == null) { + throw new CoreException(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, INTERNAL_ERROR, + "Unknown context type", null)); //$NON-NLS-1$); + } + + // Validate the word size + if (word_size < 1) { + throw new CoreException(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, NOT_SUPPORTED, + "Word size not supported (< 1)", null)); //$NON-NLS-1$ + } + + // Validate the byte count + if (count < 0) { + throw new CoreException(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Invalid word count (< 0)", null)); //$NON-NLS-1$ + } + + // everything OK + + // NOTE: We normalize word_size and count to read 1-byte words for this implementation + MemoryByte[] memoryBytes = getMemoryCache(context).getMemory(tcfMemoryService, context, address.add(offset), 1, count * word_size, + getTCFTimeout()); + // hide breakpoints inserted in the memory by debugger + Breakpoints bpService = getService(Breakpoints.class); + bpService.removeBreakpointFromMemoryBuffer(address.add(offset), memoryBytes); + if (RunControl.timeStepping()) + System.out.println("Time since stepping start: " + + ((System.currentTimeMillis() - RunControl.getSteppingStartTime()) / 1000.0)); + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + return memoryBytes; + } + + public IStatus getMemory(IEDCExecutionDMC context, IAddress address, + ArrayList memBuffer, int count, int word_size) { + try { + MemoryByte[] memArray = getMemory(context, address, 0, count, word_size); + memBuffer.addAll(Arrays.asList(memArray)); + } catch (CoreException e) { + return new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, INTERNAL_ERROR, + "Error reading memory from: " + address.toHexAddressString(), null); + } + return Status.OK_STATUS; + } + + public void flushCache(IDMContext context) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { context })); } + + if (isSnapshot()) + return; + + if (context == null) { + // reset every cache in each context + for (String key : memoryCaches.keySet()) { + memoryCaches.get(key).reset(); + } + } else { + IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(context, IMemoryDMContext.class); + if (memoryCaches.containsKey(((IEDCDMContext) memoryDMC).getID())) { + // We do not want to use the call to getMemoryCache() here. + // This is because: + // 1- if there is not an entry already , we do not want to + // automatically + // create one, just to call reset() on it. + // 2- if memoryDMC == null, we do not want to create a cache + // entry for which the key is 'null' + memoryCaches.get(((IEDCDMContext) memoryDMC).getID()).reset(); + } + } + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + public IStatus setMemory(IMemoryDMContext context, IAddress address, int word_size, int count, byte[] buffer) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { address.toHexAddressString(), count })); } + + final IStatus[] ret = new IStatus[] { Status.OK_STATUS }; + + setMemory(context, address, 0, word_size, count, buffer, new RequestMonitor(ImmediateExecutor + .getInstance(), null) { + + @Override + protected void handleFailure() { + ret[0] = getStatus(); + } + }); + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(ret[0])); } + return ret[0]; + } + + public void tcfServiceReady(IService service) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { service })); } + tcfMemoryService = (org.eclipse.tm.tcf.services.IMemory) service; + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + @DsfServiceEventHandler + public void eventDispatched(ISuspendedDMEvent e) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { e.getClass() })); } + flushCache(e.getDMContext()); + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + @DsfServiceEventHandler + public void eventDispatched(IResumedDMEvent e) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { e.getClass() })); } + if (e.getReason() != StateChangeReason.STEP) { + flushCache(e.getDMContext()); + } + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + @DsfServiceEventHandler + public void eventDispatched(IExpressionChangedDMEvent e) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { e.getClass() })); } + + // Get the context and expression service handle + final IExpressionDMContext context = e.getDMContext(); + IExpressions expressionService = getService(IExpressions.class); + + // Get the variable information and update the corresponding memory + // locations + if (expressionService != null) { + expressionService.getExpressionAddressData(context, new DataRequestMonitor( + getExecutor(), null) { + @Override + protected void handleSuccess() { + // Figure out which memory area was modified + IExpressionDMAddress expression = getData(); + final int count = expression.getSize(); + Object expAddress = expression.getAddress(); + final Addr64 address; + if (expAddress instanceof Addr64) + address = (Addr64) expAddress; + else if (expAddress instanceof IAddress) + address = new Addr64(((IAddress) expAddress).getValue()); + else + return; // not a valid memory address + + final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(context, IMemoryDMContext.class); + boolean modified = getMemoryCache(memoryDMC).refreshMemory(tcfMemoryService, memoryDMC, address, 0, + 1, count, new RequestMonitor(getExecutor(), null), getTCFTimeout()); + if (modified) { + // we've modified cache - send an event + IAddress[] addresses = new IAddress[count]; + for (int i = 0; i < count; i++) { + addresses[i] = address.add(i); + } + getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties()); + } + } + }); + } + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + private static final String MEMORY_CONTEXT = "memory_context"; + private static final String MEMORY = "memory"; + private static final String CONTEXT_ID = "context_id"; + + public void loadSnapshot(Element element) throws Exception { + memoryCaches = new HashMap(); + NodeList contextElements = element.getElementsByTagName(MEMORY_CONTEXT); + + int numContexts = contextElements.getLength(); + for (int i = 0; i < numContexts; i++) { + Element contextElement = (Element) contextElements.item(i); + String contextID = contextElement.getAttribute(CONTEXT_ID); + MemoryCache cache = new MemoryCache(getTargetEnvironmentService().getMemoryCacheMinimumBlockSize()); + cache.loadSnapshot(contextElement); + memoryCaches.put(contextID, cache); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.snapshot.ISnapshotContributor#takeShapshot(org.eclipse.cdt.debug.edc.snapshot.IAlbum, org.w3c.dom.Document, org.eclipse.core.runtime.IProgressMonitor) + */ + public Element takeSnapshot(IAlbum album, Document document, IProgressMonitor monitor) { + Element memoryElement = document.createElement(MEMORY); + SubMonitor progress = SubMonitor.convert(monitor, memoryCaches.keySet().size() * 1000); + progress.subTask("Memory"); + for (String key : memoryCaches.keySet()) { + MemoryCache cache = memoryCaches.get(key); + Element memoryCacheElement = document.createElement(MEMORY_CONTEXT); + memoryCacheElement.setAttribute(CONTEXT_ID, key); + memoryCacheElement.appendChild(cache.takeSnapshot(album, document, progress.newChild(1000))); + memoryElement.appendChild(memoryCacheElement); + } + return memoryElement; + } + + public void setTCFTimeout(long msecs) { + tcfTimeout = msecs; + } + + public long getTCFTimeout() { + return tcfTimeout; + } + + // Implementation of org.eclipse.cdt.dsf.debug.service.IMemory + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.IMemory#fillMemory(org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext, org.eclipse.cdt.core.IAddress, long, int, int, byte[], org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + public void fillMemory(final IMemoryDMContext context, final IAddress address, final long offset, final int word_size, final int count, + final byte[] pattern, final RequestMonitor rm) { + asyncExec(new Runnable() { + + public void run() { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { address.toHexAddressString(), offset, word_size, count })); } + + // Validate the context + if (context == null) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, INTERNAL_ERROR, + "Unknown context type", null)); //$NON-NLS-1$; + rm.done(); + return; + } + + // Validate the word size + if (word_size < 1) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, NOT_SUPPORTED, + "Word size not supported (< 1)", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Validate the repeat count + if (count < 0) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Invalid repeat count (< 0)", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Validate the pattern + if (pattern.length < 1) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Empty pattern", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Create an aggregate buffer so we can write in 1 shot + final int length = pattern.length; + final byte[] buffer = new byte[count * length]; + for (int i = 0; i < count; i++) { + System.arraycopy(pattern, 0, buffer, i * length, length); + } + + // All is clear: go for it + // NOTE: We normalize word_size and count to read 1-byte words for this implementation + try { + getMemoryCache(context).setMemory(tcfMemoryService, context, address, offset, 1, count * length * word_size, + buffer, getTCFTimeout()); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().log(e.getStatus()); + rm.setStatus(e.getStatus()); + } + rm.done(); + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + }, rm); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.IMemory#getMemory(org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext, org.eclipse.cdt.core.IAddress, long, int, int, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + public void getMemory(final IMemoryDMContext context, final IAddress address, final long offset, + final int word_size, final int count, final DataRequestMonitor drm) { + + asyncExec(new Runnable() { + + public void run() { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { address.toHexAddressString(), offset, word_size, count })); } + // NOTE: We normalize word_size and count to read 1-byte words for this implementation + try { + MemoryByte[] memoryBytes = getMemory(context, address, offset, word_size, count); + drm.setData(memoryBytes); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().log(e.getStatus()); + drm.setStatus(e.getStatus()); + } + drm.done(); + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + }, drm); + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.IMemory#setMemory(org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext, org.eclipse.cdt.core.IAddress, long, int, int, byte[], org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + public void setMemory(final IMemoryDMContext context, final IAddress address, final long offset, + final int word_size, final int count, final byte[] buffer, final RequestMonitor rm) { + + asyncExec(new Runnable() { + + public void run() { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { address.toHexAddressString(), offset, word_size, count })); } + + // Validate the context + if (context == null) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, INTERNAL_ERROR, + "Unknown context type", null)); //$NON-NLS-1$); + rm.done(); + return; + } + + // Validate the word size + // NOTE: We only accept 1 byte words for this implementation + if (word_size != 1) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, NOT_SUPPORTED, + "Word size not supported (!= 1)", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Validate the byte count + if (count < 0) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Invalid word count (< 0)", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Validate the buffer size + if (buffer.length < count) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Buffer too short", null)); //$NON-NLS-1$ + rm.done(); + return; + } + // everything ok + // NOTE: We normalize word_size and count to read 1-byte words for this implementation + try { + getMemoryCache(context).setMemory(tcfMemoryService, context, address, offset, word_size, count, buffer, getTCFTimeout()); + if (rm.isSuccess()) { + // we've modified memory - send an event + IAddress[] addresses = new IAddress[count]; + for (int i = 0; i < count; i++) { + addresses[i] = address.add(offset + i); + } + getSession().dispatchEvent(new MemoryChangedEvent(context, addresses), getProperties()); + } + } catch (CoreException e) { + EDCDebugger.getMessageLogger().log(e.getStatus()); + rm.setStatus(e.getStatus()); + } + rm.done(); + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + }, rm); + + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/MemoryCache.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/MemoryCache.java new file mode 100644 index 0000000..e62250b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/MemoryCache.java @@ -0,0 +1,836 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.ListIterator; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.IAddressFactory; +import org.eclipse.cdt.debug.edc.MemoryUtils; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.services.IEDCDMContext; +import org.eclipse.cdt.debug.edc.snapshot.IAlbum; +import org.eclipse.cdt.debug.edc.snapshot.ISnapshotContributor; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.cdt.utils.Addr32Factory; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.cdt.utils.Addr64Factory; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.services.IMemory; +import org.eclipse.tm.tcf.services.IMemory.DoneGetContext; +import org.eclipse.tm.tcf.services.IMemory.DoneMemory; +import org.eclipse.tm.tcf.services.IMemory.ErrorOffset; +import org.eclipse.tm.tcf.services.IMemory.MemoryContext; +import org.eclipse.tm.tcf.services.IMemory.MemoryError; +import org.eclipse.tm.tcf.util.TCFTask; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * This is adapted from + * org.eclipse.cdt.dsf.mi.service.MIMemory.MIMemoryCache + * + */ +public class MemoryCache implements ISnapshotContributor { + + // Timeout waiting for TCF agent reply. + final private int TIMEOUT = 6000; // milliseconds + private int minimumBlockSize = 0; + private final Map tcfMemoryContexts = Collections.synchronizedMap(new HashMap()); + private final SortedMemoryBlockList memoryBlockList = new SortedMemoryBlockList(); + + /** + * @param minimumBlockSize minimum size of memory block to cache. + */ + public MemoryCache(int minimumBlockSize) { + this.minimumBlockSize = minimumBlockSize; + } + + public void reset() { + // clear the memory cache + synchronized (memoryBlockList) + { + memoryBlockList.clear(); + } + } + + /** + * This function walks the address-sorted memory block list to identify + * the 'missing' blocks (i.e. the holes) that need to be fetched on the target. + * + * The idea is fairly simple but an illustration could perhaps help. + * Assume the cache holds a number of cached memory blocks with gaps i.e. + * there is un-cached memory areas between blocks A, B and C: + * + * +---------+ +---------+ +---------+ + * + A + + B + + C + + * +---------+ +---------+ +---------+ + * : : : : : : + * [a] : : [b] : : [c] : : [d] + * : : : : : : + * [e---+--] : [f--+---------+--] : : + * [g---+---------+------+---------+------+---------+----] + * : : : : : : + * : [h] : : [i----+--] : : + * + * + * We have the following cases to consider.The requested block [a-i] either: + * + * [1] Fits entirely before A, in one of the gaps, or after C + * with no overlap and no contiguousness (e.g. [a], [b], [c] and [d]) + * -> Add the requested block to the list of blocks to fetch + * + * [2] Starts before an existing block but overlaps part of it, possibly + * spilling in the gap following the cached block (e.g. [e], [f] and [g]) + * -> Determine the length of the missing part (< count) + * -> Add a request to fill the gap before the existing block + * -> Update the requested block for the next iteration: + * - Start address to point just after the end of the cached block + * - Count reduced by cached block length (possibly becoming negative, e.g. [e]) + * At this point, the updated requested block starts just beyond the cached block + * for the next iteration. + * + * [3] Starts at or into an existing block and overlaps part of it ([h] and [i]) + * -> Update the requested block for the next iteration: + * - Start address to point just after the end of the cached block + * - Count reduced by length to end of cached block (possibly becoming negative, e.g. [h]) + * At this point, the updated requested block starts just beyond the cached block + * for the next iteration. + * + * We iterate over the cached blocks list until there is no entry left or until + * the remaining requested block count is <= 0, meaning the result list contains + * only the sub-blocks needed to fill the gap(s), if any. + * + * (As is often the case, it takes much more typing to explain it than to just do it :-) + * + * What is missing is a parameter that indicates the minimal block size that is worth fetching. + * This is target-specific and straight in the realm of the coalescing function... + * + * @param reqBlockStart The address of the requested block + * @param count Its length + * @return A list of the sub-blocks to fetch in order to fill enough gaps in the memory cache + * to service the request + */ + private LinkedList getListOfMissingBlocks(IAddress reqBlockStart, int count) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { reqBlockStart.toHexAddressString(), count })); } + LinkedList list = new LinkedList(); + + synchronized (memoryBlockList) + { + ListIterator it = memoryBlockList.listIterator(); + + // Look for holes in the list of memory blocks + while (it.hasNext() && count > 0) { + MemoryBlock cachedBlock = it.next(); + IAddress cachedBlockStart = cachedBlock.fAddress; + IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength); + + // Case where we miss a block before the cached block + if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0) { + int length = (int) Math.min(reqBlockStart.distanceTo(cachedBlockStart).longValue(), count); + // If both blocks start at the same location, no need to create + // a new cached block + if (length > 0) { + IAddress blockAddress; + if (reqBlockStart instanceof Addr64) { + IAddressFactory f = new Addr64Factory(); + blockAddress = f.createAddress(reqBlockStart.getValue()); + } else { + IAddressFactory f = new Addr32Factory(); + blockAddress = f.createAddress(reqBlockStart.getValue()); + } + MemoryBlock newBlock = new MemoryBlock(blockAddress, length, new MemoryByte[0]); + list.add(newBlock); + } + // Adjust request block start and length for the next iteration + reqBlockStart = cachedBlockEnd; + count -= length + cachedBlock.fLength; + } + + // Case where the requested block starts somewhere in the cached + // block + else if (cachedBlockStart.distanceTo(reqBlockStart).longValue() > 0 + && reqBlockStart.distanceTo(cachedBlockEnd).longValue() >= 0) { + // Start of the requested block already in cache + // Adjust request block start and length for the next iteration + count -= reqBlockStart.distanceTo(cachedBlockEnd).longValue(); + reqBlockStart = cachedBlockEnd; + } + } + + // Case where we miss a block at the end of the cache + if (count > 0) { + IAddress blockAddress; + if (reqBlockStart instanceof Addr64) { + IAddressFactory f = new Addr64Factory(); + blockAddress = f.createAddress(reqBlockStart.getValue()); + } else { + IAddressFactory f = new Addr32Factory(); + blockAddress = f.createAddress(reqBlockStart.getValue()); + } + MemoryBlock newBlock = new MemoryBlock(blockAddress, count, new MemoryByte[0]); + list.add(newBlock); + } + } + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(list)); } + return list; + } + + /** + * This function walks the address-sorted memory block list to get the + * cached memory bytes (possibly from multiple contiguous blocks). This + * function is called *after* the missing blocks have been read from the + * back end i.e. the requested memory is all cached. + * + * Again, this is fairly simple. As we loop over the address-ordered list, + * There are really only 2 cases: + * + * [1] The requested block fits entirely in the cached block ([a] or [b]) + * [2] The requested block starts in a cached block and ends in the + * following (contiguous) one ([c]) in which case it is treated as 2 + * contiguous requests ([c'] and [c"]) + * + * +--------------+--------------+ + A + B + +--------------+--------------+ + * : [a----] : [b-----] : : : : : [c-----+------] : : [c'---]+[c"---] : + * + * @param reqBlockStart + * The address of the requested block + * @param count + * Its length + * @return The cached memory content + */ + private MemoryByte[] getMemoryBlockFromCache(IAddress reqBlockStart, int count) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { reqBlockStart.toHexAddressString(), count })); } + + MemoryByte[] resultBlock = new MemoryByte[count]; + + synchronized (memoryBlockList) + { + IAddress reqBlockEnd = reqBlockStart.add(count); + ListIterator iter = memoryBlockList.listIterator(); + + while (iter.hasNext()) { + MemoryBlock cachedBlock = iter.next(); + IAddress cachedBlockStart = cachedBlock.fAddress; + IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength); + + // Case where the cached block overlaps completely the requested + // memory block + if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0 + && reqBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0) { + int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue(); + System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, count); + } + + // Case where the beginning of the cached block is within the + // requested memory block + else if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0 + && cachedBlockStart.distanceTo(reqBlockEnd).longValue() > 0) { + int pos = (int) reqBlockStart.distanceTo(cachedBlockStart).longValue(); + int length = (int) Math.min(cachedBlock.fLength, count - pos); + System.arraycopy(cachedBlock.fBlock, 0, resultBlock, pos, length); + } + + // Case where the end of the cached block is within the requested + // memory block + else if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0 + && reqBlockStart.distanceTo(cachedBlockEnd).longValue() > 0) { + int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue(); + int length = (int) Math.min(cachedBlock.fLength - pos, count); + System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, length); + } + } + } + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArgs(resultBlock)); } + return resultBlock; + } + + /** + * This function walks the address-sorted memory block list and updates the + * content with the actual memory just read from the target. + * + * @param modBlockStart + * @param count + * @param modBlock + */ + private void updateMemoryCache(IAddress modBlockStart, int count, MemoryByte[] modBlock) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { modBlockStart.toHexAddressString(), count })); } + + synchronized (memoryBlockList) + { + IAddress modBlockEnd = modBlockStart.add(count); + ListIterator iter = memoryBlockList.listIterator(); + + while (iter.hasNext()) { + MemoryBlock cachedBlock = iter.next(); + IAddress cachedBlockStart = cachedBlock.fAddress; + IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength); + + // For now, we only bother to update bytes already cached. + // Note: In a better implementation (v1.1), we would augment + // the cache with the missing memory blocks since we went + // through the pains of reading them in the first place. + // (this is left as an exercise to the reader :-) + + // Case where the modified block is completely included in the + // cached block + if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0 + && modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0) { + int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue(); + System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, count); + } + + // Case where the beginning of the modified block is within the + // cached block + else if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0 + && modBlockStart.distanceTo(cachedBlockEnd).longValue() > 0) { + int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue(); + int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue(); + System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, length); + } + + // Case where the end of the modified block is within the cached + // block + else if (cachedBlockStart.distanceTo(modBlockEnd).longValue() > 0 + && modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0) { + int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue(); + int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue(); + System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, length); + } + } + } + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + return; + } + + /** + * This function iterates through missing blocks (blocks not currently + * cached, but wanted) and reads from the target and creates new cached + * blocks. + * + * @param tcfMemoryService + * @param context + * @param address + * @param word_size + * @param count + * @param drm + * @param timeOutLimit + * @throws CoreException + */ + public MemoryByte[] getMemory(final IMemory tcfMemoryService, final IMemoryDMContext context, final IAddress address, + final int word_size, final int count, long timeOutLimit) throws CoreException { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { context, address.toHexAddressString(), word_size, count })); } + + // determine number of read requests to issue + final LinkedList missingBlocks = getListOfMissingBlocks(address, count); + final int numberOfRequests = missingBlocks.size(); + + if (numberOfRequests > 0 && tcfMemoryService == null) { + throw new CoreException(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, "Fail to read memory.")); + } + // System.out.printf("MemoryCache.getMemory address=%x count=%d numberOfRequests=%d\n", + // address.getValue(), count, numberOfRequests); + for (int i = 0; i < numberOfRequests; i++) { + MemoryBlock block = missingBlocks.get(i); + IAddress blockAddress = block.fAddress; + int blockLength = (int) block.fLength; + if (blockLength < minimumBlockSize) + blockLength = minimumBlockSize; + + MemoryByte[] result; + try { + result = readBlock(tcfMemoryService, context, blockAddress, word_size, blockLength, timeOutLimit); + MemoryBlock newBlock = new MemoryBlock(blockAddress, blockLength, result); + memoryBlockList.add(newBlock); + } catch (Exception e) { + throw new CoreException(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Fail to read memory.", e.getCause())); //$NON-NLS-1$ + } + } + MemoryByte[] result = getMemoryBlockFromCache(address, count); + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + return result; + } + + private MemoryContext getTCFMemoryContext(final IMemory tcfMemoryService, final String contextID, long timeOutLimit) throws IOException, InterruptedException, ExecutionException, TimeoutException { + + MemoryContext ret = tcfMemoryContexts.get(contextID); + if (ret != null) + return ret; + + final TCFTask tcfTask = new TCFTask(TIMEOUT) { + + public void run() { + tcfMemoryService.getContext(contextID, new DoneGetContext() { + + public void doneGetContext(IToken token, Exception error, MemoryContext context) { + if (error == null) { + done(context); + } else { + error(error); + } + } + }); + } + }; + + ret = tcfTask.get(timeOutLimit, TimeUnit.MILLISECONDS); + + if (ret != null) + tcfMemoryContexts.put(contextID, ret); + + return ret; + } + + /** + * This function does the actual reading from the target. + * + * @param tcfMemoryService + * @param context + * @param address + * @param word_size + * @param count + * @param timeOutLimit + * @return + * @throws IOException + * @throws TimeoutException + * @throws ExecutionException + * @throws InterruptedException + */ + private MemoryByte[] readBlock(final IMemory tcfMemoryService, final IMemoryDMContext context, + final IAddress address, final int word_size, final int count, long timeOutLimit) throws IOException, InterruptedException, ExecutionException, TimeoutException { + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { context, address.toHexAddressString(), word_size, count })); } + + final MemoryContext tcfMC = getTCFMemoryContext(tcfMemoryService, ((IEDCDMContext)context).getID(), timeOutLimit); + + MemoryByte[] result = null; + + final TCFTask tcfTask = new TCFTask(TIMEOUT) { + + public void run() { + Number tcfAddress = address.getValue(); + final byte[] buffer = new byte[word_size * count]; + tcfMC.get(tcfAddress, word_size, buffer, 0, count * word_size, 0, new DoneMemory() { + + public void doneMemory(IToken token, MemoryError error) { + if (error == null) { + MemoryByte[] res = new MemoryByte[buffer.length]; + for (int i = 0; i < buffer.length; i++) { + res[i] = new MemoryByte(buffer[i]); + } + done(res); + } else if (error instanceof IMemory.ErrorOffset) { + boolean someStatusKnown = false; + IMemory.ErrorOffset errorOffset = (ErrorOffset) error; + MemoryByte[] res = new MemoryByte[buffer.length]; + + // TODO: figure actual endianness (MemoryByte.BIG_ENDIAN) flag; + // we leave out the flag here which defaults to little-endian + for (int i = 0; i < buffer.length; i++) { + byte flags = MemoryByte.ENDIANESS_KNOWN | MemoryByte.READABLE | MemoryByte.WRITABLE; + + int st = errorOffset.getStatus(i); + if ((st & IMemory.ErrorOffset.BYTE_UNKNOWN) != 0) { + flags = 0; + } else { + someStatusKnown = true; + if ((st & IMemory.ErrorOffset.BYTE_INVALID) != 0) { + flags &= ~(MemoryByte.READABLE + MemoryByte.WRITABLE); + } else { + if ((st & IMemory.ErrorOffset.BYTE_CANNOT_READ) != 0) + flags &= ~MemoryByte.READABLE; + if ((st & IMemory.ErrorOffset.BYTE_CANNOT_WRITE) != 0) + flags &= ~MemoryByte.WRITABLE; + } + } + res[i] = new MemoryByte(buffer[i], flags); + } + if (someStatusKnown) + done(res); + else + error(error); + } else { + error(error); + } + } + }); + } + }; + + result = tcfTask.get(timeOutLimit, TimeUnit.MILLISECONDS); + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + return result; + } + + /** + * This function writes a block of memory and then re-reads and updates any + * cached blocks. + * + * @param tcfMemoryService + * @param context + * @param address + * @param offset + * @param word_size + * @param count + * @param buffer + * @param rm + * @throws CoreException + */ + public void setMemory(IMemory tcfMemoryService, IMemoryDMContext context, final IAddress address, + final long offset, final int word_size, final int count, byte[] buffer, + long timeOutLimit) throws CoreException { + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { context, address.toHexAddressString(), offset, word_size, count })); } + + try { + writeBlock(tcfMemoryService, context, address, offset, word_size, count, buffer, timeOutLimit); + if (blockIsCached(address.add(offset), word_size * count)) { + MemoryByte[] update = readBlock(tcfMemoryService, context, address.add(offset), word_size, count, timeOutLimit); + updateMemoryCache(address.add(offset), update.length, update); + } + } catch (Exception e) { + throw new CoreException(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, "Fail to write memory.")); + } + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * This function figures out if a block of memory is already cached. + * + * @param modBlockStart + * @param count + * @return + */ + private boolean blockIsCached(IAddress modBlockStart, int count) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { modBlockStart.toHexAddressString(), count })); } + boolean cacheFound = false; + + synchronized (memoryBlockList) + { + IAddress modBlockEnd = modBlockStart.add(count); + ListIterator iter = memoryBlockList.listIterator(); + + while (iter.hasNext()) { + MemoryBlock cachedBlock = iter.next(); + IAddress cachedBlockStart = cachedBlock.fAddress; + IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength); + + // For now, we only bother to update bytes already cached. + // Note: In a better implementation (v1.1), we would augment + // the cache with the missing memory blocks since we went + // through the pains of reading them in the first place. + // (this is left as an exercise to the reader :-) + + // Case where the modified block is completely included in the + // cached block + if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0 + && modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0) { + cacheFound = true; + } + + // Case where the beginning of the modified block is within the + // cached block + else if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0 + && modBlockStart.distanceTo(cachedBlockEnd).longValue() > 0) { + cacheFound = true; + } + + // Case where the end of the modified block is within the cached + // block + else if (cachedBlockStart.distanceTo(modBlockEnd).longValue() > 0 + && modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0) { + cacheFound = true; + } + } + } + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(cacheFound)); } + return cacheFound; + } + + /** + * This function writes a memory block to the target. + * + * @param tcfMemoryService + * @param context + * @param address + * @param offset + * @param word_size + * @param count + * @param buffer + * @param timeOutLimit + * @throws IOException + * @throws TimeoutException + * @throws ExecutionException + * @throws InterruptedException + */ + private void writeBlock(final IMemory tcfMemoryService, final IMemoryDMContext context, final IAddress address, + final long offset, final int word_size, final int count, final byte[] buffer, long timeOutLimit) throws IOException, InterruptedException, ExecutionException, TimeoutException { + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { context, address.toHexAddressString(), offset, word_size, count })); } + + final TCFTask tcfTask = new TCFTask(TIMEOUT) { + + public void run() { + final TCFTask task = this; + String memoryContextID = ((IEDCDMContext) context).getID(); + tcfMemoryService.getContext(memoryContextID, new DoneGetContext() { + + public void doneGetContext(IToken token, Exception error, MemoryContext context) { + if (error == null) { + Number tcfAddress = address.add(offset).getValue(); + context.set(tcfAddress, word_size, buffer, 0, count * word_size, 0, new DoneMemory() { + + public void doneMemory(IToken token, MemoryError error) { + if (error == null) { + task.done(null); + } else { + task.error(error); + } + } + }); + } else { + task.error(error); + } + } + }); + } + }; + + tcfTask.get(timeOutLimit, TimeUnit.MILLISECONDS); + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + private class MemoryBlock { + public MemoryBlock(IAddress fAddress, long fLength, MemoryByte[] fBlock) { + super(); + this.fAddress = fAddress; + this.fLength = fLength; + this.fBlock = fBlock; + } + + public IAddress fAddress; + public long fLength; + public MemoryByte[] fBlock; + } + + @SuppressWarnings("serial") + private class SortedMemoryBlockList extends LinkedList { + public SortedMemoryBlockList() { + super(); + } + + // Insert the block in the sorted linked list and merge contiguous + // blocks if necessary + @Override + synchronized public boolean add(MemoryBlock block) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { block.fAddress.toHexAddressString(), block.fLength })); } + + // If the list is empty, just store the block + if (isEmpty()) { + addFirst(block); + return true; + } + + // Insert the block at the correct location and then + // merge the blocks if possible + ListIterator it = listIterator(); + while (it.hasNext()) { + int index = it.nextIndex(); + MemoryBlock item = it.next(); + if (block.fAddress.compareTo(item.fAddress) < 0) { + add(index, block); + compact(index); + return true; + } + } + + // Put at the end of the list and merge if necessary + addLast(block); + compact(size() - 1); + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + return true; + } + + // Merge this block with its contiguous neighbors (if any) + // Note: Merge is not performed if resulting block size would exceed + // MAXINT + private void compact(int index) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { index })); } + + MemoryBlock newBlock = get(index); + + // Case where the block is to be merged with the previous block + if (index > 0) { + MemoryBlock prevBlock = get(index - 1); + IAddress endOfPreviousBlock = prevBlock.fAddress.add(prevBlock.fLength); + if (endOfPreviousBlock.distanceTo(newBlock.fAddress).longValue() == 0) { + long newLength = prevBlock.fLength + newBlock.fLength; + if (newLength <= Integer.MAX_VALUE) { + MemoryByte[] block = new MemoryByte[(int) newLength]; + System.arraycopy(prevBlock.fBlock, 0, block, 0, (int) prevBlock.fLength); + System.arraycopy(newBlock.fBlock, 0, block, (int) prevBlock.fLength, (int) newBlock.fLength); + newBlock = new MemoryBlock(prevBlock.fAddress, newLength, block); + remove(index); + index -= 1; + set(index, newBlock); + } + } + } + + // Case where the block is to be merged with the following block + int lastIndex = size() - 1; + if (index < lastIndex) { + MemoryBlock nextBlock = get(index + 1); + IAddress endOfNewBlock = newBlock.fAddress.add(newBlock.fLength); + if (endOfNewBlock.distanceTo(nextBlock.fAddress).longValue() == 0) { + long newLength = newBlock.fLength + nextBlock.fLength; + if (newLength <= Integer.MAX_VALUE) { + MemoryByte[] block = new MemoryByte[(int) newLength]; + System.arraycopy(newBlock.fBlock, 0, block, 0, (int) newBlock.fLength); + System.arraycopy(nextBlock.fBlock, 0, block, (int) newBlock.fLength, (int) nextBlock.fLength); + newBlock = new MemoryBlock(newBlock.fAddress, newLength, block); + set(index, newBlock); + remove(index + 1); + } + } + } + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + } + + /** + * Refreshes cache blocks when memory has been changed through an event. + * + * @param tcfMemoryService + * @param context + * @param address + * @param offset + * @param word_size + * @param count + * @param rm + * @param timeOutLimit + * @return true = cache has been modified + */ + public boolean refreshMemory(IMemory tcfMemoryService, IMemoryDMContext context, IAddress address, int offset, + int word_size, int count, RequestMonitor rm, long timeOutLimit) { + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { context, address.toHexAddressString(), offset, count })); } + + boolean modified = false; + // Check if we already cache part of this memory area (which means it + // is used by a memory service client that will have to be updated) + LinkedList list = getListOfMissingBlocks(address, count); + int sizeToRead = 0; + for (MemoryBlock block : list) { + sizeToRead += block.fLength; + } + + // If none of the requested memory is in cache, just get out + if (sizeToRead == count) { + rm.done(); + return false; + } + + try { + MemoryByte[] newBlock = readBlock(tcfMemoryService, context, address, word_size, count, timeOutLimit); + MemoryByte[] oldBlock = getMemoryBlockFromCache(address, count); + boolean blocksDiffer = false; + for (int i = 0; i < oldBlock.length; i++) { + if (oldBlock[i].getValue() != newBlock[i].getValue()) { + blocksDiffer = true; + break; + } + } + if (blocksDiffer) { + updateMemoryCache(address, count, newBlock); + modified = true; + } + } catch (Exception e) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Error Writing Memory", e)); //$NON-NLS-1$ + } + rm.done(); + + if (EDCTrace.MEMORY_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + return modified; + } + + private static final String MEMORY_CACHE = "memory_cache"; + private static final String MEMORY_BLOCK = "memory_block"; + private static final String ATTR_ADDRESS = "address"; + private static final String ATTR_LENGTH = "length"; + private static final String ATTR_VALUE = "value"; + + public void loadSnapshot(Element element) throws Exception { + reset(); + NodeList blockElements = element.getElementsByTagName(MEMORY_BLOCK); + + int numBlocks = blockElements.getLength(); + for (int i = 0; i < numBlocks; i++) { + Element blockElement = (Element) blockElements.item(i); + String blockAddress = blockElement.getAttribute(ATTR_ADDRESS); + String blockLength = blockElement.getAttribute(ATTR_LENGTH); + String blockValue = blockElement.getAttribute(ATTR_VALUE); + MemoryByte[] blockBytes = MemoryUtils.convertHexStringToMemoryBytes(blockValue, blockValue.length() / 2, 2); + MemoryBlock newBlock = new MemoryBlock(new Addr64(blockAddress), Long.parseLong(blockLength), blockBytes); + memoryBlockList.add(newBlock); + } + } + + public Element takeSnapshot(IAlbum album, Document document, IProgressMonitor monitor) { + synchronized (memoryBlockList) + { + SubMonitor progress = SubMonitor.convert(monitor, memoryBlockList.size()); + progress.subTask("Memory"); + Element memoryCacheElement = document.createElement(MEMORY_CACHE); + ListIterator iter = memoryBlockList.listIterator(); + + while (iter.hasNext()) { + MemoryBlock block = iter.next(); + Element blockElement = document.createElement(MEMORY_BLOCK); + blockElement.setAttribute(ATTR_ADDRESS, block.fAddress.toHexAddressString()); + blockElement.setAttribute(ATTR_LENGTH, Long.toString(block.fLength)); + blockElement.setAttribute(ATTR_VALUE, MemoryUtils.convertMemoryBytesToHexString(block.fBlock)); + memoryCacheElement.appendChild(blockElement); + progress.worked(1); + } + return memoryCacheElement; + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Modules.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Modules.java new file mode 100644 index 0000000..0068959 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Modules.java @@ -0,0 +1,1188 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.io.Serializable; +import java.math.BigInteger; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.internal.PathUtils; +import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC; +import org.eclipse.cdt.debug.edc.internal.snapshot.SnapshotUtils; +import org.eclipse.cdt.debug.edc.internal.symbols.IRuntimeSection; +import org.eclipse.cdt.debug.edc.internal.symbols.ISection; +import org.eclipse.cdt.debug.edc.internal.symbols.RuntimeSection; +import org.eclipse.cdt.debug.edc.internal.symbols.Section; +import org.eclipse.cdt.debug.edc.internal.symbols.files.ExecutableSymbolicsReaderFactory; +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.debug.edc.services.DMContext; +import org.eclipse.cdt.debug.edc.services.IEDCDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC; +import org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCModules; +import org.eclipse.cdt.debug.edc.snapshot.IAlbum; +import org.eclipse.cdt.debug.edc.snapshot.ISnapshotContributor; +import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader; +import org.eclipse.cdt.debug.edc.symbols.ILineEntryProvider.ILineAddresses; +import org.eclipse.cdt.debug.edc.tcf.extension.ProtocolConstants.IModuleProperty; +import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.debug.service.IModules; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +public class Modules extends AbstractEDCService implements IModules, IEDCModules { + + public static final String MODULE = "module"; + public static final String SECTION = "section"; + + private static final String ADDRESS_RANGE_CACHE = "_address_range"; + private static final String LINE_ADDRESSES_CACHE = "_line_addresses"; + private static final String NO_FILE_CACHE = "_no_file"; + + /** + * Modules that are loaded for each ISymbolDMContext (process). + */ + private final Map> modules = Collections + .synchronizedMap(new HashMap>()); + + private ISourceLocator sourceLocator; + private static int nextModuleID = 100; + + public static class EDCAddressRange implements AddressRange, Serializable { + + private static final long serialVersionUID = -6475152211053407789L; + private IAddress startAddr, endAddr; + + public EDCAddressRange(IAddress start, IAddress end) { + startAddr = start; + endAddr = end; + } + + public IAddress getEndAddress() { + return endAddr; + } + + public void setEndAddress(IAddress address) { + endAddr = address; + } + + public IAddress getStartAddress() { + return startAddr; + } + + public void setStartAddress(IAddress address) { + startAddr = address; + } + + @Override + public String toString() { + return MessageFormat.format("[{0},{1})", startAddr.toHexAddressString(), endAddr.toHexAddressString()); + } + + public boolean contains(IAddress address) { + return getStartAddress().compareTo(address) <= 0 + && getEndAddress().compareTo(address) > 0; + } + } + + public static class EDCLineAddresses implements ILineAddresses, Serializable { + + private static final long serialVersionUID = 3263812332106024057L; + + private int lineNumber; + private List addresses; + + public EDCLineAddresses(int lineNumber, IAddress addr) { + super(); + this.lineNumber = lineNumber; + addresses = new ArrayList(); + addresses.add(addr); + } + + public EDCLineAddresses(int lineNumber, List addrs) { + super(); + this.lineNumber = lineNumber; + addresses = new ArrayList(addrs); + } + + public int getLineNumber() { + return lineNumber; + } + + public IAddress[] getAddress() { + return addresses.toArray(new IAddress[addresses.size()]); + } + + /** + * add addresses mapped to the line. + * @param addr + */ + public void addAddress(List addrs) { + addresses.addAll(addrs); + } + + /** + * add addresses mapped to the line. + * @param addrs + */ + public void addAddress(IAddress[] addrs) { + for (IAddress a : addrs) + addresses.add(a); + } + + @Override + public String toString() { + String addrs = ""; + for (IAddress a : addresses) { + addrs += a.toHexAddressString() + " "; + } + return "EDCLineAddresses [lineNumber=" + lineNumber + + ", addresses=(" + addrs + ")]"; + } + } + + public class ModuleDMC extends DMContext implements IEDCModuleDMContext, ISnapshotContributor, + // This means we'll install existing breakpoints + // for each newly loaded module + IBreakpointsTargetDMContext, + // This means calcAddressInfo() also applies to single module + // in addition to a process. + ISymbolDMContext { + private final ISymbolDMContext symbolContext; + + private final IPath hostFilePath; + private IEDCSymbolReader symReader; + private final List runtimeSections = new ArrayList(); + + public ModuleDMC(ISymbolDMContext symbolContext, Map props) { + super(Modules.this, symbolContext == null ? new IDMContext[0] : new IDMContext[] { symbolContext }, Integer + .toString(getNextModuleID()), props); + this.symbolContext = symbolContext; + + String filename = ""; + if (props.containsKey(IModuleProperty.PROP_FILE)) + filename = (String) props.get(IModuleProperty.PROP_FILE); + + hostFilePath = locateModuleFileOnHost(filename); + } + + public ISymbolDMContext getSymbolContext() { + return symbolContext; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext#getSymbolReader() + */ + public IEDCSymbolReader getSymbolReader() { + return symReader; + } + + public void loadSnapshot(Element element) throws Exception { + NodeList sectionElements = element.getElementsByTagName(SECTION); + + int numSections = sectionElements.getLength(); + for (int i = 0; i < numSections; i++) { + Element sectionElement = (Element) sectionElements.item(i); + Element propElement = (Element) sectionElement.getElementsByTagName(SnapshotUtils.PROPERTIES).item(0); + HashMap properties = new HashMap(); + SnapshotUtils.initializeFromXML(propElement, properties); + + IAddress linkAddress = new Addr64(sectionElement.getAttribute(ISection.PROPERTY_LINK_ADDRESS)); + int sectionID = Integer.parseInt(sectionElement.getAttribute(ISection.PROPERTY_ID)); + long size = Long.parseLong(sectionElement.getAttribute(ISection.PROPERTY_SIZE)); + + RuntimeSection section = new RuntimeSection(new Section(sectionID, size, linkAddress, properties)); + section.relocate(new Addr64(sectionElement.getAttribute(IRuntimeSection.PROPERTY_RUNTIME_ADDRESS))); + runtimeSections.add(section); + } + + initializeSymbolReader(); + } + + public Element takeSnapshot(IAlbum album, Document document, IProgressMonitor monitor) { + SubMonitor progress = SubMonitor.convert(monitor, runtimeSections.size() + 1); + progress.subTask("Modules"); + Element contextElement = document.createElement(MODULE); + contextElement.setAttribute(PROP_ID, this.getID()); + Element propsElement = SnapshotUtils.makeXMLFromProperties(document, getProperties()); + contextElement.appendChild(propsElement); + + for (IRuntimeSection s : runtimeSections) { + Element sectionElement = document.createElement(SECTION); + sectionElement.setAttribute(ISection.PROPERTY_ID, Integer.toString(s.getId())); + sectionElement.setAttribute(ISection.PROPERTY_SIZE, Long.toString(s.getSize())); + sectionElement.setAttribute(ISection.PROPERTY_LINK_ADDRESS, s.getLinkAddress().toHexAddressString()); + sectionElement.setAttribute(IRuntimeSection.PROPERTY_RUNTIME_ADDRESS, s.getRuntimeAddress() + .toHexAddressString()); + propsElement = SnapshotUtils.makeXMLFromProperties(document, s.getProperties()); + sectionElement.appendChild(propsElement); + contextElement.appendChild(sectionElement); + progress.worked(1); + } + + if (!hostFilePath.isEmpty()) { + album.addFile(hostFilePath); + IPath possibleSymFile = ExecutableSymbolicsReaderFactory.findSymbolicsFile(hostFilePath); + if (possibleSymFile != null) { + album.addFile(possibleSymFile); + } + } + progress.worked(1); + return contextElement; + } + + /** + * Relocate sections of the module. This should be called when the + * module is loaded.
    + *
    + * The relocation handling is target environment dependent. + * Implementation here has been tested for debug applications on + * Windows, Linux and Symbian.
    + * + * @param props + * - runtime section properties from OS or from loader. + */ + public void relocateSections(Map props) { + + initializeSymbolReader(); + + if (symReader != null) { + for (ISection section: symReader.getSections()) + { + runtimeSections.add(new RuntimeSection(section)); + } + } + + if (props.containsKey(IModuleProperty.PROP_IMAGE_BASE_ADDRESS)) { + // Windows module (PE file) + // + + Object base = props.get(IModuleProperty.PROP_IMAGE_BASE_ADDRESS); + IAddress imageBaseAddr = null; + if (base != null) { + if (base instanceof Integer) + imageBaseAddr = new Addr64(base.toString()); + else if (base instanceof Long) + imageBaseAddr = new Addr64(base.toString()); + else if (base instanceof String) // the string should be hex + // string + imageBaseAddr = new Addr64((String) base, 16); + else + EDCDebugger.getMessageLogger().logError( + MessageFormat.format("Module property PROP_ADDRESS has invalid format {0}.", base + .getClass()), null); + } + + Number size = 0; + if (props.containsKey(IModuleProperty.PROP_CODE_SIZE)) + size = (Number) props.get(IModuleProperty.PROP_CODE_SIZE); + + if (symReader != null) { + // relocate + // + IAddress linkBase = symReader.getBaseLinkAddress(); + if (linkBase != null && !linkBase.equals(imageBaseAddr)) { + BigInteger offset = linkBase.distanceTo(imageBaseAddr); + for (IRuntimeSection s : runtimeSections) { + IAddress runtimeB = s.getLinkAddress().add(offset); + s.relocate(runtimeB); + } + } + } else { // fill in fake section data + Map pp = new HashMap(); + pp.put(ISection.PROPERTY_NAME, ISection.NAME_TEXT); + runtimeSections.add(new RuntimeSection(new Section(0, size.longValue(), imageBaseAddr, pp))); + } + } else if (props.containsKey(IModuleProperty.PROP_CODE_ADDRESS)) { + // platforms other than Windows + // + Number codeAddr = null, dataAddr = null, bssAddr = null; + Number codeSize = null, dataSize = null, bssSize = null; + + try { + codeAddr = (Number) props.get(IModuleProperty.PROP_CODE_ADDRESS); + dataAddr = (Number) props.get(IModuleProperty.PROP_DATA_ADDRESS); + bssAddr = (Number) props.get(IModuleProperty.PROP_BSS_ADDRESS); + codeSize = (Number) props.get(IModuleProperty.PROP_CODE_SIZE); + dataSize = (Number) props.get(IModuleProperty.PROP_DATA_SIZE); + bssSize = (Number) props.get(IModuleProperty.PROP_BSS_SIZE); + } catch (ClassCastException e) { + EDCDebugger.getMessageLogger().logError("Module property value has invalid format.", null); + } + + if (symReader != null) { + // Relocate. + for (IRuntimeSection s : runtimeSections) { + if (s.getProperties().get(ISection.PROPERTY_NAME).equals(ISection.NAME_TEXT) + && codeAddr != null) + s.relocate(new Addr64(codeAddr.toString())); + else if (s.getProperties().get(ISection.PROPERTY_NAME).equals(ISection.NAME_DATA) + && dataAddr != null) + s.relocate(new Addr64(dataAddr.toString())); + else if (s.getProperties().get(ISection.PROPERTY_NAME).equals(ISection.NAME_BSS) + && bssAddr != null) + s.relocate(new Addr64(bssAddr.toString())); + } + } else { + // binary file not available. + // fill in our fake sections. If no section size available, + // don't bother. + // + Map pp = new HashMap(); + + if (codeAddr != null && codeSize != null) { + pp.put(ISection.PROPERTY_NAME, ISection.NAME_TEXT); + runtimeSections.add(new RuntimeSection(new Section(0, codeSize.intValue(), new Addr64(codeAddr.toString()), pp))); + } + if (dataAddr != null && dataSize != null) { + pp.clear(); + pp.put(ISection.PROPERTY_NAME, ISection.NAME_DATA); + runtimeSections.add(new RuntimeSection(new Section(0, dataSize.intValue(), new Addr64(dataAddr.toString()), pp))); + } + if (bssAddr != null && bssSize != null) { + pp.clear(); + pp.put(ISection.PROPERTY_NAME, ISection.NAME_BSS); + runtimeSections.add(new RuntimeSection(new Section(0, bssSize.intValue(), new Addr64(bssAddr.toString()), pp))); + } + } + } else { + // No runtime address info available from target environment. + // The runtime sections will just be the link-time sections. + // + // This works well for the case where no relocation is needed + // such as running the main executable (not DLLs nor shared + // libs) + // on Windows and Linux. + // + // However, this may also indicate an error that the debug agent + // (or even the target OS or loader) is not doing its job of + // telling us the runtime address info. + } + } + + private void initializeSymbolReader() { + if (hostFilePath.toFile().exists()) { + symReader = Symbols.getSymbolReader(hostFilePath); + if (symReader == null) + EDCDebugger.getMessageLogger().log(IStatus.WARNING, + MessageFormat.format("''{0}'' has no recognized file format.", + hostFilePath), null); + else if (! symReader.hasRecognizedDebugInformation()) { + // Log as INFO, not ERROR. + EDCDebugger.getMessageLogger().log(IStatus.INFO, + MessageFormat.format("''{0}'' has no recognized symbolics.", + hostFilePath), null); + } + } else { + // Binary file not on host. Do we want to prompt user for one ? + + // TODO: report this differently for the main executable vs. DLLs + EDCDebugger.getMessageLogger().log(IStatus.WARNING, MessageFormat + .format("Cannot debug ''{0}''; no match found on disk, through source lookup, or in Executables view", + hostFilePath), null); + + } + } + + /** + * Check if a given runtime address falls in this module + * + * @param absoluteAddr + * - absolute runtime address. + * @return + */ + public boolean containsAddress(IAddress runtimeAddress) { + for (IRuntimeSection s : runtimeSections) { + long offset = s.getRuntimeAddress().distanceTo(runtimeAddress).longValue(); + if (offset >= 0 && offset < s.getSize()) + return true; + } + + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext#toLinkAddress(org.eclipse.cdt.core.IAddress) + */ + public IAddress toLinkAddress(IAddress runtimeAddress) { + IAddress ret = null; + + for (IRuntimeSection s : runtimeSections) { + long offset = s.getRuntimeAddress().distanceTo(runtimeAddress).longValue(); + if (offset >= 0 && offset < s.getSize()) { + return s.getLinkAddress().add(offset); + } + } + + return ret; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCModuleDMContext#toRuntimeAddress(org.eclipse.cdt.core.IAddress) + */ + public IAddress toRuntimeAddress(IAddress linkAddress) { + IAddress ret = null; + + for (IRuntimeSection s : runtimeSections) { + long offset = s.getLinkAddress().distanceTo(linkAddress).longValue(); + if (offset >= 0 && offset < s.getSize()) { + return s.getRuntimeAddress().add(offset); + } + } + + return ret; + } + + /** + * Get file name (without path) of the module. + * + * @return + */ + public String getFile() { + return hostFilePath.lastSegment(); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("\nModuleDMC ["); + if (hostFilePath != null) { + builder.append("file="); + builder.append(hostFilePath.lastSegment()); + builder.append(", "); + } + + if (symbolContext != null) { + builder.append("owner="); + builder.append(symbolContext.toString()); + } + + for (IRuntimeSection s : runtimeSections) { + builder.append("\n"); + builder.append(s); + } + + builder.append("]"); + + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + getOuterType().hashCode(); + result = prime * result + ((hostFilePath == null) ? 0 : hostFilePath.hashCode()); + result = prime * result + ((symbolContext == null) ? 0 : symbolContext.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ModuleDMC other = (ModuleDMC) obj; + if (!getOuterType().equals(other.getOuterType())) + return false; + if (hostFilePath == null) { + if (other.hostFilePath != null) + return false; + } else if (!hostFilePath.equals(other.hostFilePath)) + return false; + if (symbolContext == null) { + if (other.symbolContext != null) + return false; + } else if (!symbolContext.equals(other.symbolContext)) + return false; + return true; + } + + private IEDCModules getOuterType() { + return Modules.this; + } + } + + static class ModuleDMData implements IModuleDMData { + + private final Map properties; + + public ModuleDMData(ModuleDMC dmc) { + properties = dmc.getProperties(); + } + + public String getFile() { + return (String) properties.get(IModuleProperty.PROP_FILE); + } + + public String getName() { + return (String) properties.get(IEDCDMContext.PROP_NAME); + } + + public long getTimeStamp() { + return 0; + // return (String) properties.get(IModuleProperty.PROP_TIME); + } + + public String getBaseAddress() { + // return hex string representation. + // + Object baseAddress = properties.get(IModuleProperty.PROP_IMAGE_BASE_ADDRESS); + if (baseAddress == null) + baseAddress = properties.get(IModuleProperty.PROP_CODE_ADDRESS); + + if (baseAddress != null) + return baseAddress.toString(); + else + return ""; + } + + public String getToAddress() { + // TODO this should return the end address, e.g. base + size + return getBaseAddress(); + } + + public boolean isSymbolsLoaded() { + return false; + } + + public long getSize() { + Number moduleSize = (Number) properties.get(IModuleProperty.PROP_CODE_SIZE); + if (moduleSize != null) + return moduleSize.longValue(); + else + return 0; + } + + } + + public static class ModuleLoadedEvent extends AbstractDMEvent implements ModuleLoadedDMEvent { + + private final ModuleDMC module; + private final IExecutionDMContext executionDMC; + + public ModuleLoadedEvent(ISymbolDMContext symbolContext, IExecutionDMContext executionDMC, ModuleDMC module) { + super(symbolContext); + this.module = module; + this.executionDMC = executionDMC; + } + + public IExecutionDMContext getExecutionDMC() { + return executionDMC; + } + + public IModuleDMContext getLoadedModuleContext() { + return module; + } + + } + + public static class ModuleUnloadedEvent extends AbstractDMEvent implements ModuleUnloadedDMEvent { + + private final ModuleDMC module; + private final IExecutionDMContext executionDMC; + + public ModuleUnloadedEvent(ISymbolDMContext symbolContext, IExecutionDMContext executionDMC, ModuleDMC module) { + super(symbolContext); + this.module = module; + this.executionDMC = executionDMC; + } + + public IExecutionDMContext getExecutionDMC() { + return executionDMC; + } + + public IModuleDMContext getUnloadedModuleContext() { + return module; + } + + } + + public Modules(DsfSession session) { + super(session, new String[] { IModules.class.getName(), IEDCModules.class.getName(), Modules.class.getName() }); + } + + public void setSourceLocator(ISourceLocator sourceLocator) { + this.sourceLocator = sourceLocator; + } + + public ISourceLocator getSourceLocator() { + return sourceLocator; + } + + private void addModule(ModuleDMC module) { + ISymbolDMContext symContext = module.getSymbolContext(); + if (symContext instanceof IEDCDMContext) { + String symContextID = ((IEDCDMContext) symContext).getID(); + synchronized (modules) { + List moduleList = modules.get(symContextID); + if (moduleList == null) { + moduleList = Collections.synchronizedList(new ArrayList()); + modules.put(symContextID, moduleList); + } + moduleList.add(module); + } + } + } + + private void removeModule(ModuleDMC module) { + ISymbolDMContext symContext = module.getSymbolContext(); + if (symContext instanceof IEDCDMContext) { + String symContextID = ((IEDCDMContext) symContext).getID(); + synchronized (modules) { + List moduleList = modules.get(symContextID); + if (moduleList != null) { + // other module attributes may not be passed during removal, + // so remove the module with the same name + for (ModuleDMC next : moduleList) { + if (next.getFile().equals(module.getFile())) { + moduleList.remove(next); + break; + } + } + } + } + } + + } + + /* + * The result AddressRange[] will contain absolute runtime addresses. And + * the "symCtx" can be a process or a module. + */ + @SuppressWarnings("unchecked") + public void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, + DataRequestMonitor rm) { + IModuleDMContext[] moduleList = null; + + if (symCtx instanceof IEDCExecutionDMC) { + String symContextID = ((IEDCDMContext) symCtx).getID(); + moduleList = getModulesForContext(symContextID); + } else if (symCtx instanceof IModuleDMContext) { + moduleList = new IModuleDMContext[1]; + moduleList[0] = (IModuleDMContext) symCtx; + } else { + // should not happen + assert false : "Unknown ISymbolDMContext class."; + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, MessageFormat.format( + "Unknown class implementing ISymbolDMContext : {0}", symCtx.getClass().getName()), null)); + rm.done(); + return; + } + + List addrRanges = new ArrayList(1); + + for (IModuleDMContext module : moduleList) { + ModuleDMC mdmc = (ModuleDMC) module; + IEDCSymbolReader reader = mdmc.getSymbolReader(); + + if (reader != null) { + + Collection linkAddressRanges = null; + Map> cachedRanges = new HashMap>(); + // Check the persistent cache + String cacheKey = reader.getSymbolFile().toOSString() + ADDRESS_RANGE_CACHE; + String noFileCacheKey = reader.getSymbolFile().toOSString() + NO_FILE_CACHE; + Set noFileCachedData = EDCDebugger.getDefault().getCache().getCachedData(noFileCacheKey, Set.class, reader.getModificationDate()); + if (noFileCachedData != null && noFileCachedData.contains(file)) + continue; // We have already determined that this file is not used by this module, don't bother checking again. + + Map> cachedData = EDCDebugger.getDefault().getCache().getCachedData(cacheKey, Map.class, reader.getModificationDate()); + if (cachedData != null) + { + cachedRanges = cachedData; + linkAddressRanges = cachedRanges.get(file + line); + } + + if (linkAddressRanges == null) + { + linkAddressRanges = LineEntryMapper.getAddressRangesAtSource( + reader.getModuleScope().getModuleLineEntryProvider(), + PathUtils.createPath(file), + line); + + if (linkAddressRanges == null) + { // If this file is not used by this module, cache it so we can avoid searching it again. + if (noFileCachedData == null) + noFileCachedData = new HashSet(); + noFileCachedData.add(file); + EDCDebugger.getDefault().getCache().putCachedData(noFileCacheKey, (Serializable) noFileCachedData, reader.getModificationDate()); + continue; + } + cachedRanges.put(file + line, linkAddressRanges); + EDCDebugger.getDefault().getCache().putCachedData(cacheKey, (Serializable) cachedRanges, reader.getModificationDate()); + } + + // convert addresses to runtime ones. + for (AddressRange linkAddressRange : linkAddressRanges) { + EDCAddressRange addrRange = new EDCAddressRange( + mdmc.toRuntimeAddress(linkAddressRange.getStartAddress()), + mdmc.toRuntimeAddress(linkAddressRange.getEndAddress())); + addrRanges.add(addrRange); + } + } + } + + if (addrRanges.size() > 0) { + AddressRange[] ar = addrRanges.toArray(new AddressRange[addrRanges.size()]); + rm.setData(ar); + } else { + /* + * we try to set the breakpoint for every module since we don't know + * which one the file is in. we report this error though if the file + * isn't in the module, and let the caller handle the error. + */ + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, MessageFormat.format( + "Fail to find address for source line {0}: line# {1}", file, line), null)); + } + + rm.done(); + } + + public void calcLineInfo(ISymbolDMContext symCtx, IAddress address, DataRequestMonitor rm) { + // TODO Auto-generated method stub + + } + + /** + * Given a source line (let's call it anchor), find the line closest to the + * anchor in the neighborhood (including the anchor itself) that has machine + * code. If the anchor itself has code, it's returned. Otherwise neighbor + * lines both above and below the anchor will be checked. If the closest + * line above the anchor and the closest line below the anchor have the same + * distance from the anchor, the one below will be selected. + * + * This is mainly used in setting breakpoint at anchor line. + * + * @param symCtx + * the symbol context in which to perform the lookup. It can be + * an execution context (e.g. a process), or a module (exe or + * dll) in a process. + * @param file + * the file that contains the source lines in question. + * @param anchor + * line number of the anchor source line. + * @param neighbor_limit + * specify the limit of the neighborhood: up to this number of + * lines above the anchor and up to this number of lines below + * the anchor will be checked if needed. But the check will never + * go beyond the source file. When the limit is zero, no neighbor + * lines will be checked. If the limit has value of -1, it means + * the actual limit is the source file. + * @param rm + * contains an object of {@link ILineAddresses} if the line with + * code is found. And addresses in it are runtime addresses. The + * RM will contain error status otherwise. + */ + public void findClosestLineWithCode(ISymbolDMContext symCtx, String file, int anchor, int neighbor_limit, + DataRequestMonitor rm) { + IModuleDMContext[] moduleList = null; + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, + "Find closest line with code. context: " + EDCTrace.fixArg(symCtx) + " file: " + file + " anchor: " + anchor + " limit: " + neighbor_limit); } + + if (symCtx instanceof IEDCExecutionDMC) { + String symContextID = ((IEDCDMContext) symCtx).getID(); + moduleList = getModulesForContext(symContextID); + } else if (symCtx instanceof IModuleDMContext) { + moduleList = new IModuleDMContext[1]; + moduleList[0] = (IModuleDMContext) symCtx; + } else { + // should not happen + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, MessageFormat.format( + "Unknown class implementing ISymbolDMContext : {0}", symCtx.getClass().getName()), null)); + rm.done(); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().traceExit(null, + rm.getStatus()); } + return; + } + + EDCLineAddresses result = null; + + for (IModuleDMContext module : moduleList) { + ModuleDMC mdmc = (ModuleDMC) module; + IEDCSymbolReader reader = mdmc.getSymbolReader(); + + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, + "module: " + mdmc + " reader: " + reader); } + + if (reader == null) + continue; + + List codeLines = null; + + Map> cache = new HashMap>(); + // Check the persistent cache + String cacheKey = reader.getSymbolFile().toOSString() + LINE_ADDRESSES_CACHE; + String noFileCacheKey = reader.getSymbolFile().toOSString() + NO_FILE_CACHE; + @SuppressWarnings("unchecked") + Set noFileCachedData = EDCDebugger.getDefault().getCache().getCachedData(noFileCacheKey, Set.class, reader.getModificationDate()); + if (noFileCachedData != null && noFileCachedData.contains(file)) + { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, + "Persistent cache says file not used by module"); } + continue; // We have already determined that this file is not used by this module, don't bother checking again. + } + + @SuppressWarnings("unchecked") + Map> cachedData = EDCDebugger.getDefault().getCache().getCachedData(cacheKey, Map.class, reader.getModificationDate()); + if (cachedData != null) + { + cache = cachedData; + codeLines = cachedData.get(file + anchor); + } + + if (codeLines == null) // cache missed + { + if (! reader.getModuleScope().getModuleLineEntryProvider().hasSourceFile(PathUtils.createPath(file))) + { // If this file is not used by this module, cache it so we can avoid searching it again. + if (noFileCachedData == null) + noFileCachedData = new HashSet(); + noFileCachedData.add(file); + EDCDebugger.getDefault().getCache().putCachedData(noFileCacheKey, (Serializable) noFileCachedData, reader.getModificationDate()); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, + "File not used by module"); } + continue; + } + + codeLines = reader.getModuleScope().getModuleLineEntryProvider().findClosestLineWithCode( + PathUtils.createPath(file), anchor, neighbor_limit); + + if (codeLines == null) + { + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, + "codeLines == null"); } + continue; // should not happen + } + + // Cache code lines (with their link addresses), whether we find it or not. + cache.put(file + anchor, codeLines); + EDCDebugger.getDefault().getCache().putCachedData(cacheKey, (Serializable) cache, reader.getModificationDate()); + if (EDCTrace.BREAKPOINTS_TRACE_ON) { EDCTrace.getTrace().trace(null, + "codeLines: " + codeLines); } + } + + // convert addresses to runtime ones. + // + List runtimeCLs = new ArrayList(codeLines.size()); + for (ILineAddresses cl : codeLines) { + List rt_addrs = new ArrayList(1); + for (IAddress a : cl.getAddress()) + rt_addrs.add(mdmc.toRuntimeAddress(a)); + runtimeCLs.add(new EDCLineAddresses(cl.getLineNumber(), rt_addrs)); + } + + for (ILineAddresses l : runtimeCLs) + result = selectCodeLine(result, l, anchor); + } + + if (result != null) { + rm.setData(result); + } else { + /* + * we try to set the breakpoint for every module since we don't know + * which one the file is in. we report this error though if the file + * isn't in the module, and let the caller handle the error. + */ + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, MessageFormat.format( + "Fail to find address sround source line {0}: line# {1}", file, anchor), null)); + } + + rm.done(); + } + + private EDCLineAddresses selectCodeLine(EDCLineAddresses prevChoice, + ILineAddresses newLine, int anchor) { + + if (prevChoice == null) + prevChoice = (EDCLineAddresses)newLine; + else { + if (newLine.getLineNumber() == prevChoice.getLineNumber()) { + // merge the addresses. Same source line has different addresses in different module. + prevChoice.addAddress(newLine.getAddress()); + } + else { + // code line is different for the anchor in different module + if (newLine.getLineNumber() == anchor) + // always honor anchor itself + prevChoice = (EDCLineAddresses)newLine; + else if (prevChoice.getLineNumber() != anchor) { + /* + * Two different code lines are found (from different + * modules or different CUs) and neither of them is anchor. + * Don't bother returning both of them as that would cause + * unnecessary complexity to breakpoint setting as it means + * moving breakpoint set on anchor line to two different + * lines. Just keep the one closer to anchor. And user will + * see the breakpoint works in one module (or CU) but not + * the other. + */ + int new_distance = Math.abs(newLine.getLineNumber() - anchor); + int prev_distance = Math.abs(prevChoice.getLineNumber() - anchor); + + if (new_distance < prev_distance) + prevChoice = (EDCLineAddresses)newLine; + else if (new_distance == prev_distance) { + // Same distance from anchor, choose the one below anchor + if (newLine.getLineNumber() > prevChoice.getLineNumber()) + prevChoice = (EDCLineAddresses)newLine; + } + } + } + } + + return prevChoice; + } + + /** + * Get runtime addresses mapped to given source line in given run context. + * + * @param context + * @param sourceFile + * @param lineNumber + * @param drm If no address found, holds an empty list. + */ + public void getLineAddress(IExecutionDMContext context, + String sourceFile, int lineNumber, final DataRequestMonitor> drm) { + final List addrs = new ArrayList(1); + + final ExecutionDMC dmc = (ExecutionDMC) context; + if (dmc == null) { + drm.setData(addrs); + drm.done(); + return; + } + + ISymbolDMContext symCtx = DMContexts.getAncestorOfType(context, ISymbolDMContext.class); + + sourceFile = EDCLaunch.getLaunchForSession(getSession().getId()).getCompilationPath(sourceFile); + + calcAddressInfo(symCtx, sourceFile, lineNumber, 0, + new DataRequestMonitor(getExecutor(), drm) { + + @Override + protected void handleCompleted() { + if (! isSuccess()) { + drm.setStatus(getStatus()); + drm.done(); + return; + } + + AddressRange[] addr_ranges = getData(); + + for (AddressRange range : addr_ranges) { + IAddress a = range.getStartAddress(); // this is runtime address + addrs.add(a); + } + + drm.setData(addrs); + drm.done(); + } + }); + } + + public void getModuleData(IModuleDMContext dmc, DataRequestMonitor rm) { + rm.setData(new ModuleDMData((ModuleDMC) dmc)); + rm.done(); + } + + public void getModules(ISymbolDMContext symCtx, DataRequestMonitor rm) { + String symContextID = ((IEDCDMContext) symCtx).getID(); + IModuleDMContext[] moduleList = getModulesForContext(symContextID); + rm.setData(moduleList); + rm.done(); + } + + public IModuleDMContext[] getModulesForContext(String symContextID) { + synchronized (modules) { + List moduleList = modules.get(symContextID); + if (moduleList == null) + return new IModuleDMContext[0]; + else + return moduleList.toArray(new IModuleDMContext[moduleList.size()]); + } + } + + private int getNextModuleID() { + return nextModuleID++; + } + + public void moduleLoaded(ISymbolDMContext symbolContext, IExecutionDMContext executionDMC, Map moduleProps) { + ModuleDMC module = new ModuleDMC(symbolContext, moduleProps); + module.relocateSections(moduleProps); + addModule(module); + getSession().dispatchEvent(new ModuleLoadedEvent(symbolContext, executionDMC, module), + Modules.this.getProperties()); + } + + public void moduleUnloaded(ISymbolDMContext symbolContext, IExecutionDMContext executionDMC, + Map moduleProps) { + Object fileName = moduleProps.get(IEDCDMContext.PROP_NAME); + ModuleDMC module = getModuleByName(symbolContext, fileName); + if (module == null) { + EDCDebugger.getMessageLogger().logError("Unexpected unload of module: " + fileName, null); + return; + } + Object requireResumeValue = moduleProps.get("RequireResume"); + if (requireResumeValue != null && requireResumeValue instanceof Boolean) + module.setProperty("RequireResume", requireResumeValue); + removeModule(module); + getSession().dispatchEvent(new ModuleUnloadedEvent(symbolContext, executionDMC, module), + Modules.this.getProperties()); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCModules#getModuleByAddress(org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext, org.eclipse.cdt.core.IAddress) + */ + public ModuleDMC getModuleByAddress(ISymbolDMContext symCtx, IAddress instructionAddress) { + ModuleDMC bestMatch = null; + if (symCtx instanceof ModuleDMC) { + if (((ModuleDMC)symCtx).containsAddress(instructionAddress)) + bestMatch = (ModuleDMC)symCtx; + } + else { + synchronized (modules) { + List moduleList = modules.get(((IEDCDMContext) symCtx).getID()); + if (moduleList != null) { + for (ModuleDMC moduleDMC : moduleList) { + if (moduleDMC.containsAddress(instructionAddress)) { + bestMatch = moduleDMC; + break; + } + } + + if (bestMatch == null) { + // TODO: add a bogus wrap-all module ? + } + } + } + } + return bestMatch; + } + + /** + * Find the host file that corresponds to a given module file whose name + * comes from target platform. + * + * @param originalPath + * path or filename from target platform. + * @return the path to an existing file on host, null otherwise. + */ + public IPath locateModuleFileOnHost(String originalPath) { + if (originalPath == null || originalPath.length() == 0) + return Path.EMPTY; + + // Canonicalize path for the host OS, in hopes of finding a match directly on the host, + // and for searching sources and executables below. + // + IPath path = PathUtils.findExistingPathIfCaseSensitive(PathUtils.createPath(originalPath)); + + // Try source locator, use the host-correct path. + // + Object sourceElement = null; + ISourceLocator locator = getSourceLocator(); + if (locator != null) { + if (locator instanceof ICSourceLocator || locator instanceof CSourceLookupDirector) { + if (locator instanceof ICSourceLocator) + sourceElement = ((ICSourceLocator) locator).findSourceElement(path.toOSString()); + else + sourceElement = ((CSourceLookupDirector) locator).getSourceElement(path.toOSString()); + } + if (sourceElement != null) { + if (sourceElement instanceof LocalFileStorage) { + return new Path(((LocalFileStorage) sourceElement).getFile().getAbsolutePath()); + } + } + } + + return path; + } + + public void loadModulesForContext(ISymbolDMContext context, Element element) throws Exception { + + List contextModules = Collections.synchronizedList(new ArrayList()); + + NodeList moduleElements = element.getElementsByTagName(MODULE); + + int numModules = moduleElements.getLength(); + for (int i = 0; i < numModules; i++) { + Element moduleElement = (Element) moduleElements.item(i); + Element propElement = (Element) moduleElement.getElementsByTagName(SnapshotUtils.PROPERTIES).item(0); + HashMap properties = new HashMap(); + SnapshotUtils.initializeFromXML(propElement, properties); + + ModuleDMC module = new ModuleDMC(context, properties); + module.loadSnapshot(moduleElement); + contextModules.add(module); + + } + modules.put(((IEDCDMContext) context).getID(), contextModules); + + } + + /** + * get module with given file name + * + * @param symCtx + * @param fileName + * executable name for module + * @return null if not found. + */ + public ModuleDMC getModuleByName(ISymbolDMContext symCtx, Object fileName) { + ModuleDMC module = null; + synchronized (modules) { + List moduleList = modules.get(((IEDCDMContext) symCtx).getID()); + if (moduleList != null) { + for (ModuleDMC moduleDMC : moduleList) { + if ((moduleDMC.getName().compareToIgnoreCase((String) fileName)) == 0 ) { + module = moduleDMC; + break; + } + } + } + } + return module; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Noop.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Noop.java new file mode 100644 index 0000000..2c6fc0b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Noop.java @@ -0,0 +1,64 @@ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.Status; + +/** + * Implementation of the no-op service used for testing + * + */ +public class Noop extends AbstractEDCService implements INoop { + + public Noop(DsfSession session) { + super(session, new String[] {INoop.class.getName()}); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.INoop#noop(org.eclipse.cdt.dsf.datamodel.IDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + public void noop(IDMContext ctx, DataRequestMonitor rm) { + rm.setData(true); + rm.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.INoop#longNoop(org.eclipse.cdt.dsf.datamodel.IDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) + */ + public void longNoop(IDMContext whatever, final DataRequestMonitor rm) { + new Thread() { + public void run() { + try { + for (int i = 0; i < 100; i++) { + Thread.sleep(100); + if (rm.isCanceled()) { + rm.setStatus(Status.CANCEL_STATUS); + rm.done(); + return; + } + } + } catch (InterruptedException e) {} + rm.setData(true); + rm.done(); + } + }.start(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.INoop#longNoopUsingServiceTracker(int, org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + public void longNoopUsingServiceTracker(int duration, RequestMonitor rm) { + for (int i = 0; i < duration; i++) { + // ask for any service; our own is fine + getService(INoop.class); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + return; + } + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Processes.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Processes.java new file mode 100644 index 0000000..4137a1c --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Processes.java @@ -0,0 +1,303 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC; +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.debug.edc.services.IDSFServiceUsingTCF; +import org.eclipse.cdt.debug.edc.services.IEDCDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC; +import org.eclipse.cdt.debug.edc.tcf.extension.ProtocolConstants; +import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator2; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.debug.service.IModules; +import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMContext; +import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.cdt.dsf.debug.service.command.IEventListener; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.tm.tcf.protocol.IService; +import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.protocol.Protocol; +import org.eclipse.tm.tcf.services.IProcesses.ProcessContext; + +public class Processes extends AbstractEDCService implements IProcesses, IEventListener, IDSFServiceUsingTCF { + + private org.eclipse.tm.tcf.services.IProcesses tcfProcessesService; + + /* + * The data of a corresponding thread or process. + */ + @Immutable + protected static class ExecutionDMData implements IThreadDMData { + String name = "unknown"; + String id = "unknown"; + + public ExecutionDMData(ExecutionDMC dmc) { + id = dmc.getProperty(ProtocolConstants.PROP_OS_ID).toString(); + name = (String) dmc.getProperty(IEDCDMContext.PROP_NAME); + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public boolean isDebuggerAttached() { + return true; + } + } + + public Processes(DsfSession session) { + super(session, new String[] { IProcesses.class.getName(), Processes.class.getName() }); + } + + @Override + protected void doInitialize(RequestMonitor requestMonitor) { + super.doInitialize(requestMonitor); + getSession().addServiceEventListener(this, null); + } + + public void attachDebuggerToProcess(IProcessDMContext procCtx, DataRequestMonitor rm) { + rm.done(); + } + + public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor rm) { + ExecutionDMC edcDMC = (ExecutionDMC) dmc; + rm.setData(edcDMC.canDetach()); + rm.done(); + } + + public void canTerminate(IThreadDMContext thread, DataRequestMonitor rm) { + ExecutionDMC executionDmc = (ExecutionDMC) thread; + rm.setData(executionDmc.canTerminate()); + rm.done(); + } + + public void debugNewProcess(IDMContext dmc, String file, Map attributes, + DataRequestMonitor rm) { + rm.done(); + } + + /** + * Detach debugger from all processes in the debug session. + * @param rm + */ + public void detachDebuggerFromSession(final RequestMonitor rm) { + RunControl rcService = getServicesTracker().getService(RunControl.class); + ExecutionDMC[] processes = rcService.getRootDMC().getChildren(); + + CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm); + + crm.setDoneCount(processes.length); + + for (ExecutionDMC p : processes) + detachDebuggerFromProcess(p, crm); + } + + public void detachDebuggerFromProcess(final IDMContext exeDmc, final RequestMonitor rm) { + /* + * 1. Remove all breakpoints for all modules in the process. + * 2. Resume the process. + * 3. Detach the process from agent and host debugger. + */ + + // Make sure detach from the process, not just a thread. + final IProcessDMContext dmc = DMContexts.getAncestorOfType(exeDmc, IProcessDMContext.class); + + final BreakpointsMediator2 bmService = getServicesTracker().getService(BreakpointsMediator2.class); + if (bmService == null) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Failed to get BreakpointsMediator2 service.")); + rm.done(); + return; + } + IModules modulesService = getServicesTracker().getService(IModules.class); + if (modulesService == null) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Failed to get Modules service.")); + rm.done(); + return; + } + + ISymbolDMContext symCtx = DMContexts.getAncestorOfType(dmc, ISymbolDMContext.class); + modulesService.getModules(symCtx, new DataRequestMonitor(getExecutor(), rm) { + + @Override + protected void handleCompleted() { + if (! isSuccess()) + super.handleCompleted(); + else { + IModuleDMContext[] processModules = getData(); + + CountingRequestMonitor bpRemovedCRM = new CountingRequestMonitor(getExecutor(), rm) { + + @Override + protected void handleCompleted() { + if (! isSuccess()) { + super.handleCompleted(); + return; + } + + // Now resume the process + ((ExecutionDMC)dmc).resume(new RequestMonitor(getExecutor(), rm){ + + @Override + protected void handleCompleted() { + if (!isSuccess()) + super.handleCompleted(); + else { + doDetachDebugger((ExecutionDMC)dmc, rm); + } + } + }); + } + }; + + int bpTargetsDMCCnt = 0; + for (IModuleDMContext m : processModules) { + if (m instanceof IBreakpointsTargetDMContext) { + // In EDC, each Module is a BpTargetsDMC. + bpTargetsDMCCnt++; + bmService.stopTrackingBreakpoints((IBreakpointsTargetDMContext)m, bpRemovedCRM); + } + } + assert bpTargetsDMCCnt > 0; + + bpRemovedCRM.setDoneCount(bpTargetsDMCCnt); + } + }}); + } + + /** + * ask debugger to do final detach: forget the process. + * + * @param dmc + * @param rm + */ + protected void doDetachDebugger(final ExecutionDMC dmc, final RequestMonitor rm) { + // First detach agent so that the program won't die when the agent dies. + // Then detach host debugger. + // + Protocol.invokeLater(new Runnable() { + + public void run() { + tcfProcessesService.getContext(dmc.getID(), new org.eclipse.tm.tcf.services.IProcesses.DoneGetContext() { + + public void doneGetContext(IToken token, Exception error, + ProcessContext context) { + if (error != null) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Fail to get TCF context for process: " + dmc.getID(), error)); + rm.done(); + } + else { + context.detach(new org.eclipse.tm.tcf.services.IProcesses.DoneCommand() { + + public void doneCommand(IToken token, Exception error) { + if (error != null) + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Fail to detach process \"" + dmc.getID() + "\" from TCF agent.", error)); + else { + // everything ok, now detach from host debugger, + // which will shutdown the debug session if the process + // is the last one. + dmc.detach(); + } + rm.done(); + } + }); + } + } + }); + + }}); + } + + public void getDebuggingContext(IThreadDMContext dmc, DataRequestMonitor rm) { + rm.done(); + } + + public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof IEDCExecutionDMC) + rm.setData(new ExecutionDMData((ExecutionDMC) dmc)); + rm.done(); + } + + public void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor rm) { + rm.setData(new IDMContext[0]); + DsfServicesTracker tracker = getServicesTracker(); + if (tracker != null) { + RunControl runcontrol = tracker.getService(RunControl.class); + if (runcontrol != null) { + IDMContext[] processes = runcontrol.getRootDMC().getChildren(); + rm.setData(processes); + } + } + rm.done(); + } + + public void getRunningProcesses(IDMContext dmc, DataRequestMonitor rm) { + rm.done(); + } + + public void isDebugNewProcessSupported(IDMContext dmc, DataRequestMonitor rm) { + rm.done(); + } + + public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor rm) { + rm.done(); + } + + public void isRunNewProcessSupported(IDMContext dmc, DataRequestMonitor rm) { + rm.done(); + } + + public void runNewProcess(IDMContext dmc, String file, Map attributes, + DataRequestMonitor rm) { + rm.done(); + } + + public void terminate(IThreadDMContext thread, RequestMonitor requestMonitor) { + ExecutionDMC executionDmc = (ExecutionDMC) thread; + executionDmc.terminate(requestMonitor); + } + + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + rm.done(); + } + + // Event handler when a thread or a threadGroup exits + @DsfServiceEventHandler + public void eventDispatched(IExitedDMEvent e) { + } + + public void eventReceived(Object output) { + } + + public void tcfServiceReady(IService service) { + assert service instanceof org.eclipse.tm.tcf.services.IProcesses; + tcfProcessesService = (org.eclipse.tm.tcf.services.IProcesses) service; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/RunControl.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/RunControl.java new file mode 100644 index 0000000..aee60e1 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/RunControl.java @@ -0,0 +1,2761 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.nio.ByteBuffer; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.IAddressExpressionEvaluator; +import org.eclipse.cdt.debug.edc.IJumpToAddress; +import org.eclipse.cdt.debug.edc.JumpToAddress; +import org.eclipse.cdt.debug.edc.disassembler.IDisassembledInstruction; +import org.eclipse.cdt.debug.edc.disassembler.IDisassembler; +import org.eclipse.cdt.debug.edc.disassembler.IDisassembler.IDisassemblerOptions; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.internal.formatter.FormatExtensionManager; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Breakpoints.BreakpointDMData; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.EDCAddressRange; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.ModuleDMC; +import org.eclipse.cdt.debug.edc.internal.snapshot.Album; +import org.eclipse.cdt.debug.edc.internal.snapshot.SnapshotUtils; +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.debug.edc.services.DMContext; +import org.eclipse.cdt.debug.edc.services.Disassembly; +import org.eclipse.cdt.debug.edc.services.IDSFServiceUsingTCF; +import org.eclipse.cdt.debug.edc.services.IEDCDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC; +import org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCModules; +import org.eclipse.cdt.debug.edc.services.IEDCSymbols; +import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; +import org.eclipse.cdt.debug.edc.services.Registers; +import org.eclipse.cdt.debug.edc.services.Registers.RegisterDMC; +import org.eclipse.cdt.debug.edc.services.Registers.RegisterGroupDMC; +import org.eclipse.cdt.debug.edc.services.Stack; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.services.Stack.VariableDMC; +import org.eclipse.cdt.debug.edc.snapshot.IAlbum; +import org.eclipse.cdt.debug.edc.snapshot.ISnapshotContributor; +import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.IModuleLineEntryProvider; +import org.eclipse.cdt.debug.edc.tcf.extension.ProtocolConstants; +import org.eclipse.cdt.debug.edc.tcf.extension.ProtocolConstants.IModuleProperty; +import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.debug.service.ICachingService; +import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMContext; +import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; +import org.eclipse.cdt.dsf.debug.service.IRunControl; +import org.eclipse.cdt.dsf.debug.service.IRunControl2; +import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.tm.tcf.protocol.IService; +import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.protocol.Protocol; +import org.eclipse.tm.tcf.services.IRunControl.DoneCommand; +import org.eclipse.tm.tcf.services.IRunControl.RunControlContext; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +public class RunControl extends AbstractEDCService implements IRunControl2, ICachingService, ISnapshotContributor, + IDSFServiceUsingTCF { + + public static final String EXECUTION_CONTEXT = "execution_context"; + public static final String EXECUTION_CONTEXT_REGISTERS = "execution_context_registers"; + public static final String EXECUTION_CONTEXT_MODULES = "execution_context_modules"; + public static final String EXECUTION_CONTEXT_FRAMES = "execution_context_frames"; + /** + * Context property names. Properties that are optional but have default + * implicit values are indicated below + */ + public static final String + PROP_PARENT_ID = "ParentID", + PROP_IS_CONTAINER = "IsContainer", // default = true + PROP_HAS_STATE = "HasState", + PROP_CAN_RESUME = "CanResume", // default = true + PROP_CAN_COUNT = "CanCount", + PROP_CAN_SUSPEND = "CanSuspend", // default = true + PROP_CAN_TERMINATE = "CanTerminate", // default = false + PROP_IS_SUSPENDED = "State", // default = false + PROP_MESSAGE = "Message", + PROP_SUSPEND_PC = "SuspendPC", + PROP_DISABLE_STEPPING = "DisableStepping"; + + /* + * See where this is used for more. + */ + private static final int RESUME_NOTIFICATION_DELAY = 1000; // milliseconds + + // Whether module is being loaded (if true) or unloaded (if false) + + public abstract static class DMCSuspendedEvent extends AbstractDMEvent { + + private final StateChangeReason reason; + private final Map params; + + public DMCSuspendedEvent(IExecutionDMContext dmc, StateChangeReason reason, Map params) { + super(dmc); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { dmc, reason, params })); } + this.reason = reason; + this.params = params; + } + + public StateChangeReason getReason() { + return reason; + } + + public Map getParams() { + return params; + } + + } + + public static class SuspendedEvent extends DMCSuspendedEvent implements ISuspendedDMEvent { + + public SuspendedEvent(IExecutionDMContext dmc, + StateChangeReason reason, Map params) { + super(dmc, reason, params); + } + + } + + public static class ContainerSuspendedEvent extends DMCSuspendedEvent implements IContainerSuspendedDMEvent { + + public ContainerSuspendedEvent(IExecutionDMContext dmc, + StateChangeReason reason, Map params) { + super(dmc, reason, params); + } + + public IExecutionDMContext[] getTriggeringContexts() { + return new IExecutionDMContext[]{getDMContext()}; + } + } + + public abstract static class DMCResumedEvent extends AbstractDMEvent { + + public DMCResumedEvent(IExecutionDMContext dmc) { + super(dmc); + } + + public StateChangeReason getReason() { + return StateChangeReason.USER_REQUEST; + } + } + + public static class ResumedEvent extends DMCResumedEvent implements IResumedDMEvent { + + public ResumedEvent(IExecutionDMContext dmc) { + super(dmc); + } + } + + public static class ContainerResumedEvent extends DMCResumedEvent implements IContainerResumedDMEvent { + + public ContainerResumedEvent(IExecutionDMContext dmc) { + super(dmc); + } + + public IExecutionDMContext[] getTriggeringContexts() { + return new IExecutionDMContext[]{getDMContext()}; + } +} + + private static StateChangeReason toDsfStateChangeReason(String tcfReason) { + if (tcfReason == null) + return StateChangeReason.UNKNOWN; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_USER_REQUEST)) + return StateChangeReason.USER_REQUEST; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_STEP)) + return StateChangeReason.STEP; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_BREAKPOINT)) + return StateChangeReason.BREAKPOINT; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_EXCEPTION)) + return StateChangeReason.EXCEPTION; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_CONTAINER)) + return StateChangeReason.CONTAINER; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_WATCHPOINT)) + return StateChangeReason.WATCHPOINT; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_SIGNAL)) + return StateChangeReason.SIGNAL; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_SHAREDLIB)) + return StateChangeReason.SHAREDLIB; + if (tcfReason.equals(org.eclipse.tm.tcf.services.IRunControl.REASON_ERROR)) + return StateChangeReason.ERROR; + return StateChangeReason.UNKNOWN; + } + + @Immutable + private static class ExecutionData implements IExecutionDMData2 { + private final StateChangeReason reason; + private final String details; + + ExecutionData(StateChangeReason reason, String details) { + this.reason = reason; + this.details = details; + } + + public StateChangeReason getStateChangeReason() { + return reason; + } + + public String getDetails() { + return details; + } + } + + public abstract class ExecutionDMC extends DMContext implements IExecutionDMContext, + ISnapshotContributor, IEDCExecutionDMC { + + private final List children = Collections.synchronizedList(new ArrayList()); + private StateChangeReason stateChangeReason = StateChangeReason.UNKNOWN; + private String stateChangeDetails = null; + private final RunControlContext tcfContext; + private final ExecutionDMC parentExecutionDMC; + private String latestPC = null; + private RequestMonitor steppingRM = null; + private boolean isStepping = false; + + // See where this is used for more. + private int countOfScheduledNotifications = 0 ; + + /** + * Whether user chose to "terminate" or "disconnect" the context. + */ + private boolean isTerminatingThanDisconnecting = false; + + private List disabledRanges = Collections.synchronizedList(new ArrayList()); + private boolean suspendEventsEnabled = true; + + public ExecutionDMC(ExecutionDMC parent, Map props, RunControlContext tcfContext) { + super(RunControl.this, parent == null ? new IDMContext[0] : new IDMContext[] { parent }, props); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { parent, properties })); } + this.parentExecutionDMC = parent; + this.tcfContext = tcfContext; + if (props != null) { + dmcsByID.put(getID(), this); + } + if (parent != null) + parent.addChild(this); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + private void addChild(ExecutionDMC executionDMC) { + synchronized (children) { + children.add(executionDMC); + } + } + + private void removeChild(IEDCExecutionDMC executionDMC) { + synchronized (children) { + children.remove(executionDMC); + } + } + + public ExecutionDMC[] getChildren() { + synchronized (children) { + return children.toArray(new ExecutionDMC[children.size()]); + } + } + + public boolean wantFocusInUI() { + Boolean wantFocus = (Boolean)properties.get(ProtocolConstants.PROP_WANT_FOCUS_IN_UI); + if (wantFocus == null) + wantFocus = true; // default if unknown (not set by debug agent). + return wantFocus; + } + + public abstract ExecutionDMC contextAdded(Map properties, RunControlContext tcfContext); + + public abstract boolean canDetach(); + + public abstract boolean canStep(); + + public void loadSnapshot(Element element) throws Exception { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(element)); } + NodeList ecElements = element.getElementsByTagName(EXECUTION_CONTEXT); + int numcontexts = ecElements.getLength(); + for (int i = 0; i < numcontexts; i++) { + Element contextElement = (Element) ecElements.item(i); + if (contextElement.getParentNode().equals(element)) { + try { + Element propElement = (Element) contextElement.getElementsByTagName(SnapshotUtils.PROPERTIES) + .item(0); + HashMap properties = new HashMap(); + SnapshotUtils.initializeFromXML(propElement, properties); + ExecutionDMC exeDMC = contextAdded(properties, null); + exeDMC.loadSnapshot(contextElement); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + public Element takeSnapshot(IAlbum album, Document document, IProgressMonitor monitor)throws Exception { + Element contextElement = document.createElement(EXECUTION_CONTEXT); + contextElement.setAttribute(PROP_ID, this.getID()); + + Element propsElement = SnapshotUtils.makeXMLFromProperties(document, getProperties()); + contextElement.appendChild(propsElement); + + ExecutionDMC[] dmcs = getChildren(); + SubMonitor progress = SubMonitor.convert(monitor, dmcs.length * 1000); + progress.subTask(getName()); + + for (ExecutionDMC executionDMC : dmcs) { + Element dmcElement = executionDMC.takeSnapshot(album, document, progress.newChild(1000)); + contextElement.appendChild(dmcElement); + } + + return contextElement; + } + + public boolean isSuspended() { + synchronized (properties) { + return RunControl.getProperty(properties, PROP_IS_SUSPENDED, false); + } + } + + public StateChangeReason getStateChangeReason() { + return stateChangeReason; + } + + public String getStateChangeDetails() { + return stateChangeDetails; + } + + public void setIsSuspended(boolean isSuspended) { + synchronized (properties) { + properties.put(PROP_IS_SUSPENDED, isSuspended); + } + if (getParent() != null) + getParent().childIsSuspended(isSuspended); + } + + private void childIsSuspended(boolean isSuspended) { + if (isSuspended) { + setIsSuspended(true); + } else { + boolean anySuspended = false; + for (ExecutionDMC childDMC : getChildren()) { + if (childDMC.isSuspended()) { + anySuspended = true; + break; + } + } + if (!anySuspended) + setIsSuspended(false); + } + } + + protected void contextException(String msg) { + assert getExecutor().isInExecutorThread(); + + setIsSuspended(true); + synchronized (properties) { + properties.put(PROP_MESSAGE, msg); + } + stateChangeReason = StateChangeReason.EXCEPTION; + getSession().dispatchEvent( + createSuspendedEvent(StateChangeReason.EXCEPTION, new HashMap()), + RunControl.this.getProperties()); + } + + protected void contextSuspended(String pc, String reason, final Map params) { + assert getExecutor().isInExecutorThread(); + + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(new Object[] { pc, reason, params })); } + if (pc != null) { + // the PC from TCF agent is decimal string. + // convert it to hex string. + pc = Long.toHexString(Long.parseLong(pc)); + } + + latestPC = pc; + + setIsSuspended(true); + synchronized (properties) { + properties.put(PROP_MESSAGE, reason); + properties.put(PROP_SUSPEND_PC, pc); + } + stateChangeReason = toDsfStateChangeReason(reason); + + if (stateChangeReason == StateChangeReason.SHAREDLIB) { + handleModuleEvent(this, params); + } else { + + properties.put(PROP_DISABLE_STEPPING, params.get(ProtocolConstants.PROP_DISABLE_STEPPING)); + properties.put(ProtocolConstants.PROP_WANT_FOCUS_IN_UI, params.get(ProtocolConstants.PROP_WANT_FOCUS_IN_UI)); + + stateChangeDetails = (String) params.get(ProtocolConstants.PROP_SUSPEND_DETAIL); + + // TODO This is not what the stateChangeDetails is for, we need an extended thread description + // and is "foreground" really the right term? + + // Show the context is foreground one, if possible. + // + Boolean isForeground = (Boolean)params.get(ProtocolConstants.PROP_IS_FOREGROUND); + if (isForeground != null) + stateChangeDetails += isForeground ? " [foreground]" : ""; + + final ExecutionDMC dmc = this; + + final DataRequestMonitor preprocessDrm = new DataRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + Boolean honorSuspend = getData(); + + if (honorSuspend!=null && honorSuspend) { // do suspend + + // All the following must be done in DSF dispatch + // thread to ensure data integrity. + + // Mark done of the single step RM, if any pending. + if (steppingRM != null) { + steppingRM.done(); + steppingRM = null; + } + + // Mark any stepping as done. + setStepping(false); + + // Remove temporary breakpoints set by stepping. + // Note we don't want to do this on a sharedLibrary + // event as otherwise + // stepping will be screwed up by that event. + // + Breakpoints bpService = getService(Breakpoints.class); + bpService.removeAllTempBreakpoints(new RequestMonitor(getExecutor(), null)); + + // check to see if we are in a disabled range + IAddress pcAddress = new Addr64(dmc.getPC(), 16); + EDCAddressRange disabledRange = dmc.getDisabledRange(pcAddress); + if (disabledRange != null) + { + stepAddressRange(dmc, false, pcAddress, disabledRange.getEndAddress(), new RequestMonitor(getExecutor(), null)); + } + else + { + // Only after completion of those preprocessing do + // we fire the event. + if (dmc.suspendEventsEnabled()) + getSession().dispatchEvent(dmc.createSuspendedEvent(stateChangeReason, params), + RunControl.this.getProperties()); + } + dmc.clearDisabledRanges(); + } else { + // ignore suspend if, say, breakpoint condition is not met. + RunControl.this.resume(dmc, new RequestMonitor(getExecutor(), null)); + } + } + }; + + preprocessOnSuspend(dmc, latestPC, preprocessDrm); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + protected boolean suspendEventsEnabled() { + return suspendEventsEnabled ; + } + + protected void setSuspendEventsEnabled(boolean enabled) + { + suspendEventsEnabled = enabled; + } + + protected void clearDisabledRanges() { + disabledRanges.clear(); + } + + /** + * handle module load event and unload event. A module is an executable file + * or a library (e.g. DLL or shared lib). + * + * @param dmc + * @param moduleProperties + */ + private void handleModuleEvent(final IEDCExecutionDMC dmc, final Map moduleProperties) { + // The following needs be done in DSF dispatch thread. + getSession().getExecutor().execute(new Runnable() { + public void run() { + // based on properties, either load or unload the module + boolean loaded = true; + Object loadedValue = moduleProperties.get(IModuleProperty.PROP_MODULE_LOADED); + if (loadedValue != null) { + if (loadedValue instanceof Boolean) + loaded = (Boolean) loadedValue; + } + + if (loaded) + handleModuleLoadedEvent(dmc, moduleProperties); + else + handleModuleUnloadedEvent(dmc, moduleProperties); + } + }); + } + + public Boolean canTerminate() { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null); } + boolean result = false; + synchronized (properties) { + result = RunControl.getProperty(properties, PROP_CAN_TERMINATE, result); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null, result); } + return result; + } + + /** + * Resume the context. + * + * @param rm + * this is marked done as long as the resume command + * succeeds. + */ + public boolean supportsStepMode(StepType type) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this)); } + + int mode = 0; + switch (type) { + case STEP_OVER: + mode = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER_RANGE; + break; + case STEP_INTO: + mode = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_RANGE; + break; + case STEP_RETURN: + mode = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT; + break; + case INSTRUCTION_STEP_OVER: + mode = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER; + break; + case INSTRUCTION_STEP_INTO: + mode = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO; + break; + } + + if (hasTCFContext()) + return getTCFContext().canResume(mode); + else + return false; + } + + /** + * Resume the context. + * + * @param rm + * this is marked done as long as the resume command + * succeeds. + */ + public void resume(final RequestMonitor rm) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this)); } + + flushCache(this); + + if (hasTCFContext()) { + Protocol.invokeLater(new Runnable() { + public void run() { + getTCFContext() + .resume(org.eclipse.tm.tcf.services.IRunControl.RM_RESUME, + 0, new DoneCommand() { + + public void doneCommand( + IToken token, + final Exception error) { + getExecutor().execute( + new Runnable() { + public void run() { + if (error == null) { + contextResumed(true); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { + EDCTrace.getTrace().trace(null, "Resume command succeeded."); + } + } else { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { + EDCTrace.getTrace().trace(null, "Resume command failed."); + } + rm.setStatus(new Status( + IStatus.ERROR, + EDCDebugger.PLUGIN_ID, + REQUEST_FAILED, + "Resume failed.", + null)); + } + rm.done(); + } + }); + } + }); + } + }); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * Resume the context but the request monitor is only marked done when + * the context is suspended. (vs. regular resume()).
    + * Note this method does not wait for suspended-event. + * + * @param rm + */ + protected void resumeForStepping(final RequestMonitor rm) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this)); } + + setStepping(true); + + flushCache(this); + + if (hasTCFContext()) { + Protocol.invokeLater(new Runnable() { + public void run() { + getTCFContext().resume(org.eclipse.tm.tcf.services.IRunControl.RM_RESUME, + 0, new DoneCommand() { + + public void doneCommand( + IToken token, + final Exception error) { + // do this in DSF executor thread. + getExecutor().execute( + new Runnable() { + public void run() { + handleTCFResumeDoneForStepping( + "ResumeForStepping", + error, + rm); + } + }); + } + }); + } + }); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + private void handleTCFResumeDoneForStepping(String command, Exception tcfError, RequestMonitor rm) { + assert getExecutor().isInExecutorThread(); + + String msg = command; + if (tcfError == null) { + msg += " succeeded."; + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().trace(null, msg); } + contextResumed(false); + + // we'll mark it as done when we get next + // suspend event. + assert steppingRM == null; + steppingRM = rm; + } else { + msg += " failed."; + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().trace(null, msg); } + + setStepping(false); + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, msg, tcfError)); + rm.done(); + } + } + + public void suspend(final RequestMonitor requestMonitor) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this)); } + if (isSnapshot()) + { + Album.getAlbumBySession(getSession().getId()).stopPlayingSnapshots(); + } + else + if (hasTCFContext()) { + Protocol.invokeLater(new Runnable() { + public void run() { + getTCFContext().suspend(new DoneCommand() { + + public void doneCommand(IToken token, + Exception error) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { + EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this)); + } + requestMonitor.done(); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { + EDCTrace.getTrace().traceExit(null); + } + } + }); + } + }); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + public void terminate(final RequestMonitor requestMonitor) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this)); } + + isTerminatingThanDisconnecting = true; + + if (hasTCFContext()) { + Protocol.invokeLater(new Runnable() { + public void run() { + getTCFContext().terminate(new DoneCommand() { + + public void doneCommand(IToken token, Exception error) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this)); } + if (error != null) { + requestMonitor.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, + "terminate() failed.", error)); + } + + requestMonitor.done(); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + }); + } + }); + } else { + // Snapshots, for e.g., don't have a TCF RunControlContext, so just remove all the contexts recursively + detachAllContexts(); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + protected ExecutionDMC getParent() { + return parentExecutionDMC; + } + + /** + * get latest PC register value of the context. + * + * @return hex string of the PC value. + */ + public String getPC() { + return latestPC; + } + + /** + * Change cached PC value. + * This is only supposed to be used for move-to-line & resume-from-line commands. + * + * @param pc + */ + private void setPC(String pc) { + latestPC = pc; + } + + /** + * Detach debugger from this context and all its children. + */ + public void detach(){ + isTerminatingThanDisconnecting = false; + /** + * agent side detaching is invoked by Processes service. + * Here we just purge the context. + */ + purgeFromDebugger(); + } + + /** + * Purge this context and all its children and grand-children + * from debugger UI and internal data cache. + */ + public void purgeFromDebugger(){ + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null); } + + for (ExecutionDMC e : getChildren()) + // recursively forget children first + e.purgeFromDebugger(); + + ExecutionDMC parent = getParent(); + if (parent != null) + parent.removeChild(this); + + getSession().dispatchEvent(new ExitedEvent(this, isTerminatingThanDisconnecting), RunControl.this.getProperties()); + + if (getRootDMC().getChildren().length == 0) + // no more contexts under debug, fire exitedEvent for the rootDMC which + // will trigger shutdown of the debug session. + // See EDCLaunch.eventDispatched(IExitedDMEvent e). + // Whether the root is terminated or disconnected depends on whether + // the last context is terminated or disconnected. + getSession().dispatchEvent(new ExitedEvent(getRootDMC(), isTerminatingThanDisconnecting), RunControl.this.getProperties()); + + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * Recursively marks all execution contexts as resumed + * @param dmc + */ + public void resumeAll(){ + contextResumed(true); + for (ExecutionDMC e : getChildren()){ + e.resumeAll(); + } + } + + protected void contextResumed(boolean fireResumeEventNow) { + assert getExecutor().isInExecutorThread(); + + if (children.size() > 0) { + // If it has kids (e.g. a process has threads), only need + // to mark the kids as resumed. + for (ExecutionDMC e : children){ + e.contextResumed(fireResumeEventNow); + } + return; + } + + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { this, fireResumeEventNow })); } + + setIsSuspended(false); + + if (fireResumeEventNow) + getSession().dispatchEvent(this.createResumedEvent(), RunControl.this.getProperties()); + else + scheduleResumeEvent(); + + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * Schedule a task to run after some time which will + * notify platform that the context is running. + */ + private void scheduleResumeEvent() { + countOfScheduledNotifications++; + + final ExecutionDMC dmc = this; + + Runnable notifyPlatformTask = new Runnable() { + public void run() { + /* + * Notify platform the context is running. + * + * But don't do that if another such task is scheduled + * (namely current stepping is done within the RESUME_NOTIFICATION_DELAY and + * another stepping/resume is underway). + */ + countOfScheduledNotifications--; + if (countOfScheduledNotifications == 0 && !isSuspended()) + getSession().dispatchEvent(dmc.createResumedEvent(), RunControl.this.getProperties()); + }}; + + getExecutor().schedule(notifyPlatformTask, RESUME_NOTIFICATION_DELAY, TimeUnit.MILLISECONDS); + } + + /** + * Execute a single instruction. Note the "rm" is marked done() only + * when we get the suspend event, not when we successfully send the + * command to TCF agent. + * + * @param rm + */ + protected void singleStep(final boolean stepInto, final RequestMonitor rm) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this.getName())); } + + setStepping(true); + + flushCache(this); + + if (hasTCFContext()) + { + Protocol.invokeLater(new Runnable() { + public void run() { + int mode = stepInto ? org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO + : org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER; + getTCFContext().resume(mode, 1, new DoneCommand() { + public void doneCommand(IToken token, final Exception error) { + // do this in DSF executor thread. + getExecutor().execute(new Runnable() { + public void run() { + handleTCFResumeDoneForStepping("SingleStep", error, rm); + } + }); + } + }); + } + }); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * Step out of the current function. Note the "rm" is marked done() only + * when we get the suspend event, not when we successfully send the + * command to TCF agent. + * + * @param rm + */ + protected void stepOut(final RequestMonitor rm) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this.getName())); } + + setStepping(true); + + flushCache(this); + + if (hasTCFContext()) { + Protocol.invokeLater(new Runnable() { + public void run() { + getTCFContext() + .resume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT, + 0, new DoneCommand() { + + public void doneCommand( + IToken token, + final Exception error) { + // do this in DSF executor thread. + getExecutor().execute( + new Runnable() { + public void run() { + handleTCFResumeDoneForStepping( + "StepOut", + error, + rm); + } + }); + } + }); + } + }); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + protected void stepRange(final boolean stepInto, final IAddress rangeStart, final IAddress rangeEnd, + final RequestMonitor rm) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(this.getName())); } + + setStepping(true); + + flushCache(this); + + if (hasTCFContext()) { + Protocol.invokeLater(new Runnable() { + public void run() { + int mode = stepInto ? org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_RANGE + : org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER_RANGE; + Map params = new HashMap(); + params.put("RANGE_START", rangeStart.getValue()); + params.put("RANGE_END", rangeEnd.getValue()); + + getTCFContext().resume(mode, 0, params, new DoneCommand() { + + public void doneCommand(IToken token, + final Exception error) { + // do this in DSF executor thread. + getExecutor().execute(new Runnable() { + public void run() { + handleTCFResumeDoneForStepping( + "StepRange", error, rm); + } + }); + } + }); + } + }); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + + /** + * set whether debugger is stepping in the context. + * + * @param isStepping + */ + public void setStepping(boolean isStepping) { + this.isStepping = isStepping; + } + + /** + * @return whether debugger is stepping the context. + */ + public boolean isStepping() { + return isStepping; + } + + public void addDisabledRange(IAddress lowAddress, IAddress highAddress) { + disabledRanges.add(new EDCAddressRange(lowAddress, highAddress)); + } + + public EDCAddressRange getDisabledRange(IAddress address) { + for (EDCAddressRange dRange : disabledRanges) { + if (dRange.contains(address)) + return dRange; + } + return null; + } + + protected DMCSuspendedEvent createSuspendedEvent(StateChangeReason reason, Map properties) { + return new SuspendedEvent(this, reason, properties); + } + + protected DMCResumedEvent createResumedEvent() { + return new ResumedEvent(this); + } + + public RunControlContext getTCFContext() { + return tcfContext; + } + + public boolean hasTCFContext() { + return tcfContext != null; + } + + } + + public class ProcessExecutionDMC extends ExecutionDMC implements IContainerDMContext, IProcessDMContext, + ISymbolDMContext, IBreakpointsTargetDMContext, IDisassemblyDMContext { + + public ProcessExecutionDMC(ExecutionDMC parent, Map properties, RunControlContext tcfContext) { + super(parent, properties, tcfContext); + } + + @Override + public ExecutionDMC contextAdded(Map properties, RunControlContext tcfContext) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(properties)); } + ThreadExecutionDMC newDMC = new ThreadExecutionDMC(this, properties, tcfContext); + getSession().dispatchEvent(new StartedEvent(newDMC), RunControl.this.getProperties()); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(newDMC)); } + return newDMC; + } + + public ISymbolDMContext getSymbolDMContext() { + return this; + } + + @Override + public void loadSnapshot(Element element) throws Exception { + // load modules first, since this loads a stack which must consult modules and symbolics + Modules modulesService = getService(Modules.class); + modulesService.loadModulesForContext(this, element); + super.loadSnapshot(element); + } + + @Override + public Element takeSnapshot(IAlbum album, Document document, IProgressMonitor monitor)throws Exception { + SubMonitor progress = SubMonitor.convert(monitor, 1000); + progress.subTask(getName()); + Element contextElement = super.takeSnapshot(album, document, progress.newChild(500)); + Element modulesElement = document.createElement(EXECUTION_CONTEXT_MODULES); + Modules modulesService = getService(Modules.class); + + IModuleDMContext[] modules = modulesService.getModulesForContext(this.getID()); + SubMonitor modulesMonitor = progress.newChild(500); + modulesMonitor.setWorkRemaining(modules.length * 1000); + modulesMonitor.subTask("Modules"); + for (IModuleDMContext moduleContext : modules) { + ModuleDMC moduleDMC = (ModuleDMC) moduleContext; + modulesElement.appendChild(moduleDMC.takeSnapshot(album, document, modulesMonitor.newChild(1000))); + } + + contextElement.appendChild(modulesElement); + return contextElement; + } + + @Override + public boolean canDetach() { + // Can detach from a process unless we're part of a snapshot. + return hasTCFContext(); + } + + @Override + public boolean canStep() { + // can't step a process. + return false; + } + } + + public class ThreadExecutionDMC extends ExecutionDMC implements IThreadDMContext, IDisassemblyDMContext { + + public ThreadExecutionDMC(ExecutionDMC parent, Map properties, RunControlContext tcfContext) { + super(parent, properties, tcfContext); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { + EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArgs(new Object[] { parent, properties })); + EDCTrace.getTrace().traceExit(null); + } + } + + public ISymbolDMContext getSymbolDMContext() { + return DMContexts.getAncestorOfType(this, ISymbolDMContext.class); + } + + @Override + public void loadSnapshot(Element element) throws Exception { + super.loadSnapshot(element); + Registers regService = getService(Registers.class); + regService.loadGroupsForContext(this, element); + + Stack stackService = getService(Stack.class); + NodeList frameElements = element.getElementsByTagName(EXECUTION_CONTEXT_FRAMES); + for (int i = 0; i < frameElements.getLength(); i++) { + Element frameElement = (Element) frameElements.item(i); + stackService.loadFramesForContext(this, frameElement); + } + + getSession().dispatchEvent( + createSuspendedEvent(StateChangeReason.EXCEPTION, new HashMap()), + RunControl.this.getProperties()); + } + + @Override + public Element takeSnapshot(IAlbum album, Document document, IProgressMonitor monitor)throws Exception { + SubMonitor progress = SubMonitor.convert(monitor, 1000); + progress.subTask(getName()); + Element contextElement = super.takeSnapshot(album, document, progress.newChild(100)); + Element registersElement = document.createElement(EXECUTION_CONTEXT_REGISTERS); + Registers regService = getService(Registers.class); + + IRegisterGroupDMContext[] regGroups = regService.getGroupsForContext(this); + SubMonitor registerMonitor = progress.newChild(300); + registerMonitor.setWorkRemaining(regGroups.length * 1000); + registerMonitor.subTask("Registers"); + for (IRegisterGroupDMContext registerGroupDMContext : regGroups) { + RegisterGroupDMC regDMC = (RegisterGroupDMC) registerGroupDMContext; + registersElement.appendChild(regDMC.takeSnapshot(album, document, registerMonitor.newChild(1000))); + } + + contextElement.appendChild(registersElement); + + Element framesElement = document.createElement(EXECUTION_CONTEXT_FRAMES); + Stack stackService = getService(Stack.class); + Expressions expressionsService = getService(Expressions.class); + + IFrameDMContext[] frames = stackService.getFramesForDMC(this, 0, IStack.ALL_FRAMES); + SubMonitor framesMonitor = progress.newChild(600); + framesMonitor.setWorkRemaining(frames.length * 2000); + framesMonitor.subTask("Stack Frames"); + for (IFrameDMContext frameDMContext : frames) { + StackFrameDMC frameDMC = (StackFrameDMC) frameDMContext; + + // Get the local variables for each frame + IVariableDMContext[] variables = frameDMC.getLocals(); + SubMonitor variablesMonitor = framesMonitor.newChild(1000); + variablesMonitor.setWorkRemaining(variables.length * 10); + variablesMonitor.subTask("Variables"); + for (IVariableDMContext iVariableDMContext : variables) { + VariableDMC varDMC = (VariableDMC) iVariableDMContext; + IExpressionDMContext expression = expressionsService.createExpression(frameDMContext, varDMC.getName()); + boolean wasEnabled = FormatExtensionManager.instance().isEnabled(); + FormatExtensionManager.instance().setEnabled(true); + expressionsService.loadExpressionValues(expression, Album.getVariableCaptureDepth()); + FormatExtensionManager.instance().setEnabled(wasEnabled); + variablesMonitor.worked(10); + variablesMonitor.subTask("Variables - " + varDMC.getName()); + } + + framesElement.appendChild(frameDMC.takeSnapshot(album, document, framesMonitor.newChild(1000))); + } + contextElement.appendChild(framesElement); + + return contextElement; + } + + @Override + public ExecutionDMC contextAdded(Map properties, RunControlContext tcfContext) { + assert (false); + return null; + } + + @Override + public boolean canDetach() { + // Cannot detach from a thread. + return false; + } + + @Override + public boolean canStep() { + if (isSuspended()) { + synchronized (properties) { + return !RunControl.getProperty(properties, PROP_DISABLE_STEPPING, false); + } + } + + return false; + } + } + + /** + * Context representing a program running on a bare device without OS, which + * can also be the boot-up "process" of an OS. + *

    + * It's like a thread context as it has its registers and stack frames, but + * also like a process as it has modules associated with it. Currently we + * set it as an IProcessDMContext so that it appears as a ContainerVMNode in + * debug view. See LaunchVMProvider for more. Also it's treated like a + * process in + * {@link Processes#getProcessesBeingDebugged(IDMContext, DataRequestMonitor)} + */ + public class BareDeviceExecutionDMC extends ThreadExecutionDMC + implements IProcessDMContext, ISymbolDMContext, IBreakpointsTargetDMContext { + + public BareDeviceExecutionDMC(ExecutionDMC parent, + Map properties, RunControlContext tcfContext) { + super(parent, properties, tcfContext); + assert !RunControl.getProperty(properties, PROP_IS_CONTAINER, true); + } + + @Override + protected DMCSuspendedEvent createSuspendedEvent(StateChangeReason reason, Map properties) { + return new ContainerSuspendedEvent(this, reason, properties); + } + + @Override + protected DMCResumedEvent createResumedEvent() { + return new ContainerResumedEvent(this); + } + + @Override + public boolean canDetach() { + return true; + } + + } + + public class RootExecutionDMC extends ExecutionDMC implements ISourceLookupDMContext { + + public RootExecutionDMC(Map props) { + super(null, props, null); + } + + @Override + public ExecutionDMC contextAdded(Map properties, RunControlContext tcfContext) { + ExecutionDMC newDMC; + // If the new context being added under root is a container context, + // we treat it as a Process, otherwise a bare device program context. + // + if (RunControl.getProperty(properties, PROP_IS_CONTAINER, true)) + newDMC = new ProcessExecutionDMC(this, properties, tcfContext); + else + newDMC = new BareDeviceExecutionDMC(this, properties, tcfContext); + + getSession().dispatchEvent(new StartedEvent(newDMC), RunControl.this.getProperties()); + return newDMC; + } + + public ISymbolDMContext getSymbolDMContext() { + return null; + } + + @Override + public boolean canDetach() { + return false; + } + + @Override + public boolean canStep() { + return false; + } + } + + private static final String EXECUTION_CONTEXTS = "execution_contexts"; + + private org.eclipse.tm.tcf.services.IRunControl tcfRunService; + private RootExecutionDMC rootExecutionDMC; + private final Map dmcsByID = new HashMap(); + + public RunControl(DsfSession session) { + super(session, new String[] { + IRunControl.class.getName(), + IRunControl2.class.getName(), + RunControl.class.getName(), + ISnapshotContributor.class.getName() }); + initializeRootExecutionDMC(); + } + + private void initializeRootExecutionDMC() { + HashMap props = new HashMap(); + props.put(IEDCDMContext.PROP_ID, "root"); + rootExecutionDMC = new RootExecutionDMC(props); + } + + public void canResume(IExecutionDMContext context, DataRequestMonitor rm) { + rm.setData(((ExecutionDMC) context).isSuspended() ? Boolean.TRUE : Boolean.FALSE); + rm.done(); + } + + public void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor rm) { + rm.setData(((ExecutionDMC) context).canStep() ? Boolean.TRUE : Boolean.FALSE); + rm.done(); + } + + public void canSuspend(IExecutionDMContext context, DataRequestMonitor rm) { + if (isSnapshot()) + rm.setData(Album.getAlbumBySession(getSession().getId()).isPlayingSnapshots()); + else + rm.setData(((ExecutionDMC) context).isSuspended() ? Boolean.FALSE : Boolean.TRUE); + rm.done(); + } + + public void getExecutionContexts(IContainerDMContext c, DataRequestMonitor rm) { + if (c instanceof ProcessExecutionDMC) { + ProcessExecutionDMC edmc = (ProcessExecutionDMC) c; + IEDCExecutionDMC[] threads = edmc.getChildren(); + IExecutionDMContext[] threadArray = new IExecutionDMContext[threads.length]; + System.arraycopy(threads, 0, threadArray, 0, threads.length); + rm.setData(threadArray); + } + rm.done(); + } + + public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor rm) { + if (dmc instanceof ExecutionDMC) { + ExecutionDMC exedmc = (ExecutionDMC) dmc; + if (exedmc.isSuspended()) { + rm.setData(new ExecutionData(exedmc.getStateChangeReason(), exedmc.getStateChangeDetails())); + } else { + rm.setData(new ExecutionData(StateChangeReason.UNKNOWN, null)); + } + } else + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, INVALID_HANDLE, + "Given context: " + dmc + " is not a recognized execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + } + + public boolean isStepping(IExecutionDMContext context) { + if (context instanceof ExecutionDMC) { + ExecutionDMC exedmc = (ExecutionDMC) context; + return exedmc.isStepping(); + } + return false; + } + + public boolean isSuspended(IExecutionDMContext context) { + if (context instanceof ExecutionDMC) { + ExecutionDMC exedmc = (ExecutionDMC) context; + return exedmc.isSuspended(); + } + return false; + } + + /** + * Preprocessing for suspend event. This is done before we broadcast the + * suspend event across the debugger. Here's what's done in the + * preprocessing by default:
    + * 1. Adjust PC after control hits a software breakpoint where the PC + * points at the byte right after the breakpoint instruction. This is to + * move PC back to the address of the breakpoint instruction.
    + * 2. If we stops at a breakpoint, evaluate condition of the breakpoint + * and determine if we should ignore the suspend event and resume or + * should honor the suspend event and sent it up the ladder. + *

    + * Subclass can override this method to add their own special preprocessing, + * while calling super implementation to carry out the default common. + *

    + * This must be called in DSF executor thread. + * + * @param pc + * program pointer value from the event, in the format of + * big-endian hex string. Can be null. + * @param drm + * DataRequestMonitor whose result indicates whether to honor + * the suspend. + */ + protected void preprocessOnSuspend(final ExecutionDMC dmc, final String pc, + final DataRequestMonitor drm) { + + assert getExecutor().isInExecutorThread(); + + asyncExec(new Runnable() { + + public void run() { + try { + Breakpoints bpService = getService(Breakpoints.class); + Registers regService = getService(Registers.class); + String pcString = pc; + + if (pc == null) { + // read PC register + pcString = regService.getRegisterValue(dmc, getTargetEnvironmentService().getPCRegisterID()); + } + + dmc.setPC(pcString); + + // This check is to speed up handling of suspend due to + // other reasons such as "step". + // The TCF agents should always report the + // "stateChangeReason" as BREAKPOINT when a breakpoint + // is hit. + + if (dmc.getStateChangeReason() != StateChangeReason.BREAKPOINT) { + drm.setData(true); + drm.done(); + return; + } + + if (!bpService.usesTCFBreakpointService()) { + // generic software breakpoint is used. + // We need to move PC back to the breakpoint + // instruction. + long pcValue; + + pcValue = Long.valueOf(pcString, 16); + pcValue -= getTargetEnvironmentService() + .getBreakpointInstruction(dmc, new Addr64(pcString, 16)).length; + pcString = Long.toHexString(pcValue); + + // Stopped but not due to breakpoint set by debugger. + // For instance, some Windows DLL has "int 3" + // instructions in it. + // + if (bpService.findBreakpoint(new Addr64(pcString, 16)) != null) { + // Now adjust PC register. + regService.writeRegister(dmc, getTargetEnvironmentService().getPCRegisterID(), pcString); + dmc.setPC(pcString); + } + } + + // check if a conditional breakpoint (must be a user bp) is hit + // + BreakpointDMData bp = bpService.findUserBreakpoint(new Addr64(pcString, 16)); + if (bp != null) { + // evaluate the condition + bpService.evaluateBreakpointCondition(dmc, bp, drm); + } else { + drm.setData(true); + drm.done(); + } + } catch (CoreException e) { + Status s = new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), null, e); + EDCDebugger.getMessageLogger().log(s); + drm.setStatus(s); + drm.done(); + } + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(drm.getData())); } + } + + }, drm); + } + + public void resume(IExecutionDMContext context, final RequestMonitor rm) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(MessageFormat.format("resume context {0}", context))); } + + if (!(context instanceof ExecutionDMC)) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, INVALID_HANDLE, MessageFormat.format( + "The context [{0}] is not a recognized execution context.", context), null)); + rm.done(); + } + + final ExecutionDMC dmc = (ExecutionDMC) context; + + prepareToRun(dmc, new DataRequestMonitor(getExecutor(), rm) { + + @Override + protected void handleSuccess() { + dmc.resume(rm); + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(MessageFormat.format("resume() done on context {0}", dmc))); } + } + }); + } + + /** + * Prepare for resuming or stepping by
    + * - executing current instruction if PC is at a breakpoint. + * + * @param dmc + * - the execution context, usually a thread. + * @param drm + * - data request monitor which will contain boolean value on + * done indicating whether an instruction is executed during the + * preparation. + */ + private void prepareToRun(final ExecutionDMC dmc, final DataRequestMonitor drm) { + // If there is breakpoint at current PC, remove it => Single step => + // Restore it. + + final Breakpoints bpService = getService(Breakpoints.class); + if (bpService.usesTCFBreakpointService()) { + // no need to do anything since the breakpoints service is expected to handle + // stepping past breakpoints since it's the one that sets them + drm.setData(false); + drm.done(); + return; + } + + String latestPC = dmc.getPC(); + + if (latestPC != null) { + final BreakpointDMData bp = bpService.findUserBreakpoint(new Addr64(latestPC, 16)); + if (bp != null) { + bpService.disableBreakpoint(bp, new RequestMonitor(getExecutor(), drm) { + + @Override + protected void handleSuccess() { + // Now step over the instruction + // + dmc.setSuspendEventsEnabled(false); + dmc.singleStep(true, new RequestMonitor(getExecutor(), drm) { + @Override + protected void handleCompleted() { + dmc.setSuspendEventsEnabled(true); + super.handleCompleted(); + } + + @Override + protected void handleSuccess() { + // At this point the single instruction + // execution should be done + // and the context being suspended. + // + drm.setData(true); // indicates an instruction + // is executed + + // Now restore the breakpoint. + bpService.enableBreakpoint(bp, drm); + } + }); + } + }); + } else { // no breakpoint at PC + drm.setData(false); + drm.done(); + } + } else { + drm.setData(false); + drm.done(); + } + } + + // This is a coarse timer on stepping for internal use. + // When needed, turn it on and watch output in console. + // + private static long steppingStartTime = 0; + public static boolean timeStepping() { + return false; + } + + public static long getSteppingStartTime() { + return steppingStartTime; + } + + public void step(final IExecutionDMContext context, final StepType outerStepType, final RequestMonitor rm) { + + asyncExec(new Runnable() { + + public void run() { + StepType stepType = outerStepType; + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(MessageFormat.format("{0} context {1}", stepType, context))); } + + if (!(context instanceof ExecutionDMC)) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, INVALID_HANDLE, MessageFormat.format( + "The context [{0}] is not a recognized execution context.", context), null)); + rm.done(); + } + + if (timeStepping()) + steppingStartTime = System.currentTimeMillis(); + + final ExecutionDMC dmc = (ExecutionDMC) context; + + dmc.setStepping(true); + + IAddress pcAddress = null; + + if (dmc.getPC() == null) { // PC is even unknown, can only do + // one-instruction step. + stepType = StepType.INSTRUCTION_STEP_INTO; + } else + pcAddress = new Addr64(dmc.getPC(), 16); + + // For step-out (step-return), no difference between source level or + // instruction level. + // + if (stepType == StepType.STEP_RETURN) + stepType = StepType.INSTRUCTION_STEP_RETURN; + + // Source level stepping request. + // + if (stepType == StepType.STEP_OVER || stepType == StepType.STEP_INTO) { + IEDCModules moduleService = getService(Modules.class); + + ISymbolDMContext symCtx = DMContexts.getAncestorOfType(context, ISymbolDMContext.class); + + IEDCModuleDMContext module = moduleService.getModuleByAddress(symCtx, pcAddress); + + // Check if there is source info for PC address. + // + if (module != null) { + IEDCSymbolReader reader = module.getSymbolReader(); + assert pcAddress != null; + if (reader != null) { + IAddress linkAddress = module.toLinkAddress(pcAddress); + IModuleLineEntryProvider lineEntryProvider + = reader.getModuleScope().getModuleLineEntryProvider(); + ILineEntry line = lineEntryProvider.getLineEntryAtAddress(linkAddress); + if (line != null) { + // get runtime addresses of the line boundaries. + IAddress endAddr = module.toRuntimeAddress(line.getHighAddress()); + + // get the next source line entry that has a line # + // greater than the current line # (and in the same file), + // but is not outside of the function address range + // if found, the start addr of that entry is our end + // address, otherwise use the existing end address + ILineEntry nextLine + = lineEntryProvider.getNextLineEntry( + lineEntryProvider.getLineEntryAtAddress(linkAddress), + stepType == StepType.STEP_OVER); + if (nextLine != null) { + endAddr = module.toRuntimeAddress(nextLine.getLowAddress()); + } else { // nextLine == null probably means last line + IEDCSymbols symbolsService = getService(Symbols.class); + IFunctionScope functionScope + = symbolsService.getFunctionAtAddress(dmc.getSymbolDMContext(), pcAddress); + if (stepType == StepType.STEP_OVER) { + while (functionScope != null + && functionScope.getParent() instanceof IFunctionScope) { + functionScope = (IFunctionScope)functionScope.getParent(); + } + } + if (functionScope != null) + endAddr = module.toRuntimeAddress(functionScope.getHighAddress()); + } + if (stepType == StepType.STEP_OVER) { + // Create a disabled range + Collection ranges + = lineEntryProvider.getLineEntriesForLines(line.getFilePath(), + line.getLineNumber(), + line.getLineNumber()); + if (ranges.size() > 1) + { + for (ILineEntry iLineEntry : ranges) { + dmc.addDisabledRange(module.toRuntimeAddress(iLineEntry.getLowAddress()), + module.toRuntimeAddress(iLineEntry.getHighAddress())); + } + } + } + + /* + * It's possible that PC is larger than startAddr + * (e.g. user does a few instruction level stepping + * then switch to source level stepping; or when we + * just step out a function). We just parse and + * stepping instructions within [pcAddr, endAddr) + * instead of all those within [startAddr, endAddr). + * One possible problem with the solution is when + * control jumps from within [pcAddress, endAddr) to + * somewhere within [startAddr, pcAddress), the + * stepping would stop at somewhere within + * [startAddr, pcAddress) instead of outside of the + * [startAddr, endAddr). But that case is rare (e.g. + * a source line contains a bunch of statements) and + * that "problem" is not unacceptable as user could + * just keep stepping or set a breakpoint and run. + * + * We can overcome the problem but that would incur + * much more complexity in the stepping code and + * brings down the stepping speed. + * ........................ 08/30/2009 + */ + + stepAddressRange(dmc, stepType == StepType.STEP_INTO, pcAddress, endAddr, rm); + + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null, "source level stepping."); } + return; + } + } + } + + // No source found, fall back to instruction level step. + if (stepType == StepType.STEP_INTO) + stepType = StepType.INSTRUCTION_STEP_INTO; + else + stepType = StepType.INSTRUCTION_STEP_OVER; + } + + // instruction level step + // + if (stepType == StepType.INSTRUCTION_STEP_OVER) + stepOverOneInstruction(dmc, pcAddress, rm); + else if (stepType == StepType.INSTRUCTION_STEP_INTO) + stepIntoOneInstruction(dmc, rm); + else if (stepType == StepType.INSTRUCTION_STEP_RETURN) + stepOut(dmc, pcAddress, rm); + + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceExit(null); } + } + }, rm); + } + + private void stepOut(final ExecutionDMC dmc, IAddress pcAddress, final RequestMonitor rm) { + + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, "Step out from address " + pcAddress.toHexAddressString()); } + + if (dmc.supportsStepMode(StepType.STEP_RETURN)) { + dmc.stepOut(rm); + return; + } + + Stack stackService = getService(Stack.class); + IFrameDMContext[] frames; + try { + frames = stackService.getFramesForDMC(dmc, 0, 1); + } catch (CoreException e) { + Status s = new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), null, e); + EDCDebugger.getMessageLogger().log(s); + rm.setStatus(s); + rm.done(); + return; + } + if (frames.length <= 1) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, + "Cannot step out as no caller frame is available.", null)); + rm.done(); + return; + } + + if (handleSteppingOutOfInLineFunctions(dmc, frames, rm)) + return; + + final IAddress stepToAddress = ((StackFrameDMC) frames[1]).getInstructionPtrAddress(); + + final Breakpoints bpService = getService(Breakpoints.class); + + prepareToRun(dmc, new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + + boolean goon = true; + + if (getData() == true) { + // one instruction has been executed + IAddress newPC = new Addr64(dmc.getPC(), 16); + + // And we already stepped out (that instruction is return + // instruction). + // + if (newPC.equals(stepToAddress)) { + goon = false; + } + } + + if (goon) { + bpService.setTempBreakpoint(dmc, stepToAddress, new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + dmc.resumeForStepping(rm); + } + }); + } else + rm.done(); + } + }); + } + + /** + * handle module load event. A module is an executable file + * or a library (e.g. DLL or shared lib). + * Allow subclass to override for special handling if needed. + * This must be called in DSF dispatch thread. + * + * @param dmc + * @param moduleProperties + */ + protected void handleModuleLoadedEvent(IEDCExecutionDMC dmc, Map moduleProperties) { + ISymbolDMContext symbolContext = dmc.getSymbolDMContext(); + + if (symbolContext != null) { + Modules modulesService = getService(Modules.class); + modulesService.moduleLoaded(symbolContext, dmc, moduleProperties); + } + } + + /** + * handle module unload event. A module is an executable file + * or a library (e.g. DLL or shared lib). + * Allow subclass to override for special handling if needed. + * This must be called in DSF dispatch thread. + * + * @param dmc + * @param moduleProperties + */ + protected void handleModuleUnloadedEvent(IEDCExecutionDMC dmc, Map moduleProperties) { + ISymbolDMContext symbolContext = dmc.getSymbolDMContext(); + + if (symbolContext != null) { + Modules modulesService = getService(Modules.class); + modulesService.moduleUnloaded(symbolContext, dmc, moduleProperties); + } + } + + private boolean handleSteppingOutOfInLineFunctions(final ExecutionDMC dmc, + IFrameDMContext[] frames, final RequestMonitor rm) { + + assert frames.length > 1 && frames[0] instanceof StackFrameDMC; + + StackFrameDMC currentFrame = ((StackFrameDMC) frames[0]); + + IEDCModuleDMContext module = currentFrame.getModule(); + if (module != null) { + IFunctionScope func = currentFrame.getFunctionScope(); + // if inline ... + if (func != null && (func.getParent() instanceof IFunctionScope)) { + + // ... but if PC is at beginning of function, then act like not in inline + // (i.e. step-out as though standing at call to any non-inline function) + if (currentFrame.isInlineShouldBeHidden(null)) + return false; + + // ... or if PC at at high-address, that means we're actually done with it + IAddress functRuntimeHighAddr = module.toRuntimeAddress(func.getHighAddress()); + IAddress frameInstrPtr = currentFrame.getInstructionPtrAddress(); + if (functRuntimeHighAddr.equals(frameInstrPtr)) + return false; + + // getting here means treat the line as a regular line to step over + stepAddressRange(dmc, false, frameInstrPtr, functRuntimeHighAddr, + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + rm.done(); + }}); + + return true; + } + } + return false; + } + + /** + * check if the instruction at PC is a subroutine call. If yes, set a + * breakpoint after it and resume; otherwise just execute one instruction. + * + * @param dmc + * @param pcAddress + * @param rm + */ + private void stepOverOneInstruction(final ExecutionDMC dmc, final IAddress pcAddress, final RequestMonitor rm) { + + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, "address " + pcAddress.toHexAddressString()); } + + if (dmc.supportsStepMode(StepType.INSTRUCTION_STEP_OVER)) { + dmc.singleStep(false, rm); + return; + } + + ITargetEnvironment env = getTargetEnvironmentService(); + final IDisassembler disassembler = (env != null) ? env.getDisassembler() : null; + if (disassembler == null) { + rm.setStatus(Disassembly.statusNoDisassembler()); + rm.done(); + return; + } + + Memory memoryService = getService(Memory.class); + IMemoryDMContext mem_dmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class); + + // We need to get the instruction at the PC. We have to + // retrieve memory bytes for longest instruction. + @SuppressWarnings("null") // (env == null) -> (disassembler == null) -> return above + int maxInstLength = env.getLongestInstructionLength(); + + // Note this memory read will give us memory bytes with + // debugger breakpoints removed, which is just what we want. + memoryService.getMemory(mem_dmc, pcAddress, 0, 1, maxInstLength, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + ByteBuffer codeBuf = Disassembly.translateMemoryBytes(getData(), pcAddress, rm); + if (codeBuf == null) { + return; // rm status set in checkMemoryBytes() + } + + IDisassemblyDMContext dis_dmc + = DMContexts.getAncestorOfType(dmc, IDisassemblyDMContext.class); + Map options = new HashMap(); + options.put(IDisassemblerOptions.ADDRESS_IS_PC, 1); + IDisassembledInstruction inst; + try { + inst = disassembler.disassembleOneInstruction(pcAddress, codeBuf, options, dis_dmc); + } catch (CoreException e) { + rm.setStatus(e.getStatus()); + rm.done(); + return; + } + + final boolean isSubroutineCall = inst.getJumpToAddress() != null + && inst.getJumpToAddress().isSubroutineAddress(); + final IAddress nextInstructionAddress = pcAddress.add(inst.getSize()); + + stepIntoOneInstruction(dmc, new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + if (!isSubroutineCall) + rm.done(); + else { + // If current instruction is subroutine call, set a + // temp + // breakpoint at next instruction and resume ... + // + Breakpoints bpService = getService(Breakpoints.class); + bpService.setTempBreakpoint(dmc, nextInstructionAddress, + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + dmc.resumeForStepping(rm); + } + }); + } + } + }); + } + }); + } + + /** + * Step into or over an address range. Note the startAddr is also the PC + * value. + * + * @param dmc + * @param stepIn + * - whether to step-in. + * @param startAddr + * - also the PC register value. + * @param endAddr + * @param rm + * - marked done after the stepping is over and context is + * suspended again. + */ + private void stepAddressRange(final ExecutionDMC dmc, final boolean stepIn, final IAddress startAddr, + final IAddress endAddr, final RequestMonitor rm) { + if (EDCTrace.RUN_CONTROL_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, MessageFormat.format("address range [{0},{1})", startAddr.toHexAddressString(), endAddr.toHexAddressString())); } + + if (dmc.supportsStepMode(stepIn ? StepType.STEP_INTO : StepType.STEP_OVER)) { + dmc.stepRange(stepIn, startAddr, endAddr, rm); + return; + } + + ITargetEnvironment env = getTargetEnvironmentService(); + final IDisassembler disassembler = (env != null) ? env.getDisassembler() : null; + if (disassembler == null) { + rm.setStatus(Disassembly.statusNoDisassembler()); + rm.done(); + return; + } + + final Memory memoryService = getService(Memory.class); + IMemoryDMContext mem_dmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class); + + int memSize = startAddr.distanceTo(endAddr).intValue(); + + final IAddress pcAddress = startAddr; + + // Note this memory read will give us memory bytes with + // debugger breakpoints removed, which is just what we want. + memoryService.getMemory(mem_dmc, startAddr, 0, 1, memSize, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + ByteBuffer codeBuf = Disassembly.translateMemoryBytes(getData(), startAddr, rm); + if (codeBuf == null) { + return; // rm status set in checkMemoryBytes() + } + + IDisassemblyDMContext dis_dmc + = DMContexts.getAncestorOfType(dmc, IDisassemblyDMContext.class); + + Map options = new HashMap(); + + List instList; + try { + instList + = disassembler.disassembleInstructions(startAddr, endAddr, codeBuf, + options, dis_dmc); + } catch (CoreException e) { + rm.setStatus(e.getStatus()); + rm.done(); + return; + } + + // Now collect all possible stop points + // + final List stopPoints = new ArrayList(); + final List runToAndCheckPoints = new ArrayList(); + boolean insertBPatRangeEnd = true; + + for (IDisassembledInstruction inst : instList) { + final IAddress instAddr = inst.getAddress(); + if (insertBPatRangeEnd == false) + insertBPatRangeEnd = true; + IJumpToAddress jta = inst.getJumpToAddress(); + if (jta == null) + continue; + + // the instruction is a control-change instruction + // + if (!jta.isImmediate()) { + + if (inst.getAddress().equals(pcAddress)) { + // Control is already at the instruction, evaluate + // it. + // + String expr = (String) jta.getValue(); + if (expr.equals(JumpToAddress.EXPRESSION_RETURN_FAR) + || expr.equals(JumpToAddress.EXPRESSION_RETURN_NEAR) + || expr.equals(JumpToAddress.EXPRESSION_LR)) { + // The current instruction is return instruction. Just execute it + // to step-out and we are done with the stepping. This way we avoid + // looking for return address from caller stack frame which may not + // even available. + // Is it possible that the destination address of the step-out + // is still within the [startAddr, endAddr)range ? In theory + // yes, but in practice it means one source line has several + // function bodies in it, who would do that? + // + stepIntoOneInstruction(dmc, rm); + return; + } + // evaluate the address expression + + if (!jta.isSubroutineAddress() || stepIn) + { + IAddressExpressionEvaluator evaluator = getTargetEnvironmentService() + .getAddressExpressionEvaluator(); + if (evaluator == null) { + rm.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, REQUEST_FAILED, + "No evaluator for address expression yet.", null)); + rm.done(); + return; + } + + Registers regService = getService(Registers.class); + + IAddress addr; + try { + addr = evaluator.evaluate(dmc, expr, regService, memoryService); + } catch (CoreException e) { + rm.setStatus(e.getStatus()); + rm.done(); + return; + } + // don't add an address if we already have it + if (!stopPoints.contains(addr)) + stopPoints.add(addr); + } + } else { + // we must run to this instruction first + // + /* + * What if control would skip (jump-over) this + * instruction within the [startAddr, endAddr) range + * ? So we should go on collecting stop points from + * the remaining instructions in the range and then + * do our two-phase stepping (see below) + */ + if (!runToAndCheckPoints.contains(instAddr)) + runToAndCheckPoints.add(instAddr); + } + } else { // "jta" is immediate address. + + IAddress jumpAddress = (IAddress) jta.getValue(); + + if (jta.isSoleDestination()) { + if (jta.isSubroutineAddress()) { + // is subroutine call + if (stepIn && !stopPoints.contains(jumpAddress)) { + stopPoints.add(jumpAddress); + // no need to check remaining instructions + // !! Wrong. Control may jump over (skip)this instruction + // within the [startAddr, endAddr) range, so we still need + // to parse instructions after this instruction. + // break; + } else { + // step over the call instruction. Just stop + // at next instruction. + // nothing to do. + } + } else { + // Unconditional jump instruction + // ignore jump within the address range + if (!(startAddr.compareTo(jumpAddress) <= 0 && jumpAddress.compareTo(endAddr) < 0)) { + insertBPatRangeEnd = false; + if (!stopPoints.contains(jumpAddress)) + stopPoints.add(jumpAddress); + } + } + } else { + // conditional jump + // ignore jump within the address range + if (!(startAddr.compareTo(jumpAddress) <= 0 && jumpAddress.compareTo(endAddr) < 0) + && !stopPoints.contains(jumpAddress)) + { + stopPoints.add(jumpAddress); + } + } + } + } // end of parsing instructions + + // need a temp breakpoint at the "endAddr". + if (insertBPatRangeEnd && !stopPoints.contains(endAddr)) + stopPoints.add(endAddr); + + if (runToAndCheckPoints.size() > 0) { + // Now do our two-phase stepping. + // + + if (runToAndCheckPoints.size() > 1) { + /* + * Wow, there are two control-change instructions in the + * range that requires run-to-check (let's call them RTC + * point). In theory the stepping might fail (not stop + * as desired) in such case: When we try to run to the + * first RTC, the control may skip the first RTC and run + * to second RTC (note we don't know the stop points of + * the second RTC yet) and run out of the range and be + * gone with the wind... + * + * There is no way we can solve the problem. Good thing + * is, in practice is the case even possible ? + */ + // Log (and show it, get rid of the "show" part after + // tons of test) warning here. + EDCDebugger.getMessageLogger().log( + new Status(IStatus.WARNING, EDCDebugger.PLUGIN_ID, + MessageFormat.format( + "More than one run-to-check points in the address range [{0},{1}). Stepping might fail.", + startAddr.toHexAddressString(), endAddr.toHexAddressString()))); + } + + // ------------ Phase 1: run to the first RTC. + // + // recursive call + stepAddressRange(dmc, stepIn, startAddr, runToAndCheckPoints.get(0), new RequestMonitor( + getExecutor(), rm) { + @Override + protected void handleSuccess() { + IAddress newPC = new Addr64(dmc.getPC(), 16); + + boolean doneWithStepping = false; + for (IAddress addr : stopPoints) + if (newPC.equals(addr)) { + doneWithStepping = true; // done with the + // stepping + break; + } + + Breakpoints bpService = getService(Breakpoints.class); + if (bpService.findUserBreakpoint(newPC) != null) { // hit + // a + // user + // breakpoint + doneWithStepping = true; + } + + if (!doneWithStepping) + // -------- Phase 2: run to the "endAddr". + // + stepAddressRange(dmc, stepIn, newPC, endAddr, rm); // Recursive + // call + else + rm.done(); + } + }); + } else { // no RTC points, set temp breakpoints at stopPoints + // and run... + + // Make sure we step over breakpoint at PC (if any) + // + prepareToRun(dmc, new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + + boolean goon = true; + + Breakpoints bpService = getService(Breakpoints.class); + + if (getData() == true) { + // one instruction has been executed + IAddress newPC = new Addr64(dmc.getPC(), 16); + + if (bpService.findUserBreakpoint(newPC) != null) { + // hit a user breakpoint. Stepping finishes. + goon = false; + } else { + // Check if we finish the stepping by + // checking the newPC against + // our stopPoints instead of checking if + // newPC is outside of [startAddr, endAddr) + // so that such case would not fail: step + // over this address range: + // + // 0x10000 call ... // a user breakpoint is + // set here + // 0x10004 ... + // 0x1000c ... + // + // + for (IAddress addr : stopPoints) + if (newPC.equals(addr)) { + goon = false; + break; + } + } + } + + if (goon) { + // Now set temp breakpoints at our stop points. + // + CountingRequestMonitor setTempBpRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + // we are done setting all temporary + // breakpoints + dmc.resumeForStepping(rm); + } + }; + + setTempBpRM.setDoneCount(stopPoints.size()); + + for (IAddress addr : stopPoints) { + bpService.setTempBreakpoint(dmc, addr, setTempBpRM); + } + } else + rm.done(); + } + }); + } + + } + }); + } + + /** + * step-into one instruction at current PC, namely execute only one + * instruction. + * + * @param dmc + * @param rm + * - this RequestMonitor is marked done when the execution + * finishes and target suspends again. + */ + private void stepIntoOneInstruction(final ExecutionDMC dmc, final RequestMonitor rm) { + + prepareToRun(dmc, new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + if (getData() == true /* already executed one instruction */) + // The "step" is over + rm.done(); + else { + dmc.singleStep(true, rm); + } + } + }); + } + + public void suspend(IExecutionDMContext context, RequestMonitor requestMonitor) { + if (context instanceof ExecutionDMC) { + ((ExecutionDMC) context).suspend(requestMonitor); + } else { + requestMonitor.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, INVALID_HANDLE, MessageFormat + .format("The context [{0}] is not a recognized execution context.", context), null)); + requestMonitor.done(); + } + } + + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + rm.done(); + } + + public void flushCache(IDMContext context) { + if (isSnapshot()) + return; + // Flush the Registers cache immediately + // For instance the readPCRegister() may get wrong PC value when an + // asynchronous suspend event comes too quick after resume. + Registers regService = getService(Registers.class); + regService.flushCache(context); + } + + @Override + public void shutdown(RequestMonitor monitor) { + if (tcfRunService != null) { + Protocol.invokeLater(new Runnable() { + public void run() { + tcfRunService.removeListener(runListener); + } + }); + } + unregister(); + super.shutdown(monitor); + } + + public RootExecutionDMC getRootDMC() { + return rootExecutionDMC; + } + + public static class StartedEvent extends AbstractDMEvent implements IStartedDMEvent { + + public StartedEvent(IExecutionDMContext context) { + super(context); + } + } + + public static class ExitedEvent extends AbstractDMEvent implements IExitedDMEvent { + private boolean isTerminatedThanDisconnected; + + public ExitedEvent(IExecutionDMContext context, boolean isTerminatedThanDisconnected) { + super(context); + this.isTerminatedThanDisconnected = isTerminatedThanDisconnected; + } + + public boolean isTerminatedThanDisconnected() { + return isTerminatedThanDisconnected; + } + } + + /* + * NOTE: + * Methods in this listener are invoked in TCF dispatch thread. + * When they call into DSF services/objects, make sure it's done in + * DSF executor thread so as to avoid possible racing condition. + */ + private final org.eclipse.tm.tcf.services.IRunControl.RunControlListener runListener = new org.eclipse.tm.tcf.services.IRunControl.RunControlListener() { + + public void containerResumed(String[] context_ids) { + } + + public void containerSuspended(String context, String pc, String reason, Map params, + String[] suspended_ids) { + } + + public void contextAdded(final RunControlContext[] contexts) { + getExecutor().execute(new Runnable() { + public void run() { + for (RunControlContext ctx : contexts) { + ExecutionDMC dmc = rootExecutionDMC; + String parentID = ctx.getParentID(); + if (parentID != null) + dmc = dmcsByID.get(parentID); + if (dmc != null) { + dmc.contextAdded(ctx.getProperties(), ctx); + } + } + } + }); + } + + public void contextChanged(RunControlContext[] contexts) { + } + + public void contextException(final String context, final String msg) { + getExecutor().execute(new Runnable() { + public void run() { + ExecutionDMC dmc = getContext(context); + if (dmc != null) + dmc.contextException(msg); + } + }); + } + + public void contextRemoved(final String[] context_ids) { + getExecutor().execute(new Runnable() { + public void run() { + for (String contextID : context_ids) { + ExecutionDMC dmc = getContext(contextID); + assert dmc != null; + if (dmc != null) + dmc.purgeFromDebugger(); + } + } + }); + } + + public void contextResumed(final String context) { + getExecutor().execute(new Runnable() { + public void run() { + ExecutionDMC dmc = getContext(context); + if (dmc != null) + dmc.contextResumed(false); + } + }); + } + + public void contextSuspended(final String context, final String pc, final String reason, + final Map params) { + getExecutor().execute(new Runnable() { + public void run() { + ExecutionDMC dmc = getContext(context); + if (dmc != null) + dmc.contextSuspended(pc, reason, params); + else { + EDCDebugger.getMessageLogger().logError( + MessageFormat.format("Unkown context [{0}] is reported in suspended event. Make sure TCF agent has reported contextAdded event first.", context), + null); + } + } + }); + } + }; + + public Element takeSnapshot(IAlbum album, Document document, IProgressMonitor monitor)throws Exception { + Element contextsElement = document.createElement(EXECUTION_CONTEXTS); + ExecutionDMC[] dmcs = rootExecutionDMC.getChildren(); + SubMonitor progress = SubMonitor.convert(monitor, dmcs.length * 1000); + + for (ExecutionDMC executionDMC : dmcs) { + Element dmcElement = executionDMC.takeSnapshot(album, document, progress.newChild(1000)); + contextsElement.appendChild(dmcElement); + } + return contextsElement; + } + + public ExecutionDMC getContext(String contextID) { + return dmcsByID.get(contextID); + } + + public void loadSnapshot(Element snapshotRoot) throws Exception { + NodeList ecElements = snapshotRoot.getElementsByTagName(EXECUTION_CONTEXTS); + rootExecutionDMC.resumeAll(); + initializeRootExecutionDMC(); + rootExecutionDMC.loadSnapshot((Element) ecElements.item(0)); + } + + public void tcfServiceReady(IService service) { + if (service instanceof org.eclipse.tm.tcf.services.IRunControl) { + tcfRunService = (org.eclipse.tm.tcf.services.IRunControl) service; + Protocol.invokeLater(new Runnable() { + public void run() { + tcfRunService.addListener(runListener); + } + }); + } else + assert false; + } + + /** + * Stop debugging all execution contexts. This does not kill/terminate + * the actual process or thread. + * See: {@link #terminateAllContexts(RequestMonitor)} + */ + private void detachAllContexts(){ + getRootDMC().detach(); + } + + /** + * Terminate all contexts so as to terminate the debug session. + * + * @param rm can be null. + */ + public void terminateAllContexts(final RequestMonitor rm){ + + CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleError() { + // failed to terminate at least one process, usually + // because connection to target is lost, or some processes + // cannot be killed (e.g. OS does not permit that). + // Just untarget the contexts. + detachAllContexts(); + + if (rm != null) + rm.done(); + } + + }; + + // It's assumed + // 1. First level of children under rootDMC are processes. + // 2. Killing them would kill all contexts (processes and threads) being debugged. + // + ExecutionDMC[] processes = getRootDMC().getChildren(); + crm.setDoneCount(processes.length); + + for (ExecutionDMC e : processes) { + e.terminate(crm); + } + } + + public void canRunToLine(IExecutionDMContext context, String sourceFile, + int lineNumber, final DataRequestMonitor rm) { + // I tried to have better filtering as shown in commented code. But that + // just made the command fail to be enabled as desired. Not sure about the + // exact cause yet, but one problem (from the upper framework) I've seen is + // this API is not called whenever user selects a line in source editor (or + // disassembly view) and bring up context menu. + // Hence we blindly answer yes. The behavior is on par with DSF-GDB. + // ................. 03/11/10 + rm.setData(true); + rm.done(); + +// // Return true if we can find address(es) for the line in the context. +// // +// getLineAddress(context, sourceFile, lineNumber, new DataRequestMonitor>(getExecutor(), rm){ +// @Override +// protected void handleCompleted() { +// if (! isSuccess()) +// rm.setData(false); +// else { +// rm.setData(getData().size() > 0); +// } +// rm.done(); +// }}); + } + + public void runToLine(final IExecutionDMContext context, String sourceFile, + int lineNumber, boolean skipBreakpoints, final RequestMonitor rm) { + + getLineAddress(context, sourceFile, lineNumber, new DataRequestMonitor>(getExecutor(), rm){ + @Override + protected void handleCompleted() { + if (! isSuccess()) { + rm.setStatus(getStatus()); + rm.done(); + } + else { + runToAddresses(context, getData(), rm); + } + }}); + } + + private void runToAddresses(IExecutionDMContext context, + final List addrs, final RequestMonitor rm) { + // 1. Single step over breakpoint, if PC is at a breakpoint. + // 2. Set temp breakpoint at the addresses. + // 3. Resume the context. + // + final ExecutionDMC dmc = (ExecutionDMC)context; + assert dmc != null; + + prepareToRun(dmc, new DataRequestMonitor(getExecutor(), rm){ + + @Override + protected void handleCompleted() { + if (! isSuccess()) { + rm.setStatus(getStatus()); + rm.done(); + return; + } + + CountingRequestMonitor settingBP_crm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (! isSuccess()) { + // as long as we fail to set on temp breakpoint, we bail out. + rm.setStatus(getStatus()); + rm.done(); + } + else { + // all temp breakpoints are successfully set. + // Now resume the context. + dmc.resume(rm); + } + }}; + + settingBP_crm.setDoneCount(addrs.size()); + + Breakpoints bpService = getService(Breakpoints.class); + + for (IAddress a : addrs) + bpService.setTempBreakpoint(dmc, a, settingBP_crm); + }} + ); + } + + public void canRunToAddress(IExecutionDMContext context, IAddress address, + DataRequestMonitor rm) { + // See comment in canRunToLine() for more. + rm.setData(true); + rm.done(); + +// // If the address is not in any module of the run context, return false. +// Modules moduleService = getService(Modules.class); +// +// ISymbolDMContext symCtx = DMContexts.getAncestorOfType(context, ISymbolDMContext.class); +// +// ModuleDMC m = moduleService.getModuleByAddress(symCtx, address); +// rm.setData(m == null); +// rm.done(); + } + + public void runToAddress(IExecutionDMContext context, IAddress address, + boolean skipBreakpoints, RequestMonitor rm) { + List addrs = new ArrayList(1); + addrs.add(address); + runToAddresses(context, addrs, rm); + } + + public void canMoveToLine(IExecutionDMContext context, String sourceFile, + int lineNumber, boolean resume, final DataRequestMonitor rm) { + // See comment in canRunToLine() for more. + rm.setData(true); + rm.done(); + + // Return true if we can find one and only one address for the line in the context. + // +// getLineAddress(context, sourceFile, lineNumber, new DataRequestMonitor>(getExecutor(), rm){ +// @Override +// protected void handleCompleted() { +// if (! isSuccess()) +// rm.setData(false); +// else { +// rm.setData(getData().size() == 1); +// } +// rm.done(); +// }}); + } + + public void moveToLine(final IExecutionDMContext context, String sourceFile, + int lineNumber, final boolean resume, final RequestMonitor rm) { + getLineAddress(context, sourceFile, lineNumber, new DataRequestMonitor>(getExecutor(), rm){ + @Override + protected void handleCompleted() { + if (! isSuccess()) { + rm.setStatus(getStatus()); + rm.done(); + } + else { + List addrs = getData(); + // No, canMoveToLine() does not do sanity check now. + // We just move to the first address we found, which may or + // may not be the address user wants. Is it better we return + // error if "addrs.size() > 1" ? .......03/28/10 + // assert addrs.size() == 1; // ensured by canMoveToLine(). + moveToAddress(context, addrs.get(0), resume, rm); + } + }}); + } + + public void canMoveToAddress(IExecutionDMContext context, IAddress address, + boolean resume, DataRequestMonitor rm) { + // Allow moving to any address. + rm.setData(true); + rm.done(); + } + + public void moveToAddress(IExecutionDMContext context, IAddress address, + boolean resume, RequestMonitor rm) { + + Registers regService = getService(Registers.class); + + assert(context instanceof ExecutionDMC); + ExecutionDMC dmc = (ExecutionDMC)context; + + String newPC = address.toString(16); + + if (! newPC.equals(dmc.getPC())) { + try { + // synchronously change PC, so that change occurs before any resume + String regID = getTargetEnvironmentService().getPCRegisterID(); + RegisterDMC regDMC = regService.findRegisterDMCByName(dmc, regID); + assert regDMC != null; + + regService.writeRegister(regDMC, newPC, IFormattedValues.HEX_FORMAT); + } catch (CoreException e) { + Status s = new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Error adjusting the PC register", e); + EDCDebugger.getMessageLogger().log(s); + rm.setStatus(s); + rm.done(); + return; + } + + // update cached PC. + dmc.setPC(newPC); + } + + if (resume) + resume(context, rm); + else + rm.done(); + } + + /** + * Get runtime addresses mapped to given source line in given run context. + * + * @param context + * @param sourceFile + * @param lineNumber + * @param drm holds an empty list if no address found, or the run context is not suspended. + */ + private void getLineAddress(IExecutionDMContext context, + String sourceFile, int lineNumber, DataRequestMonitor> drm) { + List addrs = new ArrayList(1); + + ExecutionDMC dmc = (ExecutionDMC) context; + if (dmc == null || ! dmc.isSuspended()) { + drm.setData(addrs); + drm.done(); + return; + } + + Modules moduleService = getService(Modules.class); + + moduleService.getLineAddress(dmc, sourceFile, lineNumber, drm); + } + + /** + * Check if this context is non-container. Only non-container context + * (thread and bare device context) can have register, stack frames, etc. + * + * @param dmc + * @return + */ + static public boolean isNonContainer(IDMContext dmc) { + return ! (dmc instanceof IContainerDMContext); + } + + public ThreadExecutionDMC[] getSuspendedThreads() + { + ExecutionDMC[] dmcs = null; + List result = new ArrayList(); + synchronized (dmcsByID) + { + Collection allDMCs = dmcsByID.values(); + dmcs = allDMCs.toArray(new ExecutionDMC[allDMCs.size()]); + } + for (ExecutionDMC executionDMC : dmcs) { + if (executionDMC instanceof ThreadExecutionDMC && executionDMC.isSuspended()) + result.add((ThreadExecutionDMC) executionDMC); + } + return result.toArray(new ThreadExecutionDMC[result.size()]); + } + + /** + * Utility method for getting a context property using a default value + * if missing + */ + private static boolean getProperty(Map properties, String name, boolean defaultValue) { + Boolean b = (Boolean)properties.get(name); + return (b == null ? defaultValue : b); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Signals.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Signals.java new file mode 100644 index 0000000..4c16ce3 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Signals.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.dsf.debug.service.ISignals; +import org.eclipse.cdt.dsf.service.DsfSession; + +public class Signals extends AbstractEDCService implements ISignals { + + public Signals(DsfSession session) { + super(session, new String[] { ISignals.class.getName(), Signals.class.getName() }); + // TODO Auto-generated constructor stub + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Snapshots.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Snapshots.java new file mode 100644 index 0000000..f1f73a7 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Snapshots.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import org.eclipse.cdt.debug.edc.internal.snapshot.Album; +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.debug.edc.services.ISnapshots; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfSession; + +public class Snapshots extends AbstractEDCService implements ISnapshots { + + public Snapshots(DsfSession session) { + super(session, new String[] { Snapshots.class.getName() }); + session.addServiceEventListener(this, null); + } + + @Override + public void shutdown(RequestMonitor rm) { + getSession().removeServiceEventListener(this); + super.shutdown(rm); + } + + @DsfServiceEventHandler + public void eventDispatched(final ISuspendedDMEvent e) { + if (!this.isSnapshot()) { + final String controlSetting = Album.getSnapshotCreationControl(); + if (!controlSetting.equals(Album.CREATE_MANUAL)){ + if (e.getReason() != StateChangeReason.SHAREDLIB + && (controlSetting.equals(Album.CREATE_WHEN_STOPPED) || controlSetting.equals(Album.CREATE_AT_BEAKPOINTS))) { + if (controlSetting.equals(Album.CREATE_WHEN_STOPPED) || + e.getReason() == StateChangeReason.BREAKPOINT) { + Album.captureSnapshotForSession(getSession()); + } + } + } + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Symbols.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Symbols.java new file mode 100644 index 0000000..59d08dd --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/services/dsf/Symbols.java @@ -0,0 +1,307 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.services.dsf; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.EDCSymbolReader; +import org.eclipse.cdt.debug.edc.internal.symbols.files.DebugInfoProviderFactory; +import org.eclipse.cdt.debug.edc.internal.symbols.files.ExecutableSymbolicsReaderFactory; +import org.eclipse.cdt.debug.edc.services.AbstractEDCService; +import org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext; +import org.eclipse.cdt.debug.edc.services.IEDCModules; +import org.eclipse.cdt.debug.edc.services.IEDCSymbols; +import org.eclipse.cdt.debug.edc.services.IFrameRegisterProvider; +import org.eclipse.cdt.debug.edc.services.IFrameRegisters; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProvider; +import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.IModuleLineEntryProvider; +import org.eclipse.cdt.debug.edc.symbols.IModuleScope; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.ISymbol; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext; +import org.eclipse.cdt.dsf.debug.service.ISymbols; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IPath; +import org.eclipse.debug.core.model.ISourceLocator; + +public class Symbols extends AbstractEDCService implements ISymbols, IEDCSymbols { + private static Map> readerCache = new HashMap>(); + private ISourceLocator sourceLocator; + + public ISourceLocator getSourceLocator() { + return sourceLocator; + } + + public void setSourceLocator(ISourceLocator sourceLocator) { + this.sourceLocator = sourceLocator; + } + + public Symbols(DsfSession session) { + super(session, new String[] { IEDCSymbols.class.getName(), ISymbols.class.getName(), Symbols.class.getName() }); + } + + public void getSymbols(ISymbolDMContext symCtx, DataRequestMonitor> rm) { + // TODO Auto-generated method stub + + } + + public void getModelData(IDMContext dmc, DataRequestMonitor rm) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCSymbols#getFunctionAtAddress(org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext, org.eclipse.cdt.core.IAddress) + */ + public IFunctionScope getFunctionAtAddress(ISymbolDMContext context, IAddress runtimeAddress) { + IEDCModules modulesService = getService(Modules.class); + IEDCModuleDMContext module = modulesService.getModuleByAddress(context, runtimeAddress); + if (module != null) { + IEDCSymbolReader reader = module.getSymbolReader(); + if (reader != null) { + IScope scope = reader.getModuleScope().getScopeAtAddress(module.toLinkAddress(runtimeAddress)); + while (scope != null && !(scope instanceof IFunctionScope)) { + scope = scope.getParent(); + } + return (IFunctionScope) scope; + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCSymbols#getFunctionAtAddress(org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext, org.eclipse.cdt.core.IAddress) + */ + public String getSymbolNameAtAddress(ISymbolDMContext context, IAddress runtimeAddress) { + IEDCModules modulesService = getService(Modules.class); + IEDCModuleDMContext module = modulesService.getModuleByAddress(context, runtimeAddress); + if (module != null) { + IEDCSymbolReader reader = module.getSymbolReader(); + if (reader != null) { + ISymbol symbol = reader.getSymbolAtAddress(module.toLinkAddress(runtimeAddress)); + if (symbol != null) + return symbol.getName(); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCSymbols#getLineEntryForAddress(org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext, org.eclipse.cdt.core.IAddress) + */ + public ILineEntry getLineEntryForAddress(ISymbolDMContext context, IAddress runtimeAddress) { + IEDCModules modulesService = getService(Modules.class); + IEDCModuleDMContext module = modulesService.getModuleByAddress(context, runtimeAddress); + if (module != null) { + IEDCSymbolReader reader = module.getSymbolReader(); + if (reader != null) { + IAddress linkAddress = module.toLinkAddress(runtimeAddress); + IModuleLineEntryProvider lineEntryProvider = reader.getModuleScope().getModuleLineEntryProvider(); + return lineEntryProvider.getLineEntryAtAddress(linkAddress); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IEDCSymbols#getLineEntriesForAddressRange(org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext, org.eclipse.cdt.core.IAddress, org.eclipse.cdt.core.IAddress) + */ + public List getLineEntriesForAddressRange(ISymbolDMContext context, IAddress start, IAddress end) { + List lineEntries = new ArrayList(); + + IEDCModules modulesService = getService(Modules.class); + IEDCModuleDMContext module = modulesService.getModuleByAddress(context, start); + if (module == null) + return lineEntries; + + IAddress linkStartAddress = module.toLinkAddress(start); + IAddress linkEndAddress = module.toLinkAddress(end); + + IEDCSymbolReader reader = module.getSymbolReader(); + if (reader != null) { + if (linkStartAddress == null) + linkStartAddress = module.getSymbolReader().getModuleScope().getLowAddress(); + if (linkEndAddress == null) + linkEndAddress = module.getSymbolReader().getModuleScope().getHighAddress(); + + IModuleScope moduleScope = reader.getModuleScope(); + + if (linkEndAddress.compareTo(moduleScope.getHighAddress()) > 0) { + // end address is out of the module sections. + // we'll keep getting source lines until we reach an address + // point where no source line is available. + linkEndAddress = moduleScope.getHighAddress(); + } + + IModuleLineEntryProvider lineEntryProvider = moduleScope.getModuleLineEntryProvider(); + + ILineEntry entry = lineEntryProvider.getLineEntryAtAddress(linkStartAddress); + while (entry != null && entry.getLowAddress().compareTo(linkEndAddress) < 0) { + lineEntries.add(entry); + // FIXME: this shouldn't happen + if (entry.getLowAddress().compareTo(entry.getHighAddress()) >= 0) + entry = lineEntryProvider.getLineEntryAtAddress(entry.getHighAddress().add(1)); + else + entry = lineEntryProvider.getLineEntryAtAddress(entry.getHighAddress()); + } + } + + return lineEntries; + } + + /** + * Get an accessor for registers in stack frames other than the current one. + *

    + * Note: this is not meaningful by itselfis typically used from {@link StackFrameDMC#getFrameRegisters()}. + * @param context + * @param runtimeAddress + * @return {@link IFrameRegisters} or null + */ + public IFrameRegisterProvider getFrameRegisterProvider(ISymbolDMContext context, IAddress runtimeAddress) { + Modules modulesService = getService(Modules.class); + IEDCModuleDMContext module = modulesService.getModuleByAddress(context, runtimeAddress); + if (module != null) { + IEDCSymbolReader reader = module.getSymbolReader(); + if (reader != null) { + IFrameRegisterProvider frameRegisterProvider = reader.getModuleScope().getFrameRegisterProvider(); + return frameRegisterProvider; + } + } + return null; + } + + public static IEDCSymbolReader getSymbolReader(IPath modulePath) { + + IEDCSymbolReader reader = null; + WeakReference cacheEntry = readerCache.get(modulePath); + + if (cacheEntry != null) + reader = cacheEntry.get(); + + if (reader != null) { + if (reader.getSymbolFile() != null + && reader.getSymbolFile().toFile().exists() + && reader.getSymbolFile().toFile().lastModified() == reader.getModificationDate()) { + return reader; + } + + // it's been deleted or modified. remove it from the cache + readerCache.remove(modulePath); + } + + IExecutableSymbolicsReader exeReader = ExecutableSymbolicsReaderFactory.createFor(modulePath); + if (exeReader != null) { + IDebugInfoProvider debugProvider = DebugInfoProviderFactory.createFor(modulePath, exeReader); // may be null + if (debugProvider != null) { + // if debug info came from a different file, the "executable" may be that symbol file too + if (!exeReader.getSymbolFile().equals(debugProvider.getExecutableSymbolicsReader().getSymbolFile())) { + exeReader.dispose(); + exeReader = debugProvider.getExecutableSymbolicsReader(); + } + } + reader = new EDCSymbolReader(exeReader, debugProvider); + } + + if (reader != null) { + readerCache.put(modulePath, new WeakReference(reader)); + } + + return reader; + } + + @Override + public void shutdown(RequestMonitor rm) { + super.shutdown(rm); + } + + /** + * This is exposed only for testing. + */ + public static void releaseReaderCache() { + Collection> readers = readerCache.values(); + for (WeakReference readerRef : readers) { + IEDCSymbolReader reader = readerRef.get(); + if (reader != null) + reader.shutDown(); + } + readerCache.clear(); + } + + /** + * A wrapper method that calls into symbol reader to get runtime address(es) + * for a given function name. + * Currently this method use symbol table instead of debug info (e.g. dwarf2) + * to get function address. See reason in the implementation. + * + * @param module where the runtime address is. + * @param functionName + * @return list of runtime addresses. + */ + public List getFunctionAddress(IEDCModuleDMContext module, String functionName) { + + List ret = new ArrayList(2); + + IEDCSymbolReader symReader = module.getSymbolReader(); + if (symReader == null) + return ret; + + // Remove "()" if any + int parenIndex = functionName.indexOf('('); + if (parenIndex >= 0) + functionName = functionName.substring(0, parenIndex); + + // Supposedly we could call this to get what we need, but this may cause full parse of + // debug info and lead to heap overflow for a large symbol file (over one giga bytes of + // memory required in parsing a 180M symbol file) and chokes the debugger. + // So before a good solution is available, we resort to symbol table of the executable. + // ................04/02/10 +// Collection functions = symReader.getModuleScope().getFunctionsByName(function); +// for (IFunctionScope f : functions) { +// IAddress breakAddr = f.getLowAddress(); +// ... + + // assume it's the human-readable name first + Collection symbols = symReader.findUnmangledSymbols(functionName); + if (symbols.isEmpty()) { + // else look for a raw symbol + symbols = symReader.findSymbols(functionName); + } + + for (ISymbol symbol : symbols) { + // don't consider zero sized symbol. + if (symbol.getSize() == 0) + continue; + + IAddress addr = symbol.getAddress(); + // convert from link to runtime address + addr = module.toRuntimeAddress(addr); + + ret.add(addr); + } + + return ret; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/Album.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/Album.java new file mode 100644 index 0000000..3f8f3eb --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/Album.java @@ -0,0 +1,1325 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.snapshot; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.PathUtils; +import org.eclipse.cdt.debug.edc.internal.ZipFileUtils; +import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl; +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.cdt.debug.edc.services.Stack; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.snapshot.IAlbum; +import org.eclipse.cdt.debug.internal.core.sourcelookup.MapEntrySourceContainer; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.containers.DirectorySourceContainer; +import org.eclipse.debug.internal.core.LaunchManager; +import org.osgi.framework.Bundle; +import org.osgi.service.prefs.BackingStoreException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * The Album class represents a series of snapshots that record moments in a + * debug session. An Album manages the collection of snapshots, common resources + * such as source files, persistence, and association with debug sessions. + * + * An Album is usually created during a debug session, saved at the conclusion + * of the session, and reopened by a launch delegate for a new snapshot debug + * session. + * + * When an Album is saved it's data and resources are archived in a snapshot + * file in a default location. When reopened the contents are expanded into a + * temporary directory and used to recreate the debug session. + */ +@SuppressWarnings("restriction") +public class Album extends PlatformObject implements IAlbum { + + // XML element names + public static final String SNAPSHOT = "snapshot"; + private static final String ALBUM = "album"; + private static final String LAUNCH = "launch"; + private static final String RESOURCES = "resources"; + private static final String FILE = "file"; + private static final String INFO = "info"; + + public static final String METADATA = "snapshotMetaData"; + public static final String SNAPSHOT_LIST = "snapshots"; + + private static final String ALBUM_DATA = "album.xml"; + private static final String ALBUM_VERSION = "100"; + + private static String[] DSA_FILE_EXTENSIONS = new String[] {"dsa"}; + + // Preferences + public static final String PREF_CREATION_CONTROL = "creation_control"; + public static final String CREATE_MANUAL = "manual"; + public static final String CREATE_WHEN_STOPPED = "suspend"; + public static final String CREATE_AT_BEAKPOINTS = "breakpoints"; + + public static final String PREF_VARIABLE_CAPTURE_DEPTH = "variable_capture_depth"; + public static final String PLAY_SNAPSHOT_DELAY_TIME = "play_snapshot_delay_time"; + + private static final String CAMERA_CLICK_WAV = "/sounds/camera_click.wav"; + + private Document document; + private Element albumRootElement; + + private final List snapshotList = new ArrayList(); + private String sessionID = ""; + private String recordingSessionID = ""; + private IPath albumRootDirectory; + private boolean launchConfigSaved; + private String launchType; + private HashMap launchProperties; + private String launchName = ""; + private String name; + private boolean loaded; + private boolean metaDataLoaded; + private final Set files = new HashSet(); + + private int currentSnapshotIndex; + private IPath location; + private boolean resourceListSaved; + private boolean metadataSaved; + private boolean albumInfoSaved; + private String displayName; + private boolean playingSnapshots; + + /** + * Listener for state changes on albums + */ + protected static List listeners = Collections.synchronizedList(new ArrayList()); + + private static Map albumsBySessionID = Collections.synchronizedMap(new HashMap()); + private static Map albumsRecordingBySessionID = Collections.synchronizedMap(new HashMap()); + private static Map albumsByLocation = Collections.synchronizedMap(new HashMap()); + private static Map launchNames = Collections.synchronizedMap(new HashMap()); + + private static boolean sessionEndedListenerAdded; + private static SessionEndedListener sessionEndedListener = new SessionEndedListener() { + + public void sessionEnded(DsfSession session) { + Album album = albumsRecordingBySessionID.get(session.getId()); + if (album == null) + album = albumsBySessionID.get(session.getId()); + if (album != null && session.getId().equals(album.getRecordingSessionID())) { + album.saveResources(new NullProgressMonitor()); + album.setRecordingSessionID(""); + } + synchronized (albumsRecordingBySessionID) { + albumsRecordingBySessionID.remove(session.getId()); + } + synchronized (albumsBySessionID) { + albumsBySessionID.remove(session.getId()); + } + + if (album != null) { + for (ISnapshotAlbumEventListener l : new ArrayList(listeners)) { + l.snapshotSessionEnded(album, session); + } + } + } + }; + + public interface IAlbumArchiveEntry { + + public String createEntryName(File file); + + } + + public Album() { + super(); + try { + setDocument(DebugPlugin.newDocument()); + if (!sessionEndedListenerAdded) + DsfSession.addSessionEndedListener(sessionEndedListener); + sessionEndedListenerAdded = true; + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getName() + */ + public String getName() { + if (name == null) { + name = getDefaultAlbumName(); + } + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getDisplayName() + */ + public String getDisplayName() { + if (displayName == null || displayName.length() == 0) { + displayName = getName(); + } + return displayName; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getSessionID() + */ + public String getSessionID() { + sessionID = ""; + if (albumsBySessionID != null) { + for (Map.Entry entry : albumsBySessionID.entrySet()){ + if (entry.getValue().location != null && entry.getValue().location.equals(getLocation())){ + sessionID = entry.getKey(); + } + } + } + return sessionID; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getRecordingSessionID() + */ + public String getRecordingSessionID() { + return recordingSessionID; + } + + public void setRecordingSessionID(String sessionID) { + this.recordingSessionID = sessionID; + if (sessionID.length() > 0) + albumsRecordingBySessionID.put(sessionID, this); + } + + public void setSessionID(String sessionID) { + this.sessionID = sessionID; + if (sessionID.length() > 0) + albumsBySessionID.put(sessionID, this); + } + + /** + * Is the album currently open for recording + * @param sessionId + * @return true if the album is currently being recording by an active debug session + */ + public static boolean isSnapshotSession(String sessionId) { + EDCLaunch launch = EDCLaunch.getLaunchForSession(sessionId); + return launch != null && launch.isSnapshotLaunch(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#createSnapshot(org.eclipse.cdt.dsf.service.DsfSession, org.eclipse.cdt.debug.edc.internal.services.dsf.Stack.StackFrameDMC, org.eclipse.core.runtime.IProgressMonitor) + */ + public Snapshot createSnapshot(DsfSession session, StackFrameDMC stackFrame, IProgressMonitor monitor) throws Exception { + SubMonitor progress = SubMonitor.convert(monitor, "Creating Snapshot", 10000); + configureAlbum(); + progress.worked(100); + + if (getLocation() == null || !getLocation().toFile().exists()){ + createEmptyAlbum(); + } + + Snapshot snapshot = new Snapshot(this, session, stackFrame); + snapshot.writeSnapshotData(progress.newChild(7900)); + + snapshotList.add(snapshot); + saveAlbum(progress.newChild(1000)); + + monitor.done(); + return snapshot; + } + + private void configureAlbum() { + saveAlbumInfo(); + saveLaunchConfiguration(); + } + + private void saveAlbumInfo() { + if (!albumInfoSaved) { + Element infoElement = document.createElement(INFO); + infoElement.setAttribute("version", ALBUM_VERSION); + Calendar calendar = Calendar.getInstance(); + infoElement.setAttribute("month", Integer.toString(calendar.get(Calendar.MONTH))); + infoElement.setAttribute("day", Integer.toString(calendar.get(Calendar.DATE))); + infoElement.setAttribute("year", Integer.toString(calendar.get(Calendar.YEAR))); + infoElement.setAttribute("hour", Integer.toString(calendar.get(Calendar.HOUR))); + infoElement.setAttribute("minute", Integer.toString(calendar.get(Calendar.MINUTE))); + infoElement.setAttribute("second", Integer.toString(calendar.get(Calendar.SECOND))); + + Properties systemProps = System.getProperties(); + Map infoProps = new HashMap(); + Set systemKeys = systemProps.keySet(); + + for (Object sysKey : systemKeys) { + if (sysKey instanceof String) + infoProps.put((String) sysKey, systemProps.get(sysKey)); + } + Element propsElement = SnapshotUtils.makeXMLFromProperties(document, infoProps); + infoElement.appendChild(propsElement); + + getAlbumRootElement().appendChild(infoElement); + albumInfoSaved = true; + } + } + + private void saveResourceList() { + if (!resourceListSaved) { + Element resourcesElement = document.createElement(RESOURCES); + for (IPath filePath : files) { + Element fileElement = document.createElement(FILE); + fileElement.setAttribute("path", filePath.toOSString()); + resourcesElement.appendChild(fileElement); + } + getAlbumRootElement().appendChild(resourcesElement); + resourceListSaved = true; + } + } + + private void saveSnapshotMetadata() { + if (!metadataSaved || isRecording()) { + + if (metadataSaved){ + // If metatdata is saved, it must be a live debug session so + // we need to add a new snapshot to the snapshot list + NodeList snapMetaDataNode = document.getElementsByTagName(METADATA); + assert snapMetaDataNode.item(0) != null; + document.getDocumentElement().removeChild(snapMetaDataNode.item(0)); + } + + Element metadataElement = document.createElement(METADATA); + + Element albumElement = document.createElement(ALBUM); + albumElement.setAttribute("albumName", this.getDisplayName()); + metadataElement.appendChild(albumElement); + + Element snapshotsElement = document.createElement(SNAPSHOT_LIST); + metadataElement.appendChild(snapshotsElement); + + for (Snapshot snap : snapshotList) { + Element snapshotMetadataElement = document.createElement(SNAPSHOT); + if (snap.getSnapshotDisplayName().length() == 0) { + snapshotMetadataElement.setAttribute("displayName", snap.getSnapshotFileName()); + } else { + snapshotMetadataElement.setAttribute("displayName", snap.getSnapshotDisplayName()); + } + if (snap.getCreationDate() != null) { + snapshotMetadataElement.setAttribute("date", snap.getCreationDate().toString()); + } else { + snapshotMetadataElement.setAttribute("date", "unknown"); + } + + snapshotMetadataElement.setAttribute("description", snap.getSnapshotDescription()); + snapshotMetadataElement.setAttribute("fileName", snap.getSnapshotFileName()); + snapshotMetadataElement.setAttribute("referenceLocationSourceFile", snap.getReferenceLocationSourceFile()); + snapshotMetadataElement.setAttribute("referenceLocationLineNumber", String.valueOf(snap.getReferenceLocationLineNumber())); + + snapshotsElement.appendChild(snapshotMetadataElement); + } + getAlbumRootElement().appendChild(metadataElement); + metadataSaved = true; + } + } + + @SuppressWarnings("unchecked") + private void saveLaunchConfiguration() { + if (!launchConfigSaved) { + EDCLaunch launch = EDCLaunch.getLaunchForSession(getRecordingSessionID()); + try { + Map map = launch.getLaunchConfiguration().getAttributes(); + Element launchElement = document.createElement(LAUNCH); + launchType = launch.getLaunchConfiguration().getType().getIdentifier(); + launchName = launch.getLaunchConfiguration().getName(); + Integer count = launchNames.get(launchName); + if (count == null) { + launchNames.put(launchName, new Integer(0)); + } + else { + count = new Integer(count.intValue() + 1); + launchNames.put(launchName, count); + launchName += " (" + count.toString() + ")"; + } + launchElement.setAttribute("type", launchType); + launchElement.setAttribute("name", launchName); + Element propsElement = SnapshotUtils.makeXMLFromProperties(document, map); + launchElement.appendChild(propsElement); + getAlbumRootElement().appendChild(launchElement); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + launchConfigSaved = true; + } + } + + private static void addZipEntry(ZipOutputStream zipOut, IAlbumArchiveEntry entry, File file) + throws FileNotFoundException, IOException { + if (file.exists()) { + if (file.isDirectory()) { + for (File child : file.listFiles()) { + addZipEntry(zipOut, entry, child); + } + } else { + // Add ZIP entry to output stream.m + String path = ""; //$NON-NLS-1$ + + if (entry != null) { + path = entry.createEntryName(file); + } else { + path = file.getName(); + } + + zipOut.putNextEntry(new ZipEntry(path)); + + // Create a buffer for reading the files + byte[] buf = new byte[1024]; + + // Transfer bytes from the file to the ZIP file + // and compress the files + FileInputStream in = new FileInputStream(file); + int len; + while ((len = in.read(buf)) > 0) { + zipOut.write(buf, 0, len); + } + + // Complete the entry + zipOut.closeEntry(); + in.close(); + } + } + } + + /** + * Create and write a full snapshot album from scratch + */ + private void saveAlbum(IProgressMonitor monitor) { + + IPath zipPath = getLocation(); + ZipOutputStream zipOut = null; + try { + SubMonitor progress = SubMonitor.convert(monitor, 2000 + (snapshotList.size() * 1000)); + progress.subTask("Saving album data"); + + zipOut = new ZipOutputStream(new FileOutputStream(zipPath.toFile())); + + zipOut.putNextEntry(new ZipEntry(ALBUM_DATA)); + + saveResourceList(); + progress.worked(1000); + saveSnapshotMetadata(); + progress.worked(1000); + + String xml = LaunchManager.serializeDocument(document); + zipOut.write(xml.getBytes("UTF8")); //$NON-NLS-1$ + zipOut.closeEntry(); + + for (Snapshot snap : snapshotList) { + zipOut.putNextEntry(new ZipEntry(snap.getSnapshotFileName())); + snap.saveSnapshot(zipOut); + progress.worked(1000); + } + + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + } finally { + try { + if (zipOut != null) { + zipOut.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * Create and write a full snapshot album from scratch + */ + private void saveResources(IProgressMonitor monitor) { + + IPath zipPath = getLocation(); + ZipOutputStream zipOut = null; + try { + // TODO: Here's we're just rewriting the entire album again + // Need to just add the resources alone using proper utils + zipOut = new ZipOutputStream(new FileOutputStream(zipPath.toFile())); + + for (IPath path : files) { + + IAlbumArchiveEntry entry = new IAlbumArchiveEntry() { + + public String createEntryName(File file) { + StringBuffer entryPath = new StringBuffer(); + + entryPath.append("Resources/"); + + IPath filepath = new Path(file.getAbsolutePath()); + + String deviceName = filepath.getDevice(); + if (deviceName != null) { + // Remove the : from the end + entryPath.append(deviceName.substring(0, deviceName.length() - 1)); + entryPath.append("/"); + } + + String[] segments = filepath.segments(); + int numSegments = segments.length - 1; + + for (int i = 0; i < numSegments; i++) { + entryPath.append(segments[i]); + entryPath.append("/"); + } + entryPath.append(file.getName()); + return entryPath.toString(); + } + }; + addZipEntry(zipOut, entry, path.toFile()); + if (monitor != null) { + monitor.worked(1); + } + } + zipOut.putNextEntry(new ZipEntry(ALBUM_DATA)); + + saveResourceList(); + saveSnapshotMetadata(); + + String xml = LaunchManager.serializeDocument(document); + zipOut.write(xml.getBytes("UTF8")); //$NON-NLS-1$ + zipOut.closeEntry(); + + for (Snapshot snap : snapshotList) { + zipOut.putNextEntry(new ZipEntry(snap.getSnapshotFileName())); + snap.saveSnapshot(zipOut); + } + + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + } finally { + try { + if (zipOut != null) { + zipOut.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private String getDefaultAlbumName() { + return getLaunchName(); + } + + public void saveAlbum(IPath path) throws TransformerException, IOException { + String xml = LaunchManager.serializeDocument(document); + File file = path.toFile(); + if (!file.exists()) { + file.createNewFile(); + } + FileOutputStream stream = new FileOutputStream(file); + stream.write(xml.getBytes("UTF8")); //$NON-NLS-1$ + stream.close(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#openSnapshot(int) + */ + public void openSnapshot(final int index) { + + final DsfSession session = DsfSession.getSession(sessionID); + + DsfRunnable openIt = new DsfRunnable() { + public void run() { + currentSnapshotIndex = index; + try { + loadAlbum(false); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + if (session != null && snapshotList.size() > index) { + Snapshot snapshot = snapshotList.get(index); + snapshot.open(session); + // Fire the event + for (ISnapshotAlbumEventListener l : new ArrayList(listeners)) { + l.snapshotOpened(snapshot); + } + } + } + }; + + if (session != null && session.getExecutor() != null) + { + if (session.getExecutor().isInExecutorThread()) + openIt.run(); + else + session.getExecutor().execute(openIt); + } + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getCurrentSnapshotIndex() + */ + public int getCurrentSnapshotIndex() { + return currentSnapshotIndex; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#openNextSnapshot() + */ + public void openNextSnapshot() throws Exception { + int nextIndex = currentSnapshotIndex + 1; + if (nextIndex >= snapshotList.size()) + nextIndex = 0; + openSnapshot(nextIndex); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#openPreviousSnapshot() + */ + public void openPreviousSnapshot() throws Exception { + int previousIndex = currentSnapshotIndex - 1; + if (previousIndex < 0) + previousIndex = snapshotList.size() - 1; + openSnapshot(previousIndex); + } + + public void loadAlbum(boolean force) throws ParserConfigurationException, SAXException, IOException { + if (force) + loaded = false; + if (!loaded) { + File albumFile = location.toFile(); + setName(albumFile.getName()); + + if (!isRecording()){ + // not creating the snapshot, so must be snapshot play back + try { + ZipFileUtils.unzipFiles(albumFile, getAlbumRootDirectory().toOSString(), new NullProgressMonitor()); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + + BufferedInputStream stream = ZipFileUtils.openFile(albumFile, ALBUM_DATA, DSA_FILE_EXTENSIONS); + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + parser.setErrorHandler(new DefaultHandler()); + setDocument(parser.parse(new InputSource(stream))); + + loadAlbumInfo(); + loadLaunchConfiguration(); + loadResourceList(); + try { + loadSnapshotMetadata(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + loaded = true; + ZipFileUtils.unmount(); + } + } + } + + /** + * A lightwieght parse to get basic album info and what snapshots are + * available. + * + * @throws ParserConfigurationException + * @throws SAXException + * @throws IOException + */ + public void loadAlbumMetada(boolean force) throws Exception { + if (force) + metaDataLoaded = false; + if (!metaDataLoaded) { + + File albumFile = location.toFile(); + setDisplayName(albumFile.getName()); + + BufferedInputStream stream = null; + try { + stream = ZipFileUtils.openFile(albumFile, ALBUM_DATA, DSA_FILE_EXTENSIONS); + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + parser.setErrorHandler(new DefaultHandler()); + setDocument(parser.parse(new InputSource(stream))); + loadSnapshotMetadata(); + loadLaunchConfiguration(); // need to load launch config in case we need to delete it + + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError("Failed to load album: " + getName(), e); + } finally { + metaDataLoaded = true; + ZipFileUtils.unmount(); + } + } + } + + private void loadAlbumInfo() { + document.getElementsByTagName(INFO).item(0); + } + + private void setDocument(Document newDoc) + { + document = newDoc; + albumRootElement = null; + } + + private Element getAlbumRootElement() + { + if (albumRootElement == null) + { + NodeList albumRootElements = document.getElementsByTagName(ALBUM); + if (albumRootElements.getLength() == 0) + { + albumRootElement = document.createElement(ALBUM); + document.appendChild(albumRootElement); + } + else + { + albumRootElement = (Element) albumRootElements.item(0); + } + } + return albumRootElement; + } + + private void loadResourceList() { + NodeList resources = document.getElementsByTagName(RESOURCES); + NodeList elementFiles = ((Element) resources.item(0)).getElementsByTagName(FILE); + int numFiles = elementFiles.getLength(); + for (int i = 0; i < numFiles; i++) { + Element fileElement = (Element) elementFiles.item(i); + String elementPath = fileElement.getAttribute("path"); + files.add(PathUtils.createPath(elementPath)); // for cross-created snapshot + } + } + + private void loadSnapshotMetadata() throws Exception { + snapshotList.clear(); + NodeList snapMetaDataNode = document.getElementsByTagName(METADATA); + + if (snapMetaDataNode.getLength() == 0) { + throw new Exception("Invalid or corrupted Album : " + getName()); + } + NodeList albumNameElement = ((Element) snapMetaDataNode.item(0)).getElementsByTagName(ALBUM); + Element albumElement = (Element) albumNameElement.item(0); + String albumDisplayName = albumElement.getAttribute("albumName"); + + setDisplayName(albumDisplayName); + + NodeList elementSnapshots = ((Element) snapMetaDataNode.item(0)).getElementsByTagName(SNAPSHOT); + int numSnapshots = elementSnapshots.getLength(); + for (int i = 0; i < numSnapshots; i++) { + Element snapshotElement = (Element) elementSnapshots.item(i); + String elementDescription = snapshotElement.getAttribute("description"); + String elementDate = snapshotElement.getAttribute("date"); + String elementDispalyName = snapshotElement.getAttribute("displayName"); + String elementFileName = snapshotElement.getAttribute("fileName"); + String referenceLocationSourceFile = snapshotElement.getAttribute("referenceLocationSourceFile"); + String referenceLocationLineNumber = snapshotElement.getAttribute("referenceLocationLineNumber"); + + Snapshot s = new Snapshot(this); + s.setCreationDate(elementDate); + s.setSnapshotFileName(elementFileName); + s.setSnapshotDisplayName(elementDispalyName); + s.setSnapshotDescription(elementDescription); + if (referenceLocationLineNumber.length() > 0){ + s.setReferenceLocationLineNumber(Long.parseLong(referenceLocationLineNumber)); + } + s.setReferenceLocationSourceFile(referenceLocationSourceFile); + snapshotList.add(s); + } + } + + private void loadLaunchConfiguration() { + NodeList launchElements = document.getElementsByTagName(LAUNCH); + Element launchElement = (Element) launchElements.item(0); + if (launchElement == null){ + return; + } + launchType = launchElement.getAttribute("type"); + launchName = launchElement.getAttribute("name"); + + Element propElement = (Element) launchElement.getElementsByTagName(SnapshotUtils.PROPERTIES).item(0); + launchProperties = new HashMap(); + try { + SnapshotUtils.initializeFromXML(propElement, launchProperties); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if (adapter.equals(Document.class)) + return document; + + return super.getAdapter(adapter); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getAlbumRootDirectory() + */ + public IPath getAlbumRootDirectory() { + if (albumRootDirectory == null) { + IPath path = EDCDebugger.getDefault().getStateLocation().append("SnapshotAlbums"); + String locationName = location.lastSegment(); + int extension = locationName.lastIndexOf("."); + if (extension > 0) { + locationName = locationName.substring(0, extension); + } + path = path.append(locationName); + File dir = path.toFile(); + if (!dir.exists()) { + dir.mkdirs(); + } + albumRootDirectory = path; + } + return albumRootDirectory; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getLaunchTypeID() + */ + public String getLaunchTypeID() { + return launchType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getLaunchProperties() + */ + public HashMap getLaunchProperties() { + return launchProperties; + } + + public void setLaunchProperties(HashMap launchProperties) { + this.launchProperties = launchProperties; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getLaunchName() + */ + public String getLaunchName() { + return launchName; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#playSnapshots(org.eclipse.cdt.dsf.service.DsfSession) + */ + public void playSnapshots() { + if (!isPlayingSnapshots()) + { + Job playSnapshotsJob = new Job("Play Snapshots for Album " + getDisplayName()){ + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + monitor.beginTask("Play Snapshots for Album " + getDisplayName(), IProgressMonitor.UNKNOWN); + while (isPlayingSnapshots() && !monitor.isCanceled()) + { + Album.this.openNextSnapshot(); + Thread.sleep(getPlaySnapshotInterval()); + } + setPlayingSnapshots(false); + monitor.done(); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + return new Status(Status.ERROR, EDCDebugger.PLUGIN_ID, null, e); + } + return Status.OK_STATUS; + } + + }; + setPlayingSnapshots(true); + playSnapshotsJob.schedule(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#addFile(org.eclipse.core.runtime.IPath) + */ + public void addFile(IPath path) { + files.add(path); + } + + public static Album getAlbumByLocation(IPath path) { + return albumsByLocation.get(path); + } + + public static IAlbum getAlbumBySession(String sessionId) { + return albumsBySessionID.get(sessionId); + } + + public static Album getRecordingForSession(String sessionId) { + return albumsRecordingBySessionID.get(sessionId); + } + + public void setLocation(IPath albumPath) { + this.location = albumPath; + albumsByLocation.put(albumPath, this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getLocation() + */ + public IPath getLocation() { + return location; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#configureSourceLookupDirector(org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector) + */ + public void configureSourceLookupDirector(ISourceLookupDirector director) { + MappingSourceContainer sourceContainer = new MappingSourceContainer(getName()); + configureMappingSourceContainer(sourceContainer); + ArrayList containers = new ArrayList(Arrays.asList(director + .getSourceContainers())); + containers.add(sourceContainer); + + DirectorySourceContainer directoryContainer = new DirectorySourceContainer(getResourcesDirectory(), true); + containers.add(directoryContainer); + + director.setSourceContainers(containers.toArray(new ISourceContainer[containers.size()])); + } + + protected IPath getResourcesDirectory() + { + return getAlbumRootDirectory().append("Resources"); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#configureMappingSourceContainer(org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer) + */ + public void configureMappingSourceContainer(MappingSourceContainer mappingContainer) { + IPath albumRoot = getResourcesDirectory(); + List containers = new ArrayList(); + Set devicesAlreadyAdded = new HashSet(); + String deviceName = null; + for (IPath iPath : files) { + deviceName = iPath.getDevice(); + if (deviceName != null && !devicesAlreadyAdded.contains(deviceName)) + { + String albumRootSuffix = deviceName; + if (albumRootSuffix.endsWith(":")) + albumRootSuffix = albumRootSuffix.substring(0, albumRootSuffix.length() - 1); + devicesAlreadyAdded.add(deviceName); + MapEntrySourceContainer newContainer = new MapEntrySourceContainer(PathUtils.createPath(deviceName), albumRoot.append(albumRootSuffix)); + containers.add(newContainer); + + } + } + mappingContainer.addMapEntries(containers.toArray(new MapEntrySourceContainer[containers.size()])); + } + + public static void setVariableCaptureDepth(int newSetting) { + IEclipsePreferences scope = InstanceScope.INSTANCE.getNode(EDCDebugger.PLUGIN_ID); + scope.putInt(PREF_VARIABLE_CAPTURE_DEPTH, newSetting); + try { + scope.flush(); + } catch (BackingStoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + + public static int getVariableCaptureDepth() { + return Platform.getPreferencesService().getInt(EDCDebugger.PLUGIN_ID, + PREF_VARIABLE_CAPTURE_DEPTH, 5, null); + } + + public static void setPlaySnapshotInterval(int delayInMilliseconds) { + IEclipsePreferences scope = InstanceScope.INSTANCE.getNode(EDCDebugger.PLUGIN_ID); + scope.putInt(PLAY_SNAPSHOT_DELAY_TIME, delayInMilliseconds); + try { + scope.flush(); + } catch (BackingStoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + + public static int getPlaySnapshotInterval() { + return Platform.getPreferencesService().getInt(EDCDebugger.PLUGIN_ID, + PLAY_SNAPSHOT_DELAY_TIME, 5000, null); + } + + public static void setSnapshotCreationControl(String newSetting) { + IEclipsePreferences scope = InstanceScope.INSTANCE.getNode(EDCDebugger.PLUGIN_ID); + scope.put(PREF_CREATION_CONTROL, newSetting); + try { + scope.flush(); + } catch (BackingStoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + + public static String getSnapshotCreationControl() { + return Platform.getPreferencesService().getString(EDCDebugger.PLUGIN_ID, + PREF_CREATION_CONTROL, CREATE_MANUAL, null); + } + + protected static void playSnapshotSound() { + Bundle bundle = Platform.getBundle(EDCDebugger.getUniqueIdentifier()); + if (bundle == null) + return; + + URL url = null; + try { + url = FileLocator.toFileURL(bundle.getEntry(CAMERA_CLICK_WAV)); + } catch (IOException e) { + } catch (RuntimeException e){ + } + finally { + if (url != null){ + File f = new File(url.getFile()); + SnapshotUtils.playSoundFile(f); + } + } + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getSnapshots() + */ + public List getSnapshots() { + if (snapshotList == null || snapshotList.size() == 0) { + try { + loadAlbumMetada(false); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError("Failed to load snapshots", e); + } + } + + return snapshotList; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#isLoaded() + */ + public boolean isLoaded() { + return loaded; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#getIndexOfSnapshot(org.eclipse.cdt.debug.edc.internal.snapshot.Snapshot) + */ + public int getIndexOfSnapshot(Snapshot snap) { + return snapshotList.indexOf(snap); + } + + public void setCurrentSnapshotIndex(int index) { + if (currentSnapshotIndex >= 0 && currentSnapshotIndex < snapshotList.size()) { + currentSnapshotIndex = index; + } + } + + /** + * Update album.xml within the Album's .dsa file with new Snapshot data + * + * @param albumName + * - Name of album to display. Use null if value should not be + * updated. + * @param snap + * - Specific snapshot to update. Use null is snapshot should not + * be updated. + */ + public void updateSnapshotMetaData(String albumName, Snapshot snap) { + NodeList snapMetaDataNode = document.getElementsByTagName(METADATA); + + // try to update album display name + if (albumName != null) { + NodeList albumNameNode = ((Element) snapMetaDataNode.item(0)).getElementsByTagName(ALBUM); + ((Element) albumNameNode.item(0)).setAttribute("albumName", albumName); + } + + // try to update snapshot data + if (snap != null) { + + NodeList elementSnapshots = ((Element) snapMetaDataNode.item(0)).getElementsByTagName(SNAPSHOT); + + int numSnapshots = elementSnapshots.getLength(); + for (int i = 0; i < numSnapshots; i++) { + Element currentSnapshotNode = (Element) elementSnapshots.item(i); + String fileName = currentSnapshotNode.getAttribute("fileName"); + if (fileName.equals(snap.getSnapshotFileName())) { + + currentSnapshotNode.setAttribute("description", snap.getSnapshotDescription()); + currentSnapshotNode.setAttribute("displayName", snap.getSnapshotDisplayName()); + + break; + } + } + } + + saveAlbumData(); + + // refresh all data + try { + loadAlbumMetada(true); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + private void saveAlbumData() { + try { + File tempFile = File.createTempFile("album", ".xml"); + File tempFile2 = new File(tempFile.getParent() + File.separator + ALBUM_DATA); + tempFile.delete(); + if (!tempFile2.exists()) { + tempFile2.delete(); + } + tempFile2.createNewFile(); + saveAlbum(new Path(tempFile2.toString())); + File[] fileList = { tempFile2 }; + ZipFileUtils.addFilesToZip(fileList, getLocation().toFile(), DSA_FILE_EXTENSIONS); + + } catch (IOException e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#deleteSnapshot(org.eclipse.cdt.debug.edc.internal.snapshot.Snapshot) + */ + public void deleteSnapshot(Snapshot snap) { + + NodeList snapMetaDataNode = document.getElementsByTagName(METADATA); + + NodeList elementSnapshotList = ((Element) snapMetaDataNode.item(0)).getElementsByTagName(SNAPSHOT_LIST); + NodeList elementSnapshots = ((Element) snapMetaDataNode.item(0)).getElementsByTagName(SNAPSHOT); + + int numSnapshots = elementSnapshots.getLength(); + for (int i = 0; i < numSnapshots; i++) { + Element currentSnapshotNode = (Element) elementSnapshots.item(i); + String fileName = currentSnapshotNode.getAttribute("fileName"); + if (fileName.equals(snap.getSnapshotFileName())) { + elementSnapshotList.item(0).removeChild(currentSnapshotNode); + break; + } + } + + snapshotList.remove(snap); + + saveAlbumData(); + + // refresh all data + try { + loadAlbum(true); + loadAlbumMetada(true); + } catch (Exception e) { + + } + + ZipFileUtils.deleteFileFromZip(snap.getSnapshotFileName(), getLocation().toFile(), DSA_FILE_EXTENSIONS); + } + + @Override + public String toString() { + return "Album [name=" + name + ", launchName=" + launchName + ", sessionID=" + sessionID + "]"; + } + + public IPath createEmptyAlbum() { + IPath zipPath = null; + try { + zipPath = SnapshotUtils.getSnapshotsProject().getLocation(); + zipPath = zipPath.append(getDefaultAlbumName()); + zipPath = zipPath.addFileExtension("dsa"); + boolean created = ZipFileUtils.createNewZip(zipPath.toFile()); + + if (created && zipPath.toFile().exists()){ + setLocation(zipPath); + } else { + return null; + } + SnapshotUtils.getSnapshotsProject().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(e.getLocalizedMessage(), e); + } + return zipPath; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.snapshot.IAlbum#isRecording() + */ + public boolean isRecording() { + return recordingSessionID.length() > 0; + } + + /** + * @noreference This method is not intended to be referenced by clients. + */ + public static void addSnapshotAlbumEventListener(ISnapshotAlbumEventListener listener) { + listeners.add(listener); + } + + /** + * @noreference This method is not intended to be referenced by clients. + */ + public static void removeSnapshotAlbumEventListener(ISnapshotAlbumEventListener listener) { + listeners.remove(listener); + } + + public static void captureSnapshotForSession(final DsfSession session) { + Job createSnapshotJob = new Job("Creating Debug Snapshot") { + + @Override + protected IStatus run(final IProgressMonitor monitor) { + + Query frameQuery = new Query() { + @Override + protected void execute( + DataRequestMonitor rm) { + DsfServicesTracker servicesTracker = new DsfServicesTracker( + EDCDebugger.getBundleContext(), + session.getId()); + try { + RunControl runControl = servicesTracker.getService(RunControl.class); + IThreadDMContext[] suspendedThreads = runControl.getSuspendedThreads(); + if (suspendedThreads.length == 0) + { + rm.setData(null); + rm.done(); + } + else + { + Stack stackService = servicesTracker.getService(Stack.class); + if (stackService != null) { + stackService.getTopFrame(suspendedThreads[0], rm); + } + } + } finally { + servicesTracker.dispose(); + } + } + }; + + session.getExecutor().execute(frameQuery); + + IStatus status = Status.OK_STATUS; + try { + final StackFrameDMC stackFrame = (StackFrameDMC) frameQuery.get(); + + String sessionId = session.getId(); + Album album = Album.getRecordingForSession(sessionId); + if (album == null) { + album = new Album(); + album.setRecordingSessionID(sessionId); + } + final Album finalAlbum = album; + playSnapshotSound(); + + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor drm) { + try { + Snapshot newSnapshot = finalAlbum.createSnapshot(session, stackFrame, monitor); + // Fire the event to anyone listening + for (ISnapshotAlbumEventListener l : new ArrayList(listeners)) { + l.snapshotCreated(finalAlbum, newSnapshot, session, stackFrame); + } + drm.setData(Status.OK_STATUS); + } catch (Exception e) { + Status s = new Status(IStatus.ERROR, EDCDebugger.getUniqueIdentifier(), "Error creating snapshot.", e); + EDCDebugger.getMessageLogger().log(s); + drm.setStatus(s); + } + drm.done(); + } + }; + + session.getExecutor().execute(query); + + status = query.get(); + } catch (Exception e) { + status = new Status(Status.ERROR, EDCDebugger.PLUGIN_ID, "Error creating snapshot", e); + } + + return status; + } + }; + + createSnapshotJob.schedule(); + } + + public boolean isPlayingSnapshots() { + return playingSnapshots; + } + + public void setPlayingSnapshots(boolean playingSnapshots) { + this.playingSnapshots = playingSnapshots; + } + + public void stopPlayingSnapshots() { + setPlayingSnapshots(false); + openSnapshot(getCurrentSnapshotIndex()); // Reloading the current snapshot will resync the UI. + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/AlbumSourceContainer.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/AlbumSourceContainer.java new file mode 100644 index 0000000..143f5c9 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/AlbumSourceContainer.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.snapshot; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.snapshot.IAlbum; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.sourcelookup.ISourceContainerType; +import org.eclipse.debug.core.sourcelookup.containers.AbstractSourceContainer; + +public class AlbumSourceContainer extends AbstractSourceContainer { + + private IAlbum album; + + public static final String TYPE_ID = EDCDebugger.getUniqueIdentifier() + ".containerType.albumMapping"; //$NON-NLS-1$ + + public AlbumSourceContainer(IAlbum album) { + this.album = album; + } + + public AlbumSourceContainer() { + } + + public Object[] findSourceElements(String name) throws CoreException { + // TODO Auto-generated method stub + return new Object[0]; + } + + public String getName() { + return album.getDisplayName(); + } + + public ISourceContainerType getType() { + return getSourceContainerType(TYPE_ID); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/AlbumSourceContainerType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/AlbumSourceContainerType.java new file mode 100644 index 0000000..289cefc --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/AlbumSourceContainerType.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.snapshot; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.AbstractSourceContainerTypeDelegate; + +public class AlbumSourceContainerType extends AbstractSourceContainerTypeDelegate { + + public ISourceContainer createSourceContainer(String memento) throws CoreException { + return new AlbumSourceContainer(); + } + + public String getMemento(ISourceContainer container) throws CoreException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/ISnapshotAlbumEventListener.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/ISnapshotAlbumEventListener.java new file mode 100644 index 0000000..0acbd7e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/ISnapshotAlbumEventListener.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.snapshot; + +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.dsf.service.DsfSession; + +public interface ISnapshotAlbumEventListener { + + public void snapshotCreated(Album album, Snapshot snapshot, + DsfSession session, StackFrameDMC stackFrame); + + public void snapshotOpened(Snapshot snapshot); + + public void snapshotSessionEnded(Album album, DsfSession session); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/Snapshot.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/Snapshot.java new file mode 100644 index 0000000..2b44aa4 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/Snapshot.java @@ -0,0 +1,305 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.snapshot; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.util.Date; +import java.util.zip.ZipOutputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.TransformerException; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.ZipFileUtils; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.snapshot.ISnapshotContributor; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.service.IDsfService; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.internal.core.LaunchManager; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.helpers.DefaultHandler; + +@SuppressWarnings("restriction") +public class Snapshot extends PlatformObject { + + // XML elements + public static final String SNAPSHOT = "snapshot"; + + public static final String SNAPSHOT_FILENAME_PREFIX = "snapshot_"; + + private Document document; + private Element snapshotRootElement; + private DsfSession session; + private Album album; + private String snapshotFileName; + private String snapshotDisplayName; + + private String creationDate; + + private String snapshotDescription; + + // Reference location information: when a snapshot is created + // we record the location in the most recently suspended stack frame. + // This is then used to create a default name for the snapshot and + // is displayed in the snapshot view. + // Of course, when debugging multiple contexts this does not + // provide a complete description of the snapshot. + + private String referenceLocationSourceFile = ""; + private long referenceLocationLineNumber; + + /* + * Create a snapshot for reading + */ + public Snapshot(Album album){ + try { + this.album = album; + document = DebugPlugin.newDocument(); + snapshotRootElement = document.createElement(SNAPSHOT); + } catch (CoreException e) { + e.printStackTrace(); + } + } + + /** + * Create a snapshot with prep for writing to file. + * @param album + * @param recentStackFrame - + */ + public Snapshot(Album album, DsfSession session, StackFrameDMC recentStackFrame){ + try { + assert session != null; + + this.album = album; + this.session = session; + document = DebugPlugin.newDocument(); + snapshotRootElement = document.createElement(SNAPSHOT); + document.appendChild(snapshotRootElement); + + if (recentStackFrame == null){ + snapshotDisplayName = snapshotFileName; + } else { + snapshotDisplayName = createSnapshotNameFromStackFrameDMC(recentStackFrame); + } + snapshotFileName = SNAPSHOT_FILENAME_PREFIX + System.currentTimeMillis() + ".xml"; + creationDate = new Date(System.currentTimeMillis()).toString(); + + if (recentStackFrame != null){ + File f = new File(recentStackFrame.getSourceFile()); + if (f != null){ + setReferenceLocationSourceFile(f.getName()); + } + setReferenceLocationLineNumber(recentStackFrame.getLineNumber()); + } + + } catch (CoreException e) { + e.printStackTrace(); + } + + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if (adapter.equals(Document.class)) + return document; + + return super.getAdapter(adapter); + } + + private static String getServiceFilter(String sessionId) { + return ("(" + IDsfService.PROP_SESSION_ID + "=" + sessionId + ")").intern(); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void open(DsfSession session) { + ServiceReference[] references; + BufferedInputStream stream = null; + try { + + stream = ZipFileUtils.openFile(album.getLocation().toFile(), snapshotFileName, new String[] {"dsa"} ); + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + parser.setErrorHandler(new DefaultHandler()); + + document = parser.parse(new InputSource(stream)); + NodeList snapNode = document.getElementsByTagName(SNAPSHOT); + Element snapShotE = (Element)snapNode.item(0); + + references = EDCDebugger.getBundleContext().getServiceReferences(ISnapshotContributor.class.getName(), + getServiceFilter(session.getId())); + for (ServiceReference serviceReference : references) { + ISnapshotContributor sc = (ISnapshotContributor) EDCDebugger.getBundleContext().getService( + serviceReference); + sc.loadSnapshot(snapShotE); + } + + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + } finally { + ZipFileUtils.unmount(); + } + } + + /** + * Write snapshot data. + * + * @param monitor the progress monitor to use for reporting progress to the user. It is the caller's responsibility + to call done() on the given monitor. Accepts null, indicating that no progress should be + reported and that the operation cannot be canceled. + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void writeSnapshotData(IProgressMonitor monitor) throws Exception{ + try { + ServiceReference[] references = EDCDebugger.getBundleContext().getServiceReferences( + ISnapshotContributor.class.getName(), getServiceFilter(session.getId())); + SubMonitor progress = SubMonitor.convert(monitor, references.length * 1000); + progress.subTask("Writing snapshot data"); + for (ServiceReference serviceReference : references) { + if (progress.isCanceled()) + break; + ISnapshotContributor sc = (ISnapshotContributor) EDCDebugger.getBundleContext().getService( + serviceReference); + Element serviceElement = sc.takeSnapshot(album, document, progress.newChild(1000)); + if (serviceElement != null) + snapshotRootElement.appendChild(serviceElement); + } + } catch (InvalidSyntaxException e) { + EDCDebugger.getMessageLogger().logError("Invalid session ID syntax", e); //$NON-NLS-1$ + } catch (IllegalStateException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + + public String getSnapshotFileName(){ + return snapshotFileName; + } + + public void setSnapshotFileName(String snapshotFileName){ + this.snapshotFileName = snapshotFileName; + } + + public void saveSnapshot(ZipOutputStream zipOut) throws TransformerException, IOException { + String xml = LaunchManager.serializeDocument(document); + zipOut.write(xml.getBytes("UTF8")); //$NON-NLS-1$ + zipOut.closeEntry(); + } + + public String getCreationDate(){ + return creationDate; + } + + public void setCreationDate(String date){ + this.creationDate = date; + } + + /** + * Set the display text for the snapshot + * @param snapshotDisplayName + */ + public void setSnapshotDisplayName(String snapshotDisplayName) { + this.snapshotDisplayName = snapshotDisplayName; + } + + /** + * Get the display name of the snapshot. If there is no display name, the XML file containing + * the snapshot data in the DSA archive will be used. + * @return + */ + public String getSnapshotDisplayName() { + if (snapshotDisplayName == null || snapshotDisplayName.length() == 0){ + snapshotDisplayName = snapshotFileName; + } + return snapshotDisplayName; + } + + /** + * Additional arbitrary notes to describe a particular snapshot + * @return + */ + public String getSnapshotDescription() { + if (snapshotDescription == null){ + snapshotDescription = ""; + } + return snapshotDescription; + } + + /** + * Set the snapshot description text. + * @param descr + */ + public void setSnapshotDescription(String descr) { + snapshotDescription = descr; + } + + /** + * Get the album this snapshot belongs to + * @return + */ + public Album getAlbum(){ + return album; + } + + /** + * Creates the snapshot name from a stack frame dmc. + * + * @param frameDMC the frame dmc + * + * @return the snapshot name + */ + public String createSnapshotNameFromStackFrameDMC(StackFrameDMC stackFrame) + { + assert stackFrame != null; + StringBuilder name = new StringBuilder(); + if (stackFrame.getFunctionName() != null && stackFrame.getFunctionName().length() != 0) { + name.append(stackFrame.getFunctionName()); + name.append("() : "); //$NON-NLS-1$ + name.append(stackFrame.getLineNumber()); + } else if (stackFrame.getModuleName() != null && stackFrame.getModuleName().length() != 0) { + name.append(stackFrame.getModuleName()); + } else if (stackFrame.getInstructionPtrAddress() != null) { + name.append(stackFrame.getInstructionPtrAddress().toHexAddressString()); + } + + return name.toString(); + } + + public void setReferenceLocationSourceFile(String referenceLocationSourceFile) { + assert referenceLocationSourceFile != null; + this.referenceLocationSourceFile = referenceLocationSourceFile; + } + + public String getReferenceLocationSourceFile() { + assert referenceLocationSourceFile != null; + return referenceLocationSourceFile; + } + + public void setReferenceLocationLineNumber(long referenceLocationLineNumber) { + this.referenceLocationLineNumber = referenceLocationLineNumber; + } + + public long getReferenceLocationLineNumber() { + return referenceLocationLineNumber; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/SnapshotLaunchSequence.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/SnapshotLaunchSequence.java new file mode 100644 index 0000000..d2b71ea --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/SnapshotLaunchSequence.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.snapshot; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.launch.AbstractFinalLaunchSequence; +import org.eclipse.cdt.debug.edc.launch.EDCLaunch; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +public class SnapshotLaunchSequence extends AbstractFinalLaunchSequence { + + private final Step[] steps = new Step[] { + + trackerStep, + + new Step() { + + @Override + public void execute(final RequestMonitor requestMonitor) { + try { + int snapIndex = getLaunch().getAlbum().getCurrentSnapshotIndex(); + getLaunch().getAlbum().openSnapshot(snapIndex); + requestMonitor.done(); + } catch (Exception e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, EDCDebugger.PLUGIN_ID, + "Failed to open snapshot. Reason: " + e.getLocalizedMessage())); + } + } + + } + + }; + + public SnapshotLaunchSequence(DsfExecutor executor, EDCLaunch launch, IProgressMonitor pm) { + super(executor, launch, pm, "Configuring Snapshot Launch", "Aborting configuring Snapshot Launch"); + } + + @Override + public Step[] getSteps() { + return steps; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.launch.AbstractFinalLaunchSequence#useLocalAgentOnly() + */ + @Override + protected boolean useLocalAgentOnly() { + return true; + } + + @Override + protected void specifyRequiredPeer() { + // No TCF agent needed. + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/SnapshotUtils.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/SnapshotUtils.java new file mode 100644 index 0000000..524c205 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/snapshot/SnapshotUtils.java @@ -0,0 +1,649 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.snapshot; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.UnsupportedAudioFileException; + +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.launch.IEDCLaunchConfigurationConstants; +import org.eclipse.cdt.debug.edc.snapshot.IAlbum; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class SnapshotUtils extends PlatformObject { + + /** + * Constants for XML element names and attributes + */ + public static final String PROPERTIES = "properties"; //$NON-NLS-1$ + private static final String KEY = "key"; //$NON-NLS-1$ + private static final String VALUE = "value"; //$NON-NLS-1$ + private static final String SET_ENTRY = "setEntry"; //$NON-NLS-1$ + private static final String MAP_ENTRY = "mapEntry"; //$NON-NLS-1$ + private static final String LIST_ENTRY = "listEntry"; //$NON-NLS-1$ + private static final String SET_ATTRIBUTE = "setAttribute"; //$NON-NLS-1$ + private static final String MAP_ATTRIBUTE = "mapAttribute"; //$NON-NLS-1$ + private static final String LIST_ATTRIBUTE = "listAttribute"; //$NON-NLS-1$ + private static final String BOOLEAN_ATTRIBUTE = "booleanAttribute"; //$NON-NLS-1$ + private static final String INT_ATTRIBUTE = "intAttribute"; //$NON-NLS-1$ + private static final String LONG_ATTRIBUTE = "longAttribute"; //$NON-NLS-1$ + private static final String BIG_INTEGER_ATTRIBUTE = "bigIntegerAttribute"; //$NON-NLS-1$ + private static final String STRING_ATTRIBUTE = "stringAttribute"; //$NON-NLS-1$ + private static final String SERIALIZED_ATTRIBUTE = "serializedAttribute"; //$NON-NLS-1$ + + @SuppressWarnings("unchecked") + static public Element makeXMLFromProperties(Document doc, Map properties) { + + Element rootElement = doc.createElement(PROPERTIES); + Iterator keys = properties.keySet().iterator(); + while (keys.hasNext()) { + String key = keys.next(); + if (key != null) { + Object value = properties.get(key); + if (value == null) { + continue; + } + Element element = null; + String valueString = null; + try { + if (value instanceof String) { + valueString = (String) value; + element = createKeyValueElement(doc, STRING_ATTRIBUTE, key, valueString); + } else if (value instanceof Integer) { + valueString = ((Integer) value).toString(); + element = createKeyValueElement(doc, INT_ATTRIBUTE, key, valueString); + } else if (value instanceof Long) { + valueString = ((Long) value).toString(); + element = createKeyValueElement(doc, LONG_ATTRIBUTE, key, valueString); + } else if (value instanceof BigInteger) { + valueString = ((BigInteger) value).toString(); + element = createKeyValueElement(doc, BIG_INTEGER_ATTRIBUTE, key, valueString); + } else if (value instanceof Boolean) { + valueString = ((Boolean) value).toString(); + element = createKeyValueElement(doc, BOOLEAN_ATTRIBUTE, key, valueString); + } else if (value instanceof List) { + element = createListElement(doc, LIST_ATTRIBUTE, key, (List) value); + } else if (value instanceof Map) { + element = createMapElement(doc, MAP_ATTRIBUTE, key, (Map) value); + } else if (value instanceof HashSet) { + element = createSetElement(doc, SET_ATTRIBUTE, key, (Set) value); + } + } catch (Exception e) { // Don't do anything here, we'll try to handle it as + // as serialized object. + } + if (element == null) + { + try { + element = createSerializedElement(doc, SERIALIZED_ATTRIBUTE, key, value); + } catch (IOException e) {EDCDebugger.getMessageLogger().logError("Error adding to snapshot: " + value.toString(), e);}; + } + rootElement.appendChild(element); + } + } + return rootElement; + } + + /** + * Helper method that creates a 'key value' element of the specified type + * with the specified attribute values. + */ + static protected Element createKeyValueElement(Document doc, String elementType, String key, String value) { + Element element = doc.createElement(elementType); + element.setAttribute(KEY, key); + element.setAttribute(VALUE, value); + return element; + } + + /** + * Creates a new Element for the specified + * java.util.List + * + * @param doc + * the doc to add the element to + * @param elementType + * the type of the element + * @param setKey + * the key for the element + * @param list + * the list to fill the new element with + * @return the new element + */ + static protected Element createListElement(Document doc, String elementType, String listKey, List list) { + Element listElement = doc.createElement(elementType); + listElement.setAttribute(KEY, listKey); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + String value = (String) iterator.next(); + Element element = doc.createElement(LIST_ENTRY); + element.setAttribute(VALUE, value); + listElement.appendChild(element); + } + return listElement; + } + + /** + * Creates a new Element for the specified + * java.util.Set + * + * @param doc + * the doc to add the element to + * @param elementType + * the type of the element + * @param setKey + * the key for the element + * @param set + * the set to fill the new element with + * @return the new element + * + * @since 3.3 + */ + static protected Element createSetElement(Document doc, String elementType, String setKey, Set set) { + Element setElement = doc.createElement(elementType); + setElement.setAttribute(KEY, setKey); + Element element = null; + for (Object object : set) { + element = doc.createElement(SET_ENTRY); + element.setAttribute(VALUE, (String) object); + setElement.appendChild(element); + } + return setElement; + } + + static protected Element createSerializedElement(Document doc, String elementType, String key, Object value) throws IOException { + Element element = doc.createElement(elementType); + element.setAttribute(KEY, key); + element.appendChild(doc.createTextNode(serializeObjectToString(value))); + return element; + } + + /** + * Creates a new Element for the specified + * java.util.Map + *

    + * NOTE: this creates a map from your map -- your ISnapshot#loadSnapshot() implementation + * must recover the right types. + * @param doc + * the doc to add the element to + * @param elementType + * the type of the element + * @param setKey + * the key for the element + * @param map + * the map to fill the new element with + * @return the new element + * + */ + static protected Element createMapElement(Document doc, String elementType, String mapKey, Map map) { + Element mapElement = doc.createElement(elementType); + mapElement.setAttribute(KEY, mapKey); + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey().toString(); + String value = entry.getValue() != null ? entry.getValue().toString() : null; + Element element = doc.createElement(MAP_ENTRY); + element.setAttribute(KEY, key); + element.setAttribute(VALUE, value); + mapElement.appendChild(element); + } + return mapElement; + } + + /** + * Initializes the mapping of attributes from the XML file + * + * @param root + * the root node from the XML document + * @throws CoreException + */ + static public void initializeFromXML(Element root, Map properties) throws CoreException { + if (root.getNodeName().equalsIgnoreCase(PROPERTIES)) { + NodeList list = root.getChildNodes(); + Node node = null; + Element element = null; + String nodeName = null; + for (int i = 0; i < list.getLength(); ++i) { + node = list.item(i); + short nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + element = (Element) node; + nodeName = element.getNodeName(); + try { + if (nodeName.equalsIgnoreCase(STRING_ATTRIBUTE)) { + setStringAttribute(element, properties); + } else if (nodeName.equalsIgnoreCase(INT_ATTRIBUTE)) { + setIntegerAttribute(element, properties); + } else if (nodeName.equalsIgnoreCase(LONG_ATTRIBUTE)) { + setLongAttribute(element, properties); + } else if (nodeName.equalsIgnoreCase(BIG_INTEGER_ATTRIBUTE)) { + setBigIntegerAttribute(element, properties); + } else if (nodeName.equalsIgnoreCase(BOOLEAN_ATTRIBUTE)) { + setBooleanAttribute(element, properties); + } else if (nodeName.equalsIgnoreCase(LIST_ATTRIBUTE)) { + setListAttribute(element, properties); + } else if (nodeName.equalsIgnoreCase(MAP_ATTRIBUTE)) { + setMapAttribute(element, properties); + } else if (nodeName.equalsIgnoreCase(SET_ATTRIBUTE)) { + setSetAttribute(element, properties); + } else if (nodeName.equalsIgnoreCase(SERIALIZED_ATTRIBUTE)) { + setSerializedAttribute(element, properties); + } else { + EDCDebugger.getMessageLogger().logError("Unsupported element: " + nodeName, null); + } + } catch (Exception e) { + // Some integers are longs and so will fail when adding + // their properties to the launch configuration. LaunchConfigurationInfo + // does not support any number but Integer (no BigInteger or Long) + // See org.eclipse.debug.internal.core.LaunchConfigurationInfo#getAsXML(). + EDCDebugger.getMessageLogger().logError("Skipping snapshot element.", e); + } finally { + // continue on to the next element + } + } + } + } + + } + + /** + * Loads a String from the specified element into the local + * attribute mapping + * + * @param element + * the element to load from + * @throws CoreException + */ + static protected void setStringAttribute(Element element, Map properties) throws CoreException { + properties.put(element.getAttribute(KEY), element.getAttribute(VALUE)); + } + + /** + * Loads an Integer from the specified element into the local + * attribute mapping + * + * @param element + * the element to load from + * @throws CoreException + */ + static protected void setIntegerAttribute(Element element, Map properties) throws CoreException { + properties.put(element.getAttribute(KEY), new Integer(element.getAttribute(VALUE))); + } + + /** + * Loads an Long from the specified element into the local + * attribute mapping + * + * @param element + * the element to load from + * @throws CoreException + */ + static protected void setLongAttribute(Element element, Map properties) throws CoreException { + properties.put(element.getAttribute(KEY), new Long(element.getAttribute(VALUE))); + } + + /** + * Loads a serialized Object from the specified element into the local + * attribute mapping + * + * @param element + * the element to load from + * @throws CoreException + * @throws IOException + * @throws ClassNotFoundException + * @throws DecoderException + */ + static protected void setSerializedAttribute(Element element, Map properties) throws CoreException, IOException, ClassNotFoundException, DecoderException { + properties.put(element.getAttribute(KEY), createSerializedObjectFromString(element.getFirstChild().getTextContent())); + } + + /** + * Loads an BigInteger from the specified element into the local + * attribute mapping + * + * @param element + * the element to load from + * @throws CoreException + */ + static protected void setBigIntegerAttribute(Element element, Map properties) throws CoreException { + properties.put(element.getAttribute(KEY), new BigInteger(element.getAttribute(VALUE))); + } + + /** + * Loads a Boolean from the specified element into the local + * attribute mapping + * + * @param element + * the element to load from + * @throws CoreException + */ + static protected void setBooleanAttribute(Element element, Map properties) throws CoreException { + properties.put(element.getAttribute(KEY), Boolean.valueOf(element.getAttribute(VALUE))); + } + + /** + * Reads a List attribute from the specified XML node and loads + * it into the mapping of attributes + * + * @param element + * the element to read the list attribute from + * @throws CoreException + * if the element has an invalid format + */ + static protected void setListAttribute(Element element, Map properties) throws CoreException { + String listKey = element.getAttribute(KEY); + NodeList nodeList = element.getChildNodes(); + int entryCount = nodeList.getLength(); + List list = new ArrayList(entryCount); + Node node = null; + Element selement = null; + for (int i = 0; i < entryCount; i++) { + node = nodeList.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + selement = (Element) node; + if (selement.getNodeName().equalsIgnoreCase(LIST_ENTRY)) { + String value = selement.getAttribute(VALUE); + list.add(value); + } + } + } + properties.put(listKey, list); + } + + /** + * Reads a Set attribute from the specified XML node and loads + * it into the mapping of attributes + * + * @param element + * the element to read the set attribute from + * @throws CoreException + * if the element has an invalid format + * + * @since 3.3 + */ + static protected void setSetAttribute(Element element, Map properties) throws CoreException { + String setKey = element.getAttribute(KEY); + NodeList nodeList = element.getChildNodes(); + int entryCount = nodeList.getLength(); + Set set = new HashSet(entryCount); + Node node = null; + Element selement = null; + for (int i = 0; i < entryCount; i++) { + node = nodeList.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + selement = (Element) node; + if (selement.getNodeName().equalsIgnoreCase(SET_ENTRY)) { + set.add(element.getAttribute(VALUE)); + } + } + } + properties.put(setKey, set); + } + + /** + * Reads a Map attribute from the specified XML node and loads + * it into the mapping of attributes + *

    + * NOTE: this creates a map -- your ISnapshot#loadSnapshot() implementation + * must recover the right types. + * + * @param element + * the element to read the map attribute from + * @throws CoreException + * if the element has an invalid format + */ + static protected void setMapAttribute(Element element, Map properties) throws CoreException { + String mapKey = element.getAttribute(KEY); + NodeList nodeList = element.getChildNodes(); + int entryCount = nodeList.getLength(); + Map map = new HashMap(entryCount); + Node node = null; + Element selement = null; + for (int i = 0; i < entryCount; i++) { + node = nodeList.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + selement = (Element) node; + if (selement.getNodeName().equalsIgnoreCase(MAP_ENTRY)) { + map.put(selement.getAttribute(KEY), selement.getAttribute(VALUE)); + } + } + } + properties.put(mapKey, map); + } + + static public IProject getSnapshotsProject() throws CoreException { + IProject snapshotsProject = null; + // See if the default project exists + String defaultProjectName = "Snapshots"; + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + snapshotsProject = workspace.getRoot().getProject( + defaultProjectName); + if (snapshotsProject.exists()) { + if (!snapshotsProject.isOpen()) + snapshotsProject.open(new NullProgressMonitor()); + } else { + IProjectDescription description = workspace.newProjectDescription(defaultProjectName); + description.setLocation(null); + try { + snapshotsProject.create(description, new NullProgressMonitor()); + snapshotsProject.open(new NullProgressMonitor()); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + return snapshotsProject; + } + + // TODO: This was taken from SnapshotLaunchDelegate. Need to refactor properly to make this common.... + /** + * Load an album and launch the session without creating a Snapshot launch configuration. + * Only creates the launch configuration type specified in the album data. + */ + static public boolean launchAlbumSession(Album album){ + IPath albumPath = album.getLocation(); + + try { + if (!album.isLoaded()){ + album.loadAlbum(false); + } + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + return false; + } + + ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); + ILaunchConfigurationType launchType = lm.getLaunchConfigurationType(album.getLaunchTypeID()); + if (launchType == null) { + // Can't launch TODO: Need error or exception + return false; + } + ILaunchConfiguration proxyLaunchConfig = findExistingLaunchForAlbum(album); + if (proxyLaunchConfig == null) { + String lcName = lm.generateLaunchConfigurationName(album.getDisplayName()); + ILaunchConfigurationWorkingCopy proxyLaunchConfigWC = null; + try { + proxyLaunchConfigWC = launchType.newInstance(null, lcName); + proxyLaunchConfigWC.setAttributes(album.getLaunchProperties()); + proxyLaunchConfigWC.setAttribute(IEDCLaunchConfigurationConstants.ATTR_ALBUM_FILE, albumPath.toOSString()); + proxyLaunchConfig = proxyLaunchConfigWC.doSave(); + + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + + } + + if (proxyLaunchConfig != null) + { + final ILaunchConfiguration finalProxyLC = proxyLaunchConfig; + Job launchJob = new Job("Launching " + albumPath.toFile().getName()) { + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + finalProxyLC.launch(ILaunchManager.DEBUG_MODE, new NullProgressMonitor(), false, true); + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + return Status.CANCEL_STATUS; + } + return Status.OK_STATUS; + } + }; + launchJob.schedule(); + } + + return false; + } + + static public boolean isSnapshotLaunchConfig(ILaunchConfiguration launchConfiguration) + { + try { + String albumFile = launchConfiguration.getAttribute(IEDCLaunchConfigurationConstants.ATTR_ALBUM_FILE, ""); + return albumFile.length() > 0; + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + return false; + } + + static public ILaunchConfiguration findExistingLaunchForAlbum(IAlbum album) { + ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); + ILaunchConfigurationType launchType = lm.getLaunchConfigurationType(album.getLaunchTypeID()); + if (launchType == null){ + return null; + } + + try { + ILaunchConfiguration[] configurations = lm.getLaunchConfigurations(launchType); + for (ILaunchConfiguration configuration : configurations) { + if (album.getLocation().toOSString().equals(configuration.getAttribute( + IEDCLaunchConfigurationConstants.ATTR_ALBUM_FILE, ""))) + return configuration; + } + } catch (CoreException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + return null; + } + + /** + * Taken from org.eclipse.cdt.debug.ui.breakpointactions#SoundAction + * @param soundFile + */ + static public void playSoundFile(final File soundFile) { + + class SoundPlayer extends Thread { + + public void run() { + AudioInputStream soundStream; + try { + soundStream = AudioSystem.getAudioInputStream(soundFile); + AudioFormat audioFormat = soundStream.getFormat(); + DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat); + SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo); + byte[] soundBuffer = new byte[5000]; + sourceDataLine.open(audioFormat); + sourceDataLine.start(); + int dataCount = 0; + + while ((dataCount = soundStream.read(soundBuffer, 0, soundBuffer.length)) != -1) { + if (dataCount > 0) { + sourceDataLine.write(soundBuffer, 0, dataCount); + } + } + sourceDataLine.drain(); + sourceDataLine.close(); + + } + // Don't report any exceptions, some VMs may not play the sound + catch (UnsupportedAudioFileException e) { + } catch (IOException e) { + } catch (IllegalArgumentException e) { + } catch (LineUnavailableException e) { + } finally { + + } + + } + + } + + if (soundFile.exists()) { + new SoundPlayer().start(); + } + } + + private static String serializeObjectToString(Object value) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(value); + return new String(new Hex().encode(baos.toByteArray())); + } + + private static Object createSerializedObjectFromString(String objectValue) throws DecoderException, IOException, ClassNotFoundException { + final ClassLoader classLoader = EDCDebugger.getDefault().getClass().getClassLoader(); + ByteArrayInputStream bais = new ByteArrayInputStream(Hex.decodeHex(objectValue.toCharArray())); + ObjectInputStream ois = new ObjectInputStream(bais) { + + @Override + protected Class resolveClass(ObjectStreamClass desc) + throws IOException, ClassNotFoundException { + String name = desc.getName(); + try { + return classLoader.loadClass(name); + } catch (ClassNotFoundException e) { + return super.resolveClass(desc); + } + }}; + return ois.readObject(); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ArrayBoundType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ArrayBoundType.java new file mode 100644 index 0000000..b995e37 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ArrayBoundType.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; + +public class ArrayBoundType extends Type implements IArrayBoundType { + + // bound of this array dimension. E.g., for "int a[7][8]", this would be + // either 7 or 8. + private final long bound; + + // number of array elements associated with each index of this array + // dimension. + // E.g., for "int a[7][8]", "a[1]" comprises 8 elements, but "a[1][2]" + // comprises 1 element. + private long elements; + + // array dimension ordinal. E.g., for "int a[7][8]", "[7]" is index 1 and + // "[8]" is index 0; + private long dimensionIndex = 0; + + public ArrayBoundType(IScope scope, long arrayBound) { + super("", scope, 0, null); //$NON-NLS-1$ + + if (arrayBound < 1) { + this.bound = 0; + this.elements = 0; + } else { + this.bound = arrayBound; + this.elements = 1; + } + } + + public long getBoundCount() { + return this.bound; + } + + public long getElementCount() { + return this.elements; + } + + public long getDimensionIndex() { + return this.dimensionIndex; + } + + public void multiplyElementCount(long multiply) { + this.elements *= multiply; + } + + public void incDimensionIndex() { + this.dimensionIndex++; + } + + @Override + public IType getType() { + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ArrayType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ArrayType.java new file mode 100644 index 0000000..1586c39 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ArrayType.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; + +public class ArrayType extends MayBeQualifiedType implements IArrayType { + + protected ArrayList bounds = new ArrayList(); + + public ArrayType(String name, IScope scope, int byteSize, Map properties) { + super(name, scope, byteSize, properties); + } + + public int getBoundsCount() { + return bounds.size(); + } + + public void addBound(IArrayBoundType bound) { + // existing array dimensions now represent bound.getBoundCount() times + // as many array elements, + // and have a higher dimensional position + for (IArrayBoundType existingBound : this.bounds) { + existingBound.multiplyElementCount(bound.getBoundCount()); + existingBound.incDimensionIndex(); + } + bounds.add(bound); + byteSize = 0; // recalculate + } + + public IArrayBoundType[] getBounds() { + IArrayBoundType[] boundsArray = new IArrayBoundType[bounds.size()]; + for (int i = 0; i < bounds.size(); i++) { + boundsArray[i] = bounds.get(i); + } + return boundsArray; + } + + // get the Nth bound. E.g., for "a[X][Y]", getBound(0) returns info for + // "[X]" + public IArrayBoundType getBound(int index) { + if (index >= 0 && index < bounds.size()) + return bounds.get(index); + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Type#getByteSize() + */ + @Override + public int getByteSize() { + if (byteSize == 0) { + if (bounds.size() > 0) { + updateByteSizeFromSubType(); + IType subtype = TypeUtils.getStrippedType(getType()); + if (subtype instanceof IArrayType) { + for (IArrayBoundType bound : ((IArrayType)subtype).getBounds()) + byteSize *= bound.getBoundCount(); + } + } + } + return byteSize; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CPPBasicType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CPPBasicType.java new file mode 100644 index 0000000..4d0b445 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CPPBasicType.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; + +public class CPPBasicType extends MayBeQualifiedType implements ICPPBasicType { + + private final int baseType; + private final int qualifierBits; + + public CPPBasicType(String name, IScope scope, int baseType, int qualifierBits, int byteSize, + Map properties) { + super(name, scope, byteSize, properties); + this.baseType = baseType; + this.qualifierBits = qualifierBits; + } + + public CPPBasicType(String name, int baseType, int qualifierBits, int byteSize) { + super(name, null, byteSize, null); + this.baseType = baseType; + this.qualifierBits = qualifierBits; + } + + + /** + * WARNING: this only works for CPPBasicType itself. No other types in + * the hierarchy implement this correctly. + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 12345; // super.hashCode(); + result = prime * result + baseType; + result = prime * result + qualifierBits; + return result; + } + + /** + * WARNING: this only works for CPPBasicType itself. No other types in + * the hierarchy implement this correctly. + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + //if (!super.equals(obj)) + // return false; + if (getClass() != obj.getClass()) + return false; + // do not test name, since it's essentially random + CPPBasicType other = (CPPBasicType) obj; + if (baseType != other.baseType) + return false; + if (qualifierBits != other.qualifierBits) + return false; + return true; + } + + public int getQualifierBits() { + return this.qualifierBits; + } + + public int getBaseType() { + return this.baseType; + } + + public boolean isLong() { + return (this.qualifierBits & ICPPBasicType.IS_LONG) != 0; + } + + public boolean isLongLong() { + return (this.qualifierBits & ICPPBasicType.IS_LONG_LONG) != 0; + } + + public boolean isShort() { + return (this.qualifierBits & ICPPBasicType.IS_SHORT) != 0; + } + + public boolean isSigned() { + return (this.qualifierBits & ICPPBasicType.IS_SIGNED) != 0; + } + + public boolean isUnsigned() { + return (this.qualifierBits & ICPPBasicType.IS_UNSIGNED) != 0; + } + + public boolean isComplex() { + return (this.qualifierBits & ICPPBasicType.IS_COMPLEX) != 0; + } + + @Override + public IType getType() { + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ClassType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ClassType.java new file mode 100644 index 0000000..b852be1 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ClassType.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class ClassType extends CompositeType { + + public ClassType(String name, IScope scope, int byteSize, Map properties) { + super(name, scope, ICompositeType.k_class, byteSize, properties, "class"); //$NON-NLS-1$ + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CompileUnitScope.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CompileUnitScope.java new file mode 100644 index 0000000..6c088ce --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CompileUnitScope.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.IModuleScope; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.core.runtime.IPath; + +public abstract class CompileUnitScope extends Scope implements ICompileUnitScope { + + protected IPath filePath; + + protected Collection lineEntries; + + public CompileUnitScope(IPath filePath, IModuleScope parent, IAddress lowAddress, IAddress highAddress) { + super(filePath != null ? filePath.lastSegment() : "", lowAddress, highAddress, parent); //$NON-NLS-1$ + + this.filePath = filePath; + } + + public IPath getFilePath() { + return filePath; + } + + public IFunctionScope getFunctionAtAddress(IAddress linkAddress) { + IScope scope = getScopeAtAddress(linkAddress); + while (scope != null && !(scope instanceof IFunctionScope)) { + scope = scope.getParent(); + } + + return (IFunctionScope) scope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ICompileUnitScope#getFunctions() + */ + public Collection getFunctions() { + List functions = new ArrayList(children.size()); + for (IScope scope : getChildren()) { + if (scope instanceof IFunctionScope) + functions.add((IFunctionScope) scope); + } + return Collections.unmodifiableCollection(functions); + } + + + /** + * Parse the line table data - to be implemented by debug format specific + * sub classes. + * + * @return the list of line table entries (may be empty) + */ + protected abstract Collection parseLineTable(); + + + public Collection getLineEntries() { + if (lineEntries == null) { + lineEntries = parseLineTable(); + } + return Collections.unmodifiableCollection(lineEntries); + } + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("CompileUnitScope ["); //$NON-NLS-1$ + builder.append("lowAddress="); //$NON-NLS-1$ + builder.append(lowAddress); + builder.append(", highAddress="); //$NON-NLS-1$ + builder.append(highAddress); + builder.append(", "); //$NON-NLS-1$ + if (filePath != null) { + builder.append("path="); //$NON-NLS-1$ + builder.append(filePath.toOSString()); + builder.append(", "); //$NON-NLS-1$ + } + builder.append("]"); //$NON-NLS-1$ + return builder.toString(); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CompositeType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CompositeType.java new file mode 100644 index 0000000..e21f369 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/CompositeType.java @@ -0,0 +1,399 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.Map; +import java.util.StringTokenizer; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class CompositeType extends MayBeQualifiedType implements ICompositeType { + + // kind of composite (class, struct, union) + private final int key; + + // composite name without "class ", "struct " or "union " prefix + private String baseName; + + // fields in the composite + protected ArrayList fields = new ArrayList(); + + // classes inherited from + protected ArrayList inheritances = null; + + // template parameters + protected ArrayList templateParams = null; + boolean nameIncludesTemplateParams; + + /** + * fields of anonymous union types, with unknown offsets + * @see org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfInfoReader#processUnionType() + */ + protected ArrayList unknownOffsetFields = null; + + protected static class OffsetAndLength { + public long offset; + public long length; + } + + public CompositeType(String name, IScope scope, int key, int byteSize, Map properties, String prefix) { + super(name, scope, byteSize, properties); + this.baseName = name; + this.name = prefix + " " + name; //$NON-NLS-1$ + this.key = key; + nameIncludesTemplateParams = name.contains("<"); //$NON-NLS-1$ + } + + public int getKey() { + return this.key; + } + + public int fieldCount() { + if (unknownOffsetFields != null) + setAnonymousUnionOffsets(); + return fields.size(); + } + + public void addField(IField field) { + if (field.getFieldOffset() < 0) { + if (unknownOffsetFields == null) + unknownOffsetFields = new ArrayList(); + unknownOffsetFields.add(field); + } else + fields.add(field); + } + + public IField[] getFields() { + if (unknownOffsetFields != null) + setAnonymousUnionOffsets(); + ArrayList fieldList = new ArrayList(fields); + + return fieldList.toArray(new IField[fields.size()]); + } + + public void addTemplateParam(ITemplateParam templateParam) { + if (templateParams == null) { + templateParams = new ArrayList(2); + } + templateParams.add(templateParam); + } + + public ITemplateParam[] getTemplateParams() { + if (templateParams == null) + return new ITemplateParam[0]; + + ArrayList templateParamList = new ArrayList(templateParams); + + return templateParamList.toArray(new ITemplateParam[templateParams.size()]); + } + + @Override + public String getName() { + if (templateParams != null && !nameIncludesTemplateParams) + addTemplateStringToNames(); + return name; + } + + public String getBaseName() { + if (templateParams != null && !nameIncludesTemplateParams) + addTemplateStringToNames(); + return baseName; + } + + // add template parameters (e.g. "") to name and base name + private void addTemplateStringToNames() { + nameIncludesTemplateParams = true; + String templateName = "<"; //$NON-NLS-1$ + for (int i = 0; i < templateParams.size(); i++) { + templateName += templateParams.get(i).getName(); + if (i + 1 < templateParams.size()) + templateName += ","; //$NON-NLS-1$ + } + templateName += ">"; //$NON-NLS-1$ + // remove composite type names (e.g., "class") + templateName = templateName.replaceAll("class ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + templateName = templateName.replaceAll("struct ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + templateName = templateName.replaceAll("union ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + name += templateName; + baseName += templateName; + } + + public int inheritanceCount() { + return inheritances == null ? 0 : inheritances.size(); + } + + public void addInheritance(IInheritance inheritance) { + if (inheritances == null) + inheritances = new ArrayList(); + inheritances.add(inheritance); + } + + public IInheritance[] getInheritances() { + if (inheritances == null) + return new IInheritance[0]; + + return inheritances.toArray(new IInheritance[inheritances.size()]); + } + + public IField[] findFields(String name) { + // For a qualified name containing "::", save the qualifiers to match against + String baseFieldName = name; + ArrayList nameQualifiers = new ArrayList(); + + if (name.contains("::")) { //$NON-NLS-1$ + StringTokenizer st = new StringTokenizer(name, "::", false); //$NON-NLS-1$ + while (st.hasMoreTokens()) { + baseFieldName = st.nextToken(); + nameQualifiers.add(baseFieldName); + } + + // last token in the array is the base field name + nameQualifiers.remove(nameQualifiers.size() - 1); + + // if the first nameQualifier is the composite's name, remove it + // E.g., if we're in class foo, change "foo::x" to "x". + if ((nameQualifiers.size() >= 0) && nameQualifiers.get(0).equals(this.baseName)) + nameQualifiers.remove(0); + } + + // try for a fast exit: match against the non-inherited fields and names of + // composites we're inheriting from + if (nameQualifiers.size() == 0) { + if (unknownOffsetFields != null) + setAnonymousUnionOffsets(); + for (int i = 0; i < fields.size(); i++) { + if (((FieldType) fields.get(i)).getName().equals(baseFieldName)) { + IField[] foundFields = new IField[1]; + foundFields[0] = fields.get(i); + return foundFields; + } + } + + if (inheritances != null) { + for (IInheritance inheritance : inheritances) { + String inheritanceName = inheritance.getName(); + // for templates, remove composite type names (e.g., "class") + if (inheritanceName.indexOf('<') != -1) { + inheritanceName = inheritanceName.replaceAll("class ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + inheritanceName = inheritanceName.replaceAll("struct ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + inheritanceName = inheritanceName.replaceAll("union ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + if (inheritanceName.equals(baseFieldName)) { + IField[] foundFields = new IField[1]; + + // treat the inherited type as a field + FieldType newField = new FieldType(inheritanceName, scope, this, + inheritance.getFieldsOffset(), 0 /* bitSize */, 0 /* bitOffset */, + inheritance.getType().getByteSize(), inheritance.getAccessibility(), + inheritance.getProperties()); + newField.setType(inheritance.getType()); + + foundFields[0] = newField; + return foundFields; + } + } + } + } + + // check the inherited types + if (inheritances == null) + return null; + + ArrayList matches = new ArrayList(); + + for (IInheritance inheritance : inheritances) { + if (inheritance.getType() instanceof ICompositeType) { + ICompositeType inheritComposite = (ICompositeType)inheritance.getType(); + matches = findInheritedByName(baseFieldName, inheritComposite, inheritComposite.getBaseName(), inheritance.getFieldsOffset(), matches); + } + } + + // eliminate partial matches + matches = pruneMatches(nameQualifiers, matches); + + // create the list of all inherited fields + IField[] foundFields = null; + + // gather the names and offsets of the inherited fields + if (matches.size() > 0) { + foundFields = new IField[matches.size()]; + for (int i = 0; i < matches.size(); i++) { + foundFields[i] = matches.get(i); + } + } + + return foundFields; + } + + /** + * From a list of fields whose name matches the one we're looking for, remove those + * whose "::" qualifiers do not match. E.g., "foo::x" would match "bar::foo::x", but + * it would not match "bar::x" - so "bar::x" would be pruned. + * + * @param nameQualifiers qualifiers of the field we're matching against + * @param matches list of fields whose base name matches, but whose qualifiers may not match + * @return list of fields whose base name and qualifiers match the field we're looking for + */ + private ArrayList pruneMatches(ArrayList nameQualifiers, ArrayList matches) { + if (nameQualifiers.size() == 0) + return matches; + + for (int i = 0; i < matches.size(); i++) { + ArrayList matchQualifiers = new ArrayList(); + String matchName = matches.get(i).getName(); + + if (!matchName.contains("::")) //$NON-NLS-1$ + continue; + + // tokenize the match's name + StringTokenizer st = new StringTokenizer(matchName, "::", false); //$NON-NLS-1$ + while (st.hasMoreTokens()) { + matchQualifiers.add(st.nextToken()); + } + + // last token in the array is the base name, which we already know matches + matchQualifiers.remove(matchQualifiers.size() - 1); + + for (int nameIndex = 0, matchIndex = 0; + nameIndex < nameQualifiers.size() && matchIndex < matchQualifiers.size(); + nameIndex++) { + // match against each name qualifier, in order + boolean found = false; + while (!found && matchIndex < matchQualifiers.size()) { + found = nameQualifiers.get(nameIndex).equals(matchQualifiers.get(matchIndex)); + matchIndex++; + } + + // if did not find a qualifier, remove the match + if (!found) { + matches.remove(i); + break; + } + } + } + + return matches; + } + + /** + * Find all inherited fields whose base name, ignoring "::" qualifiers, match the search name + * + * @param name name to match + * @param composite composite type whose fields or inherited fields may match + * @param prefix string of "::" qualifiers so far + * @param offset byte offset of the composite from the composite that inherits from it + * @param matches list of matches found so far + * @return list of matches + */ + private ArrayList findInheritedByName(String name, ICompositeType composite, String prefix, long offset, ArrayList matches) { + IField[] fields = composite.getFields(); + if (fields != null) { + for (IField field : fields) { + String fieldName = field.getName(); + + if (fieldName.equals(name)) { + // create a field with the prefixed name + FieldType newField = new FieldType(prefix + "::" + field.getName(), scope, //$NON-NLS-1$ + composite, offset + field.getFieldOffset(), 0 /* bitSize */, 0 /* bitOffset */, + field.getType().getByteSize(), field.getAccessibility(), + field.getProperties()); + newField.setType(field.getType()); + matches.add(newField); + break; + } + } + } + + IInheritance[] compositeInheritances = composite.getInheritances(); + if (compositeInheritances.length == 0) + return matches; + + for (IInheritance inheritance : compositeInheritances) { + if (inheritance.getName().equals(name)) { + // treat the inherited type as a field + FieldType newField = new FieldType(inheritance.getName(), scope, this, + offset + inheritance.getFieldsOffset(), 0 /* bitSize */, 0 /* bitOffset */, + inheritance.getType().getByteSize(), inheritance.getAccessibility(), + inheritance.getProperties()); + newField.setType(inheritance.getType()); + } + + if (inheritance.getType() instanceof ICompositeType) { + ICompositeType inheritComposite = (ICompositeType)inheritance.getType(); + matches = findInheritedByName(name, inheritComposite, prefix + "::" + inheritComposite.getBaseName(), //$NON-NLS-1$ + offset + inheritance.getFieldsOffset(), matches); + } + } + + return matches; + } + + /** + * Fields with unknown offsets may be between other members or at the end + */ + private void setAnonymousUnionOffsets() { + OffsetAndLength[] offsetSizes = new OffsetAndLength[fields.size() + inheritanceCount()]; + int count = 0; + if (fields.size() > 0) { + for ( ; count < fields.size(); count++) { + offsetSizes[count] = new OffsetAndLength(); + offsetSizes[count].offset = fields.get(count).getFieldOffset(); + offsetSizes[count].length = fields.get(count).getByteSize(); + } + } + + if (inheritances != null) { + for (IInheritance inheritance : inheritances) { + offsetSizes[count] = new OffsetAndLength(); + offsetSizes[count].offset = inheritance.getFieldsOffset(); + offsetSizes[count].length = inheritance.getType().getByteSize(); + count++; + } + } + + // sort by offsets + if (offsetSizes.length > 1) { + boolean sorted; + int passCnt = 1; + do { + sorted = true; + for (int i = 0; i < offsetSizes.length - passCnt; i++) { + if (offsetSizes[i].offset > offsetSizes[i + 1].offset) { + OffsetAndLength temp = offsetSizes[i]; + offsetSizes[i] = offsetSizes[i + 1]; + offsetSizes[i + 1] = temp; + sorted = false; + } + } + passCnt++; + } while (!sorted && passCnt < offsetSizes.length); + } + + // find the offset for each anonymous union's data - between other members or at the end + int i = 0; + long fieldOffset = 0; + for (IField unknownOffsetField : unknownOffsetFields) { + for ( ; i < offsetSizes.length; i++) { + if (fieldOffset < offsetSizes[i].offset) + break; + fieldOffset = offsetSizes[i].offset + offsetSizes[i].length; + } + unknownOffsetField.setFieldOffset(fieldOffset); + if (i >= offsetSizes.length) + fieldOffset += unknownOffsetField.getByteSize(); + fields.add(unknownOffsetField); + } + + unknownOffsetFields = null; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ConstType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ConstType.java new file mode 100644 index 0000000..6ad9b1e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ConstType.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +/** + * Pseudo-type that represents the const qualifier + */ +public class ConstType extends Type implements IConstType { + + public ConstType(IScope scope, Map properties) { + super("const", scope, 0, properties); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Type#getByteSize() + */ + @Override + public int getByteSize() { + return updateByteSizeFromSubType(); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/EDCSourceFilesProvider.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/EDCSourceFilesProvider.java new file mode 100644 index 0000000..8e8e38c --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/EDCSourceFilesProvider.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.core.executables.Executable; +import org.eclipse.cdt.debug.core.executables.ISourceFilesProvider; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Symbols; +import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader; +import org.eclipse.core.runtime.IProgressMonitor; + +public class EDCSourceFilesProvider implements ISourceFilesProvider { + + public String[] getSourceFiles(Executable executable, IProgressMonitor monitor) { + + try { + // get cached reader + IEDCSymbolReader reader = Symbols.getSymbolReader(executable.getPath()); + if (reader != null) { + // note: don't dispose reader here + return reader.getSourceFiles(monitor); + } + } catch (Exception e) { + } + + return new String[0]; + } + + public int getPriority(Executable executable) { + // this forces us to be called before the DE source files provider + return ISourceFilesProvider.HIGH_PRIORITY + 10; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Enumeration.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Enumeration.java new file mode 100644 index 0000000..95f694e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Enumeration.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IEnumerator; +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class Enumeration extends MayBeQualifiedType implements IEnumeration { + + ArrayList enumerators = new ArrayList(); + HashMap enumeratorsByConstant = new HashMap(); + + public Enumeration(String name, IScope scope, int byteSize, Map properties) { + super(name, scope, byteSize, properties); + name = "enum"; //$NON-NLS-1$ + } + + public int enumeratorCount() { + return enumerators.size(); + } + + public void addEnumerator(IEnumerator enumerator) { + enumerators.add(enumerator); + enumeratorsByConstant.put(enumerator.getValue(), enumerator); + } + + public IEnumerator getEnumeratorByName(String name) { + for (int i = 0; i < enumerators.size(); i++) { + if (enumerators.get(i).getName().equals(name)) + return enumerators.get(i); + } + return null; + } + + public IEnumerator getEnumeratorByValue(long value) { + return this.enumeratorsByConstant.get(new Long(value)); + } + + public IEnumerator[] getEnumerators() { + IEnumerator[] enumeratorArray = new IEnumerator[enumerators.size()]; + for (int i = 0; i < enumerators.size(); i++) { + enumeratorArray[i] = enumerators.get(i); + } + return enumeratorArray; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Enumerator.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Enumerator.java new file mode 100644 index 0000000..51e3b2d --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Enumerator.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IEnumerator; + +public class Enumerator implements IEnumerator { + + protected final String name; + protected final Long value; + + public Enumerator(String name, long value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public long getValue() { + return value; + } + + @Override + public String toString() { + return "name = " + name + ", value = " + value; //$NON-NLS-1$ //$NON-NLS-2$ + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FieldType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FieldType.java new file mode 100644 index 0000000..3d5b7bf --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FieldType.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class FieldType extends Type implements IField { + + private final ICompositeType compositeType; + private long fieldOffset; + private final int bitSize; + private final int bitOffset; + private final int accessibility; + + public FieldType(String name, IScope scope, ICompositeType compositeType, long fieldOffset, int bitSize, + int bitOffset, int byteSize, int accessibility, Map properties) { + super(name, scope, byteSize, properties); + + this.compositeType = compositeType; + this.fieldOffset = fieldOffset; + this.bitSize = bitSize; + this.bitOffset = bitOffset; + this.accessibility = accessibility; + } + + public long getFieldOffset() { + return this.fieldOffset; + } + + public int getBitSize() { + return this.bitSize; + } + + public int getBitOffset() { + return this.bitOffset; + } + + public int getAccessibility() { + return this.accessibility; + } + + public ICompositeType getCompositeTypeOwner() { + return this.compositeType; + } + + public void setFieldOffset(long offset) { + this.fieldOffset = offset; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Type#getByteSize() + */ + @Override + public int getByteSize() { + return updateByteSizeFromSubType(); + } + + @Override + public String toString() { + return name + " offset = " + fieldOffset //$NON-NLS-1$ + + ", byteSize = " + getByteSize() //$NON-NLS-1$ + + (bitOffset != 0 ? ", bitOffset = " + bitOffset : "") //$NON-NLS-1$ //$NON-NLS-2$ + + (bitSize != 0 ? ", bitSize = " + bitSize : "") //$NON-NLS-1$ //$NON-NLS-2$ + + ", accessibility = " + //$NON-NLS-1$ + (accessibility == ICompositeType.ACCESS_PRIVATE ? + "private" //$NON-NLS-1$ + : (accessibility == ICompositeType.ACCESS_PROTECTED ? + "protected" //$NON-NLS-1$ + : "public")); //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FileLineEntryProvider.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FileLineEntryProvider.java new file mode 100644 index 0000000..324834f --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FileLineEntryProvider.java @@ -0,0 +1,737 @@ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.PathUtils; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.EDCLineAddresses; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfCompileUnit; +import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.ILineEntryProvider; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.core.runtime.IPath; + +/** + * Manage line table entries of one source file (.c/.cpp/header) in one compile + * unit.
    + * This is an internal class used by {@linkplain ModuleLineEntryProvider}. + */ +class FileLineEntryProvider implements ILineEntryProvider { + + private List lineEntries = new ArrayList(); + private List cuEntries = null; + + /** + * Line entries sorted by line number. Line table entries mapped to the same + * source line are put together in one entry in this map. + * + * Just use TreeMap so line number keys are sorted in ascending order. + */ + private TreeMap> lineEntriesByLine = new TreeMap>(); + + private TreeMap lineEntriesByAddress = new TreeMap(); + + private IPath filePath; + + private final ICompileUnitScope compileUnitScope; + + private boolean sorted; + + public FileLineEntryProvider(ICompileUnitScope compileUnitScope, IPath path) { + this.compileUnitScope = compileUnitScope; + this.filePath = path; + this.sorted = true; + } + + protected void setCULineEntries(Collection entries) { + cuEntries = new ArrayList(entries); + } + + protected List getCULineEntries() { + if (cuEntries == null) + setCULineEntries(compileUnitScope.getLineEntries()); + return cuEntries; + } + + public ICompileUnitScope getCU() { + return compileUnitScope; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + // note: peeking into lowAddress to avoid dynamically parsing stuff while viewing #toString() + return filePath + " at " + ((CompileUnitScope)compileUnitScope).lowAddress + ": " + lineEntries.size() + " entries"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * @param entry + */ + public void addLineEntry(ILineEntry entry) { + //System.out.println("Adding " + entry + " for " + compileUnitScope); + lineEntries.add(entry); + + List currentMappings = lineEntriesByLine.get(entry.getLineNumber()); + if (currentMappings == null) { + currentMappings = new ArrayList(); + lineEntriesByLine.put(entry.getLineNumber(), currentMappings); + } + currentMappings.add(entry); + + ILineEntry currentByAddress = lineEntriesByAddress.get(entry.getLowAddress()); + + if ( currentByAddress == null + || entry.getHighAddress().compareTo(currentByAddress.getHighAddress()) > 0) { + lineEntriesByAddress.put(entry.getLowAddress(), entry); + } + + sorted = false; + } + + public ILineEntry getLineEntryAtAddress(IAddress linkAddress) { + // NOTE: lineEntries can, and does, have multiple entries with the same low address + if (!sorted) { + // sort by start address for faster lookup by address + Collections.sort(lineEntries); + sorted = true; + } + int insertion = getLineEntryInsertionForAddress(linkAddress, lineEntries); + if (-1 != insertion) + return lineEntries.get(insertion); + return null; + } + + private int getLineEntryInsertionForAddress(IAddress linkAddress, + final List entriesToSearch) { + + int insertion = Collections.binarySearch(entriesToSearch, linkAddress); + ILineEntry newEntry; + int newInsertion; + + if (insertion >= 0) { + // line entry's low address exactly matches linkAddress, but if the line + // entry has an empty address range, see if a previous or subsequent + // line entry with the same start address has a nonempty range + ILineEntry entry = entriesToSearch.get(insertion); + + if (entry.getHighAddress().compareTo(entry.getLowAddress()) != 0) + return insertion; + + if (insertion > 0) { + newInsertion = insertion - 1; + newEntry = entriesToSearch.get(newInsertion); + while (newEntry.getLowAddress().compareTo(entry.getLowAddress()) == 0) { + if (newEntry.getHighAddress().compareTo(newEntry.getLowAddress()) != 0) { + return newInsertion; + } + if (--newInsertion < 0) + break; + newEntry = entriesToSearch.get(newInsertion); + } + } + + if (insertion < entriesToSearch.size() - 1) { + newInsertion = insertion + 1; + newEntry = entriesToSearch.get(newInsertion); + while (newEntry.getLowAddress().compareTo(entry.getLowAddress()) == 0) { + if (newEntry.getHighAddress().compareTo(newEntry.getLowAddress()) != 0) { + return newInsertion; + } + if (++newInsertion == entriesToSearch.size()) + break; + newEntry = lineEntries.get(newInsertion); + } + } + + return insertion; + } + + if (insertion == -1) { + return -1; + } + + // after a failed binary search, link address is > low address of -insertion-2 + // so see if a previous entry with the same low address has a nonempty range + // that includes linkAddress + insertion = -insertion - 2; + + ILineEntry entry = entriesToSearch.get(insertion); + + // low address of entry at insertion cannot match linkAddress + if (insertion > 0 && entry.getHighAddress().compareTo(entry.getLowAddress()) == 0) { + newInsertion = insertion - 1; + newEntry = entriesToSearch.get(newInsertion); + while (newEntry.getLowAddress().compareTo(entry.getLowAddress()) == 0) { + if (newEntry.getHighAddress().compareTo(newEntry.getLowAddress()) != 0) { + if (linkAddress.compareTo(newEntry.getHighAddress()) < 0) + return newInsertion; + } + if (--newInsertion < 0) + break; + newEntry = entriesToSearch.get(newInsertion); + } + } + + if (linkAddress.compareTo(entry.getHighAddress()) < 0) + return insertion; + + return -1; + } + + public Collection getLineEntriesForLines(IPath path, int startLineNumber, int endLineNumber) { + // FIXME: ugly drive letter stuff + if (!filePath.setDevice(null).equals(path.setDevice(null)) ) + { + if (!PathUtils.isCaseSensitive() && filePath.toOSString().compareToIgnoreCase(path.toOSString()) != 0) + return Collections.emptyList(); + } + + int lntSize = lineEntries.size(); + // Note: this may not be the last line: + // lineEntries.get(lntSize-1).getLineNumber(); + // as I've seen line table like this for a source file + // (illustrated by line #s): + // 7, 8, 25, 26, 12, 14 + // where line (7, 8) forms one function, (25,26) one function, + // and (12, 14) one function. + int endLine = (endLineNumber != -1) ? endLineNumber : + lineEntriesByLine.lastKey(); + + List entries = new ArrayList(), startMappings; + + /* in case the caller has requested something other than a single line, + * make certain this doesn't fail if the the caller passes a + * startLineNumber that doesn't have a direct mapping in the LNT + */ + for (; null == (startMappings = lineEntriesByLine.get(startLineNumber)) + && startLineNumber < endLine + ; ++startLineNumber) {} + + if (startMappings != null) { + if (startLineNumber == endLineNumber) { + entries.addAll(startMappings); + } else if (endLineNumber == -1) { + // return the entries for the rest of the file + entries = lineEntries.subList(lineEntries.indexOf(startMappings.get(0)), lntSize); + } else { + List endMappings = lineEntriesByLine.get(endLineNumber); + if (endMappings != null) { + entries = lineEntries.subList(lineEntries.indexOf(startMappings.get(0)), lineEntries + .indexOf(endMappings.get(endMappings.size() - 1)) + 1); + } else { + // no mapping for end line #. just go to the end of the file + entries = lineEntries.subList(lineEntries.indexOf(startMappings.get(0)), lntSize); + } + } + } + + return Collections.unmodifiableCollection(entries); + } + + public ILineEntry getNextLineEntry(ILineEntry entry, boolean collapseInlineFunctions) { + if (entry == null || isLastEntryInCU(entry)) + return null; + IFunctionScope entryFn = compileUnitScope.getFunctionAtAddress(entry.getLowAddress()); + IFunctionScope container = ignoreInlineFunctions(entryFn); + if (container == null) // relies on ignoreInlineFunctions() to return null if func==null + return null; + + do { // loop is for continue to retry the next entry in same function + + // check if there's even a need to do further operations + IAddress desiredAddr = entry.getHighAddress(); + if (desiredAddr.compareTo(container.getHighAddress()) > 0) + return null; + + SortedMap tailAddrs + = desiredAddr.equals(entry.getLowAddress()) // can be equal due to DWARF generation bug + ? null : lineEntriesByAddress.tailMap(desiredAddr); + + // no other lines in this provider; try the CU line entries + if (tailAddrs == null || tailAddrs.isEmpty()) { + // the following case is that we are at the first line of an inline + // that would otherwise be the last line of a function. + if (collapseInlineFunctions && entryFn != container + && entry.getLowAddress().equals(entryFn.getLowAddress()) + && entryFn.getParent().equals(container)) + return getDifferentLineEntryInCU(container, entry, entryFn.getHighAddress(), + collapseInlineFunctions); + else + return getDifferentLineEntryInCU(entryFn, entry, desiredAddr, + collapseInlineFunctions); + } + + IAddress foundAddr = tailAddrs.firstKey(); + ILineEntry next = tailAddrs.get(foundAddr); + IFunctionScope foundFn = compileUnitScope.getFunctionAtAddress(foundAddr); + + // [1] if the function of our the current instr ptr entry and + // the function at the found addr are identical, then take it!! + // (i.e. we lucked out!! all lines in the gap + // in other providers are nested inlines.) + if (entryFn.equals(foundFn)) { + // ... ok, well, line number must be different, too. + if (next.getLineNumber() != entry.getLineNumber()) + return next; + entry = next; // just pretend this was the entry ... + continue; // ... and try again + + // [2]if the foundAddr is immediately after this entry ... + } else if (foundAddr.equals(desiredAddr) && foundFn != null) { // [2] + + /// ... and it is + // [2a] an inline parent of this inline + // [2b] an inline and a direct sibling (i.e. not a cousin) of this inline + // then take it!! + if (entryFn.getParent().equals(foundFn) // [2a] + || entryFn.getParent().equals(foundFn.getParent())) { // [2b] + return tailAddrs.get(foundAddr); + + // ... or if it is + // [2c] the first line of an inline whose next line in the + // lineEntriesByLine table is identical to next + // then we'll call that good enough + // (you may be reading this if you have an inline function + // in the same file as the parent function invoking it and + // nothing in between; step over is probably broken for you.) + } else if (foundFn.getParent().equals(entryFn) + && areEntriesAdjacentLines(entry, next)) { + return next; + } + + // similar to [2a] & [2b], even if foundAddr shows a gap + // [3] if the current location is an inline, and entry + // adjacent to the one passed is identical to next + // again, call it good enough for now. + } else if (collapseInlineFunctions + && (entryFn.getParent().equals(foundFn) + || entryFn.getParent().equals(container)) + && areEntriesAdjacentLines(entry, next)) { + return next; + } + + + // getting here means 1 (or both) of 2 things (both slightly irrelevant) + // + // either: + // a] entryFn is an ancestor of foundFn + // b] there's a gap between the desiredAddr & the foundAddr + // + // in either case, the next entry will be found in + // this.compileUnitScope.lineEntries . so get it from there. + return getDifferentLineEntryInCU(entryFn, entry, desiredAddr, + collapseInlineFunctions); + + } while (true); + } + + /** + * @param c the child to compare + * @param x the function we are seeking to call an ancestor + * @return true if there's a function in this linkage where x is an ancestor of c + */ + private static boolean isAncestorFunction(IFunctionScope c, IFunctionScope x) { + for (IScope p = c.getParent(); p != null; p = p.getParent()) + if (p.equals(x)) + return true; + return false; + } + + static boolean isInlinedFunction(IFunctionScope function) { + return function != null && function.getParent() instanceof IFunctionScope; + } + + private static IFunctionScope ignoreInlineFunctions(IFunctionScope function) { + if (function == null) + return null; + + while (function.getParent() instanceof IFunctionScope) { + function = (IFunctionScope) function.getParent(); + } + return function; + } + + /** + * @param entry + * @param next + */ + private boolean areEntriesAdjacentLines(ILineEntry entry, ILineEntry next) { + if (entry.getLineNumber() == next.getLineNumber()) + return false; + SortedMap> tailLines + = lineEntriesByLine.tailMap(entry.getLineNumber()); + if (tailLines != null) { + List entries = tailLines.get(entry.getLineNumber()); + if (entries != null) { + int entryIdx = entries.indexOf(entry); + if (-1 != entryIdx) { + if (entry.equals(entries.get(0)) + && ++entryIdx == entries.size()) { + entries = tailLines.get(next.getLineNumber()); + if (entries != null && next.equals(entries.get(0))) { + return true; + } } } } } + + return false; + } + + /** + * @param entryFn + * @param desiredAddr + * @return + */ + private ILineEntry getDifferentLineEntryInCU(IFunctionScope entryFn, + ILineEntry origEntry, IAddress desiredAddr, + boolean collapseInlineFunctions) { + if (compileUnitScope instanceof DwarfCompileUnit) { // known to be a sorted list + if (getCULineEntries().isEmpty()) + return null; + int insertion = getLineEntryInsertionForAddress(desiredAddr, cuEntries); + if (-1 != insertion) + for (; insertion < cuEntries.size(); ++insertion) { + ILineEntry next = cuEntries.get(insertion); + if (isGoodEntry(next, entryFn, origEntry, collapseInlineFunctions)) + return next; + } + } else { + boolean firstFound = false; + for (ILineEntry next : getCULineEntries()) { + if (!firstFound && desiredAddr.compareTo(next.getLowAddress()) < 0) + continue; + else + firstFound = true; + + if (isGoodEntry(next, entryFn, origEntry, collapseInlineFunctions)) + return next; + } + } + + + // by deduction, if we don't hit any of those 3 cases and exhaust all + // entries in the compuleUnitScope, then every entry after the current + // one is some sort of inline nested to the current function (possibly + // even several different inlines nested separately, possibly even with + // code from the original function at the original line number). + // + // in simple terms, it means the step-over that led here + // will turn into a step out + + return null; + } + + private boolean isGoodEntry(ILineEntry e, IFunctionScope origFn, + ILineEntry origEntry, boolean collapseInlineFunctions) { + IFunctionScope nextFn + = compileUnitScope.getFunctionAtAddress(e.getLowAddress()); + + if (origFn.equals(nextFn) && e.getLineNumber() != origEntry.getLineNumber()) + return true; // case [1] described in caller getNextLineEntry() + + else if (!collapseInlineFunctions || !isAncestorFunction(nextFn, origFn)) + return true; // case [2] or [3] described in caller getNextLineEntry() + + return false; + } + + private boolean isFirstEntryInCU(ILineEntry e) throws IllegalArgumentException { + if (e == null) + throw new IllegalArgumentException("isFirstEntryInCU() called with null"); + int cuEntriesSize = getCULineEntries().size(); + return (cuEntriesSize > 0 && e.equals(cuEntries.get(0))); + } + + private boolean isLastEntryInCU(ILineEntry e) throws IllegalArgumentException { + if (e == null) + throw new IllegalArgumentException("isFirstEntryInCU() called with null"); + int cuEntriesSize = getCULineEntries().size(); + return (cuEntriesSize > 0 && e.equals(cuEntries.get(cuEntriesSize-1))); + } + + public ILineEntry getPreviousLineEntry(ILineEntry entry, boolean collapseInlineFunctions) { + if (entry == null || isFirstEntryInCU(entry)) + return null; + IAddress entryAddr = entry.getLowAddress(); + IFunctionScope func = compileUnitScope.getFunctionAtAddress(entryAddr); + IFunctionScope container = ignoreInlineFunctions(func); + if (container == null) // relies on ignoreInlineFunctions() to return null if func==null + return null; + SortedMap headAddrs = lineEntriesByAddress.headMap(entryAddr); + if (headAddrs.isEmpty()) + return null; + + if (!collapseInlineFunctions) + return getPreviousLineEntryByAddress(entry, container.getLowAddress(), headAddrs); + + IFunctionScope prevFunc = compileUnitScope.getFunctionAtAddress(entryAddr); + IFunctionScope prevContainer = ignoreInlineFunctions(prevFunc); + if (prevContainer == null || !prevContainer.equals(container)) { + return null; // relies on ignoreInlineFunctions() to return null if nextFunc==null + } + + boolean inline = !func.equals(container); + boolean prevInline = !prevFunc.equals(prevContainer); + if (inline && prevInline) { + ILineEntry testPrev = headAddrs.get(headAddrs.lastKey()); + + // take the first head in tailAddrs if the function containing entry is + // [1] identical to the function containing the lastKey of headAddrs + // (i.e. in the same inline; skips nested inlines in other providers) + // [2] an inline parent of this the previous inline + // && the top addr of testPrev is immediately bottom addr of entry + // [3] an inline and a sibling of this previous inline + // && the top addr of testPrev is immediately bottom addr of entry + if (func.equals(prevFunc) // [1] + || (testPrev.getHighAddress().equals(entryAddr) + && (prevFunc.getParent().equals(func) // [2] + || prevFunc.getParent().equals(func.getParent())))) { // [3] + return testPrev; + } + + if (!filePath.equals(compileUnitScope.getFilePath())) + // fall out and force reliance on the provider mapped from the + // compileUnitScope's filePath (i.e. the parent to these inlines) + return null; + } + + SortedMap> headLines + = inline + ? lineEntriesByLine.headMap(headAddrs.get(headAddrs.lastKey()).getLineNumber()+1) + : lineEntriesByLine.headMap(entry.getLineNumber()); + + while (!headLines.isEmpty()) { + List entries = headLines.get(headLines.lastKey()); + for (int i = entries.size()-1; i >= 0; --i) { + ILineEntry prev = entries.get(i); + if (!prev.equals(entry) + && prev.getHighAddress().compareTo(entryAddr) <= 0 + && prev.getLowAddress().compareTo(container.getLowAddress()) >= 0 + && prev.getLineNumber() != entry.getLineNumber()) { + return prev; + } + } + headLines = headLines.headMap(headLines.lastKey()); + } + return null; + } + + /** + * @param entry + * @param bottom + * @param addrEntries + * @return + */ + private ILineEntry getPreviousLineEntryByAddress(ILineEntry entry, IAddress bottom, + SortedMap addrEntries) { + while (!addrEntries.isEmpty()) { + ILineEntry prev = addrEntries.get(addrEntries.lastKey()); + if (prev == null || prev.getLowAddress().compareTo(bottom) < 0) + break; + if (prev.getLineNumber() != entry.getLineNumber()) + return prev; + addrEntries = addrEntries.headMap(prev.getLowAddress()); + } + return null; + } + + public ILineEntry getLineEntryInFunction(IAddress linkAddress, IFunctionScope parentFunction) { + + // get all line entries with low address <= linkAddress + SortedMap subMap = lineEntriesByAddress.headMap(linkAddress.add(1)); + + if (subMap.isEmpty()) + { + // if no line entries have a low address <= linkAddress, but the address is + // definitely in the function, use the first entry + if (parentFunction.getLowAddress().compareTo(linkAddress) >= 0 + && parentFunction.getHighAddress().compareTo(linkAddress) < 0) + return lineEntriesByAddress.values().iterator().next(); + return null; + } + + // look for an entry that includes linkAddress; if linkAddress is in the gap between + // two lineEntriesByAddress entries, assume the gap is due to inlined functions' code + ILineEntry entry = subMap.get(subMap.lastKey()); + + if ( entry.getHighAddress().compareTo(linkAddress) >= 0 + || subMap.size() < lineEntriesByAddress.size()) { + return entry; + } + + return null; + } + + /** + * ONLY call when caller has 'collapseInlineFunctions == true' and the caller + * has failed to get the address in any other way. + * + * @param cuScope the scope in which to search for the entry of interest + * @param entry the entry in hand, for which the preceding entry is desired + * @return a line-entry whose end address is exactly first address of the passed entry + */ + protected ILineEntry getPreviousLineEntryInCU(ILineEntry entry) { + IAddress desiredEndAddress = entry.getLowAddress(); + + for (ILineEntry testEntry : getCULineEntries()) { + if (!desiredEndAddress.equals(testEntry.getHighAddress())) + continue; + IFunctionScope entryFn + = compileUnitScope.getFunctionAtAddress(entry.getLowAddress()); + IScope entryParent = entryFn.getParent(); + + IFunctionScope prevFn + = compileUnitScope.getFunctionAtAddress(testEntry.getLowAddress()); + if (isInlinedFunction(entryFn) + && (isAncestorFunction(entryFn, prevFn) + || entryParent != null && entryParent.equals(prevFn.getParent()))) { + return testEntry; + } + if (isAncestorFunction(prevFn, entryFn)) { + // TODO: add logic to get entry at start of testEntry + // something like: + // dp { + // desiredEndAddress = testEntry.getLowAddress(); + // testEntry = getPreviousLineEntryInCU(cuScope, testEntry, null); + // get back to where the function for testEntry is a sibling or + // ancestor of entryFn + // } while (testEntry != null) + // + // but this is mostly here to help with step-out while standing + // on first instruction of inline coinciding with source, so fix later + } + break; // got the address of interest; just wasn't useful as we wanted + } + return null; + } + + /* + * Find code line for the anchor in one compile unit. + * The returned value should only contain one entry. + * + * (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.ILineEntryProvider#findClosestLineWithCode(org.eclipse.core.runtime.IPath, int, int) + */ + public List findClosestLineWithCode(IPath sourceFile, + int anchorLine, int neighbor_limit) { + List ret = new ArrayList(1); + + // FIXME: ugly drive letter stuff + if (!filePath.setDevice(null).equals(sourceFile.setDevice(null)) ) + { + if (!PathUtils.isCaseSensitive() && filePath.toOSString().compareToIgnoreCase(sourceFile.toOSString()) != 0) + return ret; + } + + EDCLineAddresses codeLine = null; + + codeLine = getLineAddresses(anchorLine); + if (codeLine != null) { + // The anchor itself has code + ret.add(codeLine); + return ret; + } + + int limit; + + // Anchor has no code, but there are code lines above the anchor. + // find the closest one. + EDCLineAddresses candidate_above = null; + if (anchorLine > lineEntriesByLine.firstKey()) { + if (neighbor_limit == -1) + limit = lineEntriesByLine.firstKey(); + else { + limit = anchorLine - neighbor_limit; + if (limit < lineEntriesByLine.firstKey()) + limit = lineEntriesByLine.firstKey(); + } + + for (int i = anchorLine-1; i >= limit; i--) { + candidate_above = getLineAddresses(i); + if (candidate_above != null) + break; + } + } + + // there are code lines below the anchor. + // find the closest one. + EDCLineAddresses candidate_below = null; + if (anchorLine < lineEntriesByLine.lastKey()) { + if (neighbor_limit == -1) + limit = lineEntriesByLine.lastKey(); + else { + limit = anchorLine + neighbor_limit; + if (limit > lineEntriesByLine.lastKey()) + limit = lineEntriesByLine.lastKey(); + } + + for (int i = anchorLine+1; i <= limit; i++) { + candidate_below = getLineAddresses(i); + if (candidate_below != null) + break; + } + } + + if (candidate_above == null) + codeLine = candidate_below; + else { + if (candidate_below == null) + codeLine = candidate_above; + else { + int distance_above = anchorLine - candidate_above.getLineNumber(); + int distance_below = candidate_below.getLineNumber() - anchorLine; + + if (distance_above == distance_below) + codeLine = candidate_below; + else + codeLine = (distance_above < distance_below)? candidate_above : candidate_below; + } + } + + if (codeLine != null) + ret.add(codeLine); + + return ret; + } + + /** + * Create EDCLineAddresses object for a line if it has code. + * @param line + * @return null if the line has no code. + */ + private EDCLineAddresses getLineAddresses(int line) { + if (! lineEntriesByLine.containsKey(line)) + return null; + + List line_addrs = new ArrayList(); + int lastColumn = -2; + + for (ILineEntry e : lineEntriesByLine.get(line)) { + /* + * When there is more than one line mapping for the source line: + * + * If they are multiple logical code segments for the same source + * line, but in different columns, only remember address of the + * first entry. + * + * If they are templates or inline functions, the column will be the + * same, and we record addresses of all entries. + */ + int entryColumn = e.getColumnNumber(); + if (line_addrs.size() == 0 || lastColumn == entryColumn) + line_addrs.add(e.getLowAddress()); + + lastColumn = entryColumn; + } + + return new EDCLineAddresses(line, line_addrs); + } + +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FunctionScope.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FunctionScope.java new file mode 100644 index 0000000..d91fca1 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/FunctionScope.java @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IVariable; +import org.eclipse.core.runtime.IPath; + +public class FunctionScope extends Scope implements IFunctionScope { + + protected ILocationProvider frameBaseLocationProvider; + protected List parameters = new ArrayList(); + private int declLine; + private int declColumn; + private IPath declFile; + + public FunctionScope(String name, IScope parent, IAddress lowAddress, IAddress highAddress, + ILocationProvider frameBaseLocationProvider) { + super(name, lowAddress, highAddress, parent); + + this.frameBaseLocationProvider = frameBaseLocationProvider; + } + + public Collection getParameters() { + return Collections.unmodifiableCollection(parameters); + } + + public ILocationProvider getFrameBaseLocation() { + return frameBaseLocationProvider; + } + + public Collection getVariablesInTree() { + List variables = new ArrayList(); + variables.addAll(super.getVariables()); + + // check for variables in children as well + for (IScope child : children) { + if (child instanceof IFunctionScope) + variables.addAll(((IFunctionScope) child).getVariablesInTree()); + else if (child instanceof ILexicalBlockScope) + variables.addAll(((ILexicalBlockScope) child).getVariablesInTree()); + else + variables.addAll(child.getVariables()); + } + + return variables; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IFunctionScope#getScopedVariables(org.eclipse.cdt.core.IAddress) + */ + public Collection getScopedVariables(IAddress linkAddress) { + // Unfortunately, lexical blocks and inlined functions may span several scopes or use ranges; + // don't #getScopeAtAddress() and go up the parent chain, but iterate them top-down. + + List scoped = new ArrayList(); + List varNames = new ArrayList(); + + recurseGetScopedVariables(this, scoped, varNames, linkAddress); + + return scoped; + } + + protected static void recurseGetScopedVariables(IScope scope, List scoped, List varNames, IAddress linkAddress) { + long scopeOffset = linkAddress.add(scope.getLowAddress().getValue().negate()).getValue().longValue(); + + for (IVariable var : scope.getVariables()) { + if (scopeOffset >= var.getStartScope() && var.getLocationProvider().isLocationKnown(linkAddress)) { + String varName = var.getName(); + if (!varNames.contains(varName)) { + scoped.add(var); + varNames.add(varName); + } + } + } + + boolean isFunctionScope = (scope instanceof IFunctionScope); + if (isFunctionScope) { + for (IVariable var : ((FunctionScope) scope).getParameters()) { + if (scopeOffset >= var.getStartScope() && var.getLocationProvider().isLocationKnown(linkAddress)) { + String varName = var.getName(); + if (!varNames.contains(varName)) { + scoped.add(var); + varNames.add(varName); + } + } + } + } + + for (IScope kid : scope.getChildren()) { + // notice this is > instead of >= like caller getScopedVariables() ... + // thus stepping out of scope to next instr won't result in scoped variables still being seen + if (kid.getLowAddress().compareTo(linkAddress) <= 0 && kid.getHighAddress().compareTo(linkAddress) > 0) + recurseGetScopedVariables(kid, scoped, varNames, linkAddress); + else if (isFunctionScope && linkAddress.compareTo(kid.getHighAddress()) == 0) + recurseGetScopedVariables(kid, scoped, varNames, kid.getHighAddress()); + else if (kid instanceof ILexicalBlockScope) { + // RVCT 4.x Dwarf lexical blocks may contain local variables whose live ranges extend + // beyond the bounds of their enclosing lexical blocks, so check lexical block variables + recurseGetLexicalBlockVariables(kid, scoped, varNames, linkAddress); + } + } + } + + /** + * Find lexical block variables whose lifetimes include the given address, whether or not the address is + * inside the lexical block. + * Note: RVCT 4.x Dwarf lexical blocks may contain local variables whose live ranges extend beyond + * the bounds of their enclosing lexical blocks + **/ + private static void recurseGetLexicalBlockVariables(IScope scope, List scoped, List varNames, IAddress linkAddress) { + if (!(scope instanceof ILexicalBlockScope)) + return; + + for (IVariable var : scope.getVariables()) { + ILocationProvider locationProvider = var.getLocationProvider(); + if (!locationProvider.lifetimeMustMatchScope() && locationProvider.isLocationKnown(linkAddress)) { + String varName = var.getName(); + if (!varNames.contains(varName)) { + scoped.add(var); + varNames.add(varName); + } + } + } + + for (IScope kid : scope.getChildren()) { + recurseGetLexicalBlockVariables(kid, scoped, varNames, linkAddress); + } + } + + public void addParameter(IVariable parameter) { + parameters.add(parameter); + } + + public IPath getDeclFile() { + return declFile; + } + + public void setDeclFile(IPath declFile) { + this.declFile = declFile; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IFunctionScope#getDeclLine() + */ + public int getDeclLine() { + return declLine; + } + + public void setDeclLine(int declLine) { + this.declLine = declLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IFunctionScope#getDeclColumn() + */ + public int getDeclColumn() { + return declColumn; + } + + public void setDeclColumn(int declColumn) { + this.declColumn = declColumn; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#addChild(org.eclipse.cdt.debug.edc.internal.symbols.IScope) + */ + @Override + public void addChild(IScope scope) { + super.addChild(scope); + + if (scope instanceof IFunctionScope) + addLineInfoToParent(scope); + } + + + public void setLocationProvider(ILocationProvider locationProvider) { + this.frameBaseLocationProvider = locationProvider; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IAggregate.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IAggregate.java new file mode 100644 index 0000000..36b5979 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IAggregate.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +public interface IAggregate { +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IArrayBoundType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IArrayBoundType.java new file mode 100644 index 0000000..c2aa3dc --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IArrayBoundType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +public interface IArrayBoundType { + + /** bound of this array dimension. E.g., for "int a[7][8]", this would be + * either 7 or 8. + */ + public long getBoundCount(); + + /** number of array elements associated with each index of this array + * dimension. + * E.g., for "int a[7][8]", "a[1]" comprises 8 elements, but "a[1][2]" + * comprises 1 element. + */ + public long getElementCount(); + + /** array dimension ordinal. E.g., for "int a[7][8]", "[7]" is index 1 and + * "[8]" is index 0; + */ + public long getDimensionIndex(); + + public void multiplyElementCount(long multiply); + + public void incDimensionIndex(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IArrayType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IArrayType.java new file mode 100644 index 0000000..bf0bc44 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IArrayType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IArrayType extends IType, IAggregate { + + /** + * get the type that this is an array of + */ + public IType getType(); + + public int getBoundsCount(); + + public void addBound(IArrayBoundType bound); + + public IArrayBoundType[] getBounds(); + + // get the Nth bound. E.g., for "a[X][Y]", getBound(0) returns info for + // "[X]" + public IArrayBoundType getBound(int index); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IBasicType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IBasicType.java new file mode 100644 index 0000000..f9bff25 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IBasicType.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * Interface for basic types. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IBasicType extends IType { + + public static final int t_unspecified = IASTSimpleDeclSpecifier.t_unspecified; + public static final int t_void = IASTSimpleDeclSpecifier.t_void; + public static final int t_char = IASTSimpleDeclSpecifier.t_char; + public static final int t_int = IASTSimpleDeclSpecifier.t_int; + public static final int t_float = IASTSimpleDeclSpecifier.t_float; + public static final int t_double = IASTSimpleDeclSpecifier.t_double; + + /** + * This returns the built-in type for the declaration. The type is then + * refined by qualifiers for signed/unsigned and short/long. The type could + * also be unspecified which usually means int. + * + */ + public int getBaseType(); + + public boolean isSigned(); + + public boolean isUnsigned(); + + public boolean isShort(); + + public boolean isLong(); + + public boolean isLongLong(); + + public boolean isComplex(); +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ICPPBasicType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ICPPBasicType.java new file mode 100644 index 0000000..0ff2fec --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ICPPBasicType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; + +/** + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ICPPBasicType extends IBasicType { + + public static final int IS_LONG = 1; + public static final int IS_SHORT = 1 << 1; + public static final int IS_SIGNED = 1 << 2; + public static final int IS_UNSIGNED = 1 << 3; + public static final int IS_COMPLEX = 1 << 4; // for gpp-types + public static final int IS_IMAGINARY = 1 << 5; // for gpp-types + public static final int IS_LONG_LONG = 1 << 6; // for gpp-types + public static final int LAST = IS_LONG_LONG; + + // Extra types + public static final int t_bool = ICPPASTSimpleDeclSpecifier.t_bool; + public static final int t_wchar_t = ICPPASTSimpleDeclSpecifier.t_wchar_t; + + /** + * @return a combination of qualifiers. + */ + public int getQualifierBits(); +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ICompositeType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ICompositeType.java new file mode 100644 index 0000000..62c8cb4 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ICompositeType.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.debug.edc.symbols.IType; + +public interface ICompositeType extends IType, IAggregate { + + // accessibility of an inherited class or of a composite's field + public static int ACCESS_PUBLIC = 0; + public static int ACCESS_PROTECTED = 1; + public static int ACCESS_PRIVATE = 2; + + public static final int k_class = ICPPASTCompositeTypeSpecifier.k_class; + public static final int k_struct = IASTCompositeTypeSpecifier.k_struct; + public static final int k_union = IASTCompositeTypeSpecifier.k_union; + + /** + * Kind of composite (class, struct, union) + * + * @return kind + */ + public int getKey(); + + /** + * Number of fields/enumerators in composite + * + * @return count + */ + public int fieldCount(); + + /** + * Add a field/member to the end of the list of fields or enumerators + * Intended for use by a debug information parser. + * + * @param field + * field to add + */ + public void addField(IField field); + + /** + * Get an array of fields/enumerators in composite + * + * @return array of fields/enumerators, or IField.EMPTY_FIELD_ARRAY if no + * fields/enumerators + */ + public IField[] getFields(); + + /** + * Add a template parameter to the end of the list of template parameters + * Intended for use by a debug information parser. + * + * @param templateParam + * template parameter to add + */ + public void addTemplateParam(ITemplateParam templateParam); + + /** + * Get an array of template parameters in composite + * + * @return array of template parameters, or empty array if no + * template parameters + */ + public ITemplateParam[] getTemplateParams(); + + /** + * Find the composite fields/members with the given name + * + * @param name field name, which may contain "::" separators + * @return array of matching fields if any exist, or null otherwise + */ + public IField[] findFields(String name); + + /** + * Number of classes and structs from which the composite inherits + * + * @return count + */ + public int inheritanceCount(); + + /** + * Add an inherited-from class or struct to the end of the list + * of inherited-from classes and structs + * Intended for use by a debug information parser. + * + * @param inheritance + * information about class/struct from which this + * composite inherits + */ + public void addInheritance(IInheritance inheritance); + + /** + * Get an array of inherited-from classes/structs for composite + * + * @return array of information about classes and structs from which this + * composite inherits, or an empty array if nothing is inherited + */ + public IInheritance[] getInheritances(); + + /** + * Get the name without a type prefix (e.g., "foo" instead of "class foo") + * + * @return composite name without a type + */ + public String getBaseName(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IConstType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IConstType.java new file mode 100644 index 0000000..cdd2051 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IConstType.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +/** + * Interface used to identify pseudo-types that represent const qualifiers + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IConstType extends IQualifierType { + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IEnumeration.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IEnumeration.java new file mode 100644 index 0000000..254d26b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IEnumeration.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IEnumerator; +import org.eclipse.cdt.debug.edc.symbols.IType; + +public interface IEnumeration extends IType { + + public int enumeratorCount(); + + public void addEnumerator(IEnumerator enumerator); + + public IEnumerator getEnumeratorByName(String name); + + public IEnumerator getEnumeratorByValue(long value); + + /** + * returns an array of the IEnumerators declared in this enumeration + */ + IEnumerator[] getEnumerators(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IField.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IField.java new file mode 100644 index 0000000..14fc09c --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IField.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IField extends IType { + + public static final IField[] EMPTY_FIELD_ARRAY = new IField[0]; + + public long getFieldOffset(); + + public int getBitSize(); + + public int getBitOffset(); + + public int getAccessibility(); + + // member offset may need to be computed + public void setFieldOffset(long offset); + + /** + * Returns the composite type that owns the field. + */ + ICompositeType getCompositeTypeOwner(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IForwardTypeReference.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IForwardTypeReference.java new file mode 100644 index 0000000..76bb601 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IForwardTypeReference.java @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + + +/** + * This represents a type which is a proxy for an unparsed type. + */ +public interface IForwardTypeReference extends IType { + /** Realize (if needed) and return the actual type */ + IType getReferencedType(); +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IInheritance.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IInheritance.java new file mode 100644 index 0000000..86fe9b8 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IInheritance.java @@ -0,0 +1,57 @@ +/******************************************************************************* + + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +public interface IInheritance extends IType { + + /** + * Get offset to inherited fields + * + * @return offset within inherited type to the fields inherited + */ + public long getFieldsOffset(); + + /** + * Get type of accessibility to inherited fields (public, protected, or private) + * + * @return type of accessibility (one of: {@link ICompositeType}'s + * ACCESS_PUBLIC, ACCESS_PROTECTED, or ACCESS_PRIVATE) + */ + public int getAccessibility(); + + /** + * Get properties + * + * @return general map of type properties + */ + public Map getProperties(); + + /** + * Get type inherited from + * + * @return type + */ + public IType getType(); + + /** + * Set type inherited from + * + * @param type + * type inherited from + */ + public void setType(IType type); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ILexicalBlockScope.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ILexicalBlockScope.java new file mode 100644 index 0000000..c8e2d51 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ILexicalBlockScope.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Collection; + +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IVariable; + +/** + * Interface representing a lexical block scope. A lexical block is a block of + * code inside of a function. A lexical block may contain other lexical blocks + * as children. + */ +public interface ILexicalBlockScope extends IScope { + + /** + * Gets the list of variables in this scope and any child scopes + * + * @return unmodifiable list of variables which may be empty + */ + Collection getVariablesInTree(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IMayBeQualifedType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IMayBeQualifedType.java new file mode 100644 index 0000000..85d2397 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IMayBeQualifedType.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +public interface IMayBeQualifedType extends IType { + + /** + * Whether this is a const type + * + * @return true only if this is a const type + */ + public boolean isConst(); + + /** + * Whether this is a volatile type + * + * @return true only if this is a volatile type + */ + public boolean isVolatile(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IPointerType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IPointerType.java new file mode 100644 index 0000000..119982f --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IPointerType.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * Interface for pointer types + */ +public interface IPointerType extends IType { + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IQualifierType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IQualifierType.java new file mode 100644 index 0000000..5b68cab --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IQualifierType.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * Interface used to identify pseudo-types that represent qualifiers + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IQualifierType extends IType { + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IReferenceType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IReferenceType.java new file mode 100644 index 0000000..beea795 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IReferenceType.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +public interface IReferenceType extends IType { + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IRuntimeSection.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IRuntimeSection.java new file mode 100644 index 0000000..05eb66e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/IRuntimeSection.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.core.IAddress; + +public interface IRuntimeSection extends ISection { + + static final String PROPERTY_RUNTIME_ADDRESS = "runtime_address"; //$NON-NLS-1$ + + /** + * Get the base runtime address of the section + * + * @return the base runtime address + */ + IAddress getRuntimeAddress(); + + /** + * Relocates the section to the given runtime base address + * + * @param runtimeAddress + * the relocated base address of the section + */ + void relocate(IAddress runtimeAddress); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ISection.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ISection.java new file mode 100644 index 0000000..ce9f748 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ISection.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; + +/** + * Interface representing a section in memory. It is segment in Elf file and a + * section in PE file. + */ +public interface ISection { + + /** + * Commonly known properties of a section + */ + static final String PROPERTY_ID = "id"; //$NON-NLS-1$ + static final String PROPERTY_SIZE = "size"; //$NON-NLS-1$ + static final String PROPERTY_LINK_ADDRESS = "link_address"; //$NON-NLS-1$ + /** Canonical section name: one of NAME_TEXT, NAME_DATA, NAME_RODATA, or NAME_BSS */ + static final String PROPERTY_NAME = "name"; //$NON-NLS-1$ + + /* TODO: not used + static final String PROPERTY_READABLE = "readable"; + static final String PROPERTY_WRITABLE = "writable"; + static final String PROPERTY_EXECUTABLE = "executable"; + */ + + static final String NAME_TEXT = ".text"; //$NON-NLS-1$ + static final String NAME_DATA = ".data"; //$NON-NLS-1$ + static final String NAME_RODATA = ".rodata"; // read only data //$NON-NLS-1$ + static final String NAME_BSS = ".bss"; // uninitialized data //$NON-NLS-1$ + + /** + * Get the section id + * + * @return the section id + */ + int getId(); + + /** + * Get the section size + * + * @return the section size + */ + long getSize(); + + /** + * Get the base link address of the section + * + * @return the base link address + */ + IAddress getLinkAddress(); + + /** + * Get the properties of the section + * + * @return the section properties + */ + Map getProperties(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ISubroutineType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ISubroutineType.java new file mode 100644 index 0000000..db9607b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ISubroutineType.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * + */ +public interface ISubroutineType extends IType { + // TODO (parameters) (for now, only gathers the return type) +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ITemplateParam.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ITemplateParam.java new file mode 100644 index 0000000..01ee044 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ITemplateParam.java @@ -0,0 +1,17 @@ +/******************************************************************************* + + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +public interface ITemplateParam extends IType { +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ITypedef.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ITypedef.java new file mode 100644 index 0000000..f7308e6 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ITypedef.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.IType; + +/** + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ITypedef extends IType { + + /** + * Get the type that this is the typedef of + * + * @return typedef'ed type + */ + public IType getType(); + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/InheritanceType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/InheritanceType.java new file mode 100644 index 0000000..dfdc42e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/InheritanceType.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class InheritanceType extends Type implements IInheritance { + + // access type of inheritance + private final int accessibility; + + // offset in inherited class to the inherited fields + private final long fieldsOffset; + + public InheritanceType(IScope scope, int accessibility, long inheritanceOffset, Map properties) { + super("", scope, 0, properties); //$NON-NLS-1$ + this.accessibility = accessibility; + this.fieldsOffset = inheritanceOffset; + } + + public int getAccessibility() { + return this.accessibility; + } + + public long getFieldsOffset() { + return this.fieldsOffset; + } + + @Override + public String getName() { + if (getType() instanceof ICompositeType) + return ((ICompositeType) getType()).getBaseName(); + + if (getType() == null) + return "$"; //$NON-NLS-1$ // do not confuse expression formatter + else + return getType().getName(); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/InvalidVariableLocation.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/InvalidVariableLocation.java new file mode 100644 index 0000000..cb24243 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/InvalidVariableLocation.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.math.BigInteger; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.symbols.IInvalidVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.CoreException; + +public class InvalidVariableLocation implements IInvalidVariableLocation { + + private String message; + + public InvalidVariableLocation(String message) { + if (message == null) + this.message = ""; //$NON-NLS-1$ + else + this.message = message; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Invalid: " + getMessage(); //$NON-NLS-1$ + } + + + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + if (message == null) + this.message = ""; //$NON-NLS-1$ + else + this.message = message; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#readValue() + */ + public BigInteger readValue(int bytes) throws CoreException { + throw EDCDebugger.newCoreException(message); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#addOffset(long) + */ + public IVariableLocation addOffset(long offset) { + return this; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#getLocationName(org.eclipse.cdt.dsf.service.DsfServicesTracker) + */ + public String getLocationName() { + return ""; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#getAddress() + */ + public IAddress getAddress() { + return null; + } + + public void writeValue(int bytes, BigInteger value) throws CoreException { + throw EDCDebugger.newCoreException(SymbolsMessages.InvalidVariableLocation_CannotWriteInvalidLocation); + } + + public IDMContext getContext() { + return null; + } + + public EDCServicesTracker getServicesTracker() { + return null; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/LexicalBlockScope.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/LexicalBlockScope.java new file mode 100644 index 0000000..5137664 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/LexicalBlockScope.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IVariable; + +public class LexicalBlockScope extends Scope implements ILexicalBlockScope { + + public LexicalBlockScope(String name, IScope parent, IAddress lowAddress, IAddress highAddress) { + super(name, lowAddress, highAddress, parent); + } + + public Collection getVariablesInTree() { + List variables = new ArrayList(); + variables.addAll(super.getVariables()); + + // check for variables in children as well + for (IScope child : children) { + if (child instanceof IFunctionScope) + variables.addAll(((IFunctionScope) child).getVariablesInTree()); + else if (child instanceof ILexicalBlockScope) + variables.addAll(((ILexicalBlockScope) child).getVariablesInTree()); + else + variables.addAll(child.getVariables()); + } + + return variables; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/LineEntry.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/LineEntry.java new file mode 100644 index 0000000..efdc4b2 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/LineEntry.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.core.runtime.IPath; + +public class LineEntry implements ILineEntry { + + protected IPath filePath; + protected int lineNumber; + protected int columnNumber; + protected IAddress lowAddress; + protected IAddress highAddress; + + public LineEntry(IPath filePath, int lineNumber, int columnNumber, IAddress lowAddress, IAddress highAddress) { + this.filePath = filePath; + this.lineNumber = lineNumber; + this.columnNumber = columnNumber; + this.lowAddress = lowAddress; + this.highAddress = highAddress; + } + + public IPath getFilePath() { + return filePath; + } + + public int getLineNumber() { + return lineNumber; + } + + public int getColumnNumber() { + return columnNumber; + } + + public IAddress getLowAddress() { + return lowAddress; + } + + public IAddress getHighAddress() { + return highAddress; + } + + public void setHighAddress(IAddress highAddress) { + this.highAddress = highAddress; + } + + public int compareTo(Object o) { + if (o instanceof ILineEntry) { + // some entries have low==high + int diff = lowAddress.compareTo(((ILineEntry) o).getLowAddress()); + if (diff != 0) + return diff; + if (highAddress != null && ((ILineEntry) o).getHighAddress() != null) + return highAddress.compareTo(((ILineEntry) o).getHighAddress()); + return 0; + } else if (o instanceof IAddress) { + return lowAddress.compareTo(o); + } + + return 0; + } + + @Override + public String toString() { + return "LineEntry [lowAddress=" + + (lowAddress != null ? lowAddress.toHexAddressString() : "null") + + ", highAddress=" + + (highAddress != null ? highAddress.toHexAddressString() : "null") + + ((filePath != null) ? ", path=" + filePath.toOSString() + ", " : ", ") + + "line=" + lineNumber + ", column=" + columnNumber + + "]" ; //$NON-NLS-1$ + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/MayBeQualifiedType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/MayBeQualifiedType.java new file mode 100644 index 0000000..174dccf --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/MayBeQualifiedType.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; + +public class MayBeQualifiedType extends Type implements IMayBeQualifedType { + boolean qualifiersChecked = false; + boolean isConst = false; + boolean isVolatile = false; + + public MayBeQualifiedType(String name, IScope scope, int byteSize, Map properties) { + super(name, scope, byteSize, properties); + } + + public boolean isConst() { + if (!qualifiersChecked) + checkQualifiers(); + return isConst; + } + + public boolean isVolatile() { + if (!qualifiersChecked) + checkQualifiers(); + return isVolatile; + } + + /** + * Check whether the type is qualified. If so, set the proper booleans. + */ + private void checkQualifiers() { + IType checkedType = getType(); // so it will be resolved + while (checkedType != null && (checkedType instanceof IQualifierType)) { + isConst |= checkedType instanceof ConstType; + isVolatile |= checkedType instanceof VolatileType; + checkedType = checkedType.getType(); + } + qualifiersChecked = true; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/MemoryVariableLocation.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/MemoryVariableLocation.java new file mode 100644 index 0000000..0418415 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/MemoryVariableLocation.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.math.BigInteger; +import java.text.MessageFormat; +import java.util.ArrayList; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.MemoryUtils; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Memory; +import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.symbols.IMemoryVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.debug.core.model.MemoryByte; + +public class MemoryVariableLocation implements IMemoryVariableLocation { + + protected IAddress address; + protected boolean isRuntimeAddress; + protected EDCServicesTracker tracker; + private IDMContext context; + + public MemoryVariableLocation(EDCServicesTracker tracker, IDMContext context, BigInteger addressValue, + boolean isRuntimeAddress) { + initialize(tracker,context,addressValue,isRuntimeAddress, false); + } + + public MemoryVariableLocation(EDCServicesTracker tracker, IDMContext context, BigInteger addressValue, + boolean isRuntimeAddress, boolean checkNonLocalConstVariable) { + // checkConstVariableAddress should only be true for global or static (non-local) constant variables + initialize(tracker,context,addressValue,isRuntimeAddress, checkNonLocalConstVariable); + } + + private void initialize(EDCServicesTracker tracker, IDMContext context, BigInteger addressValue, + boolean isRuntimeAddress, boolean checkNonLocalConstVariable) { + this.tracker = tracker; + this.context = context; + BigInteger MAXADDR = BigInteger.valueOf(0xffffffffL); + ITargetEnvironment targetEnvironment = tracker.getService(ITargetEnvironment.class); + if (targetEnvironment != null && targetEnvironment.getPointerSize() == 8) { + MAXADDR = BigInteger.valueOf(0xffffffffffffffffL); + } + this.address = new Addr64(addressValue.and(MAXADDR)); + this.isRuntimeAddress = isRuntimeAddress; + + if (checkNonLocalConstVariable) + checkNonLocalConstVariableAddr(); + } + + /** + * Since a global or static constant variable may be either at a fixed ROM address or at a runtime address, + * and a compiler may not know which is correct when generating debug info, check the address + */ + private void checkNonLocalConstVariableAddr() { + // TODO: Instead of this, query whether the constant variable's address is a fixed or runtime address + + // Try reading a byte at the supposed address, and, if that fails, switch the sense of this.isRuntimeAddress + IAddress theAddress = address; + if (!isRuntimeAddress) { + StackFrameDMC frame = DMContexts.getAncestorOfType(context, StackFrameDMC.class); + if (frame == null) { + isRuntimeAddress = !isRuntimeAddress; + return; + } + theAddress = frame.getModule().toRuntimeAddress(theAddress); + } + + ExecutionDMC exeDMC = DMContexts.getAncestorOfType(context, ExecutionDMC.class); + + Memory memoryService = tracker.getService(Memory.class); + ArrayList memBuffer = new ArrayList(1); + IStatus memGetStatus = memoryService.getMemory(exeDMC, theAddress, memBuffer, 1, 1); + if (!memGetStatus.isOK()) { + isRuntimeAddress = !isRuntimeAddress; + return; + } + + if (!memBuffer.get(0).isReadable()) { + isRuntimeAddress = !isRuntimeAddress; + return; + } + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "0x" + Long.toHexString(address.getValue().longValue()) + //$NON-NLS-1$ + (isRuntimeAddress ? "" : " (link address)"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public IAddress getAddress() { + try { + return getRealAddress(); + } catch (CoreException e) { + return null; + } + } + + public boolean isRuntimeAddress() { + return isRuntimeAddress; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#readValue() + */ + public BigInteger readValue(int varSize) throws CoreException { + IAddress theAddress = address; + if (!isRuntimeAddress) { + theAddress = getRealAddress(); + } + + ExecutionDMC exeDMC = DMContexts.getAncestorOfType(context, ExecutionDMC.class); + + Memory memoryService = tracker.getService(Memory.class); + ArrayList memBuffer = new ArrayList(); + IStatus memGetStatus = memoryService.getMemory(exeDMC, theAddress, memBuffer, varSize, 1); + if (!memGetStatus.isOK()) { + throw EDCDebugger.newCoreException(MessageFormat.format( + SymbolsMessages.MemoryVariableLocation_CannotReadAddrFormat, theAddress.toHexAddressString())); + } + + // check each byte + for (int i = 0; i < memBuffer.size(); i++) { + if (!memBuffer.get(i).isReadable()) + throw EDCDebugger.newCoreException(MessageFormat.format( + SymbolsMessages.MemoryVariableLocation_CannotReadAddrFormat, theAddress.add(i).getValue().toString(16))); + } + + MemoryByte[] memArray = memBuffer.toArray(new MemoryByte[varSize]); + + return MemoryUtils.convertByteArrayToUnsignedLong( + memArray, getEndian()); + } + + private int getEndian() { + ITargetEnvironment targetEnvironment = tracker.getService(ITargetEnvironment.class); + int endian = MemoryUtils.LITTLE_ENDIAN; + if (targetEnvironment != null) + endian = targetEnvironment.isLittleEndian(context) ? MemoryUtils.LITTLE_ENDIAN : MemoryUtils.BIG_ENDIAN; + return endian; + } + + /** + * @return + * @throws CoreException + */ + private IAddress getRealAddress() throws CoreException { + IAddress theAddress = address; + if (!isRuntimeAddress) { + StackFrameDMC frame = DMContexts.getAncestorOfType(context, StackFrameDMC.class); + if (frame == null) + throw EDCDebugger.newCoreException(SymbolsMessages.MemoryVariableLocation_CannotFindFrame); + theAddress = frame.getModule().toRuntimeAddress(theAddress); + } + return theAddress; + } + + public IVariableLocation addOffset(long offset) { + return new MemoryVariableLocation(tracker, context, + address.getValue().add(BigInteger.valueOf(offset)), isRuntimeAddress); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#getLocationName(org.eclipse.cdt.dsf.service.DsfServicesTracker) + */ + public String getLocationName() { + if (!isRuntimeAddress) { + try { + return SymbolsMessages.MemoryVariableLocation_Hex + Long.toHexString(getRealAddress().getValue().longValue()); + } catch (CoreException e) { + return SymbolsMessages.MemoryVariableLocation_Hex + Long.toHexString(address.getValue().longValue()) + SymbolsMessages.MemoryVariableLocation_LinkTime; // should not happen + } + } else { + return SymbolsMessages.MemoryVariableLocation_Hex + Long.toHexString(address.getValue().longValue()); + } + } + + public void writeValue(final int bytes, BigInteger value) throws CoreException { + final byte[] buffer = MemoryUtils.convertSignedBigIntToByteArray(value, getEndian(), bytes); + final IAddress theAddress = !isRuntimeAddress ? getRealAddress() : address; + final ExecutionDMC exeDMC = DMContexts.getAncestorOfType(context, ExecutionDMC.class); + final Memory memory = tracker.getService(Memory.class); + IStatus status = memory.setMemory(exeDMC, theAddress, 1, bytes, buffer); + if (!status.isOK()) { + throw EDCDebugger.newCoreException(MessageFormat.format( + SymbolsMessages.MemoryVariableLocation_CannotWriteAddrFormat, theAddress.toHexAddressString()), status.getException()); + } + } + + public IDMContext getContext() { + return context; + } + + public EDCServicesTracker getServicesTracker() { + return tracker; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ModuleLineEntryProvider.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ModuleLineEntryProvider.java new file mode 100644 index 0000000..5dc14f8 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ModuleLineEntryProvider.java @@ -0,0 +1,434 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.PathUtils; +import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.EDCLineAddresses; +import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.ILineEntryProvider; +import org.eclipse.cdt.debug.edc.symbols.IModuleLineEntryProvider; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.core.runtime.IPath; + +/** + * This class holds a conglomeration of line entry data for an entire + * module. + */ +public class ModuleLineEntryProvider implements IModuleLineEntryProvider { + + /** + * basically, a typedef of {@link ArrayList}<{@link FileLineEntryProvider}> + */ + private final class FileLineEntryProviders extends ArrayList { + private static final long serialVersionUID = -2157263701372708990L; + } + + /** + * basically, a typedef of {@link HashMap}<{@link IPath},{@link FileLineEntryProvider}> + */ + private final class PathToLineEntryMap extends HashMap { + private static final long serialVersionUID = 7064789571684986782L; + } + + // CUs we've already considered + private Set parsedCUs = new HashSet(); + // mapping to find info for a given path + private PathToLineEntryMap pathToLineEntryMap = new PathToLineEntryMap(); + // all known providers + private FileLineEntryProviders fileProviders = new FileLineEntryProviders(); + // cached array of providers + private FileLineEntryProvider[] fileProviderArray; + + public ModuleLineEntryProvider() { + + } + + + /** + * Add the line entries from a compilation unit to the mapper. + * @param scope + */ + public void addCompileUnit(ICompileUnitScope cu) { + if (parsedCUs.contains(cu)) + return; + + parsedCUs.add(cu); + + Collection lineEntries = cu.getLineEntries(); + + if (lineEntries.size() > 0) { + // files created for this compile unit scope (union of all CUs in this.lineEntryMap) + // (kept because we visit the same file a lot in this function) + Map fileProviders = new HashMap(4); + + // go through each entry and extract entries for each file. + // + // allocate one FileLineEntryProvider per CU + // + for (ILineEntry entry : lineEntries) { + IPath path = entry.getFilePath(); + + FileLineEntryProvider provider = fileProviders.get(path); + if (provider == null) { + // This will look for an existing one and create a + // new one if none exits. + provider = getFileLineProviderForCU(cu, path); + provider.setCULineEntries(lineEntries); + fileProviders.put(path, provider); + } + + provider.addLineEntry(entry); + } + } + + // then, look for lines provided by decl file/line/column entries + for (IScope child : cu.getChildren()) { + addCompileUnitChild(cu, child); + } + } + + + + /** + * Add (or update) a compile unit child entry (function) by adding a + * line entry for its declaration location, which may differ from the + * first line inside the function to which the low PC refers. + * @param cu + * @param child + */ + public void addCompileUnitChild(ICompileUnitScope cu, IScope child) { + if (child instanceof IFunctionScope) { + IFunctionScope func = (IFunctionScope) child; + IPath declFile = func.getDeclFile(); + + if (declFile != null) { + // this is the slow path for dynamic parsing + FileLineEntryProvider provider + = getFileLineProviderForCU(cu, declFile); + + int declLine = func.getDeclLine(); + int declColumn = func.getDeclColumn(); + + // is there already an entry at this line? + Collection curEntries + = provider.getLineEntriesForLines(declFile, declLine, declLine); + if (curEntries.isEmpty()) { + // no, add one, and make it range from our start to the first actual line + + LineEntry entry + = new LineEntry(declFile, declLine, declColumn, + func.getLowAddress(), func.getLowAddress()); + provider.addLineEntry(entry); + } + } + } + } + + + private FileLineEntryProvider getFileLineProviderForCU( + ICompileUnitScope cu, IPath declFile) { + FileLineEntryProviders providers = pathToLineEntryMap.get(declFile); + if (providers != null) { + for (FileLineEntryProvider p : providers) { + if (p.getCU().equals(cu)) { + return p; + } + } + } + FileLineEntryProvider provider = new FileLineEntryProvider(cu, declFile); + registerFileLineEntryProvider(declFile, provider); + return provider; + } + + + + private void registerFileLineEntryProvider(IPath path, + FileLineEntryProvider provider) { + FileLineEntryProviders fileEntries = pathToLineEntryMap.get(path); + if (fileEntries == null) { + fileEntries = new FileLineEntryProviders(); + pathToLineEntryMap.put(path, fileEntries); + } + fileEntries.add(provider); + fileProviders.add(provider); + fileProviderArray = null; + } + + /** + * Get the line entry providers for the given source file. + * @path sourceFile the absolute path to the source file + * @return the unmodifiable list of providers for the file, possibly empty. + */ + public Collection getLineEntryProvidersForFile(IPath sourceFile) { + List cus = pathToLineEntryMap.get(sourceFile); + if (cus != null) + return Collections.unmodifiableCollection(cus); + + for (Map.Entry entry : pathToLineEntryMap.entrySet()) { + if (!PathUtils.isCaseSensitive() && entry.getKey().toOSString().compareToIgnoreCase(sourceFile.toOSString()) == 0) { + cus = entry.getValue(); + pathToLineEntryMap.put(sourceFile, entry.getValue()); + return Collections.unmodifiableCollection(cus); + } + } + + for (Map.Entry entry : pathToLineEntryMap.entrySet()) { + if (entry.getKey().equals(sourceFile)) { + cus = entry.getValue(); + return Collections.unmodifiableCollection(cus); + } + } + + return Collections.emptyList(); + } + + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ILineEntryProvider#getLineEntriesForLines(org.eclipse.core.runtime.IPath, int, int) + */ + public Collection getLineEntriesForLines(IPath file, + int startLineNumber, int endLineNumber) { + FileLineEntryProviders matches = pathToLineEntryMap.get(file); + if (matches == null) + return Collections.emptyList(); + + List ret = null; + for (FileLineEntryProvider provider : matches) { + Collection entries + = provider.getLineEntriesForLines(file, startLineNumber, endLineNumber); + if (!entries.isEmpty()) { + if (ret == null) + ret = new ArrayList(entries); + else + ret.addAll(entries); + } + } + if (ret == null) + return Collections.emptyList(); + + return ret; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ILineEntryProvider#getLineEntryAtAddress(org.eclipse.cdt.core.IAddress) + */ + public ILineEntry getLineEntryAtAddress(IAddress linkAddress) { + // scanning files can introduce new file providers; avoid ConcurrentModificationException + if (fileProviderArray == null) { + fileProviderArray = fileProviders.toArray(new FileLineEntryProvider[fileProviders.size()]); + } + for (FileLineEntryProvider provider : fileProviderArray) { + // Narrow down the search to avoid iterating potentially hundreds + // of duplicates of the same file + // (e.g. for stl_vector.h, expanded N times for N std::vector uses). + // (Don't use #getScopeAtAddress() since this preparses too much.) + if (provider.getCU().getLowAddress().compareTo(linkAddress) <= 0 + && provider.getCU().getHighAddress().compareTo(linkAddress) > 0) { + ILineEntry entry = provider.getLineEntryAtAddress(linkAddress); + if (entry != null + + /* FIXME: sigh ... + * + * yet another RVCT DWARF inlined LNT entry generation bug ... + * + * we just can't have entry.highAddr == entry.lowAddr! + * + * that just TOTALLY ruins the illusion of stepping. + * + * see, if we pass back the address we're on, + * no step-over range will get created, + * and the debugger will just run ... + * + * ... and that's just NotGood-TM . + */ + && !entry.getLowAddress().equals(entry.getHighAddress()) + + ) { + return entry; + } + } + } + return null; + } + + + public ILineEntry getLineEntryInFunction(IAddress linkAddress, IFunctionScope parentFunction) { + ILineEntry functionEntry = getLineEntryAtAddress(parentFunction.getLowAddress()); + if (functionEntry == null) + return null; + Collection parentProviders + = getLineEntryProvidersForFile(functionEntry.getFilePath()); + for (ILineEntryProvider iLineEntryProvider : parentProviders) { + if (iLineEntryProvider instanceof FileLineEntryProvider) { + ILineEntry entry + = ((FileLineEntryProvider)iLineEntryProvider).getLineEntryInFunction(linkAddress, parentFunction); + if (entry != null) + return entry; + } + } + return null; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ILineEntryProvider#getNextLineEntry(org.eclipse.cdt.debug.edc.internal.symbols.ILineEntry) + */ + public ILineEntry getNextLineEntry(final ILineEntry entry, final boolean collapseInlineFunctions) { + if (entry == null) + return null; + + final IAddress entryLowAddr = entry.getLowAddress(); + final IAddress entryHighAddr = entry.getHighAddress(); + final IPath entryPath = entry.getFilePath(); + FileLineEntryProviders matches = pathToLineEntryMap.get(entryPath); + if (matches == null) + return null; + + // avoid possible concurrent access if we read new files while searching + FileLineEntryProvider[] matchArray = matches.toArray(new FileLineEntryProvider[matches.size()]); + + for (FileLineEntryProvider provider : matchArray) { + ICompileUnitScope cuScope = provider.getCU(); + // Narrow down the search to avoid iterating potentially hundreds of duplicates of the same file + // (e.g. for stl_vector.h, expanded N times for N std::vector uses). + // (Don't use #getScopeAtAddress() since this preparses too much.). + if (cuScope.getLowAddress().compareTo(entryLowAddr) <= 0 + // NOTE: high addrs for both scope & line entries are inclusive: thus >= 0 + && cuScope.getHighAddress().compareTo(entryHighAddr) >= 0) { + + // provider.getNextLineEntry() returns null for only 1 reason: + // 1) there are no more entries at all for the compileUnitScope + // + // so there's no need to continue looking in other providers + return provider.getNextLineEntry(entry, collapseInlineFunctions); + } + } + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ILineEntryProvider#getPreviousLineEntry + */ + public ILineEntry getPreviousLineEntry(ILineEntry entry, + boolean collapseInlineFunctions) { + if (entry == null) + return null; + + FileLineEntryProviders matches = pathToLineEntryMap.get(entry.getFilePath()); + if (matches != null) { + final IAddress entryLowAddr = entry.getLowAddress(); + final IAddress entryHighAddr = entry.getHighAddress(); + boolean entryIsInline = false, inlineEstablished = false; + + // avoid possible concurrent access if we read new files while searching + FileLineEntryProvider[] matchArray = matches.toArray(new FileLineEntryProvider[matches.size()]); + + for (FileLineEntryProvider provider : matchArray) { + ICompileUnitScope cuScope = provider.getCU(); + // Narrow down the search to avoid iterating potentially hundreds of duplicates of the same file + // (e.g. for stl_vector.h, expanded N times for N std::vector uses). + // (Don't use #getScopeAtAddress() since this preparses too much.). + // + // + if (cuScope.getLowAddress().compareTo(entryLowAddr) <= 0 + // NOTE: high addrs for both scope & line entries are inclusive: thus >= 0 + && cuScope.getHighAddress().compareTo(entryHighAddr) >= 0) { + if (!inlineEstablished) { + entryIsInline = FileLineEntryProvider.isInlinedFunction(cuScope.getFunctionAtAddress(entryLowAddr)); + inlineEstablished = true; + } + ILineEntry prev = provider.getPreviousLineEntry(entry, collapseInlineFunctions); + if (prev == null && collapseInlineFunctions && entryIsInline) { + // retry with the provider mapped from the compileUnitScope.filePath + return provider.getPreviousLineEntryInCU(entry); + } + + if (prev != null) { // in case there's another provider + return prev; + } + } + } + } + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.ILineEntryProvider#findClosestLineWithCode(org.eclipse.core.runtime.IPath, int, int) + */ + public List findClosestLineWithCode(IPath sourceFile, + int anchorLine, int neighbor_limit) { + List ret = new ArrayList(1); + + /* Check all compile units in the module for code line. + */ + Collection fileProviders = + getLineEntryProvidersForFile(sourceFile); + if (fileProviders.isEmpty()) + return ret; + + for (ILineEntryProvider fileProvider : fileProviders) { + + // Find code line in one CU using the source file + List la = fileProvider.findClosestLineWithCode(sourceFile, anchorLine, neighbor_limit); + if (la.isEmpty()) + continue; + assert (la.size() == 1); + ILineAddresses newCodeLine = la.get(0); + + if (ret.isEmpty()) + ret.add(newCodeLine); + else { + boolean merged = false; + for (ILineAddresses e : ret) + if (newCodeLine.getLineNumber() == e.getLineNumber()) { + ((EDCLineAddresses)e).addAddress(newCodeLine.getAddress()); + merged = true; + break; + } + + if (!merged) + ret.add(newCodeLine); + } + } + + return ret; + } + + + public boolean hasSourceFile(IPath sourceFile) { + Collection fileProviders = + getLineEntryProvidersForFile(sourceFile); + return fileProviders != null && ! fileProviders.isEmpty(); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/PointerType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/PointerType.java new file mode 100644 index 0000000..4ba1294 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/PointerType.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class PointerType extends MayBeQualifiedType implements IPointerType { + + public PointerType(String name, IScope scope, int byteSize, Map properties) { + super(name, scope, byteSize, properties); + } + + // create an internal pointer for expression evaluation + public PointerType() { + super("", null, 0, null); //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ReferenceType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ReferenceType.java new file mode 100644 index 0000000..ce308d5 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ReferenceType.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class ReferenceType extends Type implements IReferenceType { + + public ReferenceType(String name, IScope scope, int byteSize, Map properties) { + super(name, scope, byteSize, properties); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RegisterOffsetVariableLocation.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RegisterOffsetVariableLocation.java new file mode 100644 index 0000000..b5cfd3b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RegisterOffsetVariableLocation.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.math.BigInteger; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; +import org.eclipse.cdt.debug.edc.symbols.IRegisterOffsetVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.CoreException; + +public class RegisterOffsetVariableLocation extends RegisterVariableLocation implements IRegisterOffsetVariableLocation { + + protected final long offset; + private int addressSize; + + public RegisterOffsetVariableLocation(EDCServicesTracker tracker, IDMContext context, String name, int id, long offset) { + super(tracker, context, name, id); + this.offset = offset; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.RegisterVariableLocation#toString() + */ + @Override + public String toString() { + return super.toString() + " + " + getOffset(); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IRegisterOffsetVariableLocation#getOffset() + */ + public long getOffset() { + return offset; + } + + public BigInteger readValue(int bytes) throws CoreException { + BigInteger regval = super.readValue(bytes); + return regval.add(BigInteger.valueOf(offset)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.RegisterVariableLocation#addOffset(long) + */ + @Override + public IVariableLocation addOffset(long offset) { + return new RegisterOffsetVariableLocation(tracker, context, name, id, offset + this.offset); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.RegisterVariableLocation#getLocationName(org.eclipse.cdt.dsf.service.DsfServicesTracker) + */ + @Override + public String getLocationName() { + try { + if (addressSize == 0) { + addressSize = 4; + ITargetEnvironment targetEnvironment = tracker.getService(ITargetEnvironment.class); + if (targetEnvironment != null) + addressSize = targetEnvironment.getPointerSize(); + } + BigInteger regval = super.readValue(addressSize); + regval = regval.add(BigInteger.valueOf(offset)); + return SymbolsMessages.RegisterOffsetVariableLocation_Hex + Long.toHexString(regval.longValue()); + } catch (CoreException e) { + // fallback + return super.getLocationName() + (offset < 0 ? SymbolsMessages.RegisterOffsetVariableLocation_Positive : SymbolsMessages.RegisterOffsetVariableLocation_Negative ) + Math.abs(offset); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.RegisterVariableLocation#getAddress() + */ + @Override + public IAddress getAddress() { + return null; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RegisterVariableLocation.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RegisterVariableLocation.java new file mode 100644 index 0000000..439b504 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RegisterVariableLocation.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.math.BigInteger; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.services.Registers; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.symbols.IRegisterVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.CoreException; + +public class RegisterVariableLocation implements IRegisterVariableLocation { + + protected String name; + protected int id; + protected final IDMContext context; + protected final EDCServicesTracker tracker; + + public RegisterVariableLocation(EDCServicesTracker tracker, IDMContext context, String name, int id) { + this.tracker = tracker; + this.context = context; + this.name = name; + this.id = id; + if (name == null) { + Registers registerservice = tracker.getService(Registers.class); + this.name = registerservice.getRegisterNameFromCommonID(getRegisterID()); + } + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return getRegisterName() != null ? getRegisterName() : "R" + id + //$NON-NLS-1$ + (context instanceof StackFrameDMC && ((StackFrameDMC) context).getLevel() > 0 ? + " (level " + ((StackFrameDMC) context).getLevel() + ")" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public String getRegisterName() { + return name; + } + + public int getRegisterID() { + return id; + } + + public BigInteger readValue(int bytes) throws CoreException { + if (context instanceof StackFrameDMC) + return ((StackFrameDMC)context).getFrameRegisters().getRegister(id, bytes); + else + throw EDCDebugger.newCoreException(SymbolsMessages.RegisterVariableLocation_CannotReadFramelessRegister); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#addOffset(long) + */ + public IVariableLocation addOffset(long offset) { + return new RegisterOffsetVariableLocation(tracker, context, name, id, offset); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#getLocationName(org.eclipse.cdt.dsf.service.DsfServicesTracker) + */ + public String getLocationName() { + return "$" + getRegisterName(); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#getAddress() + */ + public IAddress getAddress() { + return null; + } + + public IDMContext getContext() { + return context; + } + + public EDCServicesTracker getServicesTracker() + { + return tracker; + } + public void writeValue(int bytes, BigInteger value) throws CoreException { + if (context instanceof StackFrameDMC) + ((StackFrameDMC)context).getFrameRegisters().writeRegister(id, bytes, value); + else + throw EDCDebugger.newCoreException(SymbolsMessages.RegisterVariableLocation_CannotWriteFramelessRegister); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RuntimeSection.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RuntimeSection.java new file mode 100644 index 0000000..887fd17 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/RuntimeSection.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.text.MessageFormat; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; + +public class RuntimeSection implements IRuntimeSection { + + private ISection section; + // the relocated address of the section at runtime + private IAddress runtimeAddress; + + public RuntimeSection(ISection section) { + this.section = section; + // the section may not get relocted, so set the runtime + // address to be the link address + runtimeAddress = section.getLinkAddress(); + } + + public int getId() { + return section.getId(); + } + + public long getSize() { + return section.getSize(); + } + + public IAddress getLinkAddress() { + return section.getLinkAddress(); + } + + public Map getProperties() { + return section.getProperties(); + } + + public IAddress getRuntimeAddress() { + return runtimeAddress; + } + + public void relocate(IAddress runtimeAddress) { + this.runtimeAddress = runtimeAddress; + } + + @Override + public String toString() { + return MessageFormat.format("[sectionID={0}, link address={1}, runtime address={2}]", getId(), getLinkAddress().toHexAddressString(), //$NON-NLS-1$ + runtimeAddress.toHexAddressString()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RuntimeSection other = (RuntimeSection) obj; + if (!getLinkAddress().equals(other.getLinkAddress())) + return false; + if (!getRuntimeAddress().equals(other.getRuntimeAddress())) + return false; + if (getId() != other.getId()) + return false; + return true; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Scope.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Scope.java new file mode 100644 index 0000000..d404c3d --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Scope.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.RangeList; +import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope; +import org.eclipse.cdt.debug.edc.symbols.IEnumerator; +import org.eclipse.cdt.debug.edc.symbols.IModuleScope; +import org.eclipse.cdt.debug.edc.symbols.IRangeList; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IVariable; +import org.eclipse.cdt.debug.edc.symbols.IRangeList.Entry; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr64; + +public abstract class Scope implements IScope { + + protected String name; + protected IAddress lowAddress; + protected IAddress highAddress; + protected IScope parent; + protected List children = new ArrayList(); + protected List variables = new ArrayList(); + protected List enumerators = new ArrayList(); + private TreeMap addressToScopeMap; + + protected IRangeList rangeList; + + public Scope(String name, IAddress lowAddress, IAddress highAddress, IScope parent) { + this.name = name; + this.lowAddress = lowAddress; + this.highAddress = highAddress; + this.parent = parent; + } + + public String getName() { + return name; + } + + public IAddress getLowAddress() { + return lowAddress; + } + + public IAddress getHighAddress() { + return highAddress; + } + + /** + * Tell whether the address range for the scope is empty. + * @return flag + */ + public boolean hasEmptyRange() { + return (lowAddress == null || highAddress == null) + || (lowAddress.isZero() && highAddress.isZero()) + || (lowAddress.getValue().longValue() == -1 && highAddress.isZero()); // TODO: remove this case + } + + /** + * Return the list of non-contiguous ranges for this scope. + * @return list or null + */ + public IRangeList getRangeList() { + return rangeList; + } + + public void setLowAddress(IAddress lowAddress) { + this.lowAddress = lowAddress; + } + + public void setHighAddress(IAddress highAddress) { + this.highAddress = highAddress; + } + + public void setRangeList(IRangeList ranges) { + this.rangeList = ranges; + setLowAddress(new Addr32(rangeList.getLowAddress())); + setHighAddress(new Addr32(rangeList.getHighAddress())); + } + + public IScope getParent() { + return parent; + } + + public Collection getChildren() { + return Collections.unmodifiableCollection(children); + } + + public Collection getVariables() { + return Collections.unmodifiableCollection(variables); + } + + public Collection getEnumerators() { + return Collections.unmodifiableCollection(enumerators); + } + + public IScope getScopeAtAddress(IAddress linkAddress) { + // see if it's in this scope + if (linkAddress.compareTo(lowAddress) >= 0 && linkAddress.compareTo(highAddress) < 0) { + + ensureScopeRangeLookup(); + + long addr = linkAddress.getValue().longValue(); + IRangeList.Entry addressEntry = new IRangeList.Entry(addr, addr); + SortedMap tailMap = addressToScopeMap.tailMap(addressEntry); + + if (tailMap.isEmpty()) + return this; + + IScope child = tailMap.values().iterator().next(); + if (linkAddress.compareTo(child.getLowAddress()) >= 0 + && linkAddress.compareTo(child.getHighAddress()) < 0) { + return child.getScopeAtAddress(linkAddress); + } + + return this; + } + + return null; + } + + /** + * Make sure our mapping of address range to scope is valid. + */ + private void ensureScopeRangeLookup() { + if (addressToScopeMap == null) { + addressToScopeMap = new TreeMap(); + + for (IScope scope : children) { + addScopeRange(scope); + } + //System.out.println("Mapping for " + getName()+ ": "+ addressToScopeMap.size() + " entries"); + } + } + + /** + * @param scope + */ + private void addScopeRange(IScope scope) { + IRangeList ranges = scope.getRangeList(); + if (ranges != null) { + for (IRangeList.Entry entry : ranges) { + addressToScopeMap.put(entry, scope); + } + } else { + addressToScopeMap.put(new IRangeList.Entry( + scope.getLowAddress().getValue().longValue(), + scope.getHighAddress().getValue().longValue()), + scope); + } + } + + /** + * Adds the given scope as a child of this scope + * + * @param scope + */ + public void addChild(IScope scope) { + children.add(scope); + if (addressToScopeMap != null) { + addScopeRange(scope); + } + } + + /** + * Adds the given variable to this scope + * + * @param variable + */ + public void addVariable(IVariable variable) { + variables.add(variable); + } + + /** + * Adds the given variable to this scope + * + * @param variable + */ + public void addEnumerator(IEnumerator enumerator) { + enumerators.add(enumerator); + } + + public int compareTo(Object o) { + if (o instanceof IScope) { + return lowAddress.compareTo(((IScope) o).getLowAddress()); + } else if (o instanceof IAddress) { + return lowAddress.compareTo(o); + } + return 0; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Scope ["); //$NON-NLS-1$ + if (rangeList != null) { + builder.append("ranges="); //$NON-NLS-1$ + builder.append(rangeList); + } else { + builder.append("lowAddress="); //$NON-NLS-1$ + builder.append(lowAddress != null ? lowAddress.toHexAddressString() : "null"); + builder.append(", highAddress="); //$NON-NLS-1$ + builder.append(highAddress != null ? highAddress.toHexAddressString() : "null"); + } + builder.append(", "); //$NON-NLS-1$ + if (name != null) { + builder.append("name="); //$NON-NLS-1$ + builder.append(name); + builder.append(", "); //$NON-NLS-1$ + } + builder.append("]"); //$NON-NLS-1$ + return builder.toString(); + } + + public void fixupRanges(IAddress baseAddress) { + // compile unit scopes not generated by the compiler so + // figure it out from the functions + IAddress newLowAddress = Addr64.MAX; + IAddress newHighAddress = Addr64.ZERO; + boolean any = false; + + for (IScope kid : getChildren()) { + // the compiler may generate (bad) low/high pc's which are not + // in the actual module space for some functions. to work + // around this, only honor addresses that are above the + // actual link address + if (kid.hasEmptyRange()) { + continue; + } + + if (kid.getLowAddress().compareTo(baseAddress) > 0) { + if (kid.getLowAddress().compareTo(newLowAddress) < 0) { + newLowAddress = kid.getLowAddress(); + any = true; + } + + if (kid.getHighAddress().compareTo(newHighAddress) > 0) { + newHighAddress = kid.getHighAddress(); + any = true; + } + } + } + + if (any) { + //System.out.println("Needed to fix up ranges for " + getName()); + lowAddress = newLowAddress; + highAddress = newHighAddress; + rangeList = null; + } else { + if (lowAddress == null) { + lowAddress = highAddress = Addr32.ZERO; + } + } + } + + /** + * Merge the code range(s) from the given scope into this one. + * @param scope + */ + protected void mergeScopeRange(IScope scope) { + if (hasEmptyRange()) { + // copy range + if (scope.getRangeList() != null) { + setRangeList(scope.getRangeList()); + } else { + setLowAddress(scope.getLowAddress()); + setHighAddress(scope.getHighAddress()); + } + } else { + if (scope.getLowAddress() != null && scope.getLowAddress().compareTo(lowAddress) < 0 + && !scope.getLowAddress().isZero()) // ignore random 0 entries + { + if (rangeList != null) { + if (scope.getRangeList() != null) { + // TODO: merge properly + rangeList = null; + } else { + ((RangeList)rangeList).addLowRange(scope.getLowAddress().getValue().longValue()); + } + } + lowAddress = scope.getLowAddress(); + } + if (scope.getHighAddress() != null && scope.getHighAddress().compareTo(highAddress) > 0) { + if (rangeList != null) { + if (scope.getRangeList() != null) { + // TODO: merge properly + rangeList = null; + } else { + ((RangeList)rangeList).addHighRange(scope.getHighAddress().getValue().longValue()); + } + } + highAddress = scope.getHighAddress(); + } + } + } + + protected void addLineInfoToParent(IScope scope) { + IScope cu = parent; + while (cu != null) { + if (cu instanceof ICompileUnitScope && cu.getParent() instanceof IModuleScope) { + IModuleScope module = (IModuleScope) cu.getParent(); + ModuleLineEntryProvider provider = (ModuleLineEntryProvider) module.getModuleLineEntryProvider(); + provider.addCompileUnitChild((ICompileUnitScope) cu, scope); + break; + } + cu = cu.getParent(); + } + } + + /** + * + */ + public void dispose() { + for (IScope scope : children) + scope.dispose(); + children.clear(); + for (IVariable var : variables) + var.dispose(); + variables.clear(); + enumerators.clear(); + if (addressToScopeMap != null) + addressToScopeMap.clear(); + rangeList = null; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Section.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Section.java new file mode 100644 index 0000000..222be38 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Section.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; + +public class Section implements ISection { + + private final int id; + + private final long size; + + // the address generated by the linker + private final IAddress linkAddress; + + private final Map properties; + + public Section(int id, long size, IAddress linkAddress, Map properties) { + this.id = id; + this.size = size; + this.linkAddress = linkAddress; + this.properties = new HashMap(properties); // make a + // copy + } + + public int getId() { + return id; + } + + public long getSize() { + return size; + } + + public IAddress getLinkAddress() { + return linkAddress; + } + + public Map getProperties() { + return properties; + } + + @Override + public String toString() { + return MessageFormat.format("[sectionID={0}, link address={1}]", id, linkAddress.toHexAddressString()); //$NON-NLS-1$); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Section other = (Section) obj; + if (linkAddress != other.linkAddress) + return false; + if (id != other.id) + return false; + return true; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/StructType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/StructType.java new file mode 100644 index 0000000..78c07b3 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/StructType.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class StructType extends CompositeType { + + public StructType(String name, IScope scope, int byteSize, Map properties) { + super(name, scope, ICompositeType.k_struct, byteSize, properties, "struct"); //$NON-NLS-1$ + } + +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SubroutineType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SubroutineType.java new file mode 100644 index 0000000..37c1b2f --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SubroutineType.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class SubroutineType extends Type implements ISubroutineType { + + public SubroutineType(IScope scope, Map properties) { + super("", scope, 0, properties); //$NON-NLS-1$ + } + + // create an internal pointer for expression evaluation + public SubroutineType() { + super("", null, 0, null); //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Symbol.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Symbol.java new file mode 100644 index 0000000..ed6de1b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Symbol.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.symbols.ISymbol; + +public class Symbol implements ISymbol { + + protected String name; + protected IAddress address; + protected long size; + + public Symbol(String name, IAddress address, long size) { + this.name = name; + this.address = address; + this.size = size; + } + + public String getName() { + return name; + } + + public IAddress getAddress() { + return address; + } + + public long getSize() { + return size; + } + + public int compareTo(Object o) { + if (o instanceof Symbol) { + return address.compareTo(((Symbol) o).address); + } else if (o instanceof IAddress) { + return address.compareTo(o); + } + return 0; + } + + @Override + public String toString() { + return "name=" + name + //$NON-NLS-1$ + ", address=0x" + Long.toHexString(address.getValue().longValue()) + //$NON-NLS-1$ + ", size=" + size; //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SymbolsMessages.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SymbolsMessages.java new file mode 100644 index 0000000..928d1cc --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SymbolsMessages.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.osgi.util.NLS; + +public class SymbolsMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.edc.internal.symbols.SymbolsMessages"; //$NON-NLS-1$ + + public static String InvalidVariableLocation_CannotWriteInvalidLocation; + + public static String MemoryVariableLocation_CannotFindFrame; + public static String MemoryVariableLocation_CannotReadAddrFormat; + public static String MemoryVariableLocation_CannotWriteAddrFormat; + public static String MemoryVariableLocation_Hex; + public static String MemoryVariableLocation_LinkTime; + + public static String RegisterOffsetVariableLocation_Hex; + public static String RegisterOffsetVariableLocation_Negative; + public static String RegisterOffsetVariableLocation_Positive; + public static String RegisterVariableLocation_CannotReadFramelessRegister; + public static String RegisterVariableLocation_CannotWriteFramelessRegister; + + public static String ValueVariableLocation_CannotModifyDerivedValue; + public static String ValueVariableLocation_NoValueAvailable; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, SymbolsMessages.class); + } + + private SymbolsMessages() { + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SymbolsMessages.properties b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SymbolsMessages.properties new file mode 100644 index 0000000..d0695c4 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/SymbolsMessages.properties @@ -0,0 +1,23 @@ +############################################################################### +# Copyright (c) 2010 Nokia and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Nokia - Initial API and implementation +############################################################################### +InvalidVariableLocation_CannotWriteInvalidLocation=Can't write to an invalid variable location +MemoryVariableLocation_CannotFindFrame=Cannot find frame +MemoryVariableLocation_CannotReadAddrFormat=cannot read address {0} +MemoryVariableLocation_CannotWriteAddrFormat=cannot write address {0} +MemoryVariableLocation_Hex=0x +MemoryVariableLocation_LinkTime=\ (link time) +RegisterOffsetVariableLocation_Hex=0x +RegisterOffsetVariableLocation_Negative=\ - +RegisterOffsetVariableLocation_Positive=\ + +RegisterVariableLocation_CannotReadFramelessRegister=cannot read register without frame +RegisterVariableLocation_CannotWriteFramelessRegister=cannot write register without frame +ValueVariableLocation_CannotModifyDerivedValue=cannot modify derived value +ValueVariableLocation_NoValueAvailable=no value available diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/TemplateParamType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/TemplateParamType.java new file mode 100644 index 0000000..1a549e7 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/TemplateParamType.java @@ -0,0 +1,72 @@ +/******************************************************************************* + + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.TypeUtils; + +public class TemplateParamType implements ITemplateParam { + + final String name; + IType type; + + public TemplateParamType(String name, IType type) { + this.name = name; + this.type = type; + } + + public String getName() { + if (name == null || name.length() == 0) { + getType(); + return TypeUtils.getFullTypeName(type); + } else { + return this.name; + } + } + + public IType getType() { + if (this.type instanceof IForwardTypeReference) { + this.type = ((IForwardTypeReference) this.type).getReferencedType(); + } + + IType nextType = this.type; + while (nextType != null) { + if (nextType instanceof IForwardTypeReference) + nextType = ((IForwardTypeReference) nextType).getReferencedType(); + nextType = nextType.getType(); + } + + return this.type; + } + + public IScope getScope() { + return null; + } + + public int getByteSize() { + return 0; + } + + public Map getProperties() { + return null; + } + + public void setType(IType type) { + } + + public void dispose() { + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Type.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Type.java new file mode 100644 index 0000000..5204c57 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Type.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; + + +public class Type implements IType { + + /** This property key maps to an {@link IForwardTypeReference} object */ + public static final String TYPE_REFERENCE = "type_reference"; //$NON-NLS-1$ + + protected String name; + protected IScope scope; + protected int byteSize; + protected IType type; // subtype, if any, maybe IForwardTypeReference + protected Map properties; // may be null + + public Type(String name, IScope scope, int byteSize, Map properties) { + this.name = name; + this.scope = scope; + this.byteSize = byteSize; + this.properties = properties; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IType#dispose() + */ + public void dispose() { + properties = null; + scope = null; + type = null; + } + + public String getName() { + return name; + } + + public IScope getScope() { + return scope; + } + + public int getByteSize() { + return byteSize; + } + + public Map getProperties() { + return properties; + } + + public IType getType() { + if (type == null && properties != null) { + type = (IType) properties.get(TYPE_REFERENCE); + } + if (type instanceof IForwardTypeReference) { + type = ((IForwardTypeReference) type).getReferencedType(); + } + return type; + } + + public void setType(IType type) { + this.type = type; + } + + public void setScope(IScope scope) { + this.scope = scope; + } + + protected int updateByteSizeFromSubType() { + if (byteSize == 0) { + IType theType = getType(); + if (theType != null) + byteSize = theType.getByteSize(); + } + return byteSize; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/TypedefType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/TypedefType.java new file mode 100644 index 0000000..abb1f53 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/TypedefType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class TypedefType extends MayBeQualifiedType implements ITypedef { + + public TypedefType(String name, IScope scope, Map properties) { + super(name, scope, 0, properties); + } + + @Override + public String getName() { + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Type#getByteSize() + */ + @Override + public int getByteSize() { + return updateByteSizeFromSubType(); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/UnionType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/UnionType.java new file mode 100644 index 0000000..1719eb3 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/UnionType.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +public class UnionType extends CompositeType { + + public UnionType(String name, IScope scope, int byteSize, Map properties) { + super(name, scope, ICompositeType.k_union, byteSize, properties, "union"); //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ValueVariableLocation.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ValueVariableLocation.java new file mode 100644 index 0000000..2f00934 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/ValueVariableLocation.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.math.BigInteger; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.symbols.IValueVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.CoreException; + +/** + * This is an actual value, calculated from somewhere, which does not have a location. + */ +public class ValueVariableLocation implements IValueVariableLocation { + + private BigInteger value; + + public ValueVariableLocation(BigInteger value) { + this.value = value; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "0x" + Long.toHexString(value.longValue()); //$NON-NLS-1$ + } + + + public BigInteger readValue(int bytes) throws CoreException { + if (value == null) + throw EDCDebugger.newCoreException(SymbolsMessages.ValueVariableLocation_NoValueAvailable); + return value; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#addOffset(long) + */ + public IVariableLocation addOffset(long offset) { + return new ValueVariableLocation(value.add(BigInteger.valueOf(offset))); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#getLocationName(org.eclipse.cdt.dsf.service.DsfServicesTracker) + */ + public String getLocationName() { + return ""; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariableLocation#getAddress() + */ + public IAddress getAddress() { + return null; + } + + public void writeValue(int bytes, BigInteger value) throws CoreException { + throw EDCDebugger.newCoreException(SymbolsMessages.ValueVariableLocation_CannotModifyDerivedValue); + } + + public IDMContext getContext() { + return null; + } + + public EDCServicesTracker getServicesTracker() { + return null; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Variable.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Variable.java new file mode 100644 index 0000000..f7d66db --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/Variable.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariable; +import org.eclipse.core.runtime.IPath; + + +public class Variable implements IVariable { + + protected String name; + protected IScope scope; + protected IType type; + protected ILocationProvider locationProvider; + protected long startScope; + protected boolean isDeclared; + protected IPath definingFile; + + + public Variable(String name, IScope scope, IType type, ILocationProvider locationProvider, boolean isDeclared, IPath definingFile) { + this.name = name; + this.scope = scope; + this.type = type; + this.locationProvider = locationProvider; + this.isDeclared = isDeclared; + this.definingFile = definingFile; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IVariable#dispose() + */ + public void dispose() { + type = null; + locationProvider = null; + scope = null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IVariable#getName() + */ + public String getName() { + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IVariable#getScope() + */ + public IScope getScope() { + return scope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IVariable#getType() + */ + public IType getType() { + if (type instanceof IForwardTypeReference) + type = ((IForwardTypeReference) type).getReferencedType(); + + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IVariable#getLocationProvider() + */ + public ILocationProvider getLocationProvider() { + return locationProvider; + } + + public void setStartScope(long start) { + this.startScope = start; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IVariable#getStartScope() + */ + public long getStartScope() { + return startScope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IVariable#isDeclared() + */ + public boolean isDeclared() { + return isDeclared; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IVariable#getDefiningFile() + */ + public IPath getDefiningFile() { + return definingFile; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Var ["); //$NON-NLS-1$ + if (name != null) { + builder.append(name); + } + if (scope != null) { + builder.append(", "); //$NON-NLS-1$ + builder.append("scope="); //$NON-NLS-1$ + builder.append(scope.getName()); + } + builder.append("]"); //$NON-NLS-1$ + return builder.toString(); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/VolatileType.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/VolatileType.java new file mode 100644 index 0000000..1757625 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/VolatileType.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols; + +import java.util.Map; + +import org.eclipse.cdt.debug.edc.symbols.IScope; + +/** + * Pseudo-type that represents the volatile qualifier + */ +public class VolatileType extends Type implements IQualifierType { + + public VolatileType(IScope scope, Map properties) { + super("volatile", scope, 0, properties); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Type#getByteSize() + */ + @Override + public int getByteSize() { + return updateByteSizeFromSubType(); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfCompileUnit.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfCompileUnit.java new file mode 100644 index 0000000..203fb99 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfCompileUnit.java @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.CompileUnitScope; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.AttributeList; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.CompilationUnitHeader; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.IModuleScope; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IVariable; +import org.eclipse.core.runtime.IPath; + +public class DwarfCompileUnit extends CompileUnitScope { + + protected DwarfDebugInfoProvider provider; + protected AttributeList attributes; + private List fileList; + private boolean rangesDirty; + + // computation unit header + protected final CompilationUnitHeader header; + + // whether the computation unit has been parsed to find variables and children with address ranges + protected boolean parsedForVarsAndAddresses = false; + + // whether the computation unit has been parsed to find types + protected boolean parsedForTypes = false; + + + public DwarfCompileUnit(DwarfDebugInfoProvider provider, IModuleScope parent, IPath filePath, + IAddress lowAddress, IAddress highAddress, CompilationUnitHeader header, boolean hasChildren, + AttributeList attributes) { + super(filePath, parent, lowAddress, highAddress); + + this.provider = provider; + this.attributes = attributes; + this.header = header; + + // if there are no children, say the children have been parsed + if (!hasChildren) { + this.parsedForVarsAndAddresses = true; + this.parsedForTypes = true; + } + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + header.debugInfoOffset; + result = prime * result + provider.getSymbolFile().hashCode(); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DwarfCompileUnit other = (DwarfCompileUnit) obj; + if (header.debugInfoOffset != other.header.debugInfoOffset) + return false; + if (!provider.getSymbolFile().equals(other.provider.getSymbolFile())) + return false; + return true; + } + + public AttributeList getAttributeList() { + return attributes; + } + + @Override + protected Collection parseLineTable() { + DwarfInfoReader reader = new DwarfInfoReader(provider); + fileList = new ArrayList(); + return reader.parseLineTable(this, attributes, fileList); + } + + public void setLowAddress(IAddress address) { + this.lowAddress = address; + } + + public void setHighAddress(IAddress address) { + this.highAddress = address; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getLowAddress() + */ + @Override + public IAddress getLowAddress() { + // the address is known in the compile unit tag; + // if anything inside is outside that range, it's a bug. + return super.getLowAddress(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getHighAddress() + */ + @Override + public IAddress getHighAddress() { + // the address is known in the compile unit tag; + // if anything inside is outside that range, it's a bug. + return super.getHighAddress(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.CompileUnitScope#getFunctionAtAddress(org.eclipse.cdt.core.IAddress) + */ + @Override + public IFunctionScope getFunctionAtAddress(IAddress linkAddress) { + if (rangesDirty) { + fixupRanges(); + } + ensureParsedForAddresses(); + return super.getFunctionAtAddress(linkAddress); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.CompileUnitScope#getFunctions() + */ + @Override + public Collection getFunctions() { + ensureParsedForAddresses(); + return super.getFunctions(); + } + + /** + * For compilers that don't generate compile unit scopes, e.g. GCCE with + * dlls, this fixes up the low and high addresses of the compile unit based + * on the function scopes + */ + protected void fixupRanges() { + + // fix up scope addresses in case compiler doesn't generate them. + if (hasEmptyRange() && parsedForVarsAndAddresses) { + fixupRanges(provider.getBaseLinkAddress()); + } + + rangesDirty = false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getChildren() + */ + @Override + public Collection getChildren() { + return super.getChildren(); + } + + public void setAttributes(AttributeList attributes) { + this.attributes = attributes; + } + + public boolean isParsedForAddresses() { + return parsedForVarsAndAddresses; + } + + public boolean isParsedForVariables() { + return parsedForVarsAndAddresses; + } + + public boolean isParsedForTypes() { + return parsedForTypes; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getVariables() + */ + @Override + public Collection getVariables() { + ensureParsedForVariables(); + return super.getVariables(); + } + + public void setParsedForAddresses(boolean parsedForAddresses) { + this.parsedForVarsAndAddresses = parsedForAddresses; + } + + public void setParsedForVariables(boolean parsedForVariables) { + this.parsedForVarsAndAddresses = parsedForVariables; + } + + public void setParsedForTypes(boolean parsedForTypes) { + this.parsedForTypes = parsedForTypes; + } + + private void ensureParsedForAddresses() { + if (!parsedForVarsAndAddresses) { + DwarfInfoReader reader = new DwarfInfoReader(provider); + reader.parseCompilationUnitForAddresses(this); + } + } + + /** + * Get the file path for a file number + * @param declFileNum + * @return IPath for the file, or null + */ + public IPath getFileEntry(int declFileNum) { + if (fileList == null) + parseLineTable(); + if (declFileNum <= 0 || declFileNum > fileList.size()) + return null; + return fileList.get(declFileNum - 1); + } + + private void ensureParsedForVariables() { + if (!parsedForVarsAndAddresses) { + DwarfInfoReader reader = new DwarfInfoReader(provider); + reader.parseCompilationUnitForAddresses(this); + } + } + + @Override + public IScope getScopeAtAddress(IAddress linkAddress) { + ensureParsedForAddresses(); + return super.getScopeAtAddress(linkAddress); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("DwarfCompileUnit ["); + + builder.append("SymFile="); + builder.append(provider.getSymbolFile().lastSegment()); + + builder.append(", SectionOffset=0x"); + builder.append(Integer.toHexString(header.debugInfoOffset)); + + builder.append(", lowAddr="); + builder.append(lowAddress != null ? lowAddress.toHexAddressString() : null); + + builder.append(", highAddr="); + builder.append(highAddress != null ? highAddress.toHexAddressString() : null); + if (filePath != null) { + builder.append(", path="); + builder.append(filePath.toOSString()); + } + builder.append(", parsedForVarsAndAddresses="); + builder.append(parsedForVarsAndAddresses); + builder.append(", parsedForTypes="); + builder.append(parsedForTypes); + builder.append("]\n"); + return builder.toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#addChild(org.eclipse.cdt.debug.edc.internal.symbols.IScope) + */ + @Override + public void addChild(IScope scope) { + super.addChild(scope); + + // if we don't know our scope yet... + if (hasEmptyRange()) { + rangesDirty = true; + } else { + // the CU may have an incomplete idea of its scope; fit the new scope in + mergeScopeRange(scope); + } + + addLineInfoToParent(scope); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfConstants.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfConstants.java new file mode 100644 index 0000000..11512e1 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfConstants.java @@ -0,0 +1,636 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +/** + * DWARF constant. + */ +public class DwarfConstants { + + /* Tags. */ + + public final static int DW_TAG_array_type = 0x01; + public final static int DW_TAG_class_type = 0x02; + public final static int DW_TAG_entry_point = 0x03; + public final static int DW_TAG_enumeration_type = 0x04; + public final static int DW_TAG_formal_parameter = 0x05; + public final static int DW_TAG_imported_declaration = 0x08; + public final static int DW_TAG_label = 0x0a; + public final static int DW_TAG_lexical_block = 0x0b; + public final static int DW_TAG_member = 0x0d; + public final static int DW_TAG_pointer_type = 0x0f; + public final static int DW_TAG_reference_type = 0x10; + public final static int DW_TAG_compile_unit = 0x11; + public final static int DW_TAG_string_type = 0x12; + public final static int DW_TAG_structure_type = 0x13; + public final static int DW_TAG_subroutine_type = 0x15; + public final static int DW_TAG_typedef = 0x16; + public final static int DW_TAG_union_type = 0x17; + public final static int DW_TAG_unspecified_parameters = 0x18; + public final static int DW_TAG_variant = 0x19; + public final static int DW_TAG_common_block = 0x1a; + public final static int DW_TAG_common_inclusion = 0x1b; + public final static int DW_TAG_inheritance = 0x1c; + public final static int DW_TAG_inlined_subroutine = 0x1d; + public final static int DW_TAG_module = 0x1e; + public final static int DW_TAG_ptr_to_member_type = 0x1f; + public final static int DW_TAG_set_type = 0x20; + public final static int DW_TAG_subrange_type = 0x21; + public final static int DW_TAG_with_stmt = 0x22; + public final static int DW_TAG_access_declaration = 0x23; + public final static int DW_TAG_base_type = 0x24; + public final static int DW_TAG_catch_block = 0x25; + public final static int DW_TAG_const_type = 0x26; + public final static int DW_TAG_constant = 0x27; + public final static int DW_TAG_enumerator = 0x28; + public final static int DW_TAG_file_type = 0x29; + public final static int DW_TAG_friend = 0x2a; + public final static int DW_TAG_namelist = 0x2b; + public final static int DW_TAG_namelist_item = 0x2c; + public final static int DW_TAG_packed_type = 0x2d; + public final static int DW_TAG_subprogram = 0x2e; + public final static int DW_TAG_template_type_param = 0x2f; // called DW_TAG_template_type_parameter in DWARF 3 + public final static int DW_TAG_template_value_param = 0x30; // called DW_TAG_template_value_parameter in DWARF 3 + public final static int DW_TAG_thrown_type = 0x31; + public final static int DW_TAG_try_block = 0x32; + public final static int DW_TAG_variant_part = 0x33; + public final static int DW_TAG_variable = 0x34; + public final static int DW_TAG_volatile_type = 0x35; + public final static int DW_TAG_dwarf_procedure = 0x36; // DWARF 3 + public final static int DW_TAG_restrict_type = 0x37; // DWARF 3 + public final static int DW_TAG_interface_type = 0x38; // DWARF 3 + public final static int DW_TAG_namespace = 0x39; // DWARF 3 + public final static int DW_TAG_imported_module = 0x3a; // DWARF 3 + public final static int DW_TAG_unspecified_type = 0x3b; // DWARF 3 + public final static int DW_TAG_partial_unit = 0x3c; // DWARF 3 + public final static int DW_TAG_imported_unit = 0x3d; // DWARF 3 + public final static int DW_TAG_condition = 0x3f; // DWARF 3 + public final static int DW_TAG_shared_type = 0x40; // DWARF 3 + public final static int DW_TAG_lo_user = 0x4080; + public final static int DW_TAG_MIPS_loop = 0x4081; + public final static int DW_TAG_format_label = 0x4101; + public final static int DW_TAG_function_template = 0x4102; + public final static int DW_TAG_class_template = 0x4103; + public final static int DW_TAG_hi_user = 0xffff; + + /* Children determination encodings. */ + public final static int DW_CHILDREN_no = 0; + public final static int DW_CHILDREN_yes = 1; + + /* DWARF attributes encodings. */ + public final static short DW_AT_sibling = 0x01; + public final static short DW_AT_location = 0x02; + public final static short DW_AT_name = 0x03; + public final static short DW_AT_ordering = 0x09; + public final static short DW_AT_subscr_data = 0x0a; + public final static short DW_AT_byte_size = 0x0b; + public final static short DW_AT_bit_offset = 0x0c; + public final static short DW_AT_bit_size = 0x0d; + public final static short DW_AT_element_list = 0x0f; + public final static short DW_AT_stmt_list = 0x10; + public final static short DW_AT_low_pc = 0x11; + public final static short DW_AT_high_pc = 0x12; + public final static short DW_AT_language = 0x13; + public final static short DW_AT_member = 0x14; + public final static short DW_AT_discr = 0x15; + public final static short DW_AT_discr_value = 0x16; + public final static short DW_AT_visibility = 0x17; + public final static short DW_AT_import = 0x18; + public final static short DW_AT_string_length = 0x19; + public final static short DW_AT_common_reference = 0x1a; + public final static short DW_AT_comp_dir = 0x1b; + public final static short DW_AT_const_value = 0x1c; + public final static short DW_AT_containing_type = 0x1d; + public final static short DW_AT_default_value = 0x1e; + public final static short DW_AT_inline = 0x20; + public final static short DW_AT_is_optional = 0x21; + public final static short DW_AT_lower_bound = 0x22; + public final static short DW_AT_producer = 0x25; + public final static short DW_AT_prototyped = 0x27; + public final static short DW_AT_return_addr = 0x2a; + public final static short DW_AT_start_scope = 0x2c; + public final static short DW_AT_stride_size = 0x2e; + public final static short DW_AT_upper_bound = 0x2f; + public final static short DW_AT_abstract_origin = 0x31; + public final static short DW_AT_accessibility = 0x32; + public final static short DW_AT_address_class = 0x33; + public final static short DW_AT_artificial = 0x34; + public final static short DW_AT_base_types = 0x35; + public final static short DW_AT_calling_convention = 0x36; + public final static short DW_AT_count = 0x37; + public final static short DW_AT_data_member_location = 0x38; + public final static short DW_AT_decl_column = 0x39; + public final static short DW_AT_decl_file = 0x3a; + public final static short DW_AT_decl_line = 0x3b; + public final static short DW_AT_declaration = 0x3c; + public final static short DW_AT_discr_list = 0x3d; + public final static short DW_AT_encoding = 0x3e; + public final static short DW_AT_external = 0x3f; + public final static short DW_AT_frame_base = 0x40; + public final static short DW_AT_friend = 0x41; + public final static short DW_AT_identifier_case = 0x42; + public final static short DW_AT_macro_info = 0x43; + public final static short DW_AT_namelist_items = 0x44; + public final static short DW_AT_priority = 0x45; + public final static short DW_AT_segment = 0x46; + public final static short DW_AT_specification = 0x47; + public final static short DW_AT_static_link = 0x48; + public final static short DW_AT_type = 0x49; + public final static short DW_AT_use_location = 0x4a; + public final static short DW_AT_variable_parameter = 0x4b; + public final static short DW_AT_virtuality = 0x4c; + public final static short DW_AT_vtable_elem_location = 0x4d; + public final static short DW_AT_allocated = 0x4e; // DWARF 3 + public final static short DW_AT_associated = 0x4f; // DWARF 3 + public final static short DW_AT_data_location = 0x50; // DWARF 3 + public final static short DW_AT_byte_stride = 0x51; // DWARF 3 + public final static short DW_AT_entry_pc = 0x52; // DWARF 3 + public final static short DW_AT_use_UTF8 = 0x53; // DWARF 3 + public final static short DW_AT_extension = 0x54; // DWARF 3 + public final static short DW_AT_ranges = 0x55; // DWARF 3 + public final static short DW_AT_trampoline = 0x56; // DWARF 3 + public final static short DW_AT_call_column = 0x57; // DWARF 3 + public final static short DW_AT_call_file = 0x58; // DWARF 3 + public final static short DW_AT_call_line = 0x59; // DWARF 3 + public final static short DW_AT_description = 0x5a; // DWARF 3 + public final static short DW_AT_binary_scale = 0x5b; // DWARF 3 + public final static short DW_AT_decimal_scale = 0x5c; // DWARF 3 + public final static short DW_AT_small = 0x5d; // DWARF 3 + public final static short DW_AT_decimal_sign = 0x5e; // DWARF 3 + public final static short DW_AT_digit_count = 0x5f; // DWARF 3 + public final static short DW_AT_picture_string = 0x60; // DWARF 3 + public final static short DW_AT_mutable = 0x61; // DWARF 3 + public final static short DW_AT_threads_scaled = 0x62; // DWARF 3 + public final static short DW_AT_explicit = 0x63; // DWARF 3 + public final static short DW_AT_object_pointer = 0x64; // DWARF 3 + public final static short DW_AT_endianity = 0x65; // DWARF 3 + public final static short DW_AT_elemental = 0x66; // DWARF 3 + public final static short DW_AT_pure = 0x67; // DWARF 3 + public final static short DW_AT_recursive = 0x68; // DWARF 3 + public final static short DW_AT_lo_user = 0x2000; + public final static short DW_AT_MIPS_fde = 0x2001; + public final static short DW_AT_MIPS_loop_begin = 0x2002; + public final static short DW_AT_MIPS_tail_loop_begin = 0x2003; + public final static short DW_AT_MIPS_epilog_begin = 0x2004; + public final static short DW_AT_MIPS_loop_unroll_factor = 0x2005; + public final static short DW_AT_MIPS_software_pipeline_depth = 0x2006; + public final static short DW_AT_MIPS_linkage_name = 0x2007; + public final static short DW_AT_MIPS_stride = 0x2008; + public final static short DW_AT_MIPS_abstract_name = 0x2009; + public final static short DW_AT_MIPS_clone_origin = 0x200a; + public final static short DW_AT_MIPS_has_inlines = 0x200b; + public final static short DW_AT_MIPS_stride_byte = 0x200c; + public final static short DW_AT_MIPS_stride_elem = 0x200d; + public final static short DW_AT_MIPS_ptr_dopetype = 0x200e; + public final static short DW_AT_MIPS_allocatable_dopetype = 0x200f; + public final static short DW_AT_MIPS_assumed_shape_dopetype = 0x2010; + public final static short DW_AT_MIPS_assumed_size = 0x2011; + public final static short DW_AT_sf_names = 0x2101; + public final static short DW_AT_src_info = 0x2102; + public final static short DW_AT_mac_info = 0x2103; + public final static short DW_AT_src_coords = 0x2104; + public final static short DW_AT_body_begin = 0x2105; + public final static short DW_AT_body_end = 0x2106; + public final static short DW_AT_hi_user = 0x3fff; + + /* DWARF form encodings. */ + public final static int DW_FORM_addr = 0x01; + public final static int DW_FORM_block2 = 0x03; + public final static int DW_FORM_block4 = 0x04; + public final static int DW_FORM_data2 = 0x05; + public final static int DW_FORM_data4 = 0x06; + public final static int DW_FORM_data8 = 0x07; + public final static int DW_FORM_string = 0x08; + public final static int DW_FORM_block = 0x09; + public final static int DW_FORM_block1 = 0x0a; + public final static int DW_FORM_data1 = 0x0b; + public final static int DW_FORM_flag = 0x0c; + public final static int DW_FORM_sdata = 0x0d; + public final static int DW_FORM_strp = 0x0e; + public final static int DW_FORM_udata = 0x0f; + public final static int DW_FORM_ref_addr = 0x10; + public final static int DW_FORM_ref1 = 0x11; + public final static int DW_FORM_ref2 = 0x12; + public final static int DW_FORM_ref4 = 0x13; + public final static int DW_FORM_ref8 = 0x14; + public final static int DW_FORM_ref_udata = 0x15; + public final static int DW_FORM_indirect = 0x16; + + /* Since DWARF4 */ + public final static int DW_FORM_sec_offset = 0x17; + public final static int DW_FORM_exprloc = 0x18; + public final static int DW_FORM_flag_present = 0x19; + public final static int DW_FORM_ref_sig8 = 0x20; + /* Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ + public final static int DW_FORM_GNU_addr_index = 0x1f01; + public final static int DW_FORM_GNU_str_index = 0x1f02; + /* Extensions for DWZ multifile. + See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open . */ + public final static int DW_FORM_GNU_ref_alt = 0x1f20; + public final static int DW_FORM_GNU_strp_alt = 0x1f21; + + + /* DWARF location operation encodings. */ + public final static int DW_OP_addr = 0x03; /* Constant address. */ + public final static int DW_OP_deref = 0x06; + public final static int DW_OP_const1u = 0x08; /* Unsigned 1-byte constant. */ + public final static int DW_OP_const1s = 0x09; /* Signed 1-byte constant. */ + public final static int DW_OP_const2u = 0x0a; /* Unsigned 2-byte constant. */ + public final static int DW_OP_const2s = 0x0b; /* Signed 2-byte constant. */ + public final static int DW_OP_const4u = 0x0c; /* Unsigned 4-byte constant. */ + public final static int DW_OP_const4s = 0x0d; /* Signed 4-byte constant. */ + public final static int DW_OP_const8u = 0x0e; /* Unsigned 8-byte constant. */ + public final static int DW_OP_const8s = 0x0f; /* Signed 8-byte constant. */ + public final static int DW_OP_constu = 0x10; /* Unsigned LEB128 constant. */ + public final static int DW_OP_consts = 0x11; /* Signed LEB128 constant. */ + public final static int DW_OP_dup = 0x12; + public final static int DW_OP_drop = 0x13; + public final static int DW_OP_over = 0x14; + public final static int DW_OP_pick = 0x15; /* 1-byte stack index. */ + public final static int DW_OP_swap = 0x16; + public final static int DW_OP_rot = 0x17; + public final static int DW_OP_xderef = 0x18; + public final static int DW_OP_abs = 0x19; + public final static int DW_OP_and = 0x1a; + public final static int DW_OP_div = 0x1b; + public final static int DW_OP_minus = 0x1c; + public final static int DW_OP_mod = 0x1d; + public final static int DW_OP_mul = 0x1e; + public final static int DW_OP_neg = 0x1f; + public final static int DW_OP_not = 0x20; + public final static int DW_OP_or = 0x21; + public final static int DW_OP_plus = 0x22; + public final static int DW_OP_plus_uconst = 0x23; /* Unsigned LEB128 addend. */ + public final static int DW_OP_shl = 0x24; + public final static int DW_OP_shr = 0x25; + public final static int DW_OP_shra = 0x26; + public final static int DW_OP_xor = 0x27; + public final static int DW_OP_bra = 0x28; /* Signed 2-byte constant. */ + public final static int DW_OP_eq = 0x29; + public final static int DW_OP_ge = 0x2a; + public final static int DW_OP_gt = 0x2b; + public final static int DW_OP_le = 0x2c; + public final static int DW_OP_lt = 0x2d; + public final static int DW_OP_ne = 0x2e; + public final static int DW_OP_skip = 0x2f; /* Signed 2-byte constant. */ + public final static int DW_OP_lit0 = 0x30; /* Literal 0. */ + public final static int DW_OP_lit1 = 0x31; /* Literal 1. */ + public final static int DW_OP_lit2 = 0x32; /* Literal 2. */ + public final static int DW_OP_lit3 = 0x33; /* Literal 3. */ + public final static int DW_OP_lit4 = 0x34; /* Literal 4. */ + public final static int DW_OP_lit5 = 0x35; /* Literal 5. */ + public final static int DW_OP_lit6 = 0x36; /* Literal 6. */ + public final static int DW_OP_lit7 = 0x37; /* Literal 7. */ + public final static int DW_OP_lit8 = 0x38; /* Literal 8. */ + public final static int DW_OP_lit9 = 0x39; /* Literal 9. */ + public final static int DW_OP_lit10 = 0x3a; /* Literal 10. */ + public final static int DW_OP_lit11 = 0x3b; /* Literal 11. */ + public final static int DW_OP_lit12 = 0x3c; /* Literal 12. */ + public final static int DW_OP_lit13 = 0x3d; /* Literal 13. */ + public final static int DW_OP_lit14 = 0x3e; /* Literal 14. */ + public final static int DW_OP_lit15 = 0x3f; /* Literal 15. */ + public final static int DW_OP_lit16 = 0x40; /* Literal 16. */ + public final static int DW_OP_lit17 = 0x41; /* Literal 17. */ + public final static int DW_OP_lit18 = 0x42; /* Literal 18. */ + public final static int DW_OP_lit19 = 0x43; /* Literal 19. */ + public final static int DW_OP_lit20 = 0x44; /* Literal 20. */ + public final static int DW_OP_lit21 = 0x45; /* Literal 21. */ + public final static int DW_OP_lit22 = 0x46; /* Literal 22. */ + public final static int DW_OP_lit23 = 0x47; /* Literal 23. */ + public final static int DW_OP_lit24 = 0x48; /* Literal 24. */ + public final static int DW_OP_lit25 = 0x49; /* Literal 25. */ + public final static int DW_OP_lit26 = 0x4a; /* Literal 26. */ + public final static int DW_OP_lit27 = 0x4b; /* Literal 27. */ + public final static int DW_OP_lit28 = 0x4c; /* Literal 28. */ + public final static int DW_OP_lit29 = 0x4d; /* Literal 29. */ + public final static int DW_OP_lit30 = 0x4e; /* Literal 30. */ + public final static int DW_OP_lit31 = 0x4f; /* Literal 31. */ + public final static int DW_OP_reg0 = 0x50; /* Register 0. */ + public final static int DW_OP_reg1 = 0x51; /* Register 1. */ + public final static int DW_OP_reg2 = 0x52; /* Register 2. */ + public final static int DW_OP_reg3 = 0x53; /* Register 3. */ + public final static int DW_OP_reg4 = 0x54; /* Register 4. */ + public final static int DW_OP_reg5 = 0x55; /* Register 5. */ + public final static int DW_OP_reg6 = 0x56; /* Register 6. */ + public final static int DW_OP_reg7 = 0x57; /* Register 7. */ + public final static int DW_OP_reg8 = 0x58; /* Register 8. */ + public final static int DW_OP_reg9 = 0x59; /* Register 9. */ + public final static int DW_OP_reg10 = 0x5a; /* Register 10. */ + public final static int DW_OP_reg11 = 0x5b; /* Register 11. */ + public final static int DW_OP_reg12 = 0x5c; /* Register 12. */ + public final static int DW_OP_reg13 = 0x5d; /* Register 13. */ + public final static int DW_OP_reg14 = 0x5e; /* Register 14. */ + public final static int DW_OP_reg15 = 0x5f; /* Register 15. */ + public final static int DW_OP_reg16 = 0x60; /* Register 16. */ + public final static int DW_OP_reg17 = 0x61; /* Register 17. */ + public final static int DW_OP_reg18 = 0x62; /* Register 18. */ + public final static int DW_OP_reg19 = 0x63; /* Register 19. */ + public final static int DW_OP_reg20 = 0x64; /* Register 20. */ + public final static int DW_OP_reg21 = 0x65; /* Register 21. */ + public final static int DW_OP_reg22 = 0x66; /* Register 22. */ + public final static int DW_OP_reg23 = 0x67; /* Register 24. */ + public final static int DW_OP_reg24 = 0x68; /* Register 24. */ + public final static int DW_OP_reg25 = 0x69; /* Register 25. */ + public final static int DW_OP_reg26 = 0x6a; /* Register 26. */ + public final static int DW_OP_reg27 = 0x6b; /* Register 27. */ + public final static int DW_OP_reg28 = 0x6c; /* Register 28. */ + public final static int DW_OP_reg29 = 0x6d; /* Register 29. */ + public final static int DW_OP_reg30 = 0x6e; /* Register 30. */ + public final static int DW_OP_reg31 = 0x6f; /* Register 31. */ + public final static int DW_OP_breg0 = 0x70; /* Base register 0. */ + public final static int DW_OP_breg1 = 0x71; /* Base register 1. */ + public final static int DW_OP_breg2 = 0x72; /* Base register 2. */ + public final static int DW_OP_breg3 = 0x73; /* Base register 3. */ + public final static int DW_OP_breg4 = 0x74; /* Base register 4. */ + public final static int DW_OP_breg5 = 0x75; /* Base register 5. */ + public final static int DW_OP_breg6 = 0x76; /* Base register 6. */ + public final static int DW_OP_breg7 = 0x77; /* Base register 7. */ + public final static int DW_OP_breg8 = 0x78; /* Base register 8. */ + public final static int DW_OP_breg9 = 0x79; /* Base register 9. */ + public final static int DW_OP_breg10 = 0x7a; /* Base register 10. */ + public final static int DW_OP_breg11 = 0x7b; /* Base register 11. */ + public final static int DW_OP_breg12 = 0x7c; /* Base register 12. */ + public final static int DW_OP_breg13 = 0x7d; /* Base register 13. */ + public final static int DW_OP_breg14 = 0x7e; /* Base register 14. */ + public final static int DW_OP_breg15 = 0x7f; /* Base register 15. */ + public final static int DW_OP_breg16 = 0x80; /* Base register 16. */ + public final static int DW_OP_breg17 = 0x81; /* Base register 17. */ + public final static int DW_OP_breg18 = 0x82; /* Base register 18. */ + public final static int DW_OP_breg19 = 0x83; /* Base register 19. */ + public final static int DW_OP_breg20 = 0x84; /* Base register 20. */ + public final static int DW_OP_breg21 = 0x85; /* Base register 21. */ + public final static int DW_OP_breg22 = 0x86; /* Base register 22. */ + public final static int DW_OP_breg23 = 0x87; /* Base register 23. */ + public final static int DW_OP_breg24 = 0x88; /* Base register 24. */ + public final static int DW_OP_breg25 = 0x89; /* Base register 25. */ + public final static int DW_OP_breg26 = 0x8a; /* Base register 26. */ + public final static int DW_OP_breg27 = 0x8b; /* Base register 27. */ + public final static int DW_OP_breg28 = 0x8c; /* Base register 28. */ + public final static int DW_OP_breg29 = 0x8d; /* Base register 29. */ + public final static int DW_OP_breg30 = 0x8e; /* Base register 30. */ + public final static int DW_OP_breg31 = 0x8f; /* Base register 31. */ + public final static int DW_OP_regx = 0x90; /* Unsigned LEB128 register. */ + public final static int DW_OP_fbreg = 0x91; /* Signed LEB128 register. */ + public final static int DW_OP_bregx = 0x92; /* + * ULEB128 register followed by + * SLEB128 off. + */ + public final static int DW_OP_piece = 0x93; /* + * ULEB128 size of piece + * addressed. + */ + public final static int DW_OP_deref_size = 0x94; /* + * 1-byte size of data + * retrieved. + */ + public final static int DW_OP_xderef_size = 0x95; /* + * 1-byte size of data + * retrieved. + */ + public final static int DW_OP_nop = 0x96; + public final static int DW_OP_push_object_address = 0x97; // DWARF 3 + public final static int DW_OP_call2 = 0x98; // 2-byte offset of DIE // DWARF + // 3 + public final static int DW_OP_call4 = 0x99; // 4-byte offset of DIE // DWARF + // 3 + public final static int DW_OP_call_ref = 0x9a; // 4- or 8-byte offset of DIE + // // DWARF 3 + public final static int DW_OP_form_tls_address = 0x9b; // DWARF 3 + public final static int DW_OP_call_frame_cfa = 0x9c; // DWARF 3 + public final static int DW_OP_bit_piece = 0x9d; // DWARF 3 + + public final static int DW_OP_lo_user = 0xe0; /* + * Implementation-defined range + * start. + */ + public final static int DW_OP_hi_user = 0xff; /* + * Implementation-defined range + * end. + */ + + /* DWARF base type encodings. */ + public final static int DW_ATE_void = 0x0; + public final static int DW_ATE_address = 0x1; + public final static int DW_ATE_boolean = 0x2; + public final static int DW_ATE_complex_float = 0x3; + public final static int DW_ATE_float = 0x4; + public final static int DW_ATE_signed = 0x5; + public final static int DW_ATE_signed_char = 0x6; + public final static int DW_ATE_unsigned = 0x7; + public final static int DW_ATE_unsigned_char = 0x8; + public final static int DW_ATE_imaginary_float = 0x09; // DWARF 3 + public final static int DW_ATE_packed_decimal = 0x0a; // DWARF 3 + public final static int DW_ATE_numeric_string = 0x0b; // DWARF 3 + public final static int DW_ATE_edited = 0x0c; // DWARF 3 + public final static int DW_ATE_signed_fixed = 0x0d; // DWARF 3 + public final static int DW_ATE_unsigned_fixed = 0x0e; // DWARF 3 + public final static int DW_ATE_decimal_float = 0x0f; // DWARF 3 + + public final static int DW_ATE_lo_user = 0x80; + public final static int DW_ATE_hi_user = 0xff; + + /* DWARF decimal sign encodings. */ + public final static int DW_DS_unsigned = 0x01; // DWARF 3 + public final static int DW_DS_leading_overpunch = 0x02; // DWARF 3 + public final static int DW_DS_trailing_overpunch = 0x03;// DWARF 3 + public final static int DW_DS_leading_separate = 0x04; // DWARF 3 + public final static int DW_DS_trailing_separate = 0x05; // DWARF 3 + + /* DWARF endianity encodings. */ + public final static int DW_END_default = 0x00; // DWARF 3 + public final static int DW_END_big = 0x01; // DWARF 3 + public final static int DW_END_little = 0x02; // DWARF 3 + public final static int DW_END_lo_user = 0x40; // DWARF 3 + public final static int DW_END_hi_user = 0xff; // DWARF 3 + + /* DWARF accessibility encodings. */ + public final static int DW_ACCESS_public = 1; + public final static int DW_ACCESS_protected = 2; + public final static int DW_ACCESS_private = 3; + + /* DWARF visibility encodings. */ + public final static int DW_VIS_local = 1; + public final static int DW_VIS_exported = 2; + public final static int DW_VIS_qualified = 3; + + /* DWARF virtuality encodings. */ + public final static int DW_VIRTUALITY_none = 0; + public final static int DW_VIRTUALITY_virtual = 1; + public final static int DW_VIRTUALITY_pure_virtual = 2; + + /* DWARF language encodings. */ + public final static int DW_LANG_C89 = 0x0001; + public final static int DW_LANG_C = 0x0002; + public final static int DW_LANG_Ada83 = 0x0003; + public final static int DW_LANG_C_plus_plus = 0x0004; + public final static int DW_LANG_Cobol74 = 0x0005; + public final static int DW_LANG_Cobol85 = 0x0006; + public final static int DW_LANG_Fortran77 = 0x0007; + public final static int DW_LANG_Fortran90 = 0x0008; + public final static int DW_LANG_Pascal83 = 0x0009; + public final static int DW_LANG_Modula2 = 0x000a; + public final static int DW_LANG_Java = 0x000b; // DWARF 3 + public final static int DW_LANG_C99 = 0x000c; // DWARF 3 + public final static int DW_LANG_Ada95 = 0x000d; // DWARF 3 + public final static int DW_LANG_Fortran95 = 0x000e; // DWARF 3 + public final static int DW_LANG_PLI = 0x000f; // DWARF 3 + public final static int DW_LANG_PL1 = 0x000f; // misspelling found in + // org.eclipse.cdt.utils.debug.dwarf.DwarfConstants + public final static int DW_LANG_ObjC = 0x0010; // DWARF 3 + public final static int DW_LANG_ObjC_plus_plus = 0x0011;// DWARF 3 + public final static int DW_LANG_UPC = 0x0012; // DWARF 3 + public final static int DW_LANG_D = 0x0013; // DWARF 3 + public final static int DW_LANG_lo_user = 0x8000; + public final static int DW_LANG_Mips_Assembler = 0x8001; + public final static int DW_LANG_hi_user = 0xffff; + + /* DWARF identifier case encodings. */ + public final static int DW_ID_case_sensitive = 0; + public final static int DW_ID_up_case = 1; + public final static int DW_ID_down_case = 2; + public final static int DW_ID_case_insensitive = 3; + + /* DWARF calling conventions encodings. */ + public final static int DW_CC_normal = 0x1; + public final static int DW_CC_program = 0x2; + public final static int DW_CC_nocall = 0x3; + public final static int DW_CC_lo_user = 0x40; + public final static int DW_CC_hi_user = 0xff; + + /* DWARF inline encodings. */ + public final static int DW_INL_not_inlined = 0; + public final static int DW_INL_inlined = 1; + public final static int DW_INL_declared_not_inlined = 2; + public final static int DW_INL_declared_inlined = 3; + + /* DWARF ordering encodings. */ + public final static int DW_ORD_row_major = 0; + public final static int DW_ORD_col_major = 1; + + /* DWARF discriminant descriptor encodings. */ + public final static int DW_DSC_label = 0; + public final static int DW_DSC_range = 1; + + /* DWARF standard opcode encodings. */ + public final static int DW_LNS_copy = 1; + public final static int DW_LNS_advance_pc = 2; + public final static int DW_LNS_advance_line = 3; + public final static int DW_LNS_set_file = 4; + public final static int DW_LNS_set_column = 5; + public final static int DW_LNS_negate_stmt = 6; + public final static int DW_LNS_set_basic_block = 7; + public final static int DW_LNS_const_add_pc = 8; + public final static int DW_LNS_fixed_advance_pc = 9; + public final static int DW_LNS_set_prologue_end = 10; // DWARF 3 + public final static int DW_LNS_set_epilog_begin = 11; // misspelling found + // in + // org.eclipse.cdt.utils.debug.dwarf.DwarfConstants + public final static int DW_LNS_set_epilogue_begin = 11; // DWARF 3 + public final static int DW_LNS_set_isa = 12; // DWARF 3 + + public final static int LINE_IsStmt = 0x01; + public final static int LINE_BasicBlock = 0x02; + public final static int LINE_PrologueEnd = 0x04; + public final static int LINE_EpilogueBegin = 0x08; + public final static int LINE_EndSequence = 0x10; + + /* DWARF extended opcide encodings. */ + public final static int DW_LNE_end_sequence = 1; + public final static int DW_LNE_set_address = 2; + public final static int DW_LNE_define_file = 3; + public final static int DW_LNE_lo_user = 0x80; // DWARF 3 + public final static int DW_LNE_hi_user = 0xff; // DWARF 3 + + /* DWARF macinfo type encodings. */ + public final static int DW_MACINFO_define = 1; + public final static int DW_MACINFO_undef = 2; + public final static int DW_MACINFO_start_file = 3; + public final static int DW_MACINFO_end_file = 4; + public final static int DW_MACINFO_vendor_ext = 255; + + /* DWARF macro type encodings. */ + /* since DWARF4 */ + public final static int DW_MACRO_end = 0; + public final static int DW_MACRO_define = 1; + public final static int DW_MACRO_undef = 2; + public final static int DW_MACRO_start_file = 3; + public final static int DW_MACRO_end_file = 4; + public final static int DW_MACRO_define_indirect = 5; + public final static int DW_MACRO_undef_indirect = 6; + public final static int DW_MACRO_transparent_include = 7; + public final static int DW_MACRO_define_indirect_alt = 0x08; + public final static int DW_MACRO_undef_indirect_alt = 0x09; + public final static int DW_MACRO_transparent_include_alt = 0x0a; + public final static int DW_MACRO_lo_user = 0xe0; + public final static int DW_MACRO_hi_user = 0xff; + + /* DWARF call frame instruction encodings. */ + public final static int DW_CFA_advance_loc = 0x40; // low 6 bits delta + public final static int DW_CFA_offset = 0x80; // low 6 bits register, + // operand ULEB128 offset + public final static int DW_CFA_restore = 0xc0; // low 6 bits register + public final static int DW_CFA_extended = 0; // same as DW_CFA_nop + + public final static int DW_CFA_nop = 0x00; // same as DW_CFA_extended + public final static int DW_CFA_set_loc = 0x01; // operand: address + public final static int DW_CFA_advance_loc1 = 0x02; // operand: 1-byte delta + public final static int DW_CFA_advance_loc2 = 0x03; // operand: 2-byte delta + public final static int DW_CFA_advance_loc4 = 0x04; // operand: 4-byte delta + public final static int DW_CFA_offset_extended = 0x05; // operands: ULEB128 + // register, ULEB128 + // offset + public final static int DW_CFA_restore_extended = 0x06; // operand: ULEB128 + // register + public final static int DW_CFA_undefined = 0x07; // operand: ULEB128 + // register + public final static int DW_CFA_same_value = 0x08; // operand: ULEB128 + // register + public final static int DW_CFA_register = 0x09; // operands: ULEB128 + // register, ULEB128 + // register + public final static int DW_CFA_remember_state = 0x0a; + public final static int DW_CFA_restore_state = 0x0b; + public final static int DW_CFA_def_cfa = 0x0c; // operands: ULEB128 + // register, ULEB128 offset + public final static int DW_CFA_def_cfa_register = 0x0d; // operand: ULEB128 + // register + public final static int DW_CFA_def_cfa_offset = 0x0e; // operand: ULEB128 + // offset + public final static int DW_CFA_def_cfa_expression = 0x0f; // operand: BLOCK + // // DWARF 3 + public final static int DW_CFA_expression = 0x10; // operands: ULEB128 + // register, BLOCK // + // DWARF 3 + public final static int DW_CFA_offset_extended_sf = 0x11; // operands: + // ULEB128 + // register, + // SLEB128 + // offset // + // DWARF 3 + public final static int DW_CFA_def_cfa_sf = 0x12; // operands: ULEB128 + // register, SLEB128 + // offset // DWARF 3 + public final static int DW_CFA_def_cfa_offset_sf = 0x13;// operand: SLEB128 + // offset // DWARF 3 + public final static int DW_CFA_val_offset = 0x14; // operands: ULEB128, + // ULEB128// DWARF 3 + public final static int DW_CFA_val_offset_sf = 0x15; // operands: ULEB128, + // SLEB128// DWARF 3 + public final static int DW_CFA_val_expression = 0x16; // operands: ULEB128, + // BLOCK// DWARF 3 + public final static int DW_CFA_low_user = 0x1c; + public final static int DW_CFA_MIPS_advance_loc8 = 0x1d; + public final static int DW_CFA_GNU_window_save = 0x2d; + public final static int DW_CFA_GNU_args_size = 0x2e; + public final static int DW_CFA_high_user = 0x3f; + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfDebugInfoProvider.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfDebugInfoProvider.java new file mode 100644 index 0000000..7fb9bfa --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfDebugInfoProvider.java @@ -0,0 +1,1459 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.symbols.IForwardTypeReference; +import org.eclipse.cdt.debug.edc.internal.symbols.Scope; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.CommonInformationEntry; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.FrameDescriptionEntry; +import org.eclipse.cdt.debug.edc.services.IFrameRegisterProvider; +import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope; +import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProvider; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.IModuleScope; +import org.eclipse.cdt.debug.edc.symbols.IRangeList; +import org.eclipse.cdt.debug.edc.symbols.IRangeList.Entry; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * This class handles the low-level aspects of reading DWARF data. + * There exists one provider per symbol file. + */ +public class DwarfDebugInfoProvider implements IDebugInfoProvider { + + /** + * This represents a forward type reference, which is a type + * that resolves itself when referenced. + */ + static public class ForwardTypeReference implements IType, IForwardTypeReference { + + static public final IType NULL_TYPE_ENTRY = new IType() { + + public int getByteSize() { + return 0; + } + + public String getName() { + return DwarfMessages.DwarfDebugInfoProvider_UnhandledType; + } + + public Map getProperties() { + return Collections.emptyMap(); + } + + public IScope getScope() { + return null; + } + + public IType getType() { + return null; + } + + public void setType(IType type) { + throw new IllegalStateException(); + } + + public void dispose() { + } + }; + + private DwarfDebugInfoProvider provider; + private IType type = null; + + private final long offset; + + public ForwardTypeReference(DwarfDebugInfoProvider provider, long offset) { + this.provider = provider; + this.offset = offset; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.dwarf.IForwardTypeReference#getReferencedType() + */ + public IType getReferencedType() { + if (type == null) { + // to prevent recursion + IType newType = NULL_TYPE_ENTRY; + newType = provider.resolveTypeReference(this); + if (newType == null) { + // FIXME + newType = NULL_TYPE_ENTRY; + } + type = newType; + } + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IType#getByteSize() + */ + public int getByteSize() { + return getReferencedType().getByteSize(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IType#getName() + */ + public String getName() { + return getReferencedType().getName(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IType#getProperties() + */ + public Map getProperties() { + return getReferencedType().getProperties(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IType#getScope() + */ + public IScope getScope() { + return getReferencedType().getScope(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IType#getType() + */ + public IType getType() { + return getReferencedType().getType(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IType#setType(org.eclipse.cdt.debug.edc.internal.symbols.IType) + */ + public void setType(IType type_) { + getReferencedType().setType(type_); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IType#dispose() + */ + public void dispose() { + type = null; + provider = null; + } + } + + static public class CompilationUnitHeader { + long length; + short version; + int abbreviationOffset; + byte addressSize; + int debugInfoOffset; + byte offsetSize; + DwarfCompileUnit scope; + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Offset: " + debugInfoOffset).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + sb.append("Length: " + length).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + sb.append("Version: " + version).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + sb.append("Abbreviation: " + abbreviationOffset).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + sb.append("Address size: " + addressSize).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + sb.append("Offset size: " + offsetSize).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + return sb.toString(); + } + } + + static class AbbreviationEntry { + short tag; + ArrayList attributes; + boolean hasChildren; + + AbbreviationEntry(long code, short tag, boolean hasChildren) { + // abbreviation code not stored + this.tag = tag; + this.hasChildren = hasChildren; + attributes = new ArrayList(); + } + } + + static class Attribute { + short tag; + byte form; + + Attribute(short tag, byte form) { + this.tag = tag; + this.form = form; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("tag: " + Long.toHexString(tag)); //$NON-NLS-1$ + sb.append(" form: " + Long.toHexString(form)); //$NON-NLS-1$ + return sb.toString(); + } + } + + static class AttributeValue { + private Object value; + + // for indirect form, this is the actual form + private byte actualForm; + + AttributeValue(byte form, IStreamBuffer in, byte addressSize, IStreamBuffer debugStrings) { + actualForm = form; + + try { + value = readAttribute(in, addressSize, debugStrings); + } catch (IOException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + if (value != null) { + Class clazz = value.getClass(); + if (clazz.isArray()) { + int len = Array.getLength(value); + sb.append(len).append(' '); + sb.append(clazz.getComponentType().toString()); + sb.append(':'); + for (int i = 0; i < len; i++) { + byte b = Array.getByte(value, i); + sb.append(' ').append(Integer.toHexString(b)); + } + } else { + if (value instanceof Number) { + Number n = (Number) value; + sb.append(Long.toHexString(n.longValue())); + } else if (value instanceof String) { + sb.append(value); + } else { + sb.append(value); + } + } + } + return sb.toString(); + } + //TODO: support DWARF 64-bit format + private Object readAttribute(IStreamBuffer in, byte addressSize, IStreamBuffer debugStrings) throws IOException { + Object obj = null; + switch (actualForm) { + case DwarfConstants.DW_FORM_addr: + obj = DwarfInfoReader.readAddress(in, addressSize); + case DwarfConstants.DW_FORM_ref_addr: + break; + + case DwarfConstants.DW_FORM_block: { + int size = (int) DwarfInfoReader.read_unsigned_leb128(in); + byte[] bytes = new byte[size]; + in.get(bytes); + obj = bytes; + } + break; + + case DwarfConstants.DW_FORM_block1: { + int size = in.get() & 0xff; + byte[] bytes = new byte[size]; + in.get(bytes); + obj = bytes; + } + break; + + case DwarfConstants.DW_FORM_block2: { + int size = in.getShort(); + byte[] bytes = new byte[size]; + in.get(bytes); + obj = bytes; + } + break; + + case DwarfConstants.DW_FORM_block4: { + int size = in.getInt(); + byte[] bytes = new byte[size]; + in.get(bytes); + obj = bytes; + } + break; + + case DwarfConstants.DW_FORM_data1: + obj = new Byte(in.get()); + break; + + case DwarfConstants.DW_FORM_data2: + obj = new Short(in.getShort()); + break; + + case DwarfConstants.DW_FORM_data4: + obj = new Integer(in.getInt()); + break; + + case DwarfConstants.DW_FORM_data8: + obj = new Long(in.getLong()); + break; + + case DwarfConstants.DW_FORM_sdata: + obj = new Long(DwarfInfoReader.read_signed_leb128(in)); + break; + + case DwarfConstants.DW_FORM_udata: + obj = new Long(DwarfInfoReader.read_unsigned_leb128(in)); + break; + + case DwarfConstants.DW_FORM_string: { + int c; + StringBuffer sb = new StringBuffer(); + while ((c = (in.get() & 0xff)) != -1) { + if (c == 0) { + break; + } + sb.append((char) c); + } + obj = sb.toString(); + } + break; + + case DwarfConstants.DW_FORM_flag: + obj = new Byte(in.get()); + break; + + case DwarfConstants.DW_FORM_strp: { + int offset = in.getInt(); + if (debugStrings == null) { + obj = new String(); + } else if (offset < 0 || offset > debugStrings.capacity()) { + obj = new String(); + } else { + debugStrings.position(offset); + obj = DwarfInfoReader.readString(debugStrings); + } + } + break; + + case DwarfConstants.DW_FORM_ref1: + obj = new Integer(in.get() & 0xff); + break; + + case DwarfConstants.DW_FORM_ref2: + obj = new Integer(in.getShort() & 0xffff); + break; + + case DwarfConstants.DW_FORM_ref4: + obj = new Integer(in.getInt()); + break; + + case DwarfConstants.DW_FORM_ref8: + obj = new Long(in.getLong()); + break; + + case DwarfConstants.DW_FORM_ref_udata: + obj = new Long(DwarfInfoReader.read_unsigned_leb128(in)); + break; + + case DwarfConstants.DW_FORM_indirect: { + actualForm = (byte) DwarfInfoReader.read_unsigned_leb128(in); + return readAttribute(in, addressSize, debugStrings); + } + + case DwarfConstants.DW_FORM_sec_offset : +// if (header.offsetSize == 8) +// obj = new Long(in.getLong)); +// else + obj = new Long(in.getInt() & 0xffffffffL); + break; + case DwarfConstants.DW_FORM_exprloc : + long size = DwarfInfoReader.read_unsigned_leb128(in); + byte[] bytes = new byte[(int) size]; + in.get(bytes); + obj = bytes; + break; + case DwarfConstants.DW_FORM_flag_present : + // 0 byte value + obj = Byte.valueOf((byte)1); + break; + case DwarfConstants.DW_FORM_ref_sig8 : + obj = new Long(in.getLong()); + break; + + + default: + assert (false); + break; + } + + return obj; + } + + /** + * @param attr + * @param in + * @param addressSize + * @param debugStrings + */ + //TODO: support DWARF 64-bit format + public static void skipAttributeValue(short form, IStreamBuffer in, + byte addressSize) throws IOException { + switch (form) { + case DwarfConstants.DW_FORM_addr: + case DwarfConstants.DW_FORM_ref_addr: + in.position(in.position() + addressSize); + break; + + case DwarfConstants.DW_FORM_block: { + int size = (int) DwarfInfoReader.read_unsigned_leb128(in); + in.position(in.position() + size); + } + break; + + case DwarfConstants.DW_FORM_block1: { + int size = in.get() & 0xff; + in.position(in.position() + size); + } + break; + + case DwarfConstants.DW_FORM_block2: { + int size = in.getShort(); + in.position(in.position() + size); + } + break; + + case DwarfConstants.DW_FORM_block4: { + int size = in.getInt(); + in.position(in.position() + size); + } + break; + + case DwarfConstants.DW_FORM_data1: + in.position(in.position() + 1); + break; + + case DwarfConstants.DW_FORM_data2: + in.position(in.position() + 2); + break; + + case DwarfConstants.DW_FORM_data4: + in.position(in.position() + 4); + break; + + case DwarfConstants.DW_FORM_data8: + in.position(in.position() + 8); + break; + + case DwarfConstants.DW_FORM_sdata: + DwarfInfoReader.read_signed_leb128(in); + break; + + case DwarfConstants.DW_FORM_udata: + DwarfInfoReader.read_unsigned_leb128(in); + break; + + case DwarfConstants.DW_FORM_string: { + int c; + while ((c = (in.get() & 0xff)) != -1) { + if (c == 0) { + break; + } + } + } + break; + + case DwarfConstants.DW_FORM_flag: + in.position(in.position() + 1); + break; + + case DwarfConstants.DW_FORM_strp: + in.position(in.position() + 4); + break; + + case DwarfConstants.DW_FORM_ref1: + in.position(in.position() + 1); + break; + + case DwarfConstants.DW_FORM_ref2: + in.position(in.position() + 2); + break; + + case DwarfConstants.DW_FORM_ref4: + in.position(in.position() + 4); + break; + + case DwarfConstants.DW_FORM_ref8: + in.position(in.position() + 8); + break; + + case DwarfConstants.DW_FORM_ref_udata: + DwarfInfoReader.read_unsigned_leb128(in); + break; + + case DwarfConstants.DW_FORM_indirect: { + form = (short) DwarfInfoReader.read_unsigned_leb128(in); + skipAttributeValue(form, in, addressSize); + break; + } + + case DwarfConstants.DW_FORM_sec_offset : +// if (header.offsetSize == 8) +// in.position(in.position() + 8); +// else + in.position(in.position() + 4); + break; + case DwarfConstants.DW_FORM_exprloc : + int size = (int) DwarfInfoReader.read_unsigned_leb128(in); + in.position(in.position() + size); + break; + case DwarfConstants.DW_FORM_flag_present : + // 0 byte value + in.position(in.position() + 0); // for readability + break; + case DwarfConstants.DW_FORM_ref_sig8 : + in.position(in.position() + 8); + break; + + default: + assert (false); + break; + } + } + + /** + * Parse attributes and then skip to sibling, if any + * + * @param names array to hold up to two names + * @param entry debug info entry + * @param in buffer stream of debug info + * @param addressSize + * @param debugStrings + * @return DW_AT_name value, or null if there is no or invalid DW_AT_name attribute + */ + public static void skipAttributesToSibling(AbbreviationEntry entry, IStreamBuffer in, byte addressSize) { + + long sibling = -1; + + // go through the attributes and throw away everything except the sibling + int len = entry.attributes.size(); + for (int i = 0; i < len; i++) { + Attribute attr = entry.attributes.get(i); + try { + if (attr.tag == DwarfConstants.DW_AT_sibling) { + if (attr.form == DwarfConstants.DW_FORM_ref_udata) { + sibling = DwarfInfoReader.read_unsigned_leb128(in); + } else if (attr.form == DwarfConstants.DW_FORM_ref4) { + sibling = in.getInt(); + } else { + // TODO: allow other forms for sibling value + AttributeValue.skipAttributeValue(attr.form, in, addressSize); + } + } else { + AttributeValue.skipAttributeValue(attr.form, in, addressSize); + } + } catch (IOException e) { + EDCDebugger.getMessageLogger().logError(null, e); + break; + } + } + + if (sibling != -1) + in.position(sibling); + } + + + public byte getActualForm() { + return actualForm; + } + + /** + * Get the value as a 64-bit signed long, sign-extending any shorter attribute + * @return value as signed long + */ + public long getValueAsSignedLong() { + if (value instanceof Number) { + return ((Number) value).longValue(); + } + return 0; + } + + /** + * Get the value as a 64-bit long. + * + * A Byte, Short, or Integer is zero-extended. + * + * @return value as long + */ + public long getValueAsLong() { + if (value instanceof Byte) { + return ((Byte) value).byteValue() & 0xff; + } + if (value instanceof Short) { + return ((Short) value).shortValue() & 0xffff; + } + if (value instanceof Integer) { + return ((Integer) value).intValue() & 0xffffffff; + } + // fallthrough + if (value instanceof Number) { + return ((Number) value).longValue(); + } + return 0; + } + + /** + * Get the value as a 32-bit int. + * + * A Byte or Short is zero-extended. + * + * @return value as int + */ + public int getValueAsInt() { + if (value instanceof Byte) { + return ((Byte) value).byteValue() & 0xff; + } + if (value instanceof Short) { + return ((Short) value).shortValue() & 0xffff; + } + // fallthrough + if (value instanceof Number) { + return ((Number) value).intValue(); + } + return 0; + } + + /** + * Get the value as a string + * @return String or "" if not a string + */ + public String getValueAsString() { + if (value != null) + return value.toString(); + return null; + } + + /** + * Get the byte array value (which is empty if this is not a byte array) + * @return array + */ + public byte[] getValueAsBytes() { + if (value instanceof byte[]) + return (byte[]) value; + return new byte[0]; + } + } + + static class AttributeList { + + Map attributeMap; + + AttributeList(AbbreviationEntry entry, IStreamBuffer in, byte addressSize, IStreamBuffer debugStrings) { + + int len = entry.attributes.size(); + attributeMap = new HashMap(len); + for (int i = 0; i < len; i++) { + Attribute attr = entry.attributes.get(i); + attributeMap.put(Short.valueOf(attr.tag), new AttributeValue(attr.form, in, addressSize, debugStrings)); + } + + } + + public static void skipAttributes(AbbreviationEntry entry, IStreamBuffer in, byte addressSize) { + + int len = entry.attributes.size(); + for (int i = 0; i < len; i++) { + Attribute attr = entry.attributes.get(i); + try { + AttributeValue.skipAttributeValue(attr.form, in, addressSize); + } catch (IOException e) { + EDCDebugger.getMessageLogger().logError(null, e); + break; + } + } + + } + + public long getAttributeValueAsLong(short attributeName) { + AttributeValue attr = attributeMap.get(Short.valueOf(attributeName)); + if (attr != null) { + return attr.getValueAsLong(); + } + return 0; + } + + public int getAttributeValueAsInt(short attributeName) { + AttributeValue attr = attributeMap.get(Short.valueOf(attributeName)); + if (attr != null) { + return attr.getValueAsInt(); + } + return 0; + } + + + public long getAttributeValueAsSignedLong(short attributeName) { + AttributeValue attr = attributeMap.get(Short.valueOf(attributeName)); + if (attr != null) { + return attr.getValueAsSignedLong(); + } + return 0; + } + + public String getAttributeValueAsString(short attributeName) { + AttributeValue attr = attributeMap.get(Short.valueOf(attributeName)); + if (attr != null) { + return attr.getValueAsString(); + } + return ""; //$NON-NLS-1$ + } + + public byte[] getAttributeValueAsBytes(short attributeName) { + AttributeValue attr = attributeMap.get(Short.valueOf(attributeName)); + if (attr != null) { + return attr.getValueAsBytes(); + } + return new byte[0]; + } + + public AttributeValue getAttribute(short attributeName) { + return attributeMap.get(Short.valueOf(attributeName)); + } + + /** + * Tell whether the attributes do not have a code range. + *

    + * Note: a singular DW_AT_low_pc means an entry point + *

    + * Also note: a compile unit can have code represented by DW_AT_stmt_list + * @return true if the attributes represent code + */ + public boolean hasCodeRangeAttributes() { + return attributeMap.containsKey(DwarfConstants.DW_AT_high_pc) + || attributeMap.containsKey(DwarfConstants.DW_AT_ranges); + } + } + + static public class PublicNameInfo { + public final String nameWithNameSpace; + public final CompilationUnitHeader cuHeader; + public final short tag; // DW_TAG_xxx + + public PublicNameInfo(String nameWithNameSpace, CompilationUnitHeader cuHeader, short tag) { + this.nameWithNameSpace = nameWithNameSpace; + this.cuHeader = cuHeader; + this.tag = tag; + } + } + + // list of compilation units per source file + protected HashMap> compileUnitsPerFile = new HashMap>(); + + // list of compile units in .debug_info order + protected ArrayList compileUnits = new ArrayList(); + + // list of compile units with code (non-zero high address), sorted by low address + protected ArrayList sortedCompileUnitsWithCode = new ArrayList(); + + // function and type declarations can be referenced by offsets relative to + // the compile unit or to the entire .debug_info section. therefore we keep + // maps by .debug_info offset, and for compile unit relative offsets, we + // just add the compile unit offset into the .debug_info section. + protected Map functionsByOffset = new HashMap(); + protected Map typesByOffset = Collections.synchronizedMap(new HashMap()); + + // for casting to a type, keep certain types by name + protected Map> typesByName = new HashMap>(); + // for casting to a type, track whether the cast name includes an aggregate designator + enum TypeAggregate { Class, Struct, Union, None }; + + // map of entities which created scopes + protected Map scopesByOffset = new HashMap(); + + // entry points for CUs in the .debug_info section, used to dynamically parse CUs as needed + protected TreeMap debugOffsetsToCompileUnits = new TreeMap(); + + // forward references for tags we have not parsed yet. (These will go into typesByOffset once handled) + //Map forwardDwarfDefinitions = new HashMap(); + + // these are just for faster lookups + protected Map> functionsByName = new HashMap>(); + protected Map> variablesByName = new HashMap>(); + protected Map> publicFunctions = new HashMap>(); + protected Map> publicVariables = new HashMap>(); + + // abbreviation tables (lists of abbrev entries), mapped by .debug_abbrev offset + protected Map> abbreviationMaps = new HashMap>(); + + // mapping of PC range to frame description entries + protected TreeMap frameDescEntries = new TreeMap(); + // mapping of CIE offsets to parsed common info entries + protected Map commonInfoEntries = new HashMap(); + + + protected Set referencedFiles = new HashSet(); + protected boolean buildReferencedFilesList = true; + + private IPath symbolFilePath; + private long symbolFileLastModified; + private boolean parsedInitially = false; + private boolean parsedForVarsAndAddresses = false; + private boolean parsedForScopesAndAddresses = false; + private boolean parsedForTypes = false; + private boolean parsedForGlobalVars = false; + + private final IExecutableSymbolicsReader exeReader; + private final DwarfModuleScope moduleScope; + + final DwarfFileHelper fileHelper; + + private IFrameRegisterProvider frameRegisterProvider; + + private static String SOURCE_FILES_CACHE = "_source_files"; //$NON-NLS-1$ + + public DwarfDebugInfoProvider(IExecutableSymbolicsReader exeReader) { + this.exeReader = exeReader; + this.symbolFilePath = exeReader.getSymbolFile(); + this.symbolFileLastModified = symbolFilePath.toFile().lastModified(); + this.moduleScope = new DwarfModuleScope(this); + this.fileHelper = new DwarfFileHelper(symbolFilePath); + this.frameRegisterProvider = new DwarfFrameRegisterProvider(this); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return DwarfMessages.DwarfDebugInfoProvider_DwarfProviderFor + symbolFilePath; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IDebugInfoProvider#dispose() + */ + public void dispose() { + // several views in DSF hold onto all our debug info, + // so go through and explicitly break links + if (moduleScope != null) { + moduleScope.dispose(); + } + + // help GC + compileUnitsPerFile.clear(); + compileUnits.clear(); + functionsByOffset.clear(); + typesByOffset.clear(); + scopesByOffset.clear(); + debugOffsetsToCompileUnits.clear(); + functionsByName.clear(); + variablesByName.clear(); + publicFunctions.clear(); + publicVariables.clear(); + abbreviationMaps.clear(); + referencedFiles.clear(); + moduleScope.dispose(); + parsedInitially = false; + parsedForTypes = false; + parsedForVarsAndAddresses = false; + parsedForScopesAndAddresses = false; + + fileHelper.dispose(); + frameRegisterProvider.dispose(); + } + + void ensureParsedInitially() { + if (!parsedInitially) { + DwarfInfoReader reader = new DwarfInfoReader(this); + parsedInitially = true; + reader.parseInitial(); + } + } + + void ensureParsedForScopes() { + if (!parsedForScopesAndAddresses) { + DwarfInfoReader reader = new DwarfInfoReader(this); + if (!parsedInitially) { + parsedInitially = true; + reader.parseInitial(); + } + parsedForScopesAndAddresses = true; + reader.parseForAddresses(false); + } + } + + void ensureParsedForScope(IAddress linkAddress) { + DwarfInfoReader reader = new DwarfInfoReader(this); + if (!parsedInitially) { + parsedInitially = true; + reader.parseInitial(); + } + reader.parseForAddress(linkAddress); + } + + void ensureParsedForVariables() { + if (!parsedForVarsAndAddresses) { + DwarfInfoReader reader = new DwarfInfoReader(this); + if (!parsedInitially) { + parsedInitially = true; + reader.parseInitial(); + } + parsedForVarsAndAddresses = true; + reader.parseForAddresses(true); + } + } + + private void ensureParsedForGlobalVariables() { + if (parsedForGlobalVars) + return; + parsedForGlobalVars = true; + + if (publicVariables.size() == 0) + return; + + // determine compilation units containing globals + HashSet cuWithGlobalsArray = new HashSet(publicVariables.size()); + for (List infoList : publicVariables.values()) { + for (PublicNameInfo info : infoList) { + cuWithGlobalsArray.add(info.cuHeader); + } + } + + // parse compilation units containing global variables + DwarfInfoReader reader = new DwarfInfoReader(this); + for (CompilationUnitHeader cuHeader : cuWithGlobalsArray) + reader.parseCompilationUnitForAddresses(cuHeader.scope); + } + + void ensureParsedForTypes() { + if (!parsedForTypes) { + DwarfInfoReader reader = new DwarfInfoReader(this); + if (!parsedInitially) { + parsedInitially = true; + reader.parseInitial(); + } + parsedForTypes = true; + reader.parseForTypes(); + } + } + + public void setParsedInitially() { + parsedInitially = true; + } + + public void setParsedForAddresses() { + parsedForVarsAndAddresses = true; + } + + public IPath getSymbolFile() { + return symbolFilePath; + } + + public IModuleScope getModuleScope() { + return moduleScope; + } + + public IAddress getBaseLinkAddress() { + return exeReader.getBaseLinkAddress(); + } + + public Collection getFunctionsByName(String name) { + List result; + + ensureParsedInitially(); + + String baseName = name; + + /* use same semantics as before, where qualified name lookups would fail + // pubnames uses qualified names but is indexed by basename + if (name != null) { + int baseStart = name.lastIndexOf("::"); + if (baseStart != -1) + baseName = name.substring(baseStart + 2); + } + */ + + // first, match against public function names + if (publicFunctions.size() > 0) { + if (name != null) { + DwarfInfoReader reader = new DwarfInfoReader(this); + List nameMatches = publicFunctions.get(baseName); + + if (nameMatches != null) { + // parse the compilation units that have matches + if (nameMatches.size() == 1) { // quick usual case + reader.parseCompilationUnitForAddresses(nameMatches.get(0).cuHeader.scope); + } else { + ArrayList cuList = new ArrayList(); + + for (PublicNameInfo info : nameMatches) { + if (!cuList.contains(info.cuHeader.scope)) { + cuList.add(info.cuHeader.scope); + } + } + + for (DwarfCompileUnit cu : cuList) { + reader.parseCompilationUnitForAddresses(cu); + } + } + } else { + // not a public name, so parse all compilation units looking for functions + ensureParsedForScopes(); + } + } else { + // name is null, so parse all compilation units looking for functions + ensureParsedForScopes(); + } + } else { + // no public names, so parse all compilation units looking for functions + ensureParsedForScopes(); + } + + if (name != null) { + result = functionsByName.get(baseName); + if (result == null) + return new ArrayList(0); + } else { + result = new ArrayList(functionsByName.size()); // at least this big + for (List functions : functionsByName.values()) + result.addAll(functions); + ((ArrayList) result).trimToSize(); + } + return Collections.unmodifiableCollection(result); + } + + public Collection getVariablesByName(String name, boolean globalsOnly) { + List result; + + ensureParsedInitially(); + + if (name == null) { + if (publicVariables.size() > 0) { + // name is null, so parse all compilation units looking for variables + if (globalsOnly) + ensureParsedForGlobalVariables(); + else + ensureParsedForVariables(); + } + + result = new ArrayList(variablesByName.size()); // at least this big + for (List variables : variablesByName.values()) + result.addAll(variables); + + return Collections.unmodifiableCollection(result); + } + + String baseName = name; + int baseNameStart = name.lastIndexOf("::"); //$NON-NLS-1$ + if (baseNameStart != -1) + baseName = name.substring(baseNameStart + 2); + + // match against public variable names, which the initial parse populated + if (publicVariables.size() > 0) { + DwarfInfoReader reader = new DwarfInfoReader(this); + List nameMatches = publicVariables.get(baseName); + + if (nameMatches != null) { + // parse the compilation units that have matches + if (nameMatches.size() == 1) { // quick usual case + reader.parseCompilationUnitForAddresses(nameMatches.get(0).cuHeader.scope); + } else { + ArrayList cuList = new ArrayList(); + + for (PublicNameInfo info : nameMatches) { + if (!cuList.contains(info.cuHeader.scope)) { + cuList.add(info.cuHeader.scope); + } + } + + for (DwarfCompileUnit cu : cuList) { + reader.parseCompilationUnitForAddresses(cu); + } + } + } else { + // not a public name, so parse all compilation units looking for variables + if (!globalsOnly) + ensureParsedForVariables(); + } + } + + result = variablesByName.get(name); + + // check against unqualified name because RVCT 2.x did not include namespace + // info for globals that are inside namespaces + if (result == null && baseNameStart != -1) + result = variablesByName.get(baseName); + + if (result == null) + return new ArrayList(0); + + return Collections.unmodifiableCollection(result); + } + + /** + * @return the publicFunctions + */ + public Map> getPublicFunctions() { + ensureParsedInitially(); + return publicFunctions; + } + /** + * @return the publicVariables + */ + public Map> getPublicVariables() { + ensureParsedInitially(); + return publicVariables; + } + + public ICompileUnitScope getCompileUnitForAddress(IAddress linkAddress) { + ensureParsedForScope(linkAddress); + + IScope scope = moduleScope.getScopeAtAddress(linkAddress); + while (scope != null && !(scope instanceof ICompileUnitScope)) { + scope = scope.getParent(); + } + + return (ICompileUnitScope) scope; + } + + public List getCompileUnitsForFile(IPath filePath) { + ensureParsedInitially(); + + List cuList = compileUnitsPerFile.get(filePath); + + if (cuList != null) + return cuList; + + // FIXME: we need a looser check here: on Windows, we added drive letters to all + // paths before populating compileUnitsPerFile, even if there is not really a + // drive (see DwarFileHelper). + for (Map.Entry> entry : compileUnitsPerFile.entrySet()) { + if (entry.getKey().setDevice(null).equals(filePath.setDevice(null))) { + return entry.getValue(); + } + } + + return Collections.emptyList(); + } + + @SuppressWarnings("unchecked") + public String[] getSourceFiles(IProgressMonitor monitor) { + if (referencedFiles.isEmpty()) { + // Check the persistent cache + String cacheKey = getSymbolFile().toOSString() + SOURCE_FILES_CACHE; + Set cachedFiles = EDCDebugger.getDefault().getCache().getCachedData(cacheKey, Set.class, symbolFileLastModified); + if (cachedFiles == null) + { + DwarfInfoReader reader = new DwarfInfoReader(this); + reader.quickParseDebugInfo(monitor); + assert referencedFiles.size() > 0; + EDCDebugger.getDefault().getCache().putCachedData(cacheKey, new HashSet(referencedFiles), symbolFileLastModified); + } + else + referencedFiles = cachedFiles; + } + + return referencedFiles.toArray(new String[referencedFiles.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IDebugInfoProvider#getTypes() + */ + public Collection getTypes() { + ensureParsedForTypes(); + + ArrayList types = new ArrayList(typesByOffset.values()); + return types; + } + + ///////////////// + + // Lazy evaluation methods + + + /** + * Fetch a type lazily. Either we've already parsed the type, or we have + * a reference to it, or we can find its compilation unit and parse its types. + * We do not fix up cross references until someone asks for + * it (e.g. from an IType or IVariable implementation). + */ + public IType readType(long offset_) { + Long offset = Long.valueOf(offset_); + IType type = typesByOffset.get(offset); + if (type == null) { + // make sure we've parsed it + CompilationUnitHeader header = fetchCompileUnitHeader(offset_); + if (header != null) { + DwarfInfoReader reader = new DwarfInfoReader(this); + reader.parseCompilationUnitForTypes(header.scope); + type = typesByOffset.get(offset); + // may be unhandled currently + if (type == null) { + // workaround for GCC-E 3.x bug where some, but not all, type offsets are off by 4 + // assume if you hit this null case that the problem may be the GCC-E bug + type = typesByOffset.get(offset - 4); + if (type == null) + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfDebugInfoProvider_NotParsingType1 + Long.toHexString(offset_) + + DwarfMessages.DwarfDebugInfoProvider_NotParsingType2 + symbolFilePath, null); + } + } else { + // may be unhandled currently + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfDebugInfoProvider_CannotResolveCompUnit1 + Long.toHexString(offset_) + + DwarfMessages.DwarfDebugInfoProvider_CannotResolveCompUnit2 + symbolFilePath, null); + } + } + return type; + } + + + /** + * Scan compilation unit header for its subprograms and addresses. + */ + public CompilationUnitHeader scanCompilationHeader(long offset_) { + // make sure we've parsed it + CompilationUnitHeader header = fetchCompileUnitHeader(offset_); + if (header != null) { + DwarfInfoReader reader = new DwarfInfoReader(this); + reader.parseCompilationUnitForAddresses(header.scope); + } + return header; + } + + + /** + * Fetch a referenced type lazily. + * @param scope + */ + IType resolveTypeReference(ForwardTypeReference ref) { + IType type = typesByOffset.get(ref.offset); + if (type == null) { + type = readType(ref.offset); + } + return type; + } + /** + * @return + */ + public IExecutableSymbolicsReader getExecutableSymbolicsReader() { + return exeReader; + } + + /** + * Remember where a compilation unit header lives in the debug info. + * @param debugInfoOffset + * @param currentCUHeader + */ + public void registerCompileUnitHeader(int debugInfoOffset, + CompilationUnitHeader currentCUHeader) { + debugOffsetsToCompileUnits.put((long) debugInfoOffset, currentCUHeader); + } + + /** + * Get a compilation unit header that contains the given offset. + * @param debugInfoOffset an offset which is on or after a compilation unit's debug offset + * @return {@link CompilationUnitHeader} containing the offset + */ + public CompilationUnitHeader fetchCompileUnitHeader(long debugInfoOffset) { + CompilationUnitHeader match = debugOffsetsToCompileUnits.get(debugInfoOffset); + if (match != null) + return match; + + // it's inside one + SortedMap headMap = debugOffsetsToCompileUnits.headMap(debugInfoOffset); + // urgh, sorted map... no easy way to get to the end + for (CompilationUnitHeader header : headMap.values()) { + match = header; + } + return match; + } + + /** + * Get the frame description entry for the given PC + * @param framePC + * @return FDE or null + */ + public FrameDescriptionEntry findFrameDescriptionEntry(IAddress framePC) { + DwarfInfoReader reader = new DwarfInfoReader(this); + if (frameDescEntries.isEmpty()) { + reader.parseForFrameIndices(); + } + + long pc = framePC.getValue().longValue(); + SortedMap tailMap = frameDescEntries.tailMap(new IRangeList.Entry(pc, pc)); + if (tailMap.isEmpty()) + return null; + + FrameDescriptionEntry entry = tailMap.values().iterator().next(); + if (entry.getCIE() == null) { + CommonInformationEntry cie = null; + if (!commonInfoEntries.containsKey(entry.ciePtr)) { + try { + cie = reader.parseCommonInfoEntry(entry.ciePtr, entry.addressSize, framePC); + } catch (IOException e) { + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfDebugInfoProvider_FailedToReadCIE + entry.ciePtr, e); + } + commonInfoEntries.put(entry.ciePtr, cie); + } else { + cie = commonInfoEntries.get(entry.ciePtr); + } + entry.setCIE(cie); + } + + return entry; + } + + /** + * @return + */ + public IFrameRegisterProvider getFrameRegisterProvider() { + return frameRegisterProvider; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IDebugInfoProvider#getTypesByName(java.lang.String) + */ + public Collection getTypesByName(String name) { + // is name has "struct", "class" or "union", search without that + name = name.trim(); + + String baseName = name; + TypeAggregate aggregate = TypeAggregate.None; + + if (baseName.startsWith("class ")) { //$NON-NLS-1$ + aggregate = TypeAggregate.Class; + baseName = baseName.replace("class ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } else if (baseName.startsWith("struct ")) { //$NON-NLS-1$ + aggregate = TypeAggregate.Struct; + baseName = baseName.replace("struct ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } else if (baseName.startsWith("union ")) { //$NON-NLS-1$ + aggregate = TypeAggregate.Union; + baseName = baseName.replace("union ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + Collection types = typesByName.get(baseName); + + String templateName = null; + String templateName2 = null; + + if (types == null) { + // if we didn't match and this is a template name, + // remove extra spaces and composite type names + if (baseName.indexOf('<') != -1) { + templateName = baseName; + + while (templateName.contains(" ")) //$NON-NLS-1$ + templateName = templateName.replaceAll(" ", " "); //$NON-NLS-1$ //$NON-NLS-2$ + templateName = templateName.replaceAll(", ", ","); //$NON-NLS-1$ //$NON-NLS-2$ + templateName = templateName.replaceAll("class ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + templateName = templateName.replaceAll("struct ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + templateName = templateName.replaceAll("union ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + + types = typesByName.get(templateName); + + // template name without "<...>", rather than with "<...>", might match + if (types == null) { + templateName2 = templateName.substring(0, templateName.indexOf('<')); + + types = typesByName.get(templateName2); + + // screen out types whose template list does not match + if (types != null) { + ArrayList matchingTypes = null; + for (Iterator it = types.iterator(); it.hasNext(); ) { + IType nextType = it.next(); + String match = nextType.getName(); + // for templates, remove composite type names (e.g., "class") + match = match.replaceAll("class ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + match = match.replaceAll("struct ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + match = match.replaceAll("union ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + + if (match.equals(templateName)) { + if (matchingTypes == null) + matchingTypes = new ArrayList(types.size()); + matchingTypes.add(nextType); + } + } + types = matchingTypes; // may be null + } + } + } + + if (types == null) { + // Maybe we optimistically searched for relevant types; + // if that fails, do the full parse of types now + if (!parsedForTypes) { + ensureParsedForTypes(); + types = getTypesByName(baseName); + if (types != null) + return types; // non-template return + + if (baseName.indexOf('<') != -1) { + types = typesByName.get(templateName); + if (types == null) + types = typesByName.get(templateName2); + else + templateName2 = null; // did not match name without "<...>" + } + } + + if (types == null) + return new ArrayList(0); + } + } + + // screen out types whose template list does not match + if (templateName2 != null) { + ArrayList matchingTypes = new ArrayList(types.size()); + for (Iterator it = types.iterator(); it.hasNext(); ) { // types can't be null + IType nextType = it.next(); + String match = nextType.getName(); + // for templates, remove composite type names (e.g., "class") + match = match.replaceAll("class ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + match = match.replaceAll("struct ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + match = match.replaceAll("union ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + + if (match.equals(templateName)) + matchingTypes.add(nextType); + } + types = matchingTypes; + } + + // make sure that the aggregate type matches as well as the name + if (aggregate == TypeAggregate.None) + return Collections.unmodifiableCollection(types); + + Iterator itr = types.iterator(); + while (itr.hasNext()) { + IType nextType = itr.next(); + if ((aggregate == TypeAggregate.Class && !nextType.getName().contains("class ")) || //$NON-NLS-1$ + (aggregate == TypeAggregate.Struct && !nextType.getName().contains("struct ")) || //$NON-NLS-1$ + (aggregate == TypeAggregate.Union && !nextType.getName().contains("union "))) //$NON-NLS-1$ + types.remove(nextType); + } + + if (types.isEmpty()) + return new ArrayList(0); + + return Collections.unmodifiableCollection(types); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfDebugInfoProviderFactory.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfDebugInfoProviderFactory.java new file mode 100644 index 0000000..6e42b72 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfDebugInfoProviderFactory.java @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import org.eclipse.cdt.debug.edc.internal.symbols.files.ExecutableSymbolicsReaderFactory; +import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProvider; +import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProviderFactory; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.core.runtime.IPath; + +/** + * + */ +public class DwarfDebugInfoProviderFactory implements + IDebugInfoProviderFactory { + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IDebugInfoProviderFactory#createDebugInfoProvider(org.eclipse.core.runtime.IPath) + */ + public IDebugInfoProvider createDebugInfoProvider(IPath binaryPath, IExecutableSymbolicsReader exeReader) { + // DWARF info lives either in the executable itself or in an associated symbol file. + if (exeReader != null) { + if (exeReader.findExecutableSection(DwarfInfoReader.DWARF_DEBUG_INFO) != null) { + return new DwarfDebugInfoProvider(exeReader); + } + } + + // else, look alongside for a *.sym or *.dbg file + IPath symFile = ExecutableSymbolicsReaderFactory.findSymbolicsFile(binaryPath); + if (symFile != null) { + IExecutableSymbolicsReader symExeReader = ExecutableSymbolicsReaderFactory.createFor(symFile); + if (symExeReader != null) { + return new DwarfDebugInfoProvider(symExeReader); + } + } + + // no one has DWARF + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFileHelper.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFileHelper.java new file mode 100644 index 0000000..87ee718 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFileHelper.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.edc.internal.HostOS; +import org.eclipse.cdt.debug.edc.internal.PathUtils; +import org.eclipse.core.runtime.IPath; + +/** + * An instance of this class per DwarfDebugInfoProvider assists in + * canonicalizing filepaths (from DW_AT_comp_dir and DW_AT_stmt_list) + */ +public class DwarfFileHelper { + + private boolean DEBUG = false; + + @SuppressWarnings("unused") // no longer used, but kept for compatibility and possible futureuse + private final IPath symbolFile; + + private Map compDirAndNameMap; + + private int hits; + private long nextDump; + + public DwarfFileHelper(IPath symbolFile) { + this.symbolFile = symbolFile; + this.compDirAndNameMap = new HashMap(); + } + + protected String getKey(String compDir, String name) { + return compDir + "/" + name; + } + + /** + * This is to combine the given compDir and file name from Dwarf to form a + * file path. Some processing is done to canonicalize the path, including
    + * -- extra path delimiter are removed.
    + * -- "a/b/" and "../c/d" are combined to "/a/c/d".
    + * -- change path delimiter to native, namely on Windows "/" => "\\" and the + * opposite on unix/linux + * + * @param compDir + * compDir from dwarf data. + * @param name + * file name from dwarf data with full or partial or no path. + * @return most complete file path that we can get from Dwarf data, which + * may still be a partial path. Note letter case of the names + * remains unchanged. Empty string is returned if the given name is + * an invalid file name, e.g. . + * + */ + public IPath normalizeFilePath(String compDir, String name) { + if (name == null || name.length() == 0) + return null; + + // don't count the entry "" from GCCE compiler + if (name.charAt(0) == '<') + return null; + + // Create a key for doing a lookup in our IPath cache + String key = getKey(compDir, name); + + // Look in the cache + IPath path = compDirAndNameMap.get(key); + if (path == null) { + path = normalizePath(compDir, name); + compDirAndNameMap.put(key, path); + } else { + hits++; + } + if (DEBUG && System.currentTimeMillis() > nextDump) { + System.out.println("DwarfFileHelper entries: " + compDirAndNameMap.size() + "; hits: " + hits); + nextDump = System.currentTimeMillis() + 1000; + } + return path; + } + + /** + * Takes a DW_AT_comp_dir and a filename from DWARF, + * canonicalizes it and creates an IPath. + * + * @param compDir the compilation directory, as found in DWARF data + * @param name the file specification, as found in DWARF data + * @return IPath, never null + */ + private IPath normalizePath(String compDir, String name) { + + String fullName = name; + + IPath path = PathUtils.createPath(name); + + // Combine dir & name if needed. + if (!path.isAbsolute() && compDir.length() > 0) { + fullName = compDir; + if (!compDir.endsWith(File.separator)) + fullName += File.separatorChar; + fullName += name; + + path = PathUtils.createPath(fullName); + } + + return path; + } + + /** + * Convert cygwin path and change path delimiter to native. + * No longer used but left for backwards compatbility. + * + * @param path + * @return + */ + public IPath fixUpPath(String path) { + /* + * translate cygwin drive path like /cygdrive/c/system/main.c + * //G/System/main.cpp + */ + boolean isCygwin = false; + int deleteTill = 0; + + // These paths may appear in Cygwin-compiled code, so check on any host + if (path.length() > 12 && path.startsWith("/cygdrive/") && ('/' == path.charAt(11))) { //$NON-NLS-1$ + isCygwin = true; + deleteTill = 10; + } + + // These paths may appear in Cygwin-compiled code, so check on any host + if (path.length() > 4 && path.startsWith("//") && ('/' == path.charAt(3))) { //$NON-NLS-1$ + isCygwin = true; + deleteTill = 2; + } + + // New-style Cygwin is different and has neither prefix. + // But this check only makes sense on a Windows host, since + // it may be a valid Unix-host path. + // + // /C/sources/foo.c --> c:\sources\foo.c + if (HostOS.IS_WIN32 && path.length() > 3 + && path.charAt(0) == '/' + && Character.isLetter(path.charAt(1)) + && path.charAt(2) == '/') { + isCygwin = true; + deleteTill = 1; + } + + if (isCygwin) { + StringBuilder buf = new StringBuilder(path); + buf.delete(0, deleteTill); + buf.insert(1, ':'); + path = buf.toString(); + } + + // convert to path on runtime platform + // + return PathUtils.createPath(path); + } + + /** + * + */ + public void dispose() { + compDirAndNameMap.clear(); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFrameRegisterProvider.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFrameRegisterProvider.java new file mode 100644 index 0000000..1d79354 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFrameRegisterProvider.java @@ -0,0 +1,950 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.TreeMap; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.MemoryStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ExecutionDMC; +import org.eclipse.cdt.debug.edc.internal.symbols.MemoryVariableLocation; +import org.eclipse.cdt.debug.edc.internal.symbols.RegisterOffsetVariableLocation; +import org.eclipse.cdt.debug.edc.internal.symbols.RegisterVariableLocation; +import org.eclipse.cdt.debug.edc.internal.symbols.ValueVariableLocation; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.AttributeValue; +import org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.services.IFrameRegisterProvider; +import org.eclipse.cdt.debug.edc.services.IFrameRegisters; +import org.eclipse.cdt.debug.edc.services.Registers; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.symbols.IRangeList; +import org.eclipse.cdt.debug.edc.symbols.IRangeList.Entry; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.debug.service.IStack; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.CoreException; + +/** + * Apply the rules for the CIE and FDE to a given frame. + */ +public class DwarfFrameRegisterProvider implements IFrameRegisterProvider { + + public static class InstructionState { + public EDCServicesTracker tracker; + /** Calculated register locations for the current frame */ + public Map regRules; + /** Context for the current frame */ + public IFrameDMContext context; + /** Accessor for registers from child frame */ + public IFrameRegisters childRegisters; + /** Initial locations from CIE */ + public Map initialRules; + /** Implicit stack for DW_CFA_remember_state and DW_CFA_restore_state*/ + public Stack> stateStack; + + CFARegisterRule cfaRegRule = new CFARegisterRule(0, 0); + + private final int addressSize; + public boolean cfaOffsetsAreReversed; + + public InstructionState(EDCServicesTracker tracker, + IFrameDMContext context, + IFrameRegisters childRegisters, + FrameDescriptionEntry fde) { + this.tracker = tracker; + this.addressSize = fde.addressSize; + this.cfaOffsetsAreReversed = fde.getCIE().cfaOffsetsAreReversed; + this.regRules = new TreeMap(); + this.stateStack = new Stack>(); + this.initialRules = new TreeMap(); + + this.context = context; + this.childRegisters = childRegisters; + //this.cfaValue = BigInteger.ZERO; + } + + // pseudo register for current CFA + public static final int CFA = -1; + + /** + * Read the current CFA. + * @return + */ + public BigInteger readCFA() throws CoreException { + BigInteger regval = childRegisters.getRegister(cfaRegRule.regnum, addressSize); + return regval.add(BigInteger.valueOf(cfaOffsetsAreReversed ? -cfaRegRule.offset : cfaRegRule.offset)); + } + + /** + * Get the register which is the CFA base. + * @return register number + */ + public int getCFARegister() { + return cfaRegRule.regnum; + } + + + }; + + public static abstract class AbstractRule { + public abstract IVariableLocation evaluate(InstructionState state) throws CoreException; + } + + static class ErrorRule extends AbstractRule { + private String message; + + public ErrorRule(String message) { + this.message = message; + } + @Override + public String toString() { + return "error: " + message; + } + + @Override + public IVariableLocation evaluate(InstructionState state) throws CoreException { + throw EDCDebugger.newCoreException(message); + } + } + + static class UndefinedRule extends AbstractRule { + private final int regnum; + + public UndefinedRule(int regnum) { + this.regnum = regnum; + } + @Override + public String toString() { + return "R"+regnum+": undefined"; + } + @Override + public IVariableLocation evaluate(InstructionState state) throws CoreException { + return null; + } + } + + static class SameValueRule extends AbstractRule { + private final int regnum; + + public SameValueRule(int regnum) { + this.regnum = regnum; + } + @Override + public String toString() { + return "R"+regnum+": same value"; + } + @Override + public IVariableLocation evaluate(InstructionState state) throws CoreException { + return new ValueVariableLocation(state.childRegisters.getRegister(regnum, state.addressSize)); + } + } + + static class OffsetRule extends AbstractRule { + private final long offset; + + public OffsetRule(long offset) { + this.offset = offset; + } + @Override + public String toString() { + return "offset("+offset+")"; + } + @Override + public IVariableLocation evaluate(InstructionState state) throws CoreException { + BigInteger cfa = state.readCFA(); + return new MemoryVariableLocation(state.tracker, state.context, + cfa.add(BigInteger.valueOf(offset)), true); + } + } + static class ValueOffsetRule extends AbstractRule { + private final long offset; + + public ValueOffsetRule(long offset) { + this.offset = offset; + } + @Override + public String toString() { + return "val_offset("+offset+")"; + } + @Override + public IVariableLocation evaluate(InstructionState state) throws CoreException { + BigInteger cfa = state.readCFA(); + return new ValueVariableLocation(cfa.add(BigInteger.valueOf(offset))); + } + } + static class RegisterRule extends AbstractRule { + private final int regnum; + + public RegisterRule(int regnum) { + this.regnum = regnum; + } + @Override + public String toString() { + return "register("+regnum+")"; + } + @Override + public IVariableLocation evaluate(InstructionState state) throws CoreException { + return new RegisterVariableLocation(state.tracker, state.context, null, regnum); + } + } + + static class CFARegisterRule extends AbstractRule { + private int regnum; + private long offset; + + public CFARegisterRule(int regnum, long offset) { + this.regnum = regnum; + this.offset = offset; + } + @Override + public String toString() { + return "["+regnum+"]"+(offset < 0 ? "-" : "+")+Math.abs(offset); + } + @Override + public IVariableLocation evaluate(InstructionState state) throws CoreException { + return new RegisterOffsetVariableLocation(state.tracker, state.context, null, regnum, offset); + } + } + private static ErrorRule UNIMPLEMENTED = new ErrorRule( + "unimplemented support for reading this location"); + + + /** The base class for instructions + */ + public static abstract class AbstractInstruction { + + public AbstractInstruction() { + } + + /** + * Apply this instruction to the state. + * @param state + * @throws CoreException + */ + abstract public void applyInstruction(InstructionState state) throws CoreException; + } + + /** The base class for rules that apply to registers + */ + public static abstract class AbstractRegisterInstruction extends AbstractInstruction { + protected final int thereg; + + public AbstractRegisterInstruction(int thereg) { + super(); + this.thereg = thereg; + } + + @Override + public String toString() { + return "R"+thereg; + } + } + + public static class NopInstruction extends AbstractInstruction { + + public NopInstruction() { + super(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.AbstractRegisterRule#toString() + */ + @Override + public String toString() { + return "nop"; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.AbstractRegisterRule#applyRule(org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext, java.util.Map, java.util.Map) + */ + @Override + public void applyInstruction(InstructionState state) throws CoreException { + + } + + } + /** CFA=RN+o */ + public static class DefCFAInstruction extends AbstractInstruction { + long regnum; + long offset; + public DefCFAInstruction(long regnum, long offset) { + this.regnum = regnum; + } + @Override + public String toString() { + return "CFA := R"+regnum + " + " + offset; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.cfaRegRule.regnum = (int) regnum; + state.cfaRegRule.offset = offset; + } + } + + /** CFA=RN (+o) */ + public static class DefCFARegisterInstruction extends AbstractInstruction { + long regnum; + public DefCFARegisterInstruction(long regnum) { + this.regnum = regnum; + } + @Override + public String toString() { + return "CFA register := R"+regnum; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.cfaRegRule.regnum = (int) regnum; + } + } + + + /** CFA=(RN) +o */ + public static class DefCFAOffsetInstruction extends AbstractInstruction { + long offset; + public DefCFAOffsetInstruction(long offset) { + this.offset = offset; + } + @Override + public String toString() { + return "CFA offset := "+offset; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.cfaRegRule.offset = offset; + } + } + + + public static class DefCFAExpressionInstruction extends AbstractInstruction { + IStreamBuffer expression; + public DefCFAExpressionInstruction(IStreamBuffer expression) { + this.expression = expression; + } + @Override + public String toString() { + return "CFA := expression"; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + throw EDCDebugger.newCoreException("CFA expression not implemented"); + } + } + + public static class SameValueInstruction extends AbstractRegisterInstruction { + public SameValueInstruction(int thereg) { + super(thereg); + } + @Override + public String toString() { + return super.toString() + "same value"; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.regRules.put(thereg, new SameValueRule(thereg)); + } + } + + public static class UndefinedInstruction extends AbstractRegisterInstruction { + public UndefinedInstruction(int thereg) { + super(thereg); + } + @Override + public String toString() { + return super.toString() + "undefined"; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.regRules.put(thereg, new UndefinedRule(thereg)); + } + } + + public static class OffsetInstruction extends AbstractRegisterInstruction { + long offset; + + public OffsetInstruction(int thereg, long offset) { + super(thereg); + this.offset = offset; + } + @Override + public String toString() { + return super.toString() + "@ CFA + " + offset; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.regRules.put(thereg, new OffsetRule(offset)); + } + } + + public static class ValueOffsetInstruction extends AbstractRegisterInstruction { + long offset; + public ValueOffsetInstruction(int thereg, long offset) { + super(thereg); + this.offset = offset; + } + @Override + public String toString() { + return super.toString() + "CFA + " + offset; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.regRules.put(thereg, new ValueOffsetRule(offset)); + } + } + + public static class RegisterInstruction extends AbstractRegisterInstruction { + int regnum; + public RegisterInstruction(int thereg, int regnum) { + super(thereg); + this.regnum = regnum; + } + @Override + public String toString() { + return super.toString() + "copy R"+regnum; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + if (state.regRules.containsKey(regnum)) + state.regRules.put(thereg, state.regRules.get(regnum)); + else + state.regRules.put(thereg, new UndefinedRule(regnum)); + } + } + + public static class ExpressionInstruction extends AbstractRegisterInstruction { + IStreamBuffer expression; + public ExpressionInstruction(int thereg, IStreamBuffer expression) { + super(thereg); + this.expression = expression; + } + @Override + public String toString() { + return super.toString() + "@ expression"; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.regRules.put(thereg, UNIMPLEMENTED); + } + } + public static class ValueExpressionInstruction extends AbstractRegisterInstruction { + IStreamBuffer expression; + public ValueExpressionInstruction(int thereg, IStreamBuffer expression) { + super(thereg); + this.expression = expression; + } + @Override + public String toString() { + return super.toString() + " expression"; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.regRules.put(thereg, UNIMPLEMENTED); + } + } + public static class RestoreInstruction extends AbstractRegisterInstruction { + public RestoreInstruction(int thereg) { + super(thereg); + } + @Override + public String toString() { + return super.toString() + " restore"; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + if (state.initialRules.containsKey(thereg)) + state.regRules.put(thereg, state.initialRules.get(thereg)); + else + state.regRules.remove(thereg); + } + } + + public static class RememberStateInstruction extends AbstractInstruction { + public RememberStateInstruction() { + super(); + } + @Override + public String toString() { + return "remember state"; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.stateStack.push(new TreeMap(state.regRules)); + } + } + public static class RestoreStateInstruction extends AbstractInstruction { + public RestoreStateInstruction() { + super(); + } + @Override + public String toString() { + return "restore state"; + } + @Override + public void applyInstruction(InstructionState state) throws CoreException { + state.regRules.clear(); + state.regRules.putAll(state.stateStack.pop()); + } + } + + + /** + * A "CIE" from the .debug_frame section. + */ + public static class CommonInformationEntry { + + final long codeAlignmentFactor; + final long dataAlignmentFactor; + final int version; + final int returnAddressRegister; + final int addressSize; + final IStreamBuffer instructions; + private List initialLocations; + private CoreException initialLocationsError; + private boolean cfaOffsetSfIsFactored; + private boolean cfaOffsetsAreReversed; + + public CommonInformationEntry(long codeAlignmentFactor, + long dataAlignmentFactor, int returnAddressRegister, + int version, + IStreamBuffer instructions, + int addressSize, + String producer, String augmentation) { + + this.codeAlignmentFactor = codeAlignmentFactor; + this.dataAlignmentFactor = dataAlignmentFactor; + this.returnAddressRegister = returnAddressRegister; + this.version = version; + this.instructions = instructions; + this.addressSize = addressSize; + + checkAugmentations(producer, augmentation); + } + + /** + * Handle augmentations we find. + */ + private void checkAugmentations(String producer, String augmentation) { + // RVCT has bugs with the frame info in DWARF 1/2 and some DWARF 3 + + if (augmentation.startsWith("armcc") && augmentation.contains("+")) { + // this means bugs are fixed + + } else { + if (producer != null && producer.contains("RVCT")) { //$NON-NLS-1$ + if (version == 1) { + cfaOffsetSfIsFactored = true; + cfaOffsetsAreReversed = true; + } + + if (version == 3) { + cfaOffsetsAreReversed = true; + } + } + } + } + + /** + * Get the rules defining initial locations for all the registers + * @return list of instructions + */ + public List getInitialLocations(DwarfDebugInfoProvider provider) throws CoreException { + if (initialLocations == null) { + try { + initialLocations = parseInitialLocations(provider); + } catch (CoreException e) { + initialLocationsError = e; + } + } + if (initialLocationsError != null) + throw initialLocationsError; + return initialLocations; + } + + /** + * Parse the instructions for calculating the initial locations for all the registers + * @return map of register to rule + */ + public List parseInitialLocations(DwarfDebugInfoProvider provider) throws CoreException { + List instrs = new ArrayList(); + + IStreamBuffer buffer = instructions.wrapSubsection(instructions.capacity()); + + buffer.position(0); + + try { + while (buffer.hasRemaining()) { + int opcode = buffer.get() & 0xff; + AbstractInstruction inst = parseInstruction(opcode, buffer, provider, addressSize, dataAlignmentFactor); + if (inst != null) + instrs.add(inst); + } + } catch (Exception e) { + throw EDCDebugger.newCoreException("Malformed data at " + buffer, e); + } + + + return instrs; + } + + public AbstractInstruction parseInstruction(int opcode, IStreamBuffer buffer, + DwarfDebugInfoProvider provider, int addressSize, long dataAlignmentFactor) throws IOException { + int reg; + long offset; + IStreamBuffer expr; + + // + // CFA DEFINITION INSTRUCTIONS + // + if (opcode >= DwarfConstants.DW_CFA_offset && opcode < DwarfConstants.DW_CFA_offset + 0x40) { + reg = opcode - DwarfConstants.DW_CFA_offset; + offset = DwarfInfoReader.read_unsigned_leb128(buffer) * dataAlignmentFactor; + return new OffsetInstruction(reg, offset); + } else if (opcode >= DwarfConstants.DW_CFA_restore && opcode < DwarfConstants.DW_CFA_restore + 0x40) { + reg = opcode - DwarfConstants.DW_CFA_restore; + return new RestoreInstruction(reg); + } else { + switch (opcode) { + case DwarfConstants.DW_CFA_nop: + // ignore + return new NopInstruction(); + case DwarfConstants.DW_CFA_def_cfa: + reg = readRegister(buffer); + offset = DwarfInfoReader.read_unsigned_leb128(buffer); + if (cfaOffsetSfIsFactored) { + offset *= dataAlignmentFactor; + } + return new DefCFAInstruction(reg, offset); + case DwarfConstants.DW_CFA_def_cfa_sf: + reg = readRegister(buffer); + offset = DwarfInfoReader.read_signed_leb128(buffer) * dataAlignmentFactor; + return new DefCFAInstruction(reg, offset); + case DwarfConstants.DW_CFA_def_cfa_register: { + reg = readRegister(buffer); + return new DefCFARegisterInstruction(reg); + } + case DwarfConstants.DW_CFA_def_cfa_offset: { + offset = DwarfInfoReader.read_unsigned_leb128(buffer); // non-factored, usually + if (cfaOffsetSfIsFactored) { + offset *= dataAlignmentFactor; + } + return new DefCFAOffsetInstruction(offset); + } + case DwarfConstants.DW_CFA_def_cfa_offset_sf: { + offset = DwarfInfoReader.read_signed_leb128(buffer) * dataAlignmentFactor; + return new DefCFAOffsetInstruction(offset); + } + case DwarfConstants.DW_CFA_def_cfa_expression: { + byte form = buffer.get(); + expr = readExpression(form, addressSize, provider, buffer); + return new DefCFAExpressionInstruction(expr); + } + } + } + + // + // REGISTER RULE INSTRUCTIONS + // + if (opcode >= DwarfConstants.DW_CFA_offset && opcode < DwarfConstants.DW_CFA_offset + 0x40) { + reg = opcode - DwarfConstants.DW_CFA_offset; + offset = DwarfInfoReader.read_unsigned_leb128(buffer) * dataAlignmentFactor; + return new OffsetInstruction(reg, offset); + } else if (opcode >= DwarfConstants.DW_CFA_restore && opcode < DwarfConstants.DW_CFA_restore + 0x40) { + reg = opcode - DwarfConstants.DW_CFA_restore; + return new RestoreInstruction(reg); + } else { + switch (opcode) { + case DwarfConstants.DW_CFA_nop: + break; + + case DwarfConstants.DW_CFA_undefined: + reg = readRegister(buffer); + return new UndefinedInstruction(reg); + case DwarfConstants.DW_CFA_same_value: + reg = readRegister(buffer); + return new SameValueInstruction(reg); + case DwarfConstants.DW_CFA_offset_extended: + reg = readRegister(buffer); + offset = DwarfInfoReader.read_unsigned_leb128(buffer) * dataAlignmentFactor; + return new OffsetInstruction(reg, offset); + case DwarfConstants.DW_CFA_offset_extended_sf: + reg = readRegister(buffer); + offset = DwarfInfoReader.read_signed_leb128(buffer) * dataAlignmentFactor; + return new OffsetInstruction(reg, offset); + case DwarfConstants.DW_CFA_val_offset: + reg = readRegister(buffer); + offset = DwarfInfoReader.read_unsigned_leb128(buffer) * dataAlignmentFactor; + return new ValueOffsetInstruction(reg, offset); + case DwarfConstants.DW_CFA_val_offset_sf: + reg = readRegister(buffer); + offset = DwarfInfoReader.read_signed_leb128(buffer) * dataAlignmentFactor; + return new ValueOffsetInstruction(reg, offset); + case DwarfConstants.DW_CFA_register: { + reg = readRegister(buffer); + int otherReg = readRegister(buffer); + return new RegisterInstruction(reg, otherReg); + } + case DwarfConstants.DW_CFA_expression: { + reg = readRegister(buffer); + byte form = buffer.get(); + expr = readExpression(form, addressSize, provider, buffer); + return new ExpressionInstruction(reg, expr); + } + case DwarfConstants.DW_CFA_val_expression: { + reg = readRegister(buffer); + byte form = buffer.get(); + expr = readExpression(form, addressSize, provider, buffer); + return new ValueExpressionInstruction(reg, expr); + } + case DwarfConstants.DW_CFA_restore_extended: + reg = readRegister(buffer); + return new RestoreInstruction(reg); + case DwarfConstants.DW_CFA_remember_state: + return new RememberStateInstruction(); + case DwarfConstants.DW_CFA_restore_state: + return new RestoreStateInstruction(); + } + } + return null; + } + + /** + * @param buffer + * @return + * @throws IOException + */ + private int readRegister(IStreamBuffer buffer) throws IOException { + return (int) DwarfInfoReader.read_unsigned_leb128(buffer); + } + + private IStreamBuffer readExpression(byte form, int addressSize, + DwarfDebugInfoProvider provider, IStreamBuffer buffer) { + AttributeValue value = new AttributeValue(form, buffer, (byte) addressSize, null); + return new MemoryStreamBuffer(value.getValueAsBytes(), + provider.getExecutableSymbolicsReader().getByteOrder()); + } + + } + + + /** + * A "FDE" entry from the .debug_frame section. + */ + public static class FrameDescriptionEntry { + + final Long fdePtr; + final Long ciePtr; + final int addressSize; + private final IStreamBuffer instructions; + + private final long low, high; + + private CommonInformationEntry cie; + private CoreException parseException; + private TreeMap> instructionMap; + + public CommonInformationEntry getCIE() { + return cie; + } + + public void setCIE(CommonInformationEntry cie) { + this.cie = cie; + } + + public FrameDescriptionEntry(long fdePtr, long ciePtr, long low, long high, + IStreamBuffer instructions, int addressSize) { + this.ciePtr = ciePtr; + this.fdePtr = fdePtr; + this.instructions = instructions; + this.addressSize = addressSize; + this.low = low; + this.high = high; + } + + @Override + public String toString() { + return "FDE at " + instructions + " with CIE " + (cie != null ? cie : ciePtr); + } + + /** + * Get the register for this frame which denotes the return address + * @return register number + */ + public int getReturnAddressRegister() { + return cie != null ? cie.returnAddressRegister : 0; + } + + /** + * Get the instruction map for the FDE + * @param provider + * @return + */ + public TreeMap> getInstructions( + DwarfDebugInfoProvider provider) throws CoreException { + if (instructionMap == null) { + try { + instructionMap = parseRules(provider); + } catch (CoreException e) { + parseException = e; + } + } + if (parseException != null) + throw parseException; + return instructionMap; + } + + private TreeMap> parseRules( + DwarfDebugInfoProvider provider) throws CoreException { + TreeMap> rules = new TreeMap>(); + + IStreamBuffer buffer = instructions.wrapSubsection(instructions.capacity()); + + buffer.position(0); + + // adjust range and store row as we see set_loc/advance_loc instructions + long current = low; + List row = new ArrayList(); + + try { + while (buffer.hasRemaining()) { + int opcode = buffer.get() & 0xff; + + // + // ROW CREATION INSTRUCTIONS + // + long offset = -1; + if (opcode >= DwarfConstants.DW_CFA_advance_loc && opcode < DwarfConstants.DW_CFA_advance_loc + 0x40) { + offset = (opcode - DwarfConstants.DW_CFA_advance_loc) * cie.codeAlignmentFactor; + } else { + switch (opcode) { + case DwarfConstants.DW_CFA_set_loc: + offset = DwarfInfoReader.readAddress(buffer, addressSize) - current; + break; + case DwarfConstants.DW_CFA_advance_loc1: + offset = (buffer.get() & 0xff) * cie.codeAlignmentFactor; + break; + case DwarfConstants.DW_CFA_advance_loc2: + offset = (buffer.getShort() & 0xffff) * cie.codeAlignmentFactor; + break; + case DwarfConstants.DW_CFA_advance_loc4: + offset = (buffer.getInt() & 0xffffffff) * cie.codeAlignmentFactor; + break; + } + } + + if (offset > 0) { + rules.put(new IRangeList.Entry(current, current + offset), row); + current += offset; + row = new ArrayList(); + continue; + } + + // + // REGISTER RULE INSTRUCTIONS + // + + AbstractInstruction instr = cie.parseInstruction(opcode, buffer, provider, addressSize, cie.dataAlignmentFactor); + if (instr != null) { + row.add(instr); + } else { + assert(false); + throw EDCDebugger.newCoreException("Unimplemented opcode " + opcode + " at " + buffer); + } + } + } catch (CoreException e) { + throw e; + } catch (Exception e) { + throw EDCDebugger.newCoreException("error parsing FDE rules at " + buffer, e); + } + + if (!row.isEmpty()) { + // finish instruction stream + rules.put(new IRangeList.Entry(current, high), row); + } + return rules; + } + } + + private DwarfDebugInfoProvider provider; + + public DwarfFrameRegisterProvider( + DwarfDebugInfoProvider provider) { + this.provider = provider; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IFrameRegisterProvider#dispose() + */ + public void dispose() { + provider = null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.services.IFrameRegisterProvider#getFrameRegisters(org.eclipse.cdt.dsf.service.DsfSession, org.eclipse.cdt.dsf.service.DsfServicesTracker, org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext) + */ + public IFrameRegisters getFrameRegisters(DsfSession session, + EDCServicesTracker tracker, + IFrameDMContext context) throws CoreException { + Registers registers = tracker.getService(Registers.class); + IStack stack = tracker.getService(IStack.class); + ExecutionDMC exeDMC = DMContexts.getAncestorOfType(context, ExecutionDMC.class); + + if (registers == null || exeDMC == null || !(context instanceof StackFrameDMC)) + throw EDCDebugger.newCoreException("cannot read frame"); + + StackFrameDMC stackFrame = (StackFrameDMC) context; + + if (stackFrame.getLevel() == 0) { + // shouldn't actually get here, but whatevah + return new org.eclipse.cdt.debug.edc.services.Stack.CurrentFrameRegisters(exeDMC, registers); + } + + // get the child frame's registers + StackFrameDMC childFrame = getChildFrame(session, stack, exeDMC, stackFrame); + if (childFrame == null) + return null; + + IFrameRegisters childRegisters = childFrame.getFrameRegisters(); + + IAddress linkaddress = childFrame.getInstructionPtrAddress(); + IEDCModuleDMContext module = childFrame.getModule(); + if (module != null) { + linkaddress = module.toLinkAddress(linkaddress); + } + + FrameDescriptionEntry currentFrameEntry = provider.findFrameDescriptionEntry(linkaddress); + if (currentFrameEntry == null) + return null; + + return new DwarfFrameRegisters(tracker, childFrame, currentFrameEntry, childRegisters, provider); + } + + /** + * Find the frame called by stackFrame + */ + private StackFrameDMC getChildFrame(DsfSession session, IStack stack, + ExecutionDMC exeDMC, StackFrameDMC stackFrame) throws CoreException { + StackFrameDMC childFrame = stackFrame.getCalledFrame(); + return childFrame; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFrameRegisters.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFrameRegisters.java new file mode 100644 index 0000000..9b9f195 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFrameRegisters.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.math.BigInteger; +import java.text.MessageFormat; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.symbols.ValueVariableLocation; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.AbstractInstruction; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.AbstractRule; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.FrameDescriptionEntry; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.InstructionState; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.services.IFrameRegisters; +import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC; +import org.eclipse.cdt.debug.edc.symbols.IRangeList.Entry; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.core.runtime.CoreException; + +/** + * This class wraps the cached values from reading unwind information from the CIE and FDE + * records along each frame of the call stack to a given stack frame. + * This must be recreated on each context suspend. + */ +public class DwarfFrameRegisters implements IFrameRegisters { + + private final EDCServicesTracker tracker; + private final StackFrameDMC context; + private final IFrameRegisters childRegisters; + + // holds BigInteger or CoreException + private Map cachedRegisters = new TreeMap(); + private final FrameDescriptionEntry fde; + private final DwarfDebugInfoProvider provider; + private Map frameRegisterRules; + private InstructionState state; + + /** + * @param provider + * + */ + public DwarfFrameRegisters(EDCServicesTracker tracker, + StackFrameDMC context, + FrameDescriptionEntry fde, + IFrameRegisters childRegisters, DwarfDebugInfoProvider provider) { + if (childRegisters == null) + throw new NullPointerException(); + this.provider = provider; + this.tracker = tracker; + this.context = context; + this.fde = fde; + this.childRegisters = childRegisters; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.services.dsf.IFrameRegisters#getRegister(int) + */ + public BigInteger getRegister(int regnum, int bytes) throws CoreException { + BigInteger value = null; + CoreException exception = null; + Object object = cachedRegisters.get(regnum); + if (object == null) { + try { + IVariableLocation loc = getRegisterLocation(regnum); + if (loc == null) + throw EDCDebugger.newCoreException(MessageFormat.format(DwarfMessages.DwarfFrameRegisters_CannotReadRegister, + regnum, context.getInstructionPtrAddress().toHexAddressString())); + value = loc.readValue(bytes); + cachedRegisters.put(regnum, value); + } catch (CoreException e) { + exception = e; + cachedRegisters.put(regnum, exception); + } + } else { + if (object instanceof CoreException) + exception = (CoreException) object; + else + value = (BigInteger) object; + } + + if (exception != null) + throw exception; + + return value; + } + + + /** + * Calculate the location of a register for the current frame and PC. + * @param regnum + * @return location or null if undefined + * @throws CoreException in case of a problem calculating the location + */ + private IVariableLocation getRegisterLocation(int regnum) throws CoreException { + + if (frameRegisterRules == null) { + state = new InstructionState(tracker, context, childRegisters, fde); + frameRegisterRules = calculateFrameRegisterRules(state); + } + + AbstractRule rule = frameRegisterRules.get(regnum); + if (rule == null) { + // Note: according to DWARF-3 spec, any register not mentioned here is undefined. + // But DWARF-2 producers didn't know what to do (or is it ABI-defined?), + // so for these, assume the current register for now + if (fde.getCIE().version < 3) + if (regnum == state.getCFARegister()) + return new ValueVariableLocation(state.readCFA()); + else + return new ValueVariableLocation(childRegisters.getRegister(regnum, fde.addressSize)); + else + return null; + } + + return rule.evaluate(state); + } + + + /** + * Create locations for every register in this frame. + * @param state + * @return mapping of register to location + * @throws CoreException + */ + private Map calculateFrameRegisterRules(InstructionState state) throws CoreException { + if (fde.getCIE() == null) + throw EDCDebugger.newCoreException(MessageFormat.format(DwarfMessages.DwarfFrameRegisters_NoCommonInfoEntry, fde)); + + List initialLocationInstructions = + fde.getCIE().getInitialLocations(provider); + + for (AbstractInstruction instr : initialLocationInstructions) { + instr.applyInstruction(state); + } + + // Run through rules until we hit one past our range + TreeMap> fdeInstrs = fde.getInstructions(provider); + + long currentPC = context.getModule().toLinkAddress(context.getInstructionPtrAddress()).getValue().longValue(); + + for (Map.Entry> instrEntry : fdeInstrs.entrySet()) { + Entry entry = instrEntry.getKey(); + if (entry.low > currentPC) // execute all instructions <= PC + break; + + try { + for (AbstractInstruction instr : instrEntry.getValue()) { + instr.applyInstruction(state); + } + } catch (Exception e) { + throw EDCDebugger.newCoreException(DwarfMessages.DwarfFrameRegisters_ErrorCalculatingLocation, e); + } + } + + return state.regRules; + } + + + public void writeRegister(int regnum, int bytes, BigInteger value) throws CoreException { + CoreException exception = null; + try { + IVariableLocation loc = getRegisterLocation(regnum); + if (loc == null) + throw EDCDebugger.newCoreException(MessageFormat.format(DwarfMessages.DwarfFrameRegisters_CannotWriteRegister, + regnum, context.getInstructionPtrAddress().toHexAddressString())); + loc.writeValue(bytes, value); + cachedRegisters.put(regnum, value); + } catch (CoreException e) { + exception = e; + cachedRegisters.put(regnum, exception); + } + + if (exception != null) + throw exception; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFunctionScope.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFunctionScope.java new file mode 100644 index 0000000..9317a68 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfFunctionScope.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.FunctionScope; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.core.runtime.IPath; + +public class DwarfFunctionScope extends FunctionScope implements IFunctionScope { + protected int declFileNum; + + public DwarfFunctionScope(String name, IScope parent, IAddress lowAddress, IAddress highAddress, + ILocationProvider frameBaseLocationProvider) { + super(name, parent, lowAddress, highAddress, frameBaseLocationProvider); + } + + /** + * Set the declaration file number entry from the line number table + * @param declFileNum + */ + public void setDeclFileNum(int declFileNum) { + this.declFileNum = declFileNum; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.FunctionScope#getDeclFile() + */ + @Override + public IPath getDeclFile() { + IPath file = super.getDeclFile(); + if (file == null && declFileNum != 0) { + // ask the parent + IScope cu = getParent(); + while (cu != null) { + if (cu instanceof DwarfCompileUnit) { + return ((DwarfCompileUnit) cu).getFileEntry(declFileNum); + } + cu = cu.getParent(); + } + } + return file; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfInfoReader.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfInfoReader.java new file mode 100644 index 0000000..6b48dce --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfInfoReader.java @@ -0,0 +1,3451 @@ +/** + * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). + * All rights reserved. + * This component and the accompanying materials are made available + * under the terms of the License "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: + * + */ + +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.TreeMap; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.EDCTrace; +import org.eclipse.cdt.debug.edc.internal.MemoryStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.PathUtils; +import org.eclipse.cdt.debug.edc.internal.symbols.ArrayBoundType; +import org.eclipse.cdt.debug.edc.internal.symbols.ArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.CPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.ClassType; +import org.eclipse.cdt.debug.edc.internal.symbols.ConstType; +import org.eclipse.cdt.debug.edc.internal.symbols.Enumeration; +import org.eclipse.cdt.debug.edc.internal.symbols.Enumerator; +import org.eclipse.cdt.debug.edc.internal.symbols.FieldType; +import org.eclipse.cdt.debug.edc.internal.symbols.FunctionScope; +import org.eclipse.cdt.debug.edc.internal.symbols.IArrayType; +import org.eclipse.cdt.debug.edc.internal.symbols.IBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICompositeType; +import org.eclipse.cdt.debug.edc.internal.symbols.ISection; +import org.eclipse.cdt.debug.edc.internal.symbols.InheritanceType; +import org.eclipse.cdt.debug.edc.internal.symbols.LexicalBlockScope; +import org.eclipse.cdt.debug.edc.internal.symbols.LineEntry; +import org.eclipse.cdt.debug.edc.internal.symbols.PointerType; +import org.eclipse.cdt.debug.edc.internal.symbols.ReferenceType; +import org.eclipse.cdt.debug.edc.internal.symbols.Scope; +import org.eclipse.cdt.debug.edc.internal.symbols.StructType; +import org.eclipse.cdt.debug.edc.internal.symbols.SubroutineType; +import org.eclipse.cdt.debug.edc.internal.symbols.TemplateParamType; +import org.eclipse.cdt.debug.edc.internal.symbols.TypedefType; +import org.eclipse.cdt.debug.edc.internal.symbols.UnionType; +import org.eclipse.cdt.debug.edc.internal.symbols.VolatileType; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.AbbreviationEntry; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.Attribute; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.AttributeList; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.AttributeValue; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.CompilationUnitHeader; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.ForwardTypeReference; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.PublicNameInfo; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.CommonInformationEntry; +import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfFrameRegisterProvider.FrameDescriptionEntry; +import org.eclipse.cdt.debug.edc.internal.symbols.files.BaseExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.internal.symbols.files.UnmanglerEABI; +import org.eclipse.cdt.debug.edc.internal.symbols.files.UnmanglingException; +import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSection; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILineEntry; +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IRangeList; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IUnmangler; +import org.eclipse.cdt.debug.edc.symbols.IVariable; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +/** + * Handle restartable parsing of Dwarf information from a single module. + * This class may be instantiated multiple times to parse specific subsets + * of the Dwarf data. The {@link DwarfDebugInfoProvider} + * holds the global state of everything parsed so far. + */ +public class DwarfInfoReader { + + private class BaseAndScopedNames { + public String baseName; // e.g., "bar" + public String nameWithScope; // e.g., "foo::bar" + } + + private BaseAndScopedNames baseAndScopedNames = new BaseAndScopedNames(); + + // These are only for developer of the reader. + // + private static boolean DEBUG = false; + private static String dumpFileName = "C:\\temp\\_EDC_DwarfReaderDump.txt"; //$NON-NLS-1$ + + // TODO 64-bit Dwarf currently unsupported + + /* Section names. */ + public final static String DWARF_DEBUG_INFO = ".debug_info"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_RANGES = ".debug_ranges"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_ABBREV = ".debug_abbrev"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_ARANGES = ".debug_aranges"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_LINE = ".debug_line"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_FRAME = ".debug_frame"; //$NON-NLS-1$ + public final static String DWARF_EH_FRAME = ".eh_frame"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_LOC = ".debug_loc"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_PUBNAMES = ".debug_pubnames"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_STR = ".debug_str"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_FUNCNAMES = ".debug_funcnames"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_TYPENAMES = ".debug_typenames"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_VARNAMES = ".debug_varnames"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_WEAKNAMES = ".debug_weaknames"; //$NON-NLS-1$ + public final static String DWARF_DEBUG_MACINFO = ".debug_macinfo"; //$NON-NLS-1$ + + private Map> locationEntriesByOffset = Collections.synchronizedMap(new HashMap>()); + + // the target for all the reading + private DwarfDebugInfoProvider provider; + + private IExecutableSymbolicsReader exeReader; + private DwarfModuleScope moduleScope; + private IPath symbolFilePath; + + private IExecutableSection debugInfoSection; + private IExecutableSection publicNamesSection; + private CompilationUnitHeader currentCUHeader; + + private Map typeToParentMap = Collections.synchronizedMap(new HashMap()); + private IType currentParentType; + private Scope currentParentScope; + private DwarfCompileUnit currentCompileUnitScope; + + private DwarfFileHelper fileHelper; + + private RangeList codeRanges; + + private ICPPBasicType voidType = null; + + private IUnmangler unmangler; + + // comparator for sorting and searching based on compilation unit low address + private static Comparator sComparatorByLowAddress = new Comparator() { + public int compare(DwarfCompileUnit o1, DwarfCompileUnit o2) { + return (o1.getLowAddress().compareTo(o2.getLowAddress())); + }}; + + /** + * Create a reader for the provider. This constructor and any methods + * on this reader class will incrementally update the provider. + * @param provider + */ + public DwarfInfoReader(DwarfDebugInfoProvider provider) { + this.provider = provider; + exeReader = provider.getExecutableSymbolicsReader(); + if (exeReader instanceof BaseExecutableSymbolicsReader) + unmangler = ((BaseExecutableSymbolicsReader) exeReader).getUnmangler(); + if (unmangler == null) + unmangler = new UnmanglerEABI(); + + symbolFilePath = provider.getSymbolFile(); + fileHelper = provider.fileHelper; + moduleScope = (DwarfModuleScope) provider.getModuleScope(); + debugInfoSection = exeReader.findExecutableSection(DWARF_DEBUG_INFO); + publicNamesSection = exeReader.findExecutableSection(DWARF_DEBUG_PUBNAMES); + + codeRanges = getCodeRanges(); + } + + private String unmangle(String name) { + if (!unmangler.isMangled(name)) + return name; + + try { + name = unmangler.unmangle(name); + } catch (UnmanglingException ue) { + } + + return name; + } + + + private String unmangleType(String name) { + if (!unmangler.isMangled(name)) + return name; + + try { + name = unmangler.unmangleType(name); + } catch (UnmanglingException ue) { + } + + return name; + } + + /** + * @return + */ + private RangeList getCodeRanges() { + RangeList codeRanges = new RangeList(); + for (ISection section : exeReader.getSections()) { + if (section.getProperties().get(ISection.PROPERTY_NAME).equals(ISection.NAME_TEXT)) { + long start = section.getLinkAddress().getValue().longValue(); + long size = section.getSize(); + codeRanges.addRange(start, start + size); + } + } + return codeRanges; + } + + protected IStreamBuffer getDwarfSection(String sectionName) { + // the exe reader and section already handle caching this + IStreamBuffer buffer = null; + IExecutableSection section = exeReader.findExecutableSection(sectionName); + if (section != null) { + buffer = section.getBuffer(); + } + return buffer; + } + + /** + * Parse top-level debugging information about compilation units and globally + * visible objects, but do not expand or gather data about other objects in + * compilation units. + */ + public void parseInitial() { + Job parseInitialJob = new Job(DwarfMessages.DwarfInfoReader_ReadingSymbolInfo + symbolFilePath) { + + @Override + protected IStatus run(IProgressMonitor monitor) { + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceInitialParseFor + symbolFilePath)); } + synchronized (provider) { + parseCUDebugInfo(monitor); + parsePublicNames(); + } + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceFinishedInitialParse)); } + return Status.OK_STATUS; + } + }; + + try { + parseInitialJob.schedule(); + parseInitialJob.join(); + } catch (InterruptedException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + } + + /** + * Parse all compilation units for addresses + * + * @param includeCUWithoutCode + * whether to parse compile units without code. For variable + * info, we need to look into those CUs, whereas for scope + * info, we don't. + */ + public void parseForAddresses(boolean includeCUWithoutCode) { + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceAddressesParseFor + symbolFilePath)); } + synchronized (provider) { + for (DwarfCompileUnit compileUnit : provider.compileUnits) { + if (DEBUG) { + // For internal check. + if (compileUnit.getHighAddress().isZero()) + assert(compileUnit.getChildren().size() == 0); + else + assert(compileUnit.getChildren().size() >= 0); + } + + if (includeCUWithoutCode || // parse every CU + ! compileUnit.getHighAddress().isZero()) // parse only those with code. + { + parseCompilationUnitForAddresses(compileUnit); + } + } + } + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceFinishedAddressesParse)); } + + moduleScope.fixupRanges(Addr32.ZERO); + + if (DEBUG) { + dumpSymbols(); + } + + } + + /** + * Parse compilation unit corresponding to address + * + * @param linkAddress + * address in a compile unit that contains code + */ + public void parseForAddress(IAddress linkAddress) { + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceAddressParseFor + symbolFilePath)); } + + // find compilation unit containing address, and parse it + synchronized (provider) { + DwarfCompileUnit cu = new DwarfCompileUnit(provider, null, null, linkAddress, linkAddress, null, false, null); + int index = Collections.binarySearch (provider.sortedCompileUnitsWithCode, cu, sComparatorByLowAddress); + + if (index >= 0) { + cu = provider.sortedCompileUnitsWithCode.get(index); + parseCompilationUnitForAddresses(cu); + } else if (index < -1 && -index - 2 < provider.sortedCompileUnitsWithCode.size()) { + cu = provider.sortedCompileUnitsWithCode.get(-index - 2); + if (cu.getLowAddress().compareTo(linkAddress) <= 0 && cu.getHighAddress().compareTo(linkAddress) >= 0) + parseCompilationUnitForAddresses(cu); + } else { + return; + } + + if (moduleScope.getLowAddress().compareTo(cu.getLowAddress()) > 0) + moduleScope.setLowAddress(cu.getLowAddress()); + if (moduleScope.getHighAddress().compareTo(cu.getHighAddress()) < 0) + moduleScope.setHighAddress(cu.getHighAddress()); + } + + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceFinishedAddressParse)); } + } + + /** + * Parse names in the .debug_pubnames section + */ + private void parsePublicNames() { + + if (publicNamesSection == null || debugInfoSection == null) { // no public names and/or debug info + return; + } + + IStreamBuffer bufferPublicNames = publicNamesSection.getBuffer(); + if (bufferPublicNames == null) + return; + + IStreamBuffer bufferDebuginfo = debugInfoSection.getBuffer(); + if (bufferDebuginfo == null) + return; + + long fileIndex = 0; + long fileEndIndex = bufferPublicNames.capacity(); + + // parse all the sets in the .debug_pubnames section + while (fileIndex < fileEndIndex) { + fileIndex = parsePublicNamesSet(bufferPublicNames, fileIndex, bufferDebuginfo); + } + } + + /** + * Parse one set of global objects and functions + */ + private long parsePublicNamesSet(IStreamBuffer bufferPublicNames, long fileIndex, IStreamBuffer bufferDebugInfo) { + bufferPublicNames.position(fileIndex); + + // get the set's data length + int setLength = bufferPublicNames.getInt(); + + // get the entire set + + IStreamBuffer dataPublicNames = bufferPublicNames.wrapSubsection(setLength); + + // get header info for set of public names + // skip over Dwarf version + dataPublicNames.position(2); + int debugInfoOffset = dataPublicNames.getInt(); + int debugInfoLength = dataPublicNames.getInt(); + + try { + // read the entire compile unit + bufferDebugInfo.position(debugInfoOffset); + + IStreamBuffer dataInfoBytes = bufferDebugInfo.wrapSubsection(debugInfoLength); + + CompilationUnitHeader header = provider.debugOffsetsToCompileUnits.get(Long.valueOf(debugInfoOffset)); + + // get stored abbrev table, or read and parse an abbrev table + Map abbrevs = parseDebugAbbreviation(header.abbreviationOffset); + + // read names and corresponding types + // ignore the 4 bytes of 0 at the end of the set + while (dataPublicNames.remaining() > 4) { + // read the object offset and name + int objectOffset = dataPublicNames.getInt(); + String name = readString(dataPublicNames); + + // read the type of object + dataInfoBytes.position(objectOffset); + long code = read_unsigned_leb128(dataInfoBytes); + AbbreviationEntry entry = abbrevs.get(new Long(code)); + + // ignore empty names, names without debug info, and + // compiler-generated special symbols + if (entry != null && name.length() > 0 && !name.startsWith("<")) { + // if the name is mangled, unmangle it + name = unmangle(name); + + String baseName = name; + int baseStart = name.lastIndexOf("::"); //$NON-NLS-1$ + if (baseStart != -1) + baseName = name.substring(baseStart + 2); + if (entry.tag == DwarfConstants.DW_TAG_variable) { + List variables = provider.publicVariables.get(baseName); + if (variables == null) { + variables = new ArrayList(); + } + variables.add(new PublicNameInfo(name, header, entry.tag)); + provider.publicVariables.put(baseName, variables); + } else if (entry.tag == DwarfConstants.DW_TAG_subprogram) { + List functions = provider.publicFunctions.get(baseName); + if (functions == null) { + functions = new ArrayList(); + functions.add(new PublicNameInfo(name, header, entry.tag)); + } else { + // we don't store debug info offsets, so polymorphic functions for a compilation + // unit have identical PublicNameInfo fields; throw all but one away + ArrayList arrayList = (ArrayList)functions; + boolean found = false; + for (int i = arrayList.size() - 1; + !found && (i >= 0) && (arrayList.get(i).cuHeader == header); i--) + found = arrayList.get(i).nameWithNameSpace.equals(name); + if (!found) + functions.add(new PublicNameInfo(name, header, entry.tag)); + } + provider.publicFunctions.put(baseName, functions); + + } + } + } + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(null, t); + } + + return fileIndex + setLength + 4; + } + + /** + * Parse all compilation units for types + */ + public void parseForTypes() { + synchronized (provider) { + for (DwarfCompileUnit compileUnit : provider.compileUnits) { + parseCompilationUnitForTypes(compileUnit); + } + } + } + /** + * Parse compilation unit headers and top-level info in the .debug_info section + * @param monitor + */ + private void parseCUDebugInfo(IProgressMonitor monitor) { + + if (debugInfoSection == null) { // no Dwarf data. + return; + } + + // if we haven't built the referenced files list from a quick parse yet, + // flag it here so we can build the file list as we parse. + if (provider.referencedFiles.isEmpty()) { + provider.buildReferencedFilesList = true; + } + + IStreamBuffer buffer = debugInfoSection.getBuffer(); + IStreamBuffer debugStrings = getDebugStrings(); + boolean havePubNames = publicNamesSection != null && publicNamesSection.getBuffer() != null; + + int totalWork = (int) (buffer.capacity() / 1024); + monitor.beginTask(DwarfMessages.DwarfInfoReader_ReadDebugInfo, totalWork); + try { + if (buffer != null) { + long fileIndex = 0; + long fileEndIndex = buffer.capacity(); + + while (fileIndex < fileEndIndex) { + long oldIndex = fileIndex; + fileIndex = parseCompilationUnitForNames(buffer, fileIndex, debugStrings, fileEndIndex, havePubNames); + monitor.worked((int) ((fileIndex - oldIndex) / 1024)); + } + } + } finally { + monitor.done(); + } + provider.compileUnits.trimToSize(); + // sort by low address the list of compilation units with code + provider.sortedCompileUnitsWithCode.trimToSize(); + Collections.sort(provider.sortedCompileUnitsWithCode, sComparatorByLowAddress); + provider.buildReferencedFilesList = false; + } + + /** + * Parse the compile unit quickly looking for variables that are globally visible + * + * @return offset of next compilation unit + */ + private long parseCompilationUnitForNames(IStreamBuffer buffer, long fileIndex, IStreamBuffer debugStrings, long fileEndIndex, boolean havePubNames) { + buffer.position(fileIndex); + int lengthSize = 0; + currentCUHeader = new CompilationUnitHeader(); + try { + InitialLengthValue sectionLength = readInitialLengthField(buffer); + currentCUHeader.length = sectionLength.length; + currentCUHeader.offsetSize = sectionLength.offsetSize; + } catch (IOException e) { + e.printStackTrace(); + } + currentCUHeader.version = buffer.getShort(); + if (currentCUHeader.offsetSize == 8) { + currentCUHeader.abbreviationOffset = (int) buffer.getLong(); + lengthSize = 12; + } else { + currentCUHeader.abbreviationOffset = buffer.getInt(); + lengthSize = 4; + } + currentCUHeader.addressSize = buffer.get(); + currentCUHeader.debugInfoOffset = (int) fileIndex; + + /* + * With certain GCC-E 3.x compilers, some subset of compile unit headers can have unit + * lengths 4 bytes too long. Before reading compile unit data, make sure there is a + * valid compile unit header right after this unit's data. Adjust the length if needed. + * To validate, check that the DWARF version and the address size are + * the same as the previous compile unit's. + */ + if (fileIndex + currentCUHeader.length + (2 * lengthSize) < fileEndIndex) { + // try good case + short nextVersion; + byte nextAddrSize; + buffer.position(fileIndex + currentCUHeader.length + (2 * lengthSize)); // to next version + nextVersion = buffer.getShort(); + buffer.position(fileIndex + currentCUHeader.length + (2 * lengthSize) + 2 + currentCUHeader.offsetSize); // to next address size + nextAddrSize = buffer.get(); + // TODO: is this adjustment still necessary? + if (currentCUHeader.version != nextVersion || currentCUHeader.addressSize != nextAddrSize) { + // try adjusting back by 4 bytes + buffer.position(fileIndex + currentCUHeader.length + 4); // to next version + nextVersion = buffer.getShort(); + buffer.position(fileIndex + currentCUHeader.length + 10); // to next address size + nextAddrSize = buffer.get(); + + if (currentCUHeader.version == nextVersion && currentCUHeader.addressSize == nextAddrSize) { + // all this work to adjust the length... + currentCUHeader.length -= 4; + } + } + } + + // now read the whole compile unit into memory. note that we're + // reading the whole section including the size that we already + // read because other code will use the offset of the buffer as + // the offset of the section to store things by offset (types, + // function declarations, etc). + buffer.position(fileIndex); + + IStreamBuffer in = buffer.wrapSubsection(currentCUHeader.length + lengthSize); + + // skip over the header info we already read + if (currentCUHeader.offsetSize == 8) { + in.position(lengthSize + 2 + 8 + 1); // sizeof (length + version + offset + address size) + } else { + in.position(lengthSize + 2 + 4 + 1); // sizeof (length + version + offset + address size) + } + + try { + // get stored abbrev table, or read and parse an abbrev table + Map abbrevs = parseDebugAbbreviation(currentCUHeader.abbreviationOffset); + + // read the compile unit's attribute list + long code = read_unsigned_leb128(in); + AbbreviationEntry entry = abbrevs.get(Long.valueOf(code)); + + AttributeList attributeList = new AttributeList(entry, in, currentCUHeader.addressSize, debugStrings); + processCompileUnit(currentCUHeader, entry.hasChildren, attributeList); + + if (!havePubNames) { + // record file scope variables + byte addressSize = currentCUHeader.addressSize; + while (in.remaining() > 0) { + code = read_unsigned_leb128(in); + + if (code != 0) { + entry = abbrevs.get(Long.valueOf(code)); + + switch (entry.tag) { + // record names of interest, but not other Dwarf attributes + case DwarfConstants.DW_TAG_variable: + { + // get variable names at the compile unit scope level + parseAttributesForNames(true, baseAndScopedNames, entry, in, addressSize, debugStrings); + if (baseAndScopedNames.baseName != null) + storePublicNames(provider.publicVariables, baseAndScopedNames, currentCUHeader, (short) DwarfConstants.DW_TAG_variable); + break; + } + case DwarfConstants.DW_TAG_imported_declaration: // for possible namespace alias + case DwarfConstants.DW_TAG_namespace: + case DwarfConstants.DW_TAG_subprogram: + case DwarfConstants.DW_TAG_enumerator: + case DwarfConstants.DW_TAG_class_type: + case DwarfConstants.DW_TAG_structure_type: + case DwarfConstants.DW_TAG_array_type: + case DwarfConstants.DW_TAG_base_type: + case DwarfConstants.DW_TAG_enumeration_type: + case DwarfConstants.DW_TAG_pointer_type: + case DwarfConstants.DW_TAG_ptr_to_member_type: + case DwarfConstants.DW_TAG_subroutine_type: + case DwarfConstants.DW_TAG_typedef: + case DwarfConstants.DW_TAG_union_type: + case DwarfConstants.DW_TAG_access_declaration: + case DwarfConstants.DW_TAG_catch_block: + case DwarfConstants.DW_TAG_common_block: + case DwarfConstants.DW_TAG_common_inclusion: + case DwarfConstants.DW_TAG_condition: + case DwarfConstants.DW_TAG_const_type: + case DwarfConstants.DW_TAG_constant: + case DwarfConstants.DW_TAG_entry_point: + case DwarfConstants.DW_TAG_file_type: + case DwarfConstants.DW_TAG_formal_parameter: + case DwarfConstants.DW_TAG_friend: + case DwarfConstants.DW_TAG_imported_module: + case DwarfConstants.DW_TAG_inheritance: + case DwarfConstants.DW_TAG_inlined_subroutine: + case DwarfConstants.DW_TAG_interface_type: + case DwarfConstants.DW_TAG_label: + case DwarfConstants.DW_TAG_lexical_block: + case DwarfConstants.DW_TAG_member: + case DwarfConstants.DW_TAG_module: + case DwarfConstants.DW_TAG_namelist: + case DwarfConstants.DW_TAG_namelist_item: + case DwarfConstants.DW_TAG_packed_type: + case DwarfConstants.DW_TAG_reference_type: + case DwarfConstants.DW_TAG_restrict_type: + case DwarfConstants.DW_TAG_set_type: + case DwarfConstants.DW_TAG_shared_type: + case DwarfConstants.DW_TAG_string_type: + case DwarfConstants.DW_TAG_subrange_type: + case DwarfConstants.DW_TAG_template_type_param: + case DwarfConstants.DW_TAG_template_value_param: + case DwarfConstants.DW_TAG_thrown_type: + case DwarfConstants.DW_TAG_try_block: + case DwarfConstants.DW_TAG_unspecified_parameters: + case DwarfConstants.DW_TAG_variant: + case DwarfConstants.DW_TAG_variant_part: + case DwarfConstants.DW_TAG_volatile_type: + case DwarfConstants.DW_TAG_with_stmt: + { + AttributeValue.skipAttributesToSibling(entry, in, addressSize); + break; + } + // case DwarfConstants.DW_TAG_compile_unit: + // case DwarfConstants.DW_TAG_partial_unit: + // case DwarfConstants.DW_TAG_unspecified_type: + default: + // skip entire entries + AttributeList.skipAttributes(entry, in, addressSize); + break; + } + } + } + } + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfInfoReader_ParseDebugInfoSectionFailed1 + + debugInfoSection.getName() + DwarfMessages.DwarfInfoReader_ParseDebugInfoSectionFailed2 + symbolFilePath, t); + } + + // skip past the compile unit. note that the + // currentCUHeader.length does not include + // the size of the unit length itself + fileIndex += currentCUHeader.length + lengthSize; + + return fileIndex; + } + + /** + * Parse attributes, returning names + * + * @param onlyExternal only return names if they have external visibility + * @param names array to hold up to two names + * @param entry debug info entry + * @param in buffer stream of debug info + * @param addressSize + * @param debugStrings + * @return DW_AT_name value in names[0], unmangled DW_AT_MIPS_linkage_name value in + * names[1], or nulls + */ + private void parseAttributesForNames(boolean onlyExternal, BaseAndScopedNames baseAndScopedNames, AbbreviationEntry entry, IStreamBuffer in, + byte addressSize, IStreamBuffer debugStrings) { + + String name = null; + baseAndScopedNames.baseName = null; + baseAndScopedNames.nameWithScope = null; + boolean isExternal = false; + + // go through the attributes and throw away everything except the names + int len = entry.attributes.size(); + for (int i = 0; i < len; i++) { + Attribute attr = entry.attributes.get(i); + try { + if ( attr.tag == DwarfConstants.DW_AT_name + || attr.tag == DwarfConstants.DW_AT_MIPS_linkage_name) { + // names should be DW_FORM_string or DW_FORM_strp + if (attr.form == DwarfConstants.DW_FORM_string) { + int c; + StringBuffer sb = new StringBuffer(); + while ((c = (in.get() & 0xff)) != -1) { + if (c == 0) { + break; + } + sb.append((char) c); + } + name = sb.toString(); + } else if (attr.form == DwarfConstants.DW_FORM_strp) { + int debugStringOffset = in.getInt(); + if ( debugStrings != null + && debugStringOffset >= 0 + && debugStringOffset < debugStrings.capacity()) { + debugStrings.position(debugStringOffset); + name = DwarfInfoReader.readString(debugStrings); + } + } + + if (name != null) { + if (attr.tag == DwarfConstants.DW_AT_name) { + baseAndScopedNames.baseName = name; + baseAndScopedNames.nameWithScope = name; + } else { + if (exeReader instanceof BaseExecutableSymbolicsReader) { + try { + baseAndScopedNames.nameWithScope = unmangler.unmangle(unmangler.undecorate(name)); + } catch(UnmanglingException ue) { + } + } + } + name = null; + } + } else if (attr.tag == DwarfConstants.DW_AT_external) { + if (attr.form == DwarfConstants.DW_FORM_flag) { + isExternal = in.get() != 0; + } else { + AttributeValue.skipAttributeValue(attr.form, in, addressSize); + } + } else { + AttributeValue.skipAttributeValue(attr.form, in, addressSize); + } + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(null, t); + break; + } + } + + // if only looking for externals, throw away internals + if (onlyExternal && !isExternal) { + baseAndScopedNames.baseName = null; + baseAndScopedNames.nameWithScope = null; + } else { + // if only have the scoped name, derive the base name + if (baseAndScopedNames.nameWithScope != null && baseAndScopedNames.baseName == null) { + int baseStart = baseAndScopedNames.nameWithScope.lastIndexOf("::"); //$NON-NLS-1$ + if (baseStart != -1) + baseAndScopedNames.baseName = baseAndScopedNames.nameWithScope.substring(baseStart + 2); + else + baseAndScopedNames.baseName = baseAndScopedNames.nameWithScope; + } + } + } + + /** + * Store compilation unit level names from Dwarf .debug_info + * + * @param namesStore + * @param names + * @param offset + */ + private void storePublicNames(Map> namesStore, BaseAndScopedNames baseAndScopedNames, + CompilationUnitHeader cuHeader, short tag) { + + List currentNames = namesStore.get(baseAndScopedNames.baseName); + if (currentNames == null) { + currentNames = new ArrayList(); + namesStore.put(baseAndScopedNames.baseName, currentNames); + } + currentNames.add(new PublicNameInfo(baseAndScopedNames.nameWithScope, cuHeader, tag)); + } + + private synchronized void parseCompilationUnitForAddressesPrivate(DwarfCompileUnit compileUnit, IProgressMonitor monitor) + { + synchronized (compileUnit) { + if (compileUnit.isParsedForAddresses()) + return; + + compileUnit.setParsedForAddresses(true); + + CompilationUnitHeader header = compileUnit.header; + + if (header == null) + return; + + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().trace(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceAddressParse1 + Integer.toHexString(header.debugInfoOffset) + DwarfMessages.DwarfInfoReader_TraceAddressParse2 + header.scope.getFilePath())); } + + IStreamBuffer buffer = debugInfoSection.getBuffer(); + + if (buffer == null) + return; + + int fileIndex = header.debugInfoOffset; + + // read the compile unit debug info into memory + buffer.position(fileIndex); + + int lengthSize = 0, headerLength = 0; + if (header.offsetSize == 8) { + lengthSize = 12; + headerLength = lengthSize + 2 + 8 + 1; // unit length(8) + version + abbrev table offset + address size + } else { + lengthSize = 4; + headerLength = lengthSize + 2 + 4 + 1; // unit length(8) + version + abbrev table offset + address size + } + + IStreamBuffer data = buffer.wrapSubsection(header.length + lengthSize); + + // skip over the header, since we've already read it + data.position(headerLength); + + currentCompileUnitScope = compileUnit; + currentParentScope = compileUnit; + registerScope(header.debugInfoOffset, compileUnit); + currentCUHeader = header; + + try { + // get stored abbrev table, or read and parse an abbrev table + Map abbrevs = parseDebugAbbreviation(header.abbreviationOffset); + + parseForAddresses(data, abbrevs, header, new Stack(), monitor); + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfInfoReader_ParseDebugInfoSectionFailed1 + + debugInfoSection.getName() + DwarfMessages.DwarfInfoReader_ParseDebugInfoSectionFailed2 + symbolFilePath, t); + } + } + } + + /** + * Given compilation unit, parse to get variables and all children that have address ranges. + * + * @param compileUnit + */ + public void parseCompilationUnitForAddresses(final DwarfCompileUnit compileUnit) { + synchronized (provider) { + synchronized (compileUnit) { + if (compileUnit.isParsedForAddresses()) + return; + } + parseCompilationUnitForAddressesPrivate(compileUnit, new NullProgressMonitor()); + } + } + + synchronized public void parseCompilationUnitForTypes(DwarfCompileUnit compileUnit) { + synchronized (provider) { + synchronized(compileUnit) { + if (compileUnit.isParsedForTypes()) + return; + + compileUnit.setParsedForTypes(true); + + CompilationUnitHeader header = compileUnit.header; + + if (header == null) + return; + + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().trace(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceTypeParse1 + Integer.toHexString(header.debugInfoOffset) + DwarfMessages.DwarfInfoReader_TraceTypeParse2 + header.scope.getFilePath())); } + + IStreamBuffer buffer = debugInfoSection.getBuffer(); + + if (buffer == null) + return; + + int fileIndex = header.debugInfoOffset; + + // read the compile unit debug info into memory + buffer.position(fileIndex); + + int lengthSize = 0, headerLength = 0; + if (header.offsetSize == 8) { + lengthSize = 12; + headerLength = lengthSize + 2 + 8 + 1; // unit length(8) + version + abbrev table offset + address size + } else { + lengthSize = 4; + headerLength = lengthSize + 2 + 4 + 1; // unit length(8) + version + abbrev table offset + address size + } + + IStreamBuffer data = buffer.wrapSubsection(header.length + lengthSize); + + // skip over the header, since we've already read it + data.position(headerLength); + + currentCompileUnitScope = compileUnit; + currentParentScope = compileUnit; + registerScope(header.debugInfoOffset, compileUnit); + currentCUHeader = header; + + try { + // get stored abbrev table, or read and parse an abbrev table + Map abbrevs = parseDebugAbbreviation(header.abbreviationOffset); + + parseForTypes(data, abbrevs, header, new Stack()); + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfInfoReader_ParseTraceInfoSectionFailed1 + + debugInfoSection.getName() + DwarfMessages.DwarfInfoReader_ParseTraceInfoSectionFailed2 + symbolFilePath, t); + } + } + } + } + + public void quickParseDebugInfo(IProgressMonitor monitor) { + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceQuickParse + symbolFilePath)); } + synchronized (provider) { + doQuickParseDebugInfo(monitor); + } + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceFinishedQuickParse)); } + } + + /** + * Does a quick parse of the .debug_info section just to get a list of + * referenced files from the compile units. + */ + private void doQuickParseDebugInfo(IProgressMonitor monitor) { + + if (debugInfoSection == null) { // no Dwarf data. + return; + } + + // get the compile units out of the .debug_info section + IStreamBuffer buffer = debugInfoSection.getBuffer(); + if (buffer == null) + return; + + try { + int lengthSize = 0; + long fileIndex = 0; + long fileEndIndex = buffer.capacity(); + + monitor.beginTask(DwarfMessages.DwarfInfoReader_ReadDebugInfo, (int) (fileEndIndex / 1024)); + + buffer.position(0); + while (fileIndex < fileEndIndex) { + buffer.position(fileIndex); + long unit_length = 0; + byte offsetSize = 0; + int debug_abbrev_offset = 0; + + try { + InitialLengthValue sectionLength = readInitialLengthField(buffer); + unit_length = sectionLength.length; + offsetSize = sectionLength.offsetSize; + } catch (IOException e) { + e.printStackTrace(); + } + + short version = buffer.getShort(); + if (offsetSize == 8) { + debug_abbrev_offset = (int) buffer.getLong(); + lengthSize = 12; + } else { + debug_abbrev_offset = buffer.getInt(); + lengthSize = 4; + } + byte address_size = buffer.get(); + + /* + * With certain GCC-E 3.x compilers, some subset of compile unit headers can have unit + * lengths 4 bytes too long. So before reading this unit's data, make sure there is a + * valid compile unit header right after this unit's data. Adjust the length if needed. + * To validate, check that the DWARF version and the address size are + * the same as the previous compile unit's. + */ + if (fileIndex + unit_length + (2 * lengthSize) < fileEndIndex) { + // try good case + short nextVersion; + byte nextAddrSize; + buffer.position(fileIndex + unit_length + (2 * lengthSize)); // to next version + nextVersion = buffer.getShort(); + buffer.position(fileIndex + unit_length + (2 * lengthSize) + 2 + debug_abbrev_offset); // to next address size + nextAddrSize = buffer.get(); + // TODO: is this adjustment still necessary? + if (version != nextVersion || address_size != nextAddrSize) { + // try adjusting back by 4 bytes + buffer.position(fileIndex + unit_length + 4); // to next version + nextVersion = buffer.getShort(); + buffer.position(fileIndex + unit_length + 10); // to next address size + nextAddrSize = buffer.get(); + + if (version == nextVersion && address_size == nextAddrSize) { + unit_length -= 4; + } // otherwise, just let things bomb + } + } + + buffer.position(fileIndex + lengthSize); + IStreamBuffer data = buffer.wrapSubsection(unit_length); + // skip header info already read + if (offsetSize == 8) { + data.position(2 + 8 + 1); // sizeof (version + offset + address size) + } else { + data.position(2 + 4 + 1); // sizeof (version + offset + address size) + } + + // get the abbreviation entry for the compile unit + // find the offset to the + Map abbrevs = parseDebugAbbreviation(debug_abbrev_offset); + + long code = read_unsigned_leb128(data); + AbbreviationEntry entry = abbrevs.get(Long.valueOf(code)); + AttributeList attributeList = new AttributeList(entry, data, address_size, getDebugStrings()); + + // get comp_dir and name and figure out the path + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + String compDir = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_comp_dir); + + IPath filePath = fileHelper.normalizeFilePath(compDir, name); + provider.referencedFiles.add(filePath.toOSString()); + + // do a quick parse of the line table to get any other + // referenced files + AttributeValue a = attributeList.getAttribute(DwarfConstants.DW_AT_stmt_list); + if (a != null) { + int stmtList = a.getValueAsInt(); + quickParseLineInfo(stmtList, compDir); + } + + // skip past the compile unit. note that the unit_length does + // not include the size of the unit length itself + long oldIndex = fileIndex; + fileIndex += unit_length + lengthSize; + monitor.worked((int) ((fileIndex - oldIndex) / 1024)); + } + + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfInfoReader_ParseSectionSourceFilesFailed1 + + debugInfoSection.getName() + DwarfMessages.DwarfInfoReader_ParseSectionSourceFilesFailed2 + symbolFilePath, t); + } finally { + monitor.done(); + } + } + + /** + * + */ + class InitialLengthValue { + /** + * section length + */ + long length; + + /** + * section offset size in bytes. + */ + byte offsetSize; // + } + + /** + * Read section length field from the beginning of dwarf section. + * + *

    See Chapter 7.4 32-Bit and 64-Bit DWARF Formats

    + * @param data - stream buffer positioned at the start of section length record + * @return section length info. Cannot be null. + * @throws IOException + */ + InitialLengthValue readInitialLengthField(IStreamBuffer data) throws IOException { + InitialLengthValue info = new InitialLengthValue(); + info.length = data.getInt() & 0xffffffffL; + + if (info.length == 0xffffffffL) { + info.length = data.getLong(); + info.offsetSize = 8; + } else if (info.length == 0) { // IRIX + info.length = data.getLong(); + info.offsetSize = 8; + } else + info.offsetSize = 4; + return info; + } + + + /** + * Get the .debug_strings section. + * @return ByteBuffer or null + */ + private IStreamBuffer getDebugStrings() { + return getDwarfSection(DWARF_DEBUG_STR); + } + + /** + * Does a quick parse of the .debug_line section just to get a list of + * referenced files from the line table. + */ + private void quickParseLineInfo(int lineTableOffset, String compileUnitDirectory) { + IPath compileUnitDirectoryPath = PathUtils.createPath(compileUnitDirectory); + try { + // do a quick parse of the line table just to get referenced files + IStreamBuffer data = getDwarfSection(DWARF_DEBUG_LINE); + if (data != null) { + data.position(lineTableOffset); + + /* + * Skip past the bytes of the header that we don't care about: + * unit_length (4 bytes), version (2 bytes), header_length (4 bytes), + * minimum_instruction_length (1 byte), default_is_stmt (1 byte), + * line_base (1 byte), line_range (1 byte) + */ + data.position(data.position() + 14); + + // we need to get this value so we can skip over + // standard_opcode_lengths + int opcode_base = data.get() & 0xff; + data.position(data.position() + opcode_base - 1); + + // include_directories + ArrayList dirList = new ArrayList(); + + // add the compilation directory of the CU as the first + // directory + dirList.add(compileUnitDirectory); + + while (true) { + String str = readString(data); + if (str.length() == 0) + break; + + // if the directory is relative, append it to the CU dir + IPath dir = PathUtils.createPath(str); + if (!dir.isAbsolute() && dir.getDevice() == null) { + dir = compileUnitDirectoryPath.append(str); + } + dirList.add(dir.toString()); + } + + while (true) { + String fileName = readString(data); + if (fileName.length() == 0) // no more file entry + break; + + // dir index + long leb128 = DwarfInfoReader.read_unsigned_leb128(data); + + IPath fullPath = fileHelper.normalizeFilePath(dirList.get((int) leb128), fileName); + if (fullPath != null) { + provider.referencedFiles.add(fullPath.toOSString()); + } + + // skip the modification time and file size + leb128 = read_unsigned_leb128(data); + leb128 = read_unsigned_leb128(data); + } + } + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(null, t); + } + } + + + /** + * Parse the line table for a given compile unit + * @param attributes + * @param fileList list for file entries + * @return new array of ILineEntry + */ + @SuppressWarnings("unused") + public Collection parseLineTable(IScope scope, AttributeList attributes, List fileList) { + synchronized (provider) { + List lineEntries = new ArrayList(); + try { + IStreamBuffer data = getDwarfSection(DWARF_DEBUG_LINE); + AttributeValue a = attributes.getAttribute(DwarfConstants.DW_AT_stmt_list); + if (data != null && a != null) { + int stmtList = a.getValueAsInt(); + data.position(stmtList); + + /* + * Read line table header: + * + * total_length: 4 bytes (excluding itself) + * version: 2 + * prologue length: 4 + * minimum_instruction_len: 1 + * default_is_stmt: 0 or 1 + * line_base: 1 + * line_range: 1 + * opcode_base: 1 + * standard_opcode_lengths: (value of opcode_base) + */ + + // Remember the CU line tables we've parsed. + int length = data.getInt() + 4; + + // Skip the following till "opcode_base" + int version = data.getShort(); + int prologue_length = data.getInt(); + int minimum_instruction_length = data.get() & 0xff; + boolean default_is_stmt = data.get() > 0; + int line_base = data.get(); // signed + int line_range = data.get() & 0xff; + + int opcode_base = data.get() & 0xff; + byte[] opcodes = new byte[opcode_base - 1]; + data.get(opcodes); + + // Read in directories. + // + ArrayList dirList = new ArrayList(); + + // Put the compilation directory of the CU as the first dir + String compDir = attributes.getAttributeValueAsString(DwarfConstants.DW_AT_comp_dir); + dirList.add(compDir); + + IPath compDirPath = PathUtils.createPath(compDir); + + String str, fileName; + + while (true) { + str = readString(data); + if (str.length() == 0) + break; + // If the directory is relative, append it to the CU dir + IPath dir = PathUtils.createPath(str); + if (!dir.isAbsolute() && dir.getDevice() == null) { + dir = compDirPath.append(str); + } + dirList.add(dir.toString()); + } + + // Read file names + // + long leb128; + while (true) { + fileName = readString(data); + if (fileName.length() == 0) // no more file entry + break; + + // dir index + leb128 = read_unsigned_leb128(data); + + IPath fullPath = fileHelper.normalizeFilePath(dirList.get((int) leb128), fileName); + // add a null as a placeholder when the filename is enclosed in '<' & '>' (e.g., "") + fileList.add(fullPath); + + // Skip the following + // + // modification time + leb128 = read_unsigned_leb128(data); + + // file size in bytes + leb128 = read_unsigned_leb128(data); + } + + long info_address = 0; + long info_file = 1; + int info_line = 1; + int info_column = 0; + boolean is_stmt = default_is_stmt; + int info_flags = 0; + long info_ISA = 0; + + long lineInfoEnd = stmtList + length; + while (data.position() < lineInfoEnd) { + byte opcodeB = data.get(); + int opcode = 0xFF & opcodeB; + + if (opcode >= opcode_base) { + info_line += (((opcode - opcode_base) % line_range) + line_base); + info_address += (opcode - opcode_base) / line_range * minimum_instruction_length; + if (is_stmt && fileList.size() > 0) { + IPath path = fileList.get((int) info_file - 1); + // added a null as a placeholder when the filename was enclosed in '<' & '>' (e.g., "") + if (path != null) + lineEntries.add(new LineEntry(path, info_line, info_column, new Addr32(info_address), null)); + } + info_flags &= ~(DwarfConstants.LINE_BasicBlock | DwarfConstants.LINE_PrologueEnd | DwarfConstants.LINE_EpilogueBegin); + } else if (opcode == 0) { + long op_size = read_unsigned_leb128(data); + long op_pos = data.position(); + int code = data.get() & 0xff; + switch (code) { + case DwarfConstants.DW_LNE_define_file: { + fileName = readString(data); + long dir = read_unsigned_leb128(data); + long modTime = read_unsigned_leb128(data); + long fileSize = read_unsigned_leb128(data); + IPath fullPath = fileHelper.normalizeFilePath(dirList.get((int) dir), fileName); + if (fullPath != null) { + fileList.add(fullPath); + } + break; + } + case DwarfConstants.DW_LNE_end_sequence: + info_flags |= DwarfConstants.LINE_EndSequence; + + if (lineEntries.size() > 0) { + // this just marks the end of a line number + // program sequence. use + // its address to set the high address of the + // last line entry + lineEntries.get(lineEntries.size() - 1).setHighAddress(new Addr32(info_address)); + } + + // it also resets the state machine + info_address = 0; + info_file = 1; + info_line = 1; + info_column = 0; + is_stmt = default_is_stmt; + info_flags = 0; + info_ISA = 0; + break; + + case DwarfConstants.DW_LNE_set_address: + info_address = data.getInt(); + break; + default: + data.position((int) (data.position() + op_size - 1)); + break; + } + assert (data.position() == op_pos + op_size); + } else { + switch (opcode) { + case DwarfConstants.DW_LNS_copy: + if (is_stmt && fileList.size() > 0) { + lineEntries.add(new LineEntry(fileList.get((int) info_file - 1), info_line, + info_column, new Addr32(info_address), null)); + } + info_flags &= ~(DwarfConstants.LINE_BasicBlock | DwarfConstants.LINE_PrologueEnd | DwarfConstants.LINE_EpilogueBegin); + break; + case DwarfConstants.DW_LNS_advance_pc: + info_address += read_unsigned_leb128(data) * minimum_instruction_length; + break; + case DwarfConstants.DW_LNS_advance_line: + info_line += read_signed_leb128(data); + break; + case DwarfConstants.DW_LNS_set_file: + info_file = read_unsigned_leb128(data); + break; + case DwarfConstants.DW_LNS_set_column: + info_column = (int) read_unsigned_leb128(data); + break; + case DwarfConstants.DW_LNS_negate_stmt: + is_stmt = !is_stmt; + break; + case DwarfConstants.DW_LNS_set_basic_block: + info_flags |= DwarfConstants.LINE_BasicBlock; + break; + case DwarfConstants.DW_LNS_const_add_pc: + info_address += (255 - opcode_base) / line_range * minimum_instruction_length; + break; + case DwarfConstants.DW_LNS_fixed_advance_pc: + info_address += data.getShort(); + break; + case DwarfConstants.DW_LNS_set_prologue_end: + info_flags |= DwarfConstants.LINE_PrologueEnd; + break; + case DwarfConstants.DW_LNS_set_epilogue_begin: + info_flags |= DwarfConstants.LINE_EpilogueBegin; + break; + case DwarfConstants.DW_LNS_set_isa: + info_ISA = read_unsigned_leb128(data); + break; + default: + break; + } + } + } + } + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(null, t); + } + + // sort by start address + Collections.sort(lineEntries); + + // fill in the end addresses as needed + ILineEntry previousEntry = null; + for (ILineEntry line : lineEntries) { + if (previousEntry != null && previousEntry.getHighAddress() == null) { + previousEntry.setHighAddress(line.getLowAddress()); + } + + previousEntry = line; + } + + // the last line entry + if (previousEntry != null) { + IAddress prevHigh = previousEntry.getHighAddress(); + if (prevHigh == null) + previousEntry.setHighAddress(scope.getHighAddress()); +// FIXME: the following is causing JUnit tests to fail +// else if (prevHigh != null && prevHigh.compareTo(scope.getHighAddress()) > 0) +// previousEntry.setHighAddress(scope.getHighAddress()); + } + + return lineEntries; + } + } + + private void parseForAddresses(IStreamBuffer in, Map abbrevs, CompilationUnitHeader header, + Stack nestingStack, IProgressMonitor monitor) + throws IOException { + + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().trace(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceScopeAddressParse1 + header.scope.getName() + DwarfMessages.DwarfInfoReader_TraceScopeAddressParse2 + Long.toHexString(header.debugInfoOffset))); } + + try { + long startWork = in.remaining(); + long lastWork = startWork; + int workChunk = (int)(startWork / Integer.MAX_VALUE) + 1; + int work = (int)(startWork / workChunk); + monitor.beginTask(DwarfMessages.DwarfInfoReader_TraceScopeAddressParse1 + header.scope.getName() + DwarfMessages.DwarfInfoReader_TraceScopeAddressParse2 + Long.toHexString(header.debugInfoOffset), work); + + while (in.remaining() > 0) { + + work = (int)((lastWork - in.remaining()) / workChunk); + monitor.worked(work); + lastWork = in.remaining(); + + long offset = in.position() + currentCUHeader.debugInfoOffset; + long code = read_unsigned_leb128(in); + + if (code != 0) { + AbbreviationEntry entry = abbrevs.get(new Long(code)); + if (entry == null) { + assert false; + continue; + } + + if (entry.hasChildren) { + nestingStack.push(currentParentScope); + } + + if (isDebugInfoEntryWithAddressRange(entry.tag)) { + AttributeList attributeList = new AttributeList(entry, in, header.addressSize, getDebugStrings()); + processDebugInfoEntry(offset, entry, attributeList, header); + + // if we didn't create a scope for a routine or lexical block, then ignore its innards + switch (entry.tag) { + case DwarfConstants.DW_TAG_subprogram: + case DwarfConstants.DW_TAG_inlined_subroutine: + case DwarfConstants.DW_TAG_lexical_block: + if (entry.hasChildren && (provider.scopesByOffset.get(offset) == null)) { + // because some versions of GCC-E 3.x produce invalid sibling offsets, + // always read entry attributes, rather than skipping using siblings + // keep track of nesting just like in parseForTypes() + int nesting = 1; + while ((nesting > 0) && (in.remaining() > 0)) { + offset = in.position() + currentCUHeader.debugInfoOffset; + code = read_unsigned_leb128(in); + + if (code != 0) { + entry = abbrevs.get(new Long(code)); + if (entry == null) { + assert false; + continue; + } + if (entry.hasChildren) + nesting++; + // skip the attributes we're not reading... + AttributeList.skipAttributes(entry, in, header.addressSize); + } else { + nesting--; + } + } + + // nesting loop ends after reading 0 code of skipped entry + if (nestingStack.isEmpty()) { + // FIXME + currentParentScope = null; + } else { + currentParentScope = nestingStack.pop(); + } + } + break; + } + } else { + // skip the attributes we're not reading... + AttributeList.skipAttributes(entry, in, header.addressSize); + } + + } else { + if (code == 0) { + if (nestingStack.isEmpty()) { + // FIXME + currentParentScope = null; + } else { + currentParentScope = nestingStack.pop(); + } + } + } + } + } catch (IOException e) { + throw e; + } finally { + monitor.done(); + } + } + + + private void parseForTypes(IStreamBuffer in, Map abbrevs, CompilationUnitHeader header, + Stack nestingStack) + throws IOException { + + if (EDCTrace.SYMBOL_READER_TRACE_ON) { EDCTrace.getTrace().trace(null, EDCTrace.fixArg(DwarfMessages.DwarfInfoReader_TraceParseTypes1 + header.scope.getName() + DwarfMessages.DwarfInfoReader_TraceParseTypes2 + Long.toHexString(header.debugInfoOffset))); } + + Stack typeStack = new Stack(); + typeToParentMap.clear(); + + currentParentScope = currentCompileUnitScope; + + while (in.remaining() > 0) { + long offset = in.position() + currentCUHeader.debugInfoOffset; + long code = read_unsigned_leb128(in); + + if (code != 0) { + AbbreviationEntry entry = abbrevs.get(new Long(code)); + if (entry == null) { + assert false; + continue; + } + if (entry.hasChildren) { + nestingStack.push(currentParentScope); + typeStack.push(currentParentType); + } + + if (isForwardTypeTag(entry.tag) || isForwardTypeChildTag(entry.tag)) { + + processDebugInfoEntry(offset, entry, + new AttributeList(entry, in, header.addressSize, getDebugStrings()), + header); + + } else { + switch (entry.tag) { + case DwarfConstants.DW_TAG_subprogram: + case DwarfConstants.DW_TAG_inlined_subroutine: + case DwarfConstants.DW_TAG_lexical_block: { + Scope scope = provider.scopesByOffset.get(offset); // may be null + if (scope != null) + currentParentScope = scope; + break; + } + } + + // skip the attributes we're not reading... + AttributeList.skipAttributes(entry, in, header.addressSize); + } + } else { + // code == 0 + if (nestingStack.isEmpty()) { + // FIXME + currentParentType = null; + currentParentScope = null; + } else { + currentParentScope = nestingStack.pop(); + currentParentType = typeStack.pop(); + } + } + } + } + + /** + * Tell if a tag will be parsed on-demand to generate an IType, and will + * be accessible via provider.getType() or provider.readType(). + *

    + * Note: DW_TAG_member is usually considered a child of struct/class/etc., but + * a static class variable contains a reference to it, so we must be able to + * locate it. + * @param tag + * @return true if type is parsed and should have a ForwardDwarfDefinition + */ + private boolean isForwardTypeTag(short tag) { + switch (tag) { + case DwarfConstants.DW_TAG_array_type: + case DwarfConstants.DW_TAG_class_type: + case DwarfConstants.DW_TAG_enumeration_type: + case DwarfConstants.DW_TAG_member: + case DwarfConstants.DW_TAG_pointer_type: + case DwarfConstants.DW_TAG_reference_type: + case DwarfConstants.DW_TAG_structure_type: + case DwarfConstants.DW_TAG_subroutine_type: + case DwarfConstants.DW_TAG_typedef: + case DwarfConstants.DW_TAG_union_type: + //case DwarfConstants.DW_TAG_unspecified_parameters: + case DwarfConstants.DW_TAG_inheritance: + case DwarfConstants.DW_TAG_ptr_to_member_type: + //case DwarfConstants.DW_TAG_with_stmt: + case DwarfConstants.DW_TAG_base_type: + //case DwarfConstants.DW_TAG_catch_block: + case DwarfConstants.DW_TAG_const_type: + //case DwarfConstants.DW_TAG_enumerator: + //case DwarfConstants.DW_TAG_file_type: + //case DwarfConstants.DW_TAG_friend: + case DwarfConstants.DW_TAG_template_type_param: + //case DwarfConstants.DW_TAG_template_value_param: + //case DwarfConstants.DW_TAG_thrown_type: + //case DwarfConstants.DW_TAG_try_block: + case DwarfConstants.DW_TAG_volatile_type: + case DwarfConstants.DW_TAG_subrange_type: + return true; + } + return false; + } + + + /** + * Tell if a tag is a parsed child of an IType. This should not be explicitly + * referenced in provider.typesByOffset or .forwardDwarfDefinitions but as + * children of other ForwardDwarfDefinitions parsed on demand. + *

    + * Note: DW_TAG_member is usually considered a child of struct/class/etc., but + * a static class variable contains a reference to it, so we must be able to + * locate it. Thus, it is not listed here. + * @param tag + * @return true if component is parsed and a child of a forward definition + */ + private boolean isForwardTypeChildTag(short tag) { + switch (tag) { + //case DwarfConstants.DW_TAG_unspecified_parameters: + case DwarfConstants.DW_TAG_inheritance: + case DwarfConstants.DW_TAG_enumerator: + case DwarfConstants.DW_TAG_member: + case DwarfConstants.DW_TAG_subrange_type: + //case DwarfConstants.DW_TAG_friend: + //case DwarfConstants.DW_TAG_template_type_param: + //case DwarfConstants.DW_TAG_template_value_param: + //case DwarfConstants.DW_TAG_thrown_type: + return true; + } + return false; + } + /** + * Fully parse any debug info entry. + * @param offset + * @param entry + * @param attributeList + * @param header + * @param compositeNesting + */ + private void processDebugInfoEntry(long offset, AbbreviationEntry entry, AttributeList attributeList, + CompilationUnitHeader header) { + //System.out.println("Handling " + entry.tag + " at " + Long.toHexString(offset)); + short tag = entry.tag; + + // We are only interested in certain tags. + switch (tag) { + case DwarfConstants.DW_TAG_array_type: + processArrayType(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_class_type: + processClassType(offset, attributeList, header, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_enumeration_type: + processEnumType(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_formal_parameter: + processVariable(offset, attributeList, true); + break; + case DwarfConstants.DW_TAG_lexical_block: + processLexicalBlock(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_member: + processField(offset, attributeList, header, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_pointer_type: + processPointerType(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_reference_type: + processReferenceType(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_structure_type: + processStructType(offset, attributeList, header, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_subroutine_type: + processSubroutineType(offset, attributeList, header, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_typedef: + processTypeDef(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_union_type: + processUnionType(offset, attributeList, header, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_unspecified_parameters: + break; + case DwarfConstants.DW_TAG_inheritance: + processInheritance(offset, attributeList, header, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_ptr_to_member_type: + processPtrToMemberType(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_with_stmt: + break; + case DwarfConstants.DW_TAG_base_type: + processBasicType(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_catch_block: + break; + case DwarfConstants.DW_TAG_const_type: + processConstType(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_enumerator: + processEnumerator(offset, attributeList); + break; + case DwarfConstants.DW_TAG_file_type: + break; + case DwarfConstants.DW_TAG_friend: + break; + case DwarfConstants.DW_TAG_subprogram: + processSubprogram(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_inlined_subroutine: + processInlinedSubroutine(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_template_type_param: + processTemplateTypeParam(offset, attributeList, header, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_template_value_param: + break; + case DwarfConstants.DW_TAG_thrown_type: + break; + case DwarfConstants.DW_TAG_try_block: + break; + case DwarfConstants.DW_TAG_variable: + processVariable(offset, attributeList, false); + break; + case DwarfConstants.DW_TAG_volatile_type: + processVolatileType(offset, attributeList, entry.hasChildren); + break; + case DwarfConstants.DW_TAG_subrange_type: + processArrayBoundType(offset, attributeList, entry.hasChildren); + break; + } + } + + /** + * Tell whether a tag has or may have content with an address range + * + * Note: tag DW_TAG_compile_unit was parsed in the initial parse + * + * @param tag + * @return + */ + private boolean isDebugInfoEntryWithAddressRange(short tag) { + switch (tag) { + // tags allowed to have both DW_AT_low_pc and DW_AT_high_pc or DW_at_ranges + case DwarfConstants.DW_TAG_catch_block: + case DwarfConstants.DW_TAG_inlined_subroutine: + case DwarfConstants.DW_TAG_lexical_block: + case DwarfConstants.DW_TAG_module: + case DwarfConstants.DW_TAG_partial_unit: + case DwarfConstants.DW_TAG_subprogram: + case DwarfConstants.DW_TAG_try_block: + case DwarfConstants.DW_TAG_with_stmt: + return true; + // TODO: take DW_TAG_variable out of here? + case DwarfConstants.DW_TAG_variable: + case DwarfConstants.DW_TAG_formal_parameter: + return true; + } + return false; + } + //TODO: support DWARF 64-bit format + static long readAddress(IStreamBuffer in, int addressSize) throws IOException { + long value = 0; + + switch (addressSize) { + case 2: + value = in.getShort(); + break; + case 4: + value = in.getInt(); + break; + case 8: + value = in.getLong(); + break; + default: + // ???? + } + return value; + } + + + /* unsigned */ + static long read_unsigned_leb128(IStreamBuffer in) throws IOException { + /* unsigned */ + long result = 0; + int shift = 0; + byte b; + + while (true) { + if (!in.hasRemaining()) + break; // throw new IOException("no more data"); + b = in.get(); + result |= ((long) (b & 0x7f) << shift); + if ((b & 0x80) == 0) { + break; + } + shift += 7; + } + return result; + } + + /* signed */ + public static long read_signed_leb128(IStreamBuffer in) throws IOException { + /* unsigned */ + long result = 0; + int shift = 0; + int size = 32; + byte b; + + while (true) { + if (!in.hasRemaining()) + throw new IOException(CCorePlugin.getResourceString("Util.exception.noData")); //$NON-NLS-1$ + b = in.get(); + result |= ((long) (b & 0x7f) << shift); + shift += 7; + if ((b & 0x80) == 0) { + break; + } + } + if ((shift < size) && (b & 0x40) != 0) { + result |= -(1 << shift); + } + return result; + } + + + /** + * Read a null-ended string from the given "data" stream. data : IN, byte + * buffer + */ + public static String readString(IStreamBuffer data) { + String str; + + StringBuilder sb = new StringBuilder(); + while (data.hasRemaining()) { + byte c = data.get(); + if (c == 0) { + break; + } + sb.append((char) c); + } + + str = sb.toString(); + return str; + } + + private Collection getLocationRecord(long offset) { + // first check the cache + Collection entries = locationEntriesByOffset.get(offset); + if (entries == null) { + // not found so try to get the entries from the offset + + // note: some compilers generate MULTIPLE ENTRIES for the same location, + // and the last one tends to be more correct... use a map here when reading + TreeMap entryMap = new TreeMap(); + + try { + IStreamBuffer data = getDwarfSection(DWARF_DEBUG_LOC); + if (data != null) { + data.position(offset); + + boolean first = true; + long base = 0; + + while (data.hasRemaining()) { + + long lowPC = readAddress(data, currentCUHeader.addressSize); + long highPC = readAddress(data, currentCUHeader.addressSize); + + if (lowPC == 0 && highPC == 0) { + // end of list entry + break; + } else if (first) { + first = false; + long maxaddress = currentCUHeader.addressSize == 4 ? Integer.MAX_VALUE : Long.MAX_VALUE; + if (lowPC == maxaddress) { + // base address selection entry + base = highPC; + continue; + } else if (currentCompileUnitScope.getRangeList() == null) { + // if the compilation unit has a contiguous range, no implicit base is needed + base = currentCompileUnitScope.getLowAddress().getValue().longValue(); + } + } + + // location list entry + int numOpCodes = data.getShort(); + byte[] bytes = new byte[numOpCodes]; + data.get(bytes); + LocationEntry entry = new LocationEntry(lowPC + base, highPC + base, bytes); + entryMap.put(new IRangeList.Entry(lowPC + base, highPC + base), entry); + } + + entries = entryMap.values(); + locationEntriesByOffset.put(offset, entries); + } + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(null, t); + } + } + + return entries; + } + + + private Map parseDebugAbbreviation(int abbreviationOffset) throws IOException { + Integer key = Integer.valueOf(abbreviationOffset); + Map abbrevs = provider.abbreviationMaps.get(key); + if (abbrevs == null) { + abbrevs = new HashMap(); + provider.abbreviationMaps.put(key, abbrevs); + IStreamBuffer data = getDwarfSection(DWARF_DEBUG_ABBREV); + if (data != null) { + data.position(abbreviationOffset); + while (data.remaining() > 0) { + long code = read_unsigned_leb128(data); + if (code == 0) { + break; + } + short tag = (short) read_unsigned_leb128(data); + boolean hasChildren = data.get() == DwarfConstants.DW_CHILDREN_yes; + AbbreviationEntry entry = new AbbreviationEntry(code, tag, hasChildren); + + // attributes + short name = 0; + byte form = 0; + do { + name = (short) read_unsigned_leb128(data); + form = (byte) read_unsigned_leb128(data); + if (name != 0) { + entry.attributes.add(new Attribute(name, form)); + } + } while (name != 0 && form != 0); + entry.attributes.trimToSize(); + + abbrevs.put(Long.valueOf(code), entry); + } + } + } + return abbrevs; + } + + + private void registerType(long offset, IType type, boolean hasChildren) { + provider.typesByOffset.put(offset, type); + + typeToParentMap.put(type, currentParentType); + if (hasChildren) + currentParentType = type; + if (DEBUG) { + if (type != null) { + System.out.print(DwarfMessages.DwarfInfoReader_ReadType + type.getName()); + while (type.getType() != null) { + type = type.getType(); + System.out.print(" " + type.getName()); //$NON-NLS-1$ + } + System.out.println(); + } + } + } + + private void registerScope(long offset, Scope scope) { + provider.scopesByOffset.put(offset, scope); + } + + /** + * Read a range list referenced from a code scope. + * @param offset + * @param base the specified DW_AT_low_pc value (or 0) + * @return a new RangeList + */ + public RangeList readRangeList(int offset, AttributeValue baseValue) { + synchronized (provider) { + IStreamBuffer data = getDwarfSection(DWARF_DEBUG_RANGES); + if (data == null) { + return null; + } + + try { + data.position(offset); + + /* + * Read range list entry: + * + * start: DW_FORM_addr + * end: DW_FORM_addr + * + * When start == all ones, it is a base address selection entry, + * and end is the base address. The base address does not need to + * be specified, and is the compialtion unit's base address by default. + * + * When start == end == 0, this is the end of the list. + */ + + RangeList list = new RangeList(); + + long base = 0; + long start = data.getInt(); + long end = data.getInt(); + + if (start == -1) { + base = end; + + start = data.getInt(); + end = data.getInt(); + } else if (baseValue != null) { + base = baseValue.getValueAsLong(); + } else if (currentCompileUnitScope != null && currentCompileUnitScope.getRangeList() == null) { + base = currentCompileUnitScope.getLowAddress().getValue().longValue(); + } + do { + if (start == 0 && end == 0) { + break; + } else if (start != end) { + // ignore bogus entries: GCC-E sometimes generates these buggily (for artifical non-inlined functions) + if (base + start >= codeRanges.getLowAddress()) { + list.addRange(base + start, base + end); + } + } + start = data.getInt(); + end = data.getInt(); + + } while (true); + + return list; + + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfInfoReader_RangeReadFailed, t); + return null; + } + } + } + + + + /** + * Set up the address range for a scope by using its DW_AT_low_pc/DW_AT_high_pc + * or DW_AT_ranges attributes, or DW_AT_stmt_list in a pinch + * @param attributeList + * @param scope + */ + private void setupAddresses(AttributeList attributeList, Scope scope) { + + // get the high and low pc from the attributes list + AttributeValue value + = attributeList.getAttribute(DwarfConstants.DW_AT_high_pc); + if (value != null) { + IAddress low = new Addr32(attributeList.getAttributeValueAsLong(DwarfConstants.DW_AT_low_pc)); + scope.setLowAddress(low); + IAddress high = new Addr32(attributeList.getAttributeValueAsLong(DwarfConstants.DW_AT_high_pc)); + IScope parent = scope.getParent(); + if (low.compareTo(high) <= 0) { + if (parent instanceof DwarfFunctionScope) { + IAddress parentHigh = parent.getHighAddress(); + if (parentHigh != null && high.compareTo(parentHigh) > 0) { + ((Scope)parent).setHighAddress(high); + } + } + } else { + // relying on the following to confirm that this is an RVCT inline DWARF generation bug + if (scope instanceof DwarfFunctionScope && parent instanceof DwarfFunctionScope) { + high = fix_Dwarf_InlineHighAddress_Problem(scope); + if (high == null) + // at least prevent ecl.bz Bug 329324 from happening + high = parent.getHighAddress(); + + // wow, RVCT, you're neat... I think you mean, point to the high PC of the parent + } else if (parent != null && parent.getHighAddress() != null) { + high = parent.getHighAddress(); + // may still be bogus, check again next + } + + if (low.compareTo(high) > 0) { + scope.setLowAddress(high); + high = low; + } + } + scope.setHighAddress(high); + return; + } + + // look for a range + value = attributeList.getAttribute(DwarfConstants.DW_AT_ranges); + if (value != null) { + AttributeValue baseValue = attributeList.getAttribute(DwarfConstants.DW_AT_low_pc); + RangeList ranges = readRangeList(value.getValueAsInt(), baseValue); + if (ranges != null) { + scope.setRangeList(ranges); + + // if the range list high and low pc extend outside the parent's + // high/low range, adjust the parent (found in GCC-E) + if (ranges.getLowAddress() < scope.getParent().getLowAddress().getValue().longValue()) { + if (scope.getParent() instanceof Scope) + ((Scope)scope.getParent()).setLowAddress(new Addr32(ranges.getLowAddress())); + } + if (ranges.getHighAddress() > scope.getParent().getHighAddress().getValue().longValue()) { + if (scope.getParent() instanceof Scope) + ((Scope)scope.getParent()).setHighAddress(new Addr32(ranges.getHighAddress())); + } + return; + } + } + + // in a CU, GCC-E may have only generated this, so we need to dig into the line table + if (scope instanceof ICompileUnitScope) { + value = attributeList.getAttribute(DwarfConstants.DW_AT_stmt_list); + if (value != null) { + RangeList ranges = new RangeList(); + for (ILineEntry entry : ((ICompileUnitScope) scope).getLineEntries()) { + // ignore (for now) entries that seem far out of range + if (entry.getLowAddress().getValue().longValue() >= codeRanges.getLowAddress()) { + ranges.addRange(entry.getLowAddress().getValue().longValue(), + entry.getHighAddress().getValue().longValue()); + } + } + scope.setRangeList(ranges); + return; + } + } + + // no code, apparently + scope.setLowAddress(new Addr32(0)); + scope.setHighAddress(new Addr32(0)); + } + + /** + * for cases where the compiler generates an incorrect high-address, + * the line entry provider can give information about the current and + * subsequent lines within an inline. + *
    + * caveats: this is not meant to handle nested broken inlines. the + * algorithm assumes + * - an outer inline nesting another inline will use set of ranges, not a high-low + * - an inline function will likely be in another file + * - if not, it will likely be prior to the function that inlines it + * - and if not, it will likely be more than 32 lines after the function that inlines it + * @param scope + * @return high address if determined, or null if prerequisites for finding it aren't met. + */ + private IAddress fix_Dwarf_InlineHighAddress_Problem(Scope scope) { + IAddress low = scope.getLowAddress(); + IAddress highest = scope.getParent().getHighAddress(); + Iterator lineEntries + = currentCompileUnitScope.getLineEntries().iterator(); + + ILineEntry entry; + do { + entry = lineEntries.next(); + if (entry == null) + return null; + } while (low.compareTo(entry.getHighAddress()) > 0); + + IAddress high = null; + IPath actualPath = entry.getFilePath(), otherPath = null; + int actualLine = entry.getLineNumber(); + int thisLine = actualLine, lastLine = 0; // XXX false positive on uninitialized variable below causes needless initialization of lastLine = 0 + boolean jumpedBack = false, jumpedAway = false; + OUTER:do { + IAddress nextHigh = entry.getHighAddress(); + if (highest != null && nextHigh != null && highest.compareTo(nextHigh) < 0) { + nextHigh = entry.getLowAddress(); + if (high == null || nextHigh.compareTo(high) < 0) + high = nextHigh; + break; + } + high = nextHigh; + if (!jumpedAway && otherPath == null) + lastLine = thisLine; + + if (high == null) + break OUTER; + + do { + entry = lineEntries.next(); + if (entry == null) + break OUTER; + } while (high.equals(entry.getHighAddress())); + + if (otherPath != null) { + if (entry.getFilePath().equals(actualPath)) // done with nesting + break; + } else if (!entry.getFilePath().equals(actualPath)) {// easiest test for done with inline + otherPath = entry.getFilePath(); + } else { + thisLine = entry.getLineNumber(); + if (!jumpedBack && !jumpedAway) { + if (thisLine < actualLine) { + jumpedBack = true; + } else if (thisLine > lastLine + 24) { // XXX false positive here causes needless init of lastLine = 0 above + jumpedAway = true; + } + } else if (jumpedBack) { + if (thisLine > actualLine) // jumped back ahead; done + break; + } else if (jumpedAway) { + if (thisLine < actualLine + || thisLine < lastLine + || thisLine > lastLine + 24) + break; + } + } + } while (entry != null); + + return high; + } + + /** + * Process a compile unit + * + * @param attributeList + * @param childrenPosition + */ + private void processCompileUnit(CompilationUnitHeader header, boolean hasChildren, AttributeList attributeList) { + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + String compDir = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_comp_dir); + //System.out.println("processing compile unit: " + Integer.toHexString(header.debugInfoOffset) + ": " + name); + + IPath filePath = fileHelper.normalizeFilePath(compDir, name); + + currentCompileUnitScope = new DwarfCompileUnit(provider, moduleScope, filePath, null, null, header, hasChildren, attributeList); + header.scope = currentCompileUnitScope; + currentParentScope = currentCompileUnitScope; + + setupAddresses(attributeList, currentCompileUnitScope); + + // some compilers (RVCT) may generate multiple compile units for the + // same file. + List matchingCompileUnits = provider.compileUnitsPerFile.get(filePath); + + if (matchingCompileUnits == null) { + // first one. create it now. + matchingCompileUnits = new ArrayList(); + } + + matchingCompileUnits.add(currentCompileUnitScope); + provider.compileUnitsPerFile.put(filePath, matchingCompileUnits); + provider.compileUnits.add(currentCompileUnitScope); + + if (!currentCompileUnitScope.getHighAddress().isZero()) // has code + provider.sortedCompileUnitsWithCode.add(currentCompileUnitScope); + + moduleScope.addChild(currentCompileUnitScope); + + provider.registerCompileUnitHeader(currentCUHeader.debugInfoOffset, currentCUHeader); + + if (provider.buildReferencedFilesList) { + provider.referencedFiles.add(filePath.toOSString()); + + // do a quick parse of the line table to get any other referenced files. + // note that even the full parse doesn't parse the line table information. + // that is calculated (and then cached) on demand + AttributeValue a = attributeList.getAttribute(DwarfConstants.DW_AT_stmt_list); + if (a != null) { + int stmtList = a.getValueAsInt(); + quickParseLineInfo(stmtList, compDir); + } + } + + // remove unused attributes + attributeList.attributeMap.remove(DwarfConstants.DW_AT_name); + //attributeList.attributeMap.remove(DwarfConstants.DW_AT_comp_dir); // needed later + attributeList.attributeMap.remove(DwarfConstants.DW_AT_low_pc); + attributeList.attributeMap.remove(DwarfConstants.DW_AT_high_pc); + attributeList.attributeMap.remove(DwarfConstants.DW_AT_ranges); + } + + private void processLexicalBlock(long offset, AttributeList attributeList, boolean hasChildren) { + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + + if (!attributeList.hasCodeRangeAttributes()) { + // ignore any that don't have a valid range + return; + } + + LexicalBlockScope lb = new LexicalBlockScope(name, currentParentScope, null, null); + setupAddresses(attributeList, lb); + + currentParentScope.addChild(lb); + registerScope(offset, lb); + if (hasChildren) + currentParentScope = lb; + } + + static class DereferencedAttributes { + public CompilationUnitHeader header; + public AttributeList attributeList; + + public DereferencedAttributes(CompilationUnitHeader header, + AttributeList attributeList) { + this.header = header; + this.attributeList = attributeList; + } + + } + + /** + * DW_AT_abstract_origin and DW_AT_specification can refer to types in other + * compilation units. This will dynamically parse that CU if needed in order + * to get the attributes for the type. + * + * @param debugInfoOffset + * @return AttributeList or null (should not happen) + */ + private DereferencedAttributes getDereferencedAttributes(AttributeList attributeList, short tag) { + CompilationUnitHeader providingCU = currentCUHeader; + AttributeValue derefLocation = attributeList.getAttribute(tag); + if (derefLocation == null) + return null; + + // get the offset into the .debug_info section + long debugInfoOffset = derefLocation.getValueAsLong(); + if (derefLocation.getActualForm() == DwarfConstants.DW_FORM_ref_addr) { + // this is already relative to the .debug_info section + } else { + // relative to the CU + debugInfoOffset += providingCU.debugInfoOffset; + } + + AttributeList attributes = provider.functionsByOffset.get(debugInfoOffset); + if (attributes == null) { + // dereferenced function does not exist yet + providingCU = provider.fetchCompileUnitHeader(debugInfoOffset); + attributes = provider.functionsByOffset.get(debugInfoOffset); + if (attributes == null) { + // dereferenced entry is not parsed yet, perhaps because it's + // later in the current compile unit (despite Dwarf 3 spec saying + // that's not allowed) + IStreamBuffer buffer = getDwarfSection(DWARF_DEBUG_INFO); + + if (buffer != null) { + buffer.position(debugInfoOffset); + + try { + // get stored abbrev table, or read and parse an abbrev table + Map abbrevs = parseDebugAbbreviation(providingCU.abbreviationOffset); + + long code = read_unsigned_leb128(buffer); + + if (code != 0) { + AbbreviationEntry entry = abbrevs.get(new Long(code)); + if (entry != null) { + attributes = new AttributeList(entry, buffer, providingCU.addressSize, getDebugStrings()); + } + } + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfInfoReader_ParseDebugInfoSectionFailed1 + + debugInfoSection.getName() + DwarfMessages.DwarfInfoReader_ParseDebugInfoSectionFailed2 + symbolFilePath, t); + } + } + } + } else { + providingCU = provider.fetchCompileUnitHeader(debugInfoOffset); + if (providingCU == null) { + assert(false); + return null; + } + } + + if (attributes == null) + return null; + + return new DereferencedAttributes(providingCU, attributes); + } + + private void processSubprogram(long offset, AttributeList attributeList, boolean hasChildren) { + // if it's a declaration just add to the offsets map for later lookup + if (attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_declaration) > 0) { + provider.functionsByOffset.put(offset, attributeList); + return; + } + + // functions with no high/low pc aren't real functions. just treat them + // as declarations as they will be pointed to by abstract_origin from + // another subprogram tag + if (!attributeList.hasCodeRangeAttributes()) { + provider.functionsByOffset.put(offset, attributeList); + return; + } + + CompilationUnitHeader otherCU = null; + + boolean isArtificial = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_artificial) > 0; + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + if (name.length() == 0) { + // no name. see if we can get it from a declaration + DereferencedAttributes deref = getDereferencedAttributes(attributeList, DwarfConstants.DW_AT_abstract_origin); + if (deref != null) { + // this should either have a name or point to another + // declaration + otherCU = deref.header; + AttributeList attributes = deref.attributeList; + name = attributes.getAttributeValueAsString(DwarfConstants.DW_AT_name); + isArtificial |= attributes.getAttributeValueAsInt(DwarfConstants. DW_AT_artificial) > 0; + if (name.length() == 0) { + deref = getDereferencedAttributes(attributes, DwarfConstants.DW_AT_specification); + if (deref != null) { + // this should either have a name or point to another + // declaration + otherCU = deref.header; + attributes = deref.attributeList; + name = attributes.getAttributeValueAsString(DwarfConstants.DW_AT_name); + isArtificial |= attributes.getAttributeValueAsInt(DwarfConstants. DW_AT_artificial) > 0; + } + } + } + } + if (name.length() == 0) { + DereferencedAttributes deref = getDereferencedAttributes(attributeList, DwarfConstants.DW_AT_specification); + if (deref != null) { + // this should either have a name or point to another + // declaration + otherCU = deref.header; + AttributeList attributes = deref.attributeList; + name = attributes.getAttributeValueAsString(DwarfConstants.DW_AT_name); + } + } + + if (name.length() == 0) { + // the name should either be an attribute of the compile unit, or be + // in the declaration which according to the spec will always be + // before its definition in the Dwarf. + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfInfoReader_SubprogramNameNotFound1 + Long.toHexString(offset) + + DwarfMessages.DwarfInfoReader_SubprogramNameNotFound2, null); + return; + } + + DwarfFunctionScope function = new DwarfFunctionScope(name, currentCompileUnitScope, null, null, null); + setupAddresses(attributeList, function); + + Scope originalParentScope = currentParentScope; + registerScope(offset, function); + currentParentScope = function; // needed for getLocationProvider(), etc. + + AttributeValue frameBaseAttribute = attributeList.getAttribute(DwarfConstants.DW_AT_frame_base); + ILocationProvider locationProvider = getLocationProvider(frameBaseAttribute); + function.setLocationProvider(locationProvider); + + // Note: we may still have cases where DW_AT_low_pc and/or DW_AT_high_pc are 0x0 + // (some "ignored inlined" functions in GCC). We want to keep track of their scope + // (though not store them in the CU), because child tag parses expect to find a parent into + // which to write their formal parameters and locals. + if (!function.getLowAddress().isZero() && !function.getHighAddress().isZero() && !isArtificial) { + // find the declaration location + int declLine = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_decl_line); + int declColumn = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_decl_column); + int declFileNum = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_decl_file); + + if (otherCU != null) + function.setDeclFile(otherCU.scope.getFileEntry(declFileNum)); + else + function.setDeclFileNum(declFileNum); + function.setDeclLine(declLine); + function.setDeclColumn(declColumn); + + currentCompileUnitScope.addChild(function); + + // keep track of all functions by name for faster lookup + List functions = provider.functionsByName.get(name); + if (functions == null) { + functions = new ArrayList(); + provider.functionsByName.put(name, functions); + } + functions.add(function); + } + + // if the entry has no children, then restore the original parent scope + if (!hasChildren) + currentParentScope = originalParentScope; + } + + /** + * Get the already-parsed or forward reference to a type from a DW_AT_type attribute, if present + * @param attributeMap the map of Long, AttributeValue from AttributeList or Object, Object from Type + * @return offset to referenced type or 0 if no type attribute + */ + private IType getTypeOrReference(AttributeList attributeList, CompilationUnitHeader header) { + AttributeValue typeAttribute = attributeList.getAttribute(DwarfConstants.DW_AT_type); + if (typeAttribute == null) + return null; + return getTypeOrReference(typeAttribute, header); + } + /** + * Get the already-parsed or forward reference to a type from a DW_AT_type attribute, if present + * @param attributeMap the map of Long, AttributeValue from AttributeList or Object, Object from Type + * @return offset to referenced type or 0 if no type attribute + */ + private IType getTypeOrReference(AttributeValue typeAttribute, CompilationUnitHeader header) { + if (typeAttribute == null) + return null; + + // get the offset into the .debug_info section + long debugInfoOffset = typeAttribute.getValueAsLong(); + if (typeAttribute.getActualForm() == DwarfConstants.DW_FORM_ref_addr) { + // this is already relative to the .debug_info section + } else { + debugInfoOffset += header.debugInfoOffset; + } + + IType type = provider.typesByOffset.get(debugInfoOffset); + if (type == null) { + type = new ForwardTypeReference(provider, debugInfoOffset); + } + return type; + } + + private void processInlinedSubroutine(long offset, AttributeList attributeList, boolean hasChildren) { + // functions with no high/low pc aren't real (probably an error) + if (!attributeList.hasCodeRangeAttributes()) { + return; + } + + DereferencedAttributes deref = getDereferencedAttributes(attributeList, DwarfConstants.DW_AT_abstract_origin); + if (deref == null) { + if (attributeList.getAttribute(DwarfConstants.DW_AT_abstract_origin) != null) { + // TODO: GCC-E can reference forward tags (!) so we need to handle these another way + } else { + assert(false); + } + return; + } + + CompilationUnitHeader otherCU = deref.header; + AttributeList origAttributes = deref.attributeList; + + // this should either have a name or point to another + // declaration + String name = origAttributes.getAttributeValueAsString(DwarfConstants.DW_AT_name); + if (name.length() == 0) { + deref = getDereferencedAttributes(origAttributes, DwarfConstants.DW_AT_specification); + if (deref != null) { + // this should either have a name or point to another + // declaration + //otherCU = deref.header; + AttributeList declarationAttributes = deref.attributeList; + name = declarationAttributes.getAttributeValueAsString(DwarfConstants.DW_AT_name); + } + } + + if (name.length() == 0) { + // the name should either be an attribute of the compile unit, or be + // in the declaration which according to the spec will always be + // before its definition in the Dwarf. + return; + } + + // find the declaration location + int declLine = origAttributes.getAttributeValueAsInt(DwarfConstants.DW_AT_decl_line); + int declColumn = origAttributes.getAttributeValueAsInt(DwarfConstants.DW_AT_decl_column); + int declFileNum = origAttributes.getAttributeValueAsInt(DwarfConstants.DW_AT_decl_file); + + if (declFileNum == 0) { + assert(false); + return; + } + + DwarfFunctionScope function = new DwarfFunctionScope(name, currentParentScope, null, null, null); + setupAddresses(attributeList, function); + + function.setDeclFile(otherCU.scope.getFileEntry(declFileNum)); + function.setDeclLine(declLine); + function.setDeclColumn(declColumn); + + currentParentScope.addChild(function); + + registerScope(offset, function); + if (hasChildren) + currentParentScope = function; + + // keep track of all functions by name for faster lookup + List functions = provider.functionsByName.get(name); + if (functions == null) { + functions = new ArrayList(); + provider.functionsByName.put(name, functions); + } + functions.add(function); + } + + private void processSubroutineType(long offset, AttributeList attributeList, CompilationUnitHeader header, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + SubroutineType type = new SubroutineType(currentParentScope, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + + // TODO: associate parameters with this type in child tag parse + + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processClassType(long offset, AttributeList attributeList, CompilationUnitHeader header, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + + // if the name is mangled, unmangle it + name = unmangleType(name); + + // GCC may put the template parameter of an inherited class at the end of the name, + // so strip that off + // TODO: support template parameters at end of name or as separate DW_TAG_template_value_param + if (name.endsWith(">")) { + int templateStart = name.indexOf("<"); + if (templateStart != -1) + name = name.substring(0, templateStart); + } + + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + + ClassType type = new ClassType(name, currentParentScope, byteSize, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + storeTypeByName(name, type); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processStructType(long offset, AttributeList attributeList, CompilationUnitHeader header, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + + // if the name is mangled, unmangle it + name = unmangleType(name); + + StructType type = new StructType(name, currentParentScope, byteSize, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + storeTypeByName(name, type); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processUnionType(long offset, AttributeList attributeList, CompilationUnitHeader header, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + + // if the name is mangled, unmangle it + name = unmangleType(name); + + UnionType type = new UnionType(name, currentParentScope, byteSize, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + storeTypeByName(name, type); + + /* + * For an anonymous union, which has members accessible by methods in a class, ARM RVCT + * does not create an unnamed class member so you know the offset of the union's members. + * Instead, it just gives the anonymous union's type a name of the form "__C" followed + * by a number. And it places the union's DWARF info after all class member and inherited + * member DWARF info. + * + * E.g., when you have 2 named members and 2 anonymous unions in this order: + * 4-byte union + * 4-byte long long1 + * 4-byte union + * 4-byte long long2 + * ARM RVCT DWARF info says the class has 2 members: + * long1 at offset 4 + * long2 at offset 12 + * ARM RVCT DWARF info is in the order: + * member long1 + * member long2 + * type union + * type union + * So the rules for handling anonymous unions in RVCT DWARF are: + * 1st read offsets and sizes of non-anonymous members, which leaves offset holes + * for anonymous unions + * 2nd read anonymous union type info, which have compiler-generated names of + * "__C" following by a number, and assign unnamed members to offset holes + */ + boolean isRVCTAnonymousUnion = false; + try { + isRVCTAnonymousUnion = name.startsWith("__C") && (name.length() > 3) && //$NON-NLS-1$ + (name.charAt(3) != '-') && (Long.parseLong(name.substring(3)) > -1); + } catch (NumberFormatException nfe) {} + + // if needed, create an "unnamed" member field with an offset to be determined later + if (isRVCTAnonymousUnion && getCompositeParent(typeToParentMap.get(currentParentType)) != null) { + ICompositeType compositeType = getCompositeParent(typeToParentMap.get(currentParentType)); + + // unnamed member accessibility depends on the enclosing composite's type - + // public for a struct or union, private for a class + int accessibility = ICompositeType.ACCESS_PUBLIC; + if (compositeType instanceof ClassType) + accessibility = ICompositeType.ACCESS_PRIVATE; + + // empty field names confuse the expressions service + String fieldName = "$unnamed$" + (compositeType.fieldCount() + 1); //$NON-NLS-1$ + + // since we're generating a field, give it a -1 offset. We cannot tell the real + // offset until we determine offsets of all previously defined members - which + // may include inherited types not yet read in Dwarf info + FieldType fieldType = new FieldType(fieldName, currentParentScope, compositeType, -1, 0, 0, + byteSize, accessibility, null); + fieldType.setType(type); + + // add the member to the deepest nested (last added) compositeNesting + // member + compositeType.addField(fieldType); + registerType(offset, fieldType, false); + } + + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processInheritance(long offset, AttributeList attributeList, CompilationUnitHeader header, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + ICompositeType compositeType = getCompositeParent(); + + // The allowed attributes are DW_AT_type, DW_AT_data_member_location, + // and DW_AT_accessibility + long fieldsOffset = 0; + byte[] offsetBlock = attributeList.getAttributeValueAsBytes(DwarfConstants.DW_AT_data_member_location); + // unsigned LEB128 encoding + if (offsetBlock.length > 0 && offsetBlock[0] == DwarfConstants.DW_OP_plus_uconst) { + for (int i = 1, shift = 0; i < offsetBlock.length; i++) { + fieldsOffset += (offsetBlock[i] & 0x7f) << shift; + shift += 7; + } + } + + // default accessibility is private + int accessibility = ICompositeType.ACCESS_PRIVATE; + if (attributeList.getAttribute(DwarfConstants.DW_AT_accessibility) != null) { + accessibility = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_accessibility); + + if (accessibility == DwarfConstants.DW_ACCESS_public) + accessibility = ICompositeType.ACCESS_PUBLIC; + else if (accessibility == DwarfConstants.DW_ACCESS_private) + accessibility = ICompositeType.ACCESS_PRIVATE; + else + accessibility = ICompositeType.ACCESS_PROTECTED; + } + + InheritanceType type = new InheritanceType(currentParentScope, accessibility, fieldsOffset, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + + // add the member to the deepest nested (last added) compositeNesting + // member + if (compositeType != null) + compositeType.addInheritance(type); + + registerType(offset, type, hasChildren); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processField(long offset, AttributeList attributeList, CompilationUnitHeader header, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + + // GCC-E has fields like "_vptr.BaseClass" which will be a problem for us + // (since '.' is an operator); rename these here + name = name.replace('.', '$'); + + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + int bitSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_bit_size); + int bitOffset = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_bit_offset); + + long fieldOffset = 0; + byte[] offsetBlock = attributeList.getAttributeValueAsBytes(DwarfConstants.DW_AT_data_member_location); + // unsigned LEB128 encoding + if (offsetBlock.length > 0 && offsetBlock[0] == DwarfConstants.DW_OP_plus_uconst) { + for (int i = 1, shift = 0; i < offsetBlock.length; i++) { + fieldOffset += (offsetBlock[i] & 0x7f) << shift; + shift += 7; + } + } + + ICompositeType compositeType = getCompositeParent(); + + // default accessibility depends on the composite type - + // public for a struct or union, private for a class + int accessibility = ICompositeType.ACCESS_PUBLIC; + if (attributeList.getAttribute(DwarfConstants.DW_AT_accessibility) != null) { + accessibility = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_accessibility); + + if (accessibility == DwarfConstants.DW_ACCESS_public) + accessibility = ICompositeType.ACCESS_PUBLIC; + else if (accessibility == DwarfConstants.DW_ACCESS_private) + accessibility = ICompositeType.ACCESS_PRIVATE; + else + accessibility = ICompositeType.ACCESS_PROTECTED; + } else if (compositeType != null && compositeType instanceof ClassType) + accessibility = ICompositeType.ACCESS_PRIVATE; + + // Empty fields confuse the expressions service (#10369) + if (name.length() == 0) { + if (compositeType != null) { + name = "$unnamed$" + (compositeType.fieldCount() + 1); //$NON-NLS-1$ + } else { + name = "$unnamed$"; //$NON-NLS-1$ + } + } + + FieldType type = new FieldType(name, currentParentScope, compositeType, fieldOffset, bitSize, bitOffset, + byteSize, accessibility, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + // add the member to the deepest nested (last added) compositeNesting + // member + if (compositeType != null) + compositeType.addField(type); + registerType(offset, type, hasChildren); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processTemplateTypeParam(long offset, AttributeList attributeList, CompilationUnitHeader header, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + IType paramType = getTypeOrReference(attributeList.getAttribute(DwarfConstants.DW_AT_type), currentCUHeader); + + TemplateParamType type = new TemplateParamType(name, paramType); + + ICompositeType compositeType = getCompositeParent(); + + // add the template param to the deepest nested (last added) compositeNesting + // member + if (compositeType != null) + compositeType.addTemplateParam(type); + registerType(offset, type, hasChildren); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private ICompositeType getCompositeParent() { + return getCompositeParent(currentParentType); + } + + private ICompositeType getCompositeParent(IType parent) { + while (parent != null) { + if (parent instanceof ICompositeType) + return ((ICompositeType) parent); + parent = typeToParentMap.get(parent); + } + return null; + } + + private void processArrayType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + + ArrayType type = new ArrayType(name, currentParentScope, byteSize, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private IArrayType getArrayParent() { + IType parent = currentParentType; + while (parent != null) { + if (parent instanceof IArrayType) + return ((IArrayType) parent); + parent = typeToParentMap.get(parent); + } + return null; + } + + private void processArrayBoundType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + long arrayBound = 0; + if (attributeList.getAttribute(DwarfConstants.DW_AT_upper_bound) != null) + arrayBound = attributeList.getAttributeValueAsLong(DwarfConstants.DW_AT_upper_bound) + 1; + + ArrayBoundType type = new ArrayBoundType(currentParentScope, arrayBound); + + IArrayType array = getArrayParent(); + if (array == null) + throw new IllegalStateException(); + array.addBound(type); + + registerType(offset, type, hasChildren); + + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processReferenceType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + + if (byteSize == 0) + byteSize = currentCUHeader.addressSize; + + ReferenceType type = new ReferenceType(name, currentParentScope, byteSize, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processPointerType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + + if (byteSize == 0) + byteSize = currentCUHeader.addressSize; + + PointerType type = new PointerType(name, currentParentScope, byteSize, null); + type.setType(getTypeOrReferenceOrVoid(attributeList)); + registerType(offset, type, hasChildren); + storeTypeByName(name, type); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processPtrToMemberType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + + // unnamed data types don't get stored by name + if (name.length() == 0) + name = "" + offset; + + PointerType type = new PointerType(name, currentParentScope, currentCUHeader.addressSize, null); + type.setType(getTypeOrReferenceOrVoid(attributeList)); + registerType(offset, type, hasChildren); + storeTypeByName(name, type); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processConstType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + ConstType type = new ConstType(currentParentScope, null); + type.setType(getTypeOrReferenceOrVoid(attributeList)); + registerType(offset, type, hasChildren); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processVolatileType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + VolatileType type = new VolatileType(currentParentScope, null); + type.setType(getTypeOrReferenceOrVoid(attributeList)); + registerType(offset, type, hasChildren); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + // for void pointers, GCC will produce qualifiers and pointers without types or references, + // so create a void to be qualified or pointed to + private IType getTypeOrReferenceOrVoid(AttributeList attributeList) { + IType typeOrReference = getTypeOrReference(attributeList, currentCUHeader); + if (typeOrReference != null) + return typeOrReference; + + if (moduleScope != null && voidType == null) { + voidType = new CPPBasicType("void", moduleScope, IBasicType.t_void, 0, 0, null); + } + + if (voidType != null) + return voidType; + + return new CPPBasicType("void", currentParentScope, IBasicType.t_void, 0, 0, null); + } + + private void processEnumType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + // if the name is mangled, unmangle it + name = unmangleType(name); + + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + + Enumeration type = new Enumeration(name, currentParentScope, byteSize, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + storeTypeByName(name, type); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private Enumeration getEnumerationParent() { + IType parent = currentParentType; + while (parent != null) { + if (parent instanceof Enumeration) + return ((Enumeration) parent); + parent = typeToParentMap.get(parent); + } + return null; + } + + private void processEnumerator(long offset, AttributeList attributeList) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + if (unmangler.isMangled(name)) { + try { + name = unmangler.unmangle(name); + } catch (UnmanglingException ue) { + } + } + long value = attributeList.getAttributeValueAsSignedLong(DwarfConstants.DW_AT_const_value); + + Enumerator enumerator = new Enumerator(name, value); + + Enumeration enumeration = getEnumerationParent(); + if (enumeration == null) + throw new IllegalStateException(); + enumeration.addEnumerator(enumerator); + ((Scope)enumeration.getScope()).addEnumerator(enumerator); + + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(enumerator)); } + } + + private void processTypeDef(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + + // if the name is mangled, unmangle it + name = unmangleType(name); + + TypedefType type = new TypedefType(name, currentParentScope, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + storeTypeByName(name, type); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processBasicType(long offset, AttributeList attributeList, boolean hasChildren) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(offset)); } + + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + int byteSize = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_byte_size); + + int baseType = IBasicType.t_unspecified; + int qualifierBits = 0; + int encoding = attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_encoding); + + switch (encoding) { + case DwarfConstants.DW_ATE_boolean: + baseType = ICPPBasicType.t_bool; + break; + case DwarfConstants.DW_ATE_float: + if (name.contains("float")) { //$NON-NLS-1$ + baseType = IBasicType.t_float; + } else if (name.contains("long double")) { //$NON-NLS-1$ + baseType = IBasicType.t_double; + qualifierBits |= ICPPBasicType.IS_LONG; + } else if (name.contains("double")) { //$NON-NLS-1$ + baseType = IBasicType.t_double; + } + break; + case DwarfConstants.DW_ATE_signed: + baseType = IBasicType.t_int; + qualifierBits |= ICPPBasicType.IS_SIGNED; + if (name.contains("short")) { //$NON-NLS-1$ + qualifierBits |= ICPPBasicType.IS_SHORT; + } else if (name.contains("long long")) { //$NON-NLS-1$ + qualifierBits |= ICPPBasicType.IS_LONG_LONG; + } else if (name.contains("long")) { //$NON-NLS-1$ + qualifierBits |= ICPPBasicType.IS_LONG; + } + break; + case DwarfConstants.DW_ATE_signed_char: + baseType = IBasicType.t_char; + qualifierBits |= ICPPBasicType.IS_SIGNED; + break; + case DwarfConstants.DW_ATE_unsigned: + baseType = IBasicType.t_int; + qualifierBits |= ICPPBasicType.IS_UNSIGNED; + if (name.contains("short")) { //$NON-NLS-1$ + qualifierBits |= ICPPBasicType.IS_SHORT; + } else if (name.contains("long long")) { //$NON-NLS-1$ + qualifierBits |= ICPPBasicType.IS_LONG_LONG; + } else if (name.contains("long")) { //$NON-NLS-1$ + qualifierBits |= ICPPBasicType.IS_LONG; + } + break; + case DwarfConstants.DW_ATE_unsigned_char: + baseType = IBasicType.t_char; + qualifierBits |= ICPPBasicType.IS_UNSIGNED; + break; + case DwarfConstants.DW_ATE_complex_float: + qualifierBits |= ICPPBasicType.IS_COMPLEX; + if (name.contains("float")) { //$NON-NLS-1$ + baseType = IBasicType.t_float; + } else if (name.contains("long double")) { //$NON-NLS-1$ + baseType = IBasicType.t_double; + qualifierBits |= ICPPBasicType.IS_LONG; + } else if (name.contains("double")) { //$NON-NLS-1$ + baseType = IBasicType.t_double; + } + break; + case DwarfConstants.DW_ATE_imaginary_float: + qualifierBits |= ICPPBasicType.IS_IMAGINARY; + if (name.contains("float")) { //$NON-NLS-1$ + baseType = IBasicType.t_float; + } else if (name.contains("long double")) { //$NON-NLS-1$ + baseType = IBasicType.t_double; + qualifierBits |= ICPPBasicType.IS_LONG; + } else if (name.contains("double")) { //$NON-NLS-1$ + baseType = IBasicType.t_double; + } + break; + case DwarfConstants.DW_ATE_void: + baseType = IBasicType.t_void; + break; + case DwarfConstants.DW_ATE_address: + case DwarfConstants.DW_ATE_packed_decimal: + case DwarfConstants.DW_ATE_numeric_string: + case DwarfConstants.DW_ATE_edited: + case DwarfConstants.DW_ATE_signed_fixed: + case DwarfConstants.DW_ATE_unsigned_fixed: + case DwarfConstants.DW_ATE_decimal_float: + default: + break; + } + + // RVCT has interesting conceptions about "encoding" here. Be sure not to get confused later. + if (name.equals("void") && byteSize == 0) //$NON-NLS-1$ + baseType = IBasicType.t_void; + + CPPBasicType type = new CPPBasicType(name, currentParentScope, baseType, qualifierBits, byteSize, null); + type.setType(getTypeOrReference(attributeList, currentCUHeader)); + registerType(offset, type, hasChildren); + storeTypeByName(name, type); + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(type)); } + } + + private void processVariable(long offset, AttributeList attributeList, boolean isParameter) { + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceEntry(null, EDCTrace.fixArg(attributeList)); } + + AttributeValue locationAttribute = attributeList.getAttribute(DwarfConstants.DW_AT_location); + ILocationProvider locationProvider = getLocationProvider(locationAttribute); + if (locationProvider == null) { + // No location means either this is a placeholder (in a subprogram declaration) + // or it may have been optimized out. See section + // 2.6 of the Dwarf3 spec. for now we're ignoring it but we may be able + // to show it in the view with some special decoration to indicate that + // it's been optimized out + + // assume it is a forward reference if we're inside a function (formal_parameter or local)... + provider.functionsByOffset.put(offset, attributeList); + return; + } + + // variables can have abstract origins with most of their contents + CompilationUnitHeader otherCU = currentCUHeader; + AttributeList otherAttributes = attributeList; + String name = attributeList.getAttributeValueAsString(DwarfConstants.DW_AT_name); + if (name.length() == 0) { + // no name. + // if there is a DW_AT_specification or DW_AT_abstract_origin attribute, use it to get variable attributes + DereferencedAttributes deref = getDereferencedAttributes(attributeList, DwarfConstants.DW_AT_specification); + if (deref == null) + deref = getDereferencedAttributes(attributeList, DwarfConstants.DW_AT_abstract_origin); + if (deref != null) { + // this should either have a name or point to another + // declaration + otherCU = deref.header; + otherAttributes = deref.attributeList; + name = otherAttributes.getAttributeValueAsString(DwarfConstants.DW_AT_name); + } + } + + boolean global = (otherAttributes.getAttributeValueAsInt(DwarfConstants.DW_AT_external) == 1); + + // if the name is mangled, unmangle it + if (name.startsWith("_Z")) { + name = unmangle(name); + } else if (global) { + // GCCE uses DW_AT_MIPS_linkage_name for the mangled name of an externally visible variable + String mangledName = otherAttributes.getAttributeValueAsString(DwarfConstants.DW_AT_MIPS_linkage_name); + if (unmangler.isMangled(mangledName)) { + try { + name = unmangler.unmangle(mangledName); + } catch (UnmanglingException ue) { + } + } + } + + IType type = getTypeOrReference(otherAttributes.getAttribute(DwarfConstants.DW_AT_type), otherCU); + if (type != null) { + long startScope = attributeList.getAttributeValueAsLong(DwarfConstants.DW_AT_start_scope); + boolean isDeclared = otherAttributes.getAttributeValueAsInt(DwarfConstants.DW_AT_artificial) <= 0; + + int definingFileNum = otherAttributes.getAttributeValueAsInt(DwarfConstants.DW_AT_decl_file); + if (definingFileNum > 0 && attributeList.getAttributeValueAsInt(DwarfConstants.DW_AT_declaration) > 0) { + // variable is declared here, but not defined here + definingFileNum = 0; + } + + IPath definingFile = null; + + // find the file it's defined in + if (definingFileNum > 0) { + // find the enclosing compile unit to get access to its list of + // .debug_line file names + IScope cuScope = currentParentScope; + while (cuScope != null && !(cuScope instanceof DwarfCompileUnit)) + cuScope = cuScope.getParent(); + + if (cuScope != null) { + definingFile = ((DwarfCompileUnit) cuScope).getFileEntry(definingFileNum); + } + } + + DwarfVariable variable = new DwarfVariable(name, + global ? moduleScope : currentParentScope, + locationProvider, + type, + isDeclared, + definingFile); + + variable.setStartScope(startScope); + + if (isParameter) { + if (currentParentScope instanceof FunctionScope) { + ((FunctionScope) currentParentScope).addParameter(variable); + } else { + assert (false); + } + } else { + if (global) { + // add global variables to the module scope + moduleScope.addVariable(variable); + // AND to the CU scope + if (currentCompileUnitScope != null) { + currentCompileUnitScope.addVariable(variable); + } + } else { + // the parent scope could be compile unit, function or + // lexical block + currentParentScope.addVariable(variable); + } + + // keep track of all variables by name for faster lookup + List variables = provider.variablesByName.get(name); + if (variables == null) { + variables = new ArrayList(); + provider.variablesByName.put(name, variables); + } + variables.add(variable); + } + + if (EDCTrace.SYMBOL_READER_VERBOSE_TRACE_ON) { EDCTrace.getTrace().traceExit(null, EDCTrace.fixArg(variable)); } + } + } + + + private ILocationProvider getLocationProvider(AttributeValue locationValue) { + if (locationValue != null) { + byte actualForm = locationValue.getActualForm(); + if (actualForm == DwarfConstants.DW_FORM_data4) { + // location list + Collection entryList = getLocationRecord(locationValue.getValueAsLong()); + if (entryList != null) { + return new LocationList(entryList.toArray(new LocationEntry[entryList.size()]), + exeReader.getByteOrder(), + currentCUHeader.addressSize, currentParentScope); + } + } else if (actualForm == DwarfConstants.DW_FORM_block + || actualForm == DwarfConstants.DW_FORM_block1 + || actualForm == DwarfConstants.DW_FORM_block2 + || actualForm == DwarfConstants.DW_FORM_block4) { + // location expression + IStreamBuffer locationData = new MemoryStreamBuffer(locationValue.getValueAsBytes(), exeReader.getByteOrder()); + return new LocationExpression(locationData, + currentCUHeader.addressSize, + currentParentScope); + } else { + // should not happen according to the spec + assert (false); + } + } + + return null; + } + + private void dumpSymbols() { + if (DEBUG) { + PrintStream out = null; + try { + out = new PrintStream(new File(dumpFileName)); + } catch (FileNotFoundException e) { + System.out.println(DwarfMessages.DwarfInfoReader_DumpFileOpenOrCreateFailed + dumpFileName); + return; + } + + // If to write to console + // PrintStream out = System.out; + + out.println("Module - " + symbolFilePath); + out.println(" Variables - " + moduleScope.getVariables().size()); + out.println(" Compile units - " + moduleScope.getChildren().size()); + out.println(); + + for (IScope cu : moduleScope.getChildren()) { + out.println(" Compile unit - " + cu.toString()); + out.println(" Variables - " + cu.getVariables().size()); + out.println(" Functions - " + cu.getChildren().size()); + out.println(); + + for (IScope func : cu.getChildren()) { + out.println(" Function - " + func.toString()); + out.println(" Variables - " + func.getVariables().size()); + out.println(" Parameters - " + ((IFunctionScope) func).getParameters().size()); + out.println(" Lexical blocks - " + func.getChildren().size()); + out.println(); + + // not accurate: can contain IFunctionScope too! + for (IScope block : func.getChildren()) { + out.println(" Lexical block - " + block.toString()); + out.println(" Variables - " + block.getVariables().size()); + out.println(); + } + } + } + + out.close(); + } + } + + public void parseForFrameIndices() { + synchronized (provider) { + if (!provider.frameDescEntries.isEmpty()) + return; + + IExecutableSection frameSection = exeReader.findExecutableSection(DWARF_DEBUG_FRAME); + if (frameSection == null) + return; + + IStreamBuffer buffer = frameSection.getBuffer(); + buffer.position(0); + + int addressSize = 4; // TODO: 64-bit Dwarf + long cie_id = addressSize == 4 ? 0xffffffff : ~0L; + + // in the first pass, just get a mapping of PC ranges to FDEs, + // so we can locate entries quickly (don't pre-parse CIEs or decompile FDE instructions yet) + while (buffer.position() < buffer.capacity()) { + try { + long fdePtr = buffer.position(); + long headerLength = readAddress(buffer, addressSize); + long nextPosition = buffer.position() + headerLength; + + long ciePtr = readAddress(buffer, addressSize); + if (ciePtr != cie_id) { + long initialLocation = readAddress(buffer, addressSize); + long addressRange = readAddress(buffer, addressSize); + IStreamBuffer instructions = buffer.wrapSubsection(nextPosition - buffer.position()); + IRangeList.Entry entry = new IRangeList.Entry(initialLocation, initialLocation + addressRange); + FrameDescriptionEntry fde = new FrameDescriptionEntry(fdePtr, ciePtr, + entry.low, entry.high, + instructions, addressSize); + provider.frameDescEntries.put(entry, fde); + } + + buffer.position(nextPosition); + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError(DwarfMessages.DwarfInfoReader_FrameIndicesReadFailed, t); + break; + } + + } + } + } + + /** + * Parse a CIE + * @param ciePtr + * @param addressSize + * @param framePC + * @return the CIE or null in case of error + */ + public CommonInformationEntry parseCommonInfoEntry(Long ciePtr, int addressSize, IAddress framePC) throws IOException { + synchronized (provider) { + IExecutableSection frameSection = exeReader.findExecutableSection(DWARF_DEBUG_FRAME); + if (frameSection == null) + return null; + + IStreamBuffer buffer = frameSection.getBuffer(); + buffer.position(ciePtr); + + long headerLength = readAddress(buffer, addressSize); + if (headerLength > buffer.capacity()) { + assert(false); + return null; + } + + long nextPosition = buffer.position() + headerLength; + + /* cie_id = */ readAddress(buffer, addressSize); + + byte version = buffer.get(); + String augmentation = readString(buffer); + long codeAlignmentFactor = read_unsigned_leb128(buffer); + long dataAlignmentFactor = read_signed_leb128(buffer); + int returnAddressRegister = version < 3 ? buffer.get() & 0xff : (int) read_unsigned_leb128(buffer); + + + IStreamBuffer instructions = buffer.wrapSubsection(nextPosition - buffer.position()); + + String producer = null; + ICompileUnitScope cuScope = provider.getCompileUnitForAddress(framePC); + if (cuScope instanceof DwarfCompileUnit) + producer = ((DwarfCompileUnit) cuScope).getAttributeList().getAttributeValueAsString(DwarfConstants.DW_AT_producer); + + return new CommonInformationEntry(codeAlignmentFactor, dataAlignmentFactor, + returnAddressRegister, version, instructions, addressSize, + producer, augmentation); + } + } + + private void storeTypeByName(String name, IType type) { + if (name.length() == 0) + return; + + List typeList = provider.typesByName.get(name); + if (typeList == null) { + typeList = new ArrayList(); + + // for a template, remove extra spaces and composite type names (e.g., "class") + if (name.indexOf('<') != -1) { + while (name.contains(" ")) //$NON-NLS-1$ + name = name.replaceAll(" ", " "); //$NON-NLS-1$ //$NON-NLS-2$ + name = name.replaceAll(", ", ","); //$NON-NLS-1$ //$NON-NLS-2$ + name = name.replaceAll("class ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + name = name.replaceAll("struct ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + name = name.replaceAll("union ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + provider.typesByName.put(name, typeList); + } + typeList.add(type); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfMessages.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfMessages.java new file mode 100644 index 0000000..d372bca --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfMessages.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import org.eclipse.osgi.util.NLS; + +public class DwarfMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfMessages"; //$NON-NLS-1$ + + public static String DwarfDebugInfoProvider_FailedToReadCIE; + + public static String DwarfDebugInfoProvider_DwarfProviderFor; + + public static String DwarfDebugInfoProvider_NotParsingType1; + public static String DwarfDebugInfoProvider_NotParsingType2; + + public static String DwarfDebugInfoProvider_CannotResolveCompUnit1; + public static String DwarfDebugInfoProvider_CannotResolveCompUnit2; + + public static String DwarfDebugInfoProvider_UnhandledType; + + public static String DwarfFrameRegisters_CannotReadRegister; + + public static String DwarfFrameRegisters_CannotWriteRegister; + + public static String DwarfFrameRegisters_ErrorCalculatingLocation; + + public static String DwarfFrameRegisters_NoCommonInfoEntry; + + public static String DwarfInfoReader_DumpFileOpenOrCreateFailed; + + public static String DwarfInfoReader_FrameIndicesReadFailed; + + public static String DwarfInfoReader_ParseDebugInfoSectionFailed1; + public static String DwarfInfoReader_ParseDebugInfoSectionFailed2; + + public static String DwarfInfoReader_ParseSectionSourceFilesFailed1; + public static String DwarfInfoReader_ParseSectionSourceFilesFailed2; + + public static String DwarfInfoReader_ParseTraceInfoSectionFailed1; + public static String DwarfInfoReader_ParseTraceInfoSectionFailed2; + + public static String DwarfInfoReader_RangeReadFailed; + + public static String DwarfInfoReader_ReadDebugInfo; + + public static String DwarfInfoReader_ReadingSymbolInfo; + + public static String DwarfInfoReader_ReadType; + + public static String DwarfInfoReader_SubprogramNameNotFound1; + public static String DwarfInfoReader_SubprogramNameNotFound2; + + public static String DwarfInfoReader_TraceAddressParse1; + public static String DwarfInfoReader_TraceAddressParse2; + + public static String DwarfInfoReader_TraceAddressesParseFor; + public static String DwarfInfoReader_TraceFinishedAddressesParse; + + public static String DwarfInfoReader_TraceAddressParseFor; + public static String DwarfInfoReader_TraceFinishedAddressParse; + + public static String DwarfInfoReader_TraceFinishedInitialParse; + + public static String DwarfInfoReader_TraceFinishedQuickParse; + + public static String DwarfInfoReader_TraceInitialParseFor; + + public static String DwarfInfoReader_TraceParseTypes1; + public static String DwarfInfoReader_TraceParseTypes2; + + public static String DwarfInfoReader_TraceQuickParse; + + public static String DwarfInfoReader_TraceScopeAddressParse1; + public static String DwarfInfoReader_TraceScopeAddressParse2; + + public static String DwarfInfoReader_TraceTypeParse1; + public static String DwarfInfoReader_TraceTypeParse2; + + public static String UnknownVariableAddress; + public static String NotImplementedFormat; + public static String InternalErrorFormat; + + public static String LocationExpression_BadStackSize; + + public static String LocationExpression_DW_OP; + + public static String LocationExpression_MultiRegisterVariable; + + public static String LocationExpression_UnexpectedOperand; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, DwarfMessages.class); + } + + private DwarfMessages() { + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfMessages.properties b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfMessages.properties new file mode 100644 index 0000000..2fe9c42 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfMessages.properties @@ -0,0 +1,58 @@ +############################################################################### +# Copyright (c) 2010 Nokia and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Nokia - Initial API and implementation +############################################################################### +UnknownVariableAddress=Unknown variable address +NotImplementedFormat=Not implemented ({0}) +DwarfDebugInfoProvider_CannotResolveCompUnit1=Cannot resolve compilation unit header for type at +DwarfDebugInfoProvider_CannotResolveCompUnit2=\ in +DwarfDebugInfoProvider_DwarfProviderFor=DWARF debug info provider for +DwarfDebugInfoProvider_FailedToReadCIE=Failed to read CIE at +DwarfDebugInfoProvider_NotParsingType1=Cannot parse type at +DwarfDebugInfoProvider_NotParsingType2=\ in +DwarfDebugInfoProvider_UnhandledType=<> +DwarfFrameRegisters_CannotReadRegister=Cannot read register {0} at {1} +DwarfFrameRegisters_CannotWriteRegister=Cannot write register {0} at {1} +DwarfFrameRegisters_ErrorCalculatingLocation=Internal error calculating location +DwarfFrameRegisters_NoCommonInfoEntry=No CIE for {0} +DwarfInfoReader_DumpFileOpenOrCreateFailed=Failed to open or create the dump file: +DwarfInfoReader_FrameIndicesReadFailed=Failed to read frame indices +DwarfInfoReader_ParseDebugInfoSectionFailed1=Failed to parse debug info from section +DwarfInfoReader_ParseDebugInfoSectionFailed2=\ in file +DwarfInfoReader_ParseSectionSourceFilesFailed1=Failed to parse source files from section +DwarfInfoReader_ParseSectionSourceFilesFailed2=\ in file +DwarfInfoReader_ParseTraceInfoSectionFailed1=Failed to parse type debug info from section +DwarfInfoReader_ParseTraceInfoSectionFailed2=\ in file +DwarfInfoReader_RangeReadFailed=Failed to read ranges +DwarfInfoReader_ReadDebugInfo=Read Debug Info +DwarfInfoReader_ReadingSymbolInfo=Reading Debug Symbol Information: +DwarfInfoReader_ReadType=Read type +DwarfInfoReader_SubprogramNameNotFound1=Name of subprogram at +DwarfInfoReader_SubprogramNameNotFound2=\ not found +DwarfInfoReader_TraceAddressParse1=Address parse for +DwarfInfoReader_TraceAddressParse2=\ : +DwarfInfoReader_TraceAddressesParseFor=Addresses parse for +DwarfInfoReader_TraceFinishedAddressesParse=Finished addresses parse +DwarfInfoReader_TraceAddressParseFor=Address parse for +DwarfInfoReader_TraceFinishedAddressParse=Finished address parse +DwarfInfoReader_TraceFinishedInitialParse=Finished initial parse +DwarfInfoReader_TraceFinishedQuickParse=Finished quick parse +DwarfInfoReader_TraceInitialParseFor=Initial parse for +DwarfInfoReader_TraceParseTypes1=Parsing types for +DwarfInfoReader_TraceParseTypes2=\ @ +DwarfInfoReader_TraceQuickParse=Quick parse for +DwarfInfoReader_TraceScopeAddressParse1=Address parse of +DwarfInfoReader_TraceScopeAddressParse2=\ @ +DwarfInfoReader_TraceTypeParse1=Type parse of +DwarfInfoReader_TraceTypeParse2=\ : +InternalErrorFormat=Internal error ({0}) +LocationExpression_BadStackSize=Stack size not 1 +LocationExpression_DW_OP=DW_OP +LocationExpression_MultiRegisterVariable=multi-register variable +LocationExpression_UnexpectedOperand=Unexpected DW_OP diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfModuleScope.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfModuleScope.java new file mode 100644 index 0000000..737f4b4 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfModuleScope.java @@ -0,0 +1,268 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.ISection; +import org.eclipse.cdt.debug.edc.internal.symbols.ModuleLineEntryProvider; +import org.eclipse.cdt.debug.edc.internal.symbols.Scope; +import org.eclipse.cdt.debug.edc.services.IFrameRegisterProvider; +import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope; +import org.eclipse.cdt.debug.edc.symbols.IEnumerator; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.IModuleLineEntryProvider; +import org.eclipse.cdt.debug.edc.symbols.IModuleScope; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.cdt.debug.edc.symbols.IVariable; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.core.runtime.IPath; + +/** + * This represents the high-level view of an executable module's symbolics. + */ +public class DwarfModuleScope extends Scope implements IModuleScope { + + private final DwarfDebugInfoProvider provider; + private ModuleLineEntryProvider lineEntryMapper; + + public DwarfModuleScope(DwarfDebugInfoProvider provider) { + super("", null, null, null); + this.provider = provider; + + if (provider == null) { + lowAddress = Addr32.ZERO; + highAddress = Addr32.ZERO; + } else { + name = provider.getSymbolFile().lastSegment(); + + // for now, use the code sections' ranges + lowAddress = Addr32.MAX; + highAddress = Addr32.ZERO; + for (ISection section : provider.getExecutableSymbolicsReader().getSections()) { + if (section.getProperties().get(ISection.PROPERTY_NAME).equals(ISection.NAME_DATA)) { + if (section.getLinkAddress().compareTo(lowAddress) < 0) + lowAddress = section.getLinkAddress(); + IAddress end = section.getLinkAddress().add(section.getSize()); + if (end.compareTo(highAddress) > 0) + highAddress = end; + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IModuleScope#getSymbolFile() + */ + public IPath getSymbolFile() { + return provider.getSymbolFile(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IModuleScope#getCompileUnitForAddress(org.eclipse.cdt.core.IAddress) + */ + public ICompileUnitScope getCompileUnitForAddress(IAddress linkAddress) { + if (provider != null) + return provider.getCompileUnitForAddress(linkAddress); + else + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IModuleScope#getCompileUnitForFile(org.eclipse.core.runtime.IPath) + */ + public List getCompileUnitsForFile(IPath filePath) { + if (provider != null) + return provider.getCompileUnitsForFile(filePath); + else + return Collections.emptyList(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IModuleScope#getFunctionsByName(java.lang.String) + */ + public Collection getFunctionsByName(String name) { + if (provider != null) + return provider.getFunctionsByName(name); + else + return Collections.emptyList(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IModuleScope#getVariablesByName(java.lang.String) + */ + public Collection getVariablesByName(String name, boolean globalsOnly) { + // at the module scope, the variables we want are global + if (provider != null) + return provider.getVariablesByName(name, globalsOnly); + else + return Collections.emptyList(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getScopeAtAddress(org.eclipse.cdt.core.IAddress) + */ + @Override + public IScope getScopeAtAddress(IAddress linkAddress) { + ensureParsed(); + return super.getScopeAtAddress(linkAddress); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getEnumerators() + */ + @Override + public Collection getEnumerators() { + ensureParsed(); + return super.getEnumerators(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getChildren() + */ + @Override + public Collection getChildren() { + ensureParsed(); + return super.getChildren(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getVariables() + */ + @Override + public Collection getVariables() { + ensureParsedForVariables(); + return super.getVariables(); + } + + private void ensureParsed() { + if (provider != null) + provider.ensureParsedInitially(); + } + + private void ensureParsedForVariables() { + if (provider != null) + provider.ensureParsedForVariables(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IModuleScope#getTypes() + */ + public Collection getTypes() { + if (provider != null) + return provider.getTypes(); + else + return Collections.emptyList(); + } + + /** + * Fixup ranges after a full-module address parse. + */ + /* + public void fixupRanges() { + System.out.println("Fixing up ranges for " + getChildren().size() + " children"); + + // fix up scope addresses in case compiler doesn't generate them. + for (IScope cu : getChildren()) { + ((DwarfCompileUnit) cu).fixupRanges(); + } + + IAddress newLowAddress = new Addr64(BigInteger.valueOf(0xFFFFFFFFL)); + IAddress newHighAddress = new Addr64(BigInteger.valueOf(0)); + + // now fix up the module scope + for (IScope cu : getChildren()) { + if (cu.getLowAddress().compareTo(newLowAddress) < 0) { + newLowAddress = cu.getLowAddress(); + } + + if (cu.getHighAddress().compareTo(newHighAddress) > 0) { + newHighAddress = cu.getHighAddress(); + } + } + + this.lowAddress = newLowAddress; + this.highAddress = newHighAddress; + } + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.IModuleScope#getModuleLineEntryProvider() + */ + public IModuleLineEntryProvider getModuleLineEntryProvider() { + if (lineEntryMapper == null) { + lineEntryMapper = new ModuleLineEntryProvider(); + + // handle the currently parsed children + for (IScope scope : getChildren()) { + if (scope instanceof ICompileUnitScope) { + lineEntryMapper.addCompileUnit((ICompileUnitScope) scope); + } + } + } + return lineEntryMapper; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#addChild(org.eclipse.cdt.debug.edc.internal.symbols.IScope) + */ + @Override + public void addChild(IScope scope) { + super.addChild(scope); + + // initial module scope range is a guess + mergeScopeRange(scope); + + if (scope instanceof ICompileUnitScope && lineEntryMapper != null) { + lineEntryMapper.addCompileUnit((ICompileUnitScope) scope); + } + } + + /** + * Update info when a compile unit has been fully parsed. + * @param scope + */ + public void updateLineInfoForCU(ICompileUnitScope scope) { + // be sure the decl entries for inlined functions are detected + if (lineEntryMapper != null) + lineEntryMapper.addCompileUnit(scope); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.symbols.IModuleScope#getFrameRegisterProvider() + */ + public IFrameRegisterProvider getFrameRegisterProvider() { + if (provider != null) + return provider.getFrameRegisterProvider(); + else + return null; + } + + /** + * Help garbage collection + */ + public void dispose() { + lineEntryMapper = null; + super.dispose(); + } +} + diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfVariable.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfVariable.java new file mode 100644 index 0000000..c99be39 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/DwarfVariable.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import org.eclipse.cdt.debug.edc.internal.symbols.Variable; +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.core.runtime.IPath; + +public class DwarfVariable extends Variable { + + public DwarfVariable(String name, IScope scope, ILocationProvider locationProvider, + IType type, boolean isDeclared, IPath definingFile) { + super(name, scope, null, locationProvider, isDeclared, definingFile); + + this.type = type; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/EDCSymbolReader.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/EDCSymbolReader.java new file mode 100644 index 0000000..7df0952 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/EDCSymbolReader.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.nio.ByteOrder; +import java.util.Collection; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.symbols.ISection; +import org.eclipse.cdt.debug.edc.internal.symbols.files.BaseExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProvider; +import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSection; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.IModuleScope; +import org.eclipse.cdt.debug.edc.symbols.ISymbol; +import org.eclipse.cdt.debug.edc.symbols.IUnmangler; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +/** + * This class handles the high-level retrieval of symbolic information, using + * {@link IDebugInfoProvider} and {@link IExecutableSymbolicsReader}. + */ +public class EDCSymbolReader implements IEDCSymbolReader { + + private static final String[] NO_SOURCE_FILES = new String[0]; + + private static final IModuleScope EMPTY_MODULE_SCOPE = new DwarfModuleScope(null); + + private IDebugInfoProvider debugInfoProvider; + private IExecutableSymbolicsReader exeSymReader; + + public EDCSymbolReader(IExecutableSymbolicsReader exeSymReader, IDebugInfoProvider debugInfoProvider) { + if (exeSymReader == null) + throw new IllegalArgumentException(); + + this.exeSymReader = exeSymReader; + this.debugInfoProvider = debugInfoProvider; + + // we expect these two files to be the same + if (debugInfoProvider != null) + if (!debugInfoProvider.getSymbolFile().equals(exeSymReader.getSymbolFile())) + throw new IllegalArgumentException(); + } + + public void shutDown() { + if (exeSymReader != null) { + exeSymReader.dispose(); + exeSymReader = null; + } + if (debugInfoProvider != null) { + debugInfoProvider.dispose(); + debugInfoProvider = null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.IExecutableSymbolicsReader#dispose() + */ + public void dispose() { + exeSymReader.dispose(); + } + + public Collection getExecutableSections() { + return exeSymReader.getExecutableSections(); + } + + public IExecutableSection findExecutableSection(String sectionName) { + return exeSymReader.findExecutableSection(sectionName); + } + + public Collection getSections() { + return exeSymReader.getSections(); + } + + public IAddress getBaseLinkAddress() { + return exeSymReader.getBaseLinkAddress(); + } + + public long getModificationDate() { + return exeSymReader.getModificationDate(); + } + + public Collection findSymbols(String name) { + return exeSymReader.findSymbols(name); + } + + public Collection findUnmangledSymbols(String name) { + return exeSymReader.findUnmangledSymbols(name); + } + + public Collection getSymbols() { + return exeSymReader.getSymbols(); + } + + public ISymbol getSymbolAtAddress(IAddress linkAddress) { + return exeSymReader.getSymbolAtAddress(linkAddress); + } + + public IPath getSymbolFile() { + return debugInfoProvider != null ? debugInfoProvider.getSymbolFile() : + (exeSymReader != null ? exeSymReader.getSymbolFile() : null); + } + + public ByteOrder getByteOrder() { + return exeSymReader.getByteOrder(); + } + + public IModuleScope getModuleScope() { + if (debugInfoProvider != null) + return debugInfoProvider.getModuleScope(); + else + return EMPTY_MODULE_SCOPE; + } + + public String[] getSourceFiles() { + if (debugInfoProvider != null) + { + final String[][] resultHolder = new String[1][]; + Job quickParseJob = new Job("Reading Debug Symbol Information: " + debugInfoProvider.getSymbolFile().toOSString()) { + + @Override + protected IStatus run(IProgressMonitor monitor) { + String[] sourceFiles = getSourceFiles(monitor); + resultHolder[0] = sourceFiles; + return Status.OK_STATUS; + } + }; + + try { + quickParseJob.schedule(); + quickParseJob.join(); + } catch (InterruptedException e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + return resultHolder[0]; + } + else + return NO_SOURCE_FILES; + } + + public String[] getSourceFiles(IProgressMonitor monitor) { + if (debugInfoProvider != null) + return debugInfoProvider.getSourceFiles(monitor); + else + return NO_SOURCE_FILES; + } + + public boolean hasRecognizedDebugInformation() { + return debugInfoProvider != null; + } + + public IDebugInfoProvider getDebugInfoProvider() { + return debugInfoProvider; + } + + public IUnmangler getUnmangler() { + if (exeSymReader instanceof BaseExecutableSymbolicsReader) + return ((BaseExecutableSymbolicsReader) exeSymReader).getUnmangler(); + return null; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationEntry.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationEntry.java new file mode 100644 index 0000000..685dd7c --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationEntry.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.util.Arrays; + +public class LocationEntry { + + private final long highPC; + private final long lowPC; + private final byte[] bytes; + + public LocationEntry(long lowPC, long highPC, byte[] bytes) { + this.lowPC = lowPC; + this.highPC = highPC; + this.bytes = bytes; + } + + /** Get the link address for the exclusive high end of the range. */ + public long getHighPC() { + return highPC; + } + + /** Get the link address for the inclusive low end of the range. */ + public long getLowPC() { + return lowPC; + } + + public byte[] getBytes() { + return bytes; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("LocationEntry ["); //$NON-NLS-1$ + if (bytes != null) { + builder.append("bytes="); //$NON-NLS-1$ + builder.append(Arrays.toString(bytes)); + builder.append(", "); //$NON-NLS-1$ + } + builder.append("highPC="); //$NON-NLS-1$ + builder.append(highPC); + builder.append(", lowPC="); //$NON-NLS-1$ + builder.append(lowPC); + builder.append("]"); //$NON-NLS-1$ + return builder.toString(); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationExpression.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationExpression.java new file mode 100644 index 0000000..0125fcc --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationExpression.java @@ -0,0 +1,323 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.math.BigInteger; +import java.text.MessageFormat; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.symbols.InvalidVariableLocation; +import org.eclipse.cdt.debug.edc.internal.symbols.MemoryVariableLocation; +import org.eclipse.cdt.debug.edc.internal.symbols.RegisterVariableLocation; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.symbols.IFunctionScope; +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IRegisterVariableLocation; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.core.runtime.CoreException; + +public class LocationExpression implements ILocationProvider { + + protected final IStreamBuffer location; + protected final int addressSize; + protected final IScope scope; + + public LocationExpression(IStreamBuffer location, int addressSize, IScope scope) { + this.location = location; + this.addressSize = addressSize; + this.scope = scope; + } + + synchronized public IVariableLocation getLocation(EDCServicesTracker tracker, IFrameDMContext context, IAddress forLinkAddress, boolean isNonLocalConstVariable) { + + if (location == null) { + return null; + } + + // This is intentionally small. No existing code that I've seen has more + // than a sprinkling of operands, much less ones that push. + IVariableLocation[] opStack = new IVariableLocation[8]; + int opStackPtr = 0; + + location.position(0); + + try { + while (location.hasRemaining()) { + byte opcodeB = location.get(); + int opcode = 0xFF & opcodeB; + + if (opcode >= DwarfConstants.DW_OP_lit0 && opcode <= DwarfConstants.DW_OP_lit31) { + opStack[opStackPtr++] = new MemoryVariableLocation(tracker, + context, + BigInteger.valueOf(opcode - DwarfConstants.DW_OP_lit0), true); + } + else if (opcode >= DwarfConstants.DW_OP_reg0 && opcode <= DwarfConstants.DW_OP_reg31) { + opStack[opStackPtr++] = new RegisterVariableLocation(tracker, context, null, (opcode - DwarfConstants.DW_OP_reg0)); + } + else if (opcode >= DwarfConstants.DW_OP_breg0 && opcode <= DwarfConstants.DW_OP_breg31) { + RegisterVariableLocation loc = new RegisterVariableLocation(tracker, context, null, (opcode - DwarfConstants.DW_OP_breg0)); + try { + BigInteger value = loc.readValue(addressSize); + + long offset = DwarfInfoReader.read_signed_leb128(location); + opStack[opStackPtr++] = new MemoryVariableLocation(tracker, context, + value.add(BigInteger.valueOf(offset)), true); + } catch (CoreException e) { + return new InvalidVariableLocation(e.getMessage()); + } + } else { + + switch (opcode) { + case DwarfConstants.DW_OP_nop: + // ignore + break; + + case DwarfConstants.DW_OP_addr: /* Constant address. */ + long addrValue = DwarfInfoReader.readAddress(location, addressSize); + opStack[opStackPtr++] = new MemoryVariableLocation(tracker, context, + BigInteger.valueOf(addrValue), true, isNonLocalConstVariable); + break; + + case DwarfConstants.DW_OP_deref: { + ensureStack(opStackPtr, 1); + try { + BigInteger addr = opStack[opStackPtr - 1].readValue(addressSize); + IVariableLocation loc = new MemoryVariableLocation(tracker, context, + addr, true, isNonLocalConstVariable); + opStack[opStackPtr - 1] = loc; + } catch (CoreException e) { + return new InvalidVariableLocation(e.getMessage()); + } + break; + } + + case DwarfConstants.DW_OP_plus_uconst: { + ensureStack(opStackPtr, 1); + long offset = DwarfInfoReader.read_unsigned_leb128(location); + opStack[opStackPtr-1] = opStack[opStackPtr-1].addOffset(offset); + break; + } + + case DwarfConstants.DW_OP_const1u: /* + * Unsigned 1-byte + * constant. + */ + case DwarfConstants.DW_OP_const1s: /* + * Signed 1-byte + * constant. + */ + case DwarfConstants.DW_OP_const2u: /* + * Unsigned 2-byte + * constant. + */ + case DwarfConstants.DW_OP_const2s: /* + * Signed 2-byte + * constant. + */ + case DwarfConstants.DW_OP_const4u: /* + * Unsigned 4-byte + * constant. + */ + case DwarfConstants.DW_OP_const4s: /* + * Signed 4-byte + * constant. + */ + case DwarfConstants.DW_OP_const8u: /* + * Unsigned 8-byte + * constant. + */ + case DwarfConstants.DW_OP_const8s: /* + * Signed 8-byte + * constant. + */ + case DwarfConstants.DW_OP_constu: /* Unsigned LEB128 constant. */ + case DwarfConstants.DW_OP_consts: /* Signed LEB128 constant. */ + case DwarfConstants.DW_OP_dup: + case DwarfConstants.DW_OP_drop: + case DwarfConstants.DW_OP_over: + case DwarfConstants.DW_OP_pick: /* 1-byte stack index. */ + case DwarfConstants.DW_OP_swap: + case DwarfConstants.DW_OP_rot: + case DwarfConstants.DW_OP_xderef: + case DwarfConstants.DW_OP_abs: + case DwarfConstants.DW_OP_and: + case DwarfConstants.DW_OP_div: + case DwarfConstants.DW_OP_minus: + case DwarfConstants.DW_OP_mod: + case DwarfConstants.DW_OP_mul: + case DwarfConstants.DW_OP_neg: + case DwarfConstants.DW_OP_not: + case DwarfConstants.DW_OP_or: + case DwarfConstants.DW_OP_plus: + case DwarfConstants.DW_OP_shl: + case DwarfConstants.DW_OP_shr: + case DwarfConstants.DW_OP_shra: + case DwarfConstants.DW_OP_xor: + case DwarfConstants.DW_OP_bra: /* Signed 2-byte constant. */ + case DwarfConstants.DW_OP_eq: + case DwarfConstants.DW_OP_ge: + case DwarfConstants.DW_OP_gt: + case DwarfConstants.DW_OP_le: + case DwarfConstants.DW_OP_lt: + case DwarfConstants.DW_OP_ne: + case DwarfConstants.DW_OP_skip: /* Signed 2-byte constant. */ + return new InvalidVariableLocation(MessageFormat.format( + DwarfMessages.NotImplementedFormat, DwarfMessages.LocationExpression_DW_OP + opcode)); + + case DwarfConstants.DW_OP_regx: /* Unsigned LEB128 register. */ + long regNum = DwarfInfoReader.read_unsigned_leb128(location); + opStack[opStackPtr++] = new RegisterVariableLocation(tracker, context, null, ((int) regNum)); + break; + + case DwarfConstants.DW_OP_fbreg: /* Signed LEB128 offset. */ + long offset = DwarfInfoReader.read_signed_leb128(location); + + IFunctionScope functionScope = null; + functionScope = getFunctionScope(forLinkAddress); + + IVariableLocation framePtrLoc = functionScope.getFrameBaseLocation().getLocation(tracker, + context, forLinkAddress, false); + if (framePtrLoc != null) { + if (framePtrLoc instanceof InvalidVariableLocation) + return framePtrLoc; + + // first resolve the frame base value and then add + // the offset + if (framePtrLoc instanceof IRegisterVariableLocation) { + BigInteger frame = framePtrLoc.readValue(addressSize); + + opStack[opStackPtr++] = new MemoryVariableLocation(tracker, context, + frame.add(BigInteger.valueOf(offset)), true); + } else { + opStack[opStackPtr++] = framePtrLoc.addOffset(offset); + } + } + + break; + + case DwarfConstants.DW_OP_piece: + /* + * ULEB128 size of piece + * addressed. + * TODO: GCC emits this for long long (is a composition operator + * that combines values -- this may tax the IVariableLocation concept) + */ + assert (false); + return new InvalidVariableLocation(MessageFormat.format(DwarfMessages.NotImplementedFormat, + DwarfMessages.LocationExpression_MultiRegisterVariable)); + + case DwarfConstants.DW_OP_bregx: /* + * ULEB128 register followed + * by SLEB128 off. + */ + case DwarfConstants.DW_OP_deref_size: /* + * 1-byte size of data + * retrieved. + */ + case DwarfConstants.DW_OP_xderef_size: /* + * 1-byte size of + * data retrieved. + */ + case DwarfConstants.DW_OP_push_object_address: + case DwarfConstants.DW_OP_call2: + case DwarfConstants.DW_OP_call4: + case DwarfConstants.DW_OP_call_ref: + assert (false); + return new InvalidVariableLocation(MessageFormat.format(DwarfMessages.NotImplementedFormat, + DwarfMessages.LocationExpression_DW_OP + opcode)); + + default: + assert (false); + return new InvalidVariableLocation(MessageFormat.format(DwarfMessages.InternalErrorFormat, + DwarfMessages.LocationExpression_UnexpectedOperand + opcode)); + } + + } + + } + } catch (CoreException e) { + return new InvalidVariableLocation(e.getMessage()); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError(null, e); + } + + if (opStackPtr != 1) { + assert(false); + return new InvalidVariableLocation(MessageFormat.format(DwarfMessages.InternalErrorFormat, + DwarfMessages.LocationExpression_BadStackSize)); + } + + return opStack[0]; + } + + /** + */ + private void ensureStack(int opStackPtr, int needed) throws CoreException { + if (opStackPtr < needed) { + throw EDCDebugger.newCoreException(MessageFormat.format( + DwarfMessages.InternalErrorFormat, + MessageFormat.format("expected {0} stack operands but had {1}", needed, opStackPtr))); + } + } + + /** + * @param forLinkAddress + * @param functionScope + * @return + * @throws CoreException + */ + private IFunctionScope getFunctionScope(IAddress forLinkAddress) throws CoreException { + IFunctionScope functionScope = null; + + if (scope instanceof IFunctionScope) { + functionScope = (IFunctionScope) scope; + } else { + IScope parent = scope.getParent(); + while (parent != null && !(parent instanceof IFunctionScope)) { + parent = parent.getParent(); + } + + if (parent == null) { + throw EDCDebugger.newCoreException("No function scope for " + scope + " at " + forLinkAddress.toHexAddressString()); + } else { + functionScope = (IFunctionScope) parent; + } + } + + // inlined functions may be nested + while (functionScope.getParent() instanceof IFunctionScope) + functionScope = (IFunctionScope) functionScope.getParent(); + return functionScope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ILocationProvider#isLocationKnown(org.eclipse.cdt.core.IAddress) + */ + public boolean isLocationKnown(IAddress forLinkAddress) { + // a location expression has the lifetime of its scope + return true; + } + + public IScope getScope() { + return scope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ILocationProvider#lifetimeMustMatchScope() + */ + public boolean lifetimeMustMatchScope() { + return true; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationList.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationList.java new file mode 100644 index 0000000..2d6b121 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/LocationList.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.nio.ByteOrder; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.MemoryStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.symbols.InvalidVariableLocation; +import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; +import org.eclipse.cdt.debug.edc.symbols.ILocationProvider; +import org.eclipse.cdt.debug.edc.symbols.IModuleScope; +import org.eclipse.cdt.debug.edc.symbols.IScope; +import org.eclipse.cdt.debug.edc.symbols.IVariableLocation; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; + +public class LocationList implements ILocationProvider { + + protected LocationEntry[] locationList; + protected int addressSize; + protected IScope scope; + protected ByteOrder byteOrder; + + public LocationList(LocationEntry[] locationList, ByteOrder byteOrder, int addressSize, IScope scope) { + this.locationList = locationList; + this.byteOrder = byteOrder; + this.addressSize = addressSize; + this.scope = scope; + } + + public LocationEntry[] getLocationEntries() { + return locationList; + } + + public IVariableLocation getLocation(EDCServicesTracker tracker, IFrameDMContext context, IAddress forLinkAddress, boolean isNonLocalConstVariable) { + + if (locationList != null) { + IScope searchScope = scope; + do { + // the scope may be an inlined function scope, whose frame base is only provided in a parent. + IVariableLocation location = searchForLocation(tracker, context, forLinkAddress, searchScope); + if (location != null) { + return location; + } + searchScope = searchScope.getParent(); + } while (!(searchScope instanceof IModuleScope)); + } + + // variable may exist in the current scope, but not be live at the given + // address + return locationList != null ? new InvalidVariableLocation(DwarfMessages.UnknownVariableAddress) : null; + } + + private IVariableLocation searchForLocation(EDCServicesTracker tracker, + IFrameDMContext context, IAddress forLinkAddress, + IScope scope) { + long address = forLinkAddress.getValue().longValue(); + + // find the location entry for the given address + for (LocationEntry entry : locationList) { + if (address >= entry.getLowPC() && address < entry.getHighPC()) { + IStreamBuffer locationData = new MemoryStreamBuffer(entry.getBytes(), byteOrder); + LocationExpression expression = new LocationExpression(locationData, addressSize, scope); + return expression.getLocation(tracker, context, forLinkAddress, false); + } + } + + return null; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ILocationProvider#isLocationKnown(org.eclipse.cdt.core.IAddress) + */ + public boolean isLocationKnown(IAddress forLinkAddress) { + long address = forLinkAddress.getValue().longValue(); + + for (LocationEntry entry : locationList) { + if (address >= entry.getLowPC() && address < entry.getHighPC()) { + return true; + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.ILocationProvider#lifetimeMustMatchScope() + */ + public boolean lifetimeMustMatchScope() { + return false; // may or may not match + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/RangeList.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/RangeList.java new file mode 100644 index 0000000..51f77c4 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/dwarf/RangeList.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.dwarf; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import org.eclipse.cdt.debug.edc.symbols.IRangeList; + +/** + * This is a range of non-contiguous addresses + */ +public class RangeList implements IRangeList { + /** consecutive start, end entries */ + private List ranges = new ArrayList(); + private long low = Long.MAX_VALUE, high = Long.MIN_VALUE; + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "[0x" + Long.toHexString(getLowAddress()) + " to 0x" + Long.toHexString(getHighAddress()) + ")"; + } + + public void addRange(long start, long end) { + if (!ranges.isEmpty()) { + if (ranges.get(ranges.size() - 1) == start) { + ranges.set(ranges.size() - 1, end); + if (end > high) + high = end; + return; + } + } + ranges.add(start); + ranges.add(end); + + // track these dynamically since the list is not guaranteed to be ordered + if (start < low) + low = start; + if (end > high) + high = end; + } + + public long getLowAddress() { + if (ranges.isEmpty()) + return 0; + else + return low; + } + + public long getHighAddress() { + if (ranges.isEmpty()) + return 0; + else + return high; + } + + /** Get an iterator over the ranges. Fetch two entries at a time, + * which describe a [start, end) range. */ + public Iterator iterator() { + return new Iterator() { + int index = 0; + + public boolean hasNext() { + return index < ranges.size(); + } + + public Entry next() { + if (index >= ranges.size()) + throw new NoSuchElementException(); + index += 2; + return new IRangeList.Entry(ranges.get(index - 2), ranges.get(index - 1)); + } + + public void remove() { + // TODO Auto-generated method stub + + } + + }; + } + + /** + * Fixup a range list by adding a new low range + * @param addr + */ + public void addLowRange(long addr) { + if (low > addr) { + low = addr; + if (!ranges.isEmpty()) { + ranges.set(0, low); + } + } + } + + /** + * Fixup a range list by adding a new high range + * @param addr + */ + public void addHighRange(long addr) { + if (high < addr) { + high = addr; + if (!ranges.isEmpty()) { + ranges.set(ranges.size() - 1, addr); + } + } + + } + + /** + * Tell if an address is in a range. + * @param addr + */ + public boolean isInRange(long addr) { + for (Entry entry : this) { + if (entry.low >= addr && addr < entry.high) + return true; + } + return false; + } +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/BufferedRandomReadAccessFile.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/BufferedRandomReadAccessFile.java new file mode 100644 index 0000000..ae5d7d9 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/BufferedRandomReadAccessFile.java @@ -0,0 +1,388 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.symbols.elf; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.FileStreamBuffer; + +/** + * Buffering version of the {@link IRandomReadAccessFile} interface that uses the + * {@link IStreamBuffer} implementation. + */ +public class BufferedRandomReadAccessFile implements + IRandomReadAccessFile { + + /** source file */ + private RandomAccessFile file; + + /** endian-aware buffer */ + private FileStreamBuffer buffer; + /** native Java (big endian) buffer */ + private FileStreamBuffer bigEndianBuffer; + + /** current basis pointer */ + private long filePointer; + + /** + * @param osString + * @throws IOException + */ + public BufferedRandomReadAccessFile(String file, boolean isle) throws IOException { + this.file = new RandomAccessFile(file, "r"); //$NON-NLS-1$ + // for ELF-aware reading + this.buffer = new FileStreamBuffer(this.file, isle ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); + // for native DataInput APIs + this.bigEndianBuffer = new FileStreamBuffer(this.file, ByteOrder.BIG_ENDIAN); + } + + /* (non-Javadoc) + * @see java.io.DataInput#readFully(byte[]) + */ + public void readFully(byte[] b) throws IOException { + try { + bigEndianBuffer.get(b); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readFully(byte[], int, int) + */ + public void readFully(byte[] b, int off, int len) throws IOException { + try { + bigEndianBuffer.get(b, off, len); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#skipBytes(int) + */ + public int skipBytes(int n) throws IOException { + long cap = bigEndianBuffer.capacity(); + long cur = bigEndianBuffer.position(); + long pos = Math.min(cap, cur + n); + bigEndianBuffer.position(pos); + buffer.position(pos); + return (int) (pos - cur); + } + + /* (non-Javadoc) + * @see java.io.DataInput#readBoolean() + */ + public boolean readBoolean() throws IOException { + try { + return bigEndianBuffer.get() != 0; + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readByte() + */ + public byte readByte() throws IOException { + try { + return bigEndianBuffer.get(); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readUnsignedByte() + */ + public int readUnsignedByte() throws IOException { + try { + return bigEndianBuffer.get() & 0xff; + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readShort() + */ + public short readShort() throws IOException { + try { + return bigEndianBuffer.getShort(); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readUnsignedShort() + */ + public int readUnsignedShort() throws IOException { + try { + return bigEndianBuffer.getShort() & 0xffff; + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readChar() + */ + public char readChar() throws IOException { + try { + return bigEndianBuffer.getChar(); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readInt() + */ + public int readInt() throws IOException { + try { + return bigEndianBuffer.getInt(); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readLong() + */ + public long readLong() throws IOException { + try { + return bigEndianBuffer.getLong(); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readFloat() + */ + public float readFloat() throws IOException { + try { + return Float.intBitsToFloat(bigEndianBuffer.getInt()); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readDouble() + */ + public double readDouble() throws IOException { + try { + return Double.longBitsToDouble(bigEndianBuffer.getLong()); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readLine() + */ + public String readLine() throws IOException { + try { + StringBuilder sb = new StringBuilder(); + try { + int b; + while ((b = bigEndianBuffer.get()) != 0) { + sb.append((char) (b & 0xff)); + } + } catch (BufferUnderflowException e) { + if (sb.length() == 0) + return null; + } + return sb.toString(); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.DataInput#readUTF() + */ + public String readUTF() throws IOException { + try { + short length = bigEndianBuffer.getShort(); + StringBuilder sb = new StringBuilder(); + while (length-- > 0) { + // TODO + int c = (bigEndianBuffer.get()) & 0xff; + if (c >= 0x80) + assert false; + sb.append(c); + } + return sb.toString(); + } finally { + buffer.position(bigEndianBuffer.position()); + } + } + + /* (non-Javadoc) + * @see java.io.Closeable#close() + */ + public void close() throws IOException { + file.close(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#setEndian(boolean) + */ + public void setEndian(boolean le) { + buffer.setOrder(le ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); + + // keep bigEndianBuffer the same + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#setFileOffset(long) + */ + public void setFileOffset(long offset) throws IOException { + this.filePointer = offset; + try { + buffer.position(offset); + } catch (IllegalArgumentException e) { + throw (IOException) (new IOException().initCause(e)); + } finally { + bigEndianBuffer.position(offset); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#getFilePointer() + */ + public long getFilePointer() throws IOException { + return filePointer; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#seek(long) + */ + public void seek(long pos) throws IOException { + try { + buffer.position(pos + filePointer); + } catch (IllegalArgumentException e) { + throw (IOException) (new IOException().initCause(e)); + } finally { + bigEndianBuffer.position(pos + filePointer); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#readShortE() + */ + public short readShortE() throws IOException { + try { + return buffer.getShort(); + } finally { + bigEndianBuffer.position(buffer.position()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#readIntE() + */ + public long readIntE() throws IOException { + try { + return buffer.getInt(); + } finally { + bigEndianBuffer.position(buffer.position()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#readLongE() + */ + public long readLongE() throws IOException { + try { + return buffer.getLong(); + } finally { + bigEndianBuffer.position(buffer.position()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#readFullyE(byte[]) + */ + public void readFullyE(byte[] bytes) throws IOException { + try { + buffer.get(bytes); + if (buffer.getOrder() != ByteOrder.BIG_ENDIAN) { + for(int i=0; i < (bytes.length / 2); i++) + { + byte tmp = bytes[i]; + bytes[i] = bytes[bytes.length - i -1]; + bytes[bytes.length - i -1] = tmp; + } + } + } finally { + bigEndianBuffer.position(buffer.position()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#read(byte[], int, int) + */ + public int read(byte[] b, int off, int len) throws IOException { + try { + long max = bigEndianBuffer.capacity(); + int toRead = (int) Math.min(max - (off + len), len); + buffer.get(b, off, toRead); + return toRead; + } finally { + bigEndianBuffer.position(buffer.position()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#read(byte[]) + */ + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#length() + */ + public long length() throws IOException { + return buffer.capacity(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#createReadByteBuffer(long, long) + */ + public ByteBuffer createReadByteBuffer(long offset, long size) + throws IOException { + // we don't use this in EDC, so this is slower than wanted + // TODO + assert false; + try { + byte[] contents = new byte[(int) size]; + long cur = buffer.position(); + buffer.position(offset); + buffer.get(contents); + buffer.position(cur); + return ByteBuffer.wrap(contents); + } catch (IllegalArgumentException e) { + throw (IOException) (new IOException().initCause(e)); + } + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/ERandomAccessFile.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/ERandomAccessFile.java new file mode 100644 index 0000000..d03dfd9 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/ERandomAccessFile.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2000, 2009 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.elf; + + +import java.io.EOFException; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel.MapMode; + +import org.eclipse.cdt.debug.edc.internal.symbols.elf.IRandomReadAccessFile; + +/** + * @noextend This class is not intended to be subclassed by clients. + */ +public class ERandomAccessFile extends RandomAccessFile implements IRandomReadAccessFile { + private boolean isle; + private long ptr_offset; + int val[] = new int[4]; + + public ERandomAccessFile(String file, String mode) throws IOException { + super(file, mode); + } + + public ERandomAccessFile(File file, String mode) throws IOException { + super(file, mode); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomAccessFile#setEndian(boolean) + */ + public void setEndian(boolean le) + { + isle = le; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomAccessFile#readShortE() + */ + public final short readShortE() throws IOException { + val[0] = read(); + val[1] = read(); + if ((val[0] | val[1]) < 0) + throw new EOFException(); + if ( isle ) { + return (short)((val[1] << 8) + val[0]); + } + return (short)((val[0] << 8) + val[1]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomAccessFile#readIntE() + */ + public final long readIntE() throws IOException + { + val[0] = read(); + val[1] = read(); + val[2] = read(); + val[3] = read(); + if ((val[0] | val[1] | val[2] | val[3]) < 0) + throw new EOFException(); + if ( isle ) { + return ((val[3] << 24) + (val[2] << 16) + (val[1] << 8) + val[0]); + } + return ((val[0] << 24) + (val[1] << 16) + (val[2] << 8) + val[3]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomAccessFile#readLongE() + */ + public final long readLongE() throws IOException + { + byte [] bytes = new byte[8]; + long result = 0; + super.readFully(bytes); + int shift = 0; + if ( isle ) + for(int i=7; i >= 0; i-- ) + { + shift = i*8; + result += ( ((long)bytes[i]) << shift ) & ( 0xffL << shift ); + } + else + for(int i=0; i <= 7; i++ ) + { + shift = (7-i)*8; + result += ( ((long)bytes[i]) << shift ) & ( 0xffL << shift ); + } + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomAccessFile#readFullyE(byte[]) + */ + public final void readFullyE(byte [] bytes) throws IOException + { + super.readFully(bytes); + byte tmp = 0; + if( isle ) + for(int i=0; i < (bytes.length / 2); i++) + { + tmp = bytes[i]; + bytes[i] = bytes[bytes.length - i -1]; + bytes[bytes.length - i -1] = tmp; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomAccessFile#setFileOffset(long) + */ + public void setFileOffset( long offset ) throws IOException { + ptr_offset = offset; + super.seek( offset ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomAccessFile#getFilePointer() + */ + @Override + public long getFilePointer() throws IOException { + long ptr = super.getFilePointer(); + ptr = ptr - ptr_offset; + return ptr; + } + + @Override + public void seek( long pos ) throws IOException { + long real_pos = pos + ptr_offset; + super.seek( real_pos ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.IRandomReadAccessFile#createByteBuffer(long, long) + */ + public ByteBuffer createReadByteBuffer(long offset, long size) throws IOException { + return getChannel().map(MapMode.READ_ONLY, offset, size).load().asReadOnlyBuffer(); + } +} + + diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/Elf.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/Elf.java new file mode 100644 index 0000000..88759f2 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/Elf.java @@ -0,0 +1,1231 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - initial API and implementation + * Markus Schorn (Wind River Systems) + * Ed Swartz (Nokia) - temporary fork into EDC to adapt to IRandomReadAccessFile + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.elf; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.IAddressFactory; +import org.eclipse.cdt.core.ISymbolReader; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr32Factory; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.cdt.utils.Addr64Factory; + +public class Elf { + public final static int ELF32_ADDR_SIZE = 4; + public final static int ELF32_OFF_SIZE = 4; + public final static int ELF64_ADDR_SIZE = 8; + public final static int ELF64_OFF_SIZE = 8; + + protected IRandomReadAccessFile efile; + + protected ELFhdr ehdr; + protected Section[] sections; + protected String file; + protected byte[] section_strtab; + + private int syms = 0; + private Symbol[] symbols; + private Symbol[] symtab_symbols; + private Section symtab_sym; + private Symbol[] dynsym_symbols; + private Section dynsym_sym; + private boolean sections_mapped; // Have sections been mapped? Used to clean up properly in Elf.Dispose. + + protected String EMPTY_STRING = ""; //$NON-NLS-1$ + + public class ELFhdr { + + /* e_ident offsets */ + public final static int EI_MAG0 = 0; + public final static int EI_MAG1 = 1; + public final static int EI_MAG2 = 2; + public final static int EI_MAG3 = 3; + public final static int EI_CLASS = 4; + public final static int EI_DATA = 5; + public final static int EI_VERSION = 6; + public final static int EI_PAD = 7; + public final static int EI_NDENT = 16; + + /* e_ident[EI_CLASS] */ + public final static int ELFCLASSNONE = 0; + public final static int ELFCLASS32 = 1; + public final static int ELFCLASS64 = 2; + + /* e_ident[EI_DATA] */ + public final static int ELFDATANONE = 0; + public final static int ELFDATA2LSB = 1; + public final static int ELFDATA2MSB = 2; + + /* values of e_type */ + public final static int ET_NONE = 0; + public final static int ET_REL = 1; + public final static int ET_EXEC = 2; + public final static int ET_DYN = 3; + public final static int ET_CORE = 4; + public final static int ET_LOPROC = 0xff00; + public final static int ET_HIPROC = 0xffff; + + /* values of e_machine */ + public final static int EM_NONE = 0; + public final static int EM_M32 = 1; + public final static int EM_SPARC = 2; + public final static int EM_386 = 3; + public final static int EM_68K = 4; + public final static int EM_88K = 5; + public final static int EM_486 = 6; + public final static int EM_860 = 7; + public final static int EM_MIPS = 8; + public final static int EM_MIPS_RS3_LE = 10; + public final static int EM_RS6000 = 11; + public final static int EM_PARISC = 15; + public final static int EM_nCUBE = 16; + public final static int EM_VPP550 = 17; + public final static int EM_SPARC32PLUS = 18; + public final static int EM_PPC = 20; + public final static int EM_PPC64 = 21; + public final static int EM_ARM = 40; + public final static int EM_SH = 42; + public final static int EM_SPARCV9 = 43; + public final static int EM_TRICORE = 44; + public final static int EM_H8_300 = 46; + public final static int EM_H8_300H = 47; + public final static int EM_IA_64 = 50; + public final static int EM_COLDFIRE = 52; + public final static int EM_STARCORE = 58; + public final static int EM_X86_64 = 62; + public final static int EM_ST100 = 60; + + /** @since 5.2 */ + public final static int EM_68HC08 = 71; /* Freescale MC68HC08 Microcontroller */ + + public final static int EM_AVR = 83; + public final static int EM_FR30 = 84; /* Fujitsu FR30 */ + public final static int EM_V850 = 87; + public final static int EM_M32R = 88; + public final static int EM_MN10300 = 89; + public final static int EM_MN10200 = 90; + public final static int EM_XTENSA = 94; + public final static int EM_MSP430 = 105; + public final static int EM_BLACKFIN = 106; + public final static int EM_EXCESS = 111; + public final static int EM_NIOSII = 113; + public final static int EM_C166 = 116; + public final static int EM_M16C = 117; + + /** @since 5.2 */ + public final static int EM_RS08 = 132; /* Freescale RS08 embedded processor */ + + public final static int EM_MMDSP = 160; + public final static int EM_NIOS = 0xFEBB; + public final static int EM_CYGNUS_POWERPC = 0x9025; + public final static int EM_CYGNUS_M32R = 0x9041; + public final static int EM_CYGNUS_V850 = 0x9080; + public final static int EM_CYGNUS_MN10200 = 0xdead; + public final static int EM_CYGNUS_MN10300 = 0xbeef; + public final static int EM_CYGNUS_FR30 = 0x3330; + public final static int EM_XSTORMY16 = 0xad45; + public final static int EM_CYGNUS_FRV = 0x5441; + public final static int EM_IQ2000 = 0xFEBA; + public static final int EM_XILINX_MICROBLAZE = 0xbaab; + public static final int EM_SDMA = 0xcafe; + public static final int EM_CRADLE = 0x4d55; + + public byte e_ident[] = new byte[EI_NDENT]; + public int e_type; /* file type (Elf32_Half) */ + public int e_machine; /* machine type (Elf32_Half) */ + public long e_version; /* version number (Elf32_Word) */ + public IAddress e_entry; /* entry point (Elf32_Addr) */ + public long e_phoff; /* Program hdr offset (Elf32_Off) */ + public long e_shoff; /* Section hdr offset (Elf32_Off) */ + public long e_flags; /* Processor flags (Elf32_Word) */ + public short e_ehsize; /* sizeof ehdr (Elf32_Half) */ + public short e_phentsize; /* Program header entry size (Elf32_Half) */ + public short e_phnum; /* Number of program headers (Elf32_Half) */ + public short e_shentsize; /* Section header entry size (Elf32_Half) */ + public short e_shnum; /* Number of section headers (Elf32_Half) */ + public short e_shstrndx; /* String table index (Elf32_Half) */ + + protected ELFhdr() throws IOException { + efile.seek(0); + efile.readFully(e_ident); + if (e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' || e_ident[ELFhdr.EI_MAG2] != 'L' + || e_ident[ELFhdr.EI_MAG3] != 'F') + throw new IOException(CCorePlugin.getResourceString("Util.exception.notELF")); //$NON-NLS-1$ + efile.setEndian(e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB); + e_type = efile.readShortE(); + e_machine = efile.readShortE(); + e_version = efile.readIntE(); + switch (e_ident[ELFhdr.EI_CLASS]) { + case ELFhdr.ELFCLASS32 : { + byte[] addrArray = new byte[ELF32_ADDR_SIZE]; + efile.readFullyE(addrArray); + e_entry = new Addr32(addrArray); + e_phoff = efile.readIntE(); + e_shoff = efile.readIntE(); + } + break; + case ELFhdr.ELFCLASS64 : { + byte[] addrArray = new byte[ELF64_ADDR_SIZE]; + efile.readFullyE(addrArray); + e_entry = new Addr64(addrArray); + e_phoff = readUnsignedLong(efile); + e_shoff = readUnsignedLong(efile); + } + break; + case ELFhdr.ELFCLASSNONE : + default : + throw new IOException("Unknown ELF class " + e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + } + e_flags = efile.readIntE(); + e_ehsize = efile.readShortE(); + e_phentsize = efile.readShortE(); + e_phnum = efile.readShortE(); + e_shentsize = efile.readShortE(); + e_shnum = efile.readShortE(); + e_shstrndx = efile.readShortE(); + } + + protected ELFhdr(byte[] bytes) throws IOException { + if (bytes.length <= e_ident.length) { + throw new EOFException(CCorePlugin.getResourceString("Util.exception.notELF")); //$NON-NLS-1$ + } + System.arraycopy(bytes, 0, e_ident, 0, e_ident.length); + if (e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' || e_ident[ELFhdr.EI_MAG2] != 'L' + || e_ident[ELFhdr.EI_MAG3] != 'F') + throw new IOException(CCorePlugin.getResourceString("Util.exception.notELF")); //$NON-NLS-1$ + boolean isle = (e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB); + int offset = e_ident.length; + e_type = makeShort(bytes, offset, isle); + offset += 2; + e_machine = makeShort(bytes, offset, isle); + offset += 2; + e_version = makeInt(bytes, offset, isle); + offset += 4; + switch (e_ident[ELFhdr.EI_CLASS]) { + case ELFhdr.ELFCLASS32 : { + byte[] addrArray = new byte[ELF32_ADDR_SIZE]; + System.arraycopy(bytes, offset, addrArray, 0, ELF32_ADDR_SIZE); + offset += ELF32_ADDR_SIZE; + e_entry = new Addr32(addrArray); + e_phoff = makeInt(bytes, offset, isle); + offset += ELF32_OFF_SIZE; + e_shoff = makeInt(bytes, offset, isle); + offset += ELF32_OFF_SIZE; + } + break; + case ELFhdr.ELFCLASS64 : { + byte[] addrArray = new byte[ELF64_ADDR_SIZE]; + System.arraycopy(bytes, offset, addrArray, 0, ELF64_ADDR_SIZE); + offset += ELF64_ADDR_SIZE; + e_entry = new Addr64(addrArray); + e_phoff = makeUnsignedLong(bytes, offset, isle); + offset += ELF64_OFF_SIZE; + e_shoff = makeUnsignedLong(bytes, offset, isle); + offset += ELF64_OFF_SIZE; + } + break; + case ELFhdr.ELFCLASSNONE : + default : + throw new IOException("Unknown ELF class " + e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + } + e_flags = makeInt(bytes, offset, isle); + offset += 4; + e_ehsize = makeShort(bytes, offset, isle); + offset += 2; + e_phentsize = makeShort(bytes, offset, isle); + offset += 2; + e_phnum = makeShort(bytes, offset, isle); + offset += 2; + e_shentsize = makeShort(bytes, offset, isle); + offset += 2; + e_shnum = makeShort(bytes, offset, isle); + offset += 2; + e_shstrndx = makeShort(bytes, offset, isle); + offset += 2; + } + + private final short makeShort(byte[] val, int offset, boolean isle) throws IOException { + if (val.length < offset + 2) + throw new IOException(); + if (isle) { + return (short) ( (val[offset + 1] << 8) + val[offset + 0]); + } + return (short) ( (val[offset + 0] << 8) + val[offset + 1]); + } + + private final long makeInt(byte[] val, int offset, boolean isle) throws IOException { + if (val.length < offset + 4) + throw new IOException(); + if (isle) { + return ( (val[offset + 3] << 24) + (val[offset + 2] << 16) + (val[offset + 1] << 8) + val[offset + 0]); + } + return ( (val[offset + 0] << 24) + (val[offset + 1] << 16) + (val[offset + 2] << 8) + val[offset + 3]); + } + + private final long makeLong(byte[] val, int offset, boolean isle) throws IOException { + long result = 0; + int shift = 0; + if (isle) + for (int i = 7; i >= 0; i--) { + shift = i * 8; + result += ( ((long)val[offset + i]) << shift) & (0xffL << shift); + } + else + for (int i = 0; i <= 7; i++) { + shift = (7 - i) * 8; + result += ( ((long)val[offset + i]) << shift) & (0xffL << shift); + } + return result; + } + + private final long makeUnsignedLong(byte[] val, int offset, boolean isle) throws IOException { + long result = makeLong(val, offset, isle); + if (result < 0) { + throw new IOException("Maximal file offset is " + Long.toHexString(Long.MAX_VALUE) + //$NON-NLS-1$ + " given offset is " + Long.toHexString(result)); //$NON-NLS-1$ + } + return result; + + } + + } + + public class Section { + + /* sh_type */ + public final static int SHT_NULL = 0; + public final static int SHT_PROGBITS = 1; + public final static int SHT_SYMTAB = 2; + public final static int SHT_STRTAB = 3; + public final static int SHT_RELA = 4; + public final static int SHT_HASH = 5; + public final static int SHT_DYNAMIC = 6; + public final static int SHT_NOTE = 7; + public final static int SHT_NOBITS = 8; + public final static int SHT_REL = 9; + public final static int SHT_SHLIB = 10; + public final static int SHT_DYNSYM = 11; + + public final static int SHT_LOPROC = 0x70000000; + + /* sh_flags */ + public final static int SHF_WRITE = 1; + public final static int SHF_ALLOC = 2; + public final static int SHF_EXECINTR = 4; + + public long sh_name; + public long sh_type; + public long sh_flags; + public IAddress sh_addr; + public long sh_offset; + public long sh_size; + public long sh_link; + public long sh_info; + public long sh_addralign; + public long sh_entsize; + + /** + * @since 5.1 + */ + public ByteBuffer mapSectionData() throws IOException { + sections_mapped = true; + return efile.createReadByteBuffer(sh_offset, sh_size); + } + + public byte[] loadSectionData() throws IOException { + byte[] data = new byte[(int)sh_size]; + efile.seek(sh_offset); + efile.read(data); + return data; + } + + @Override + public String toString() { + try { + if (section_strtab == null) { + final int shstrndx= ehdr.e_shstrndx & 0xffff; // unsigned short + if (shstrndx > sections.length || shstrndx < 0) + return EMPTY_STRING; + int size = (int)sections[shstrndx].sh_size; + if (size <= 0 || size > efile.length()) + return EMPTY_STRING; + section_strtab = new byte[size]; + efile.seek(sections[shstrndx].sh_offset); + efile.read(section_strtab); + } + int str_size = 0; + if (sh_name > section_strtab.length) { + return EMPTY_STRING; + } + while (section_strtab[(int)sh_name + str_size] != 0) + str_size++; + return new String(section_strtab, (int)sh_name, str_size); + } catch (IOException e) { + return EMPTY_STRING; + } + } + } + + protected String string_from_elf_section(Elf.Section section, int index) throws IOException { + if (index > section.sh_size) { + return EMPTY_STRING; + } + + StringBuffer str = new StringBuffer(); + //Most string symbols will be less than 50 bytes in size + byte [] tmp = new byte[50]; + + efile.seek(section.sh_offset + index); + while(true) { + int len = efile.read(tmp); + for(int i = 0; i < len; i++) { + if(tmp[i] == 0) { + len = 0; + break; + } + str.append((char)tmp[i]); + } + if(len <= 0) { + break; + } + } + + return str.toString(); + } + + public class Symbol implements Comparable { + + /* Symbol bindings */ + public final static int STB_LOCAL = 0; + public final static int STB_GLOBAL = 1; + public final static int STB_WEAK = 2; + /* Symbol type */ + public final static int STT_NOTYPE = 0; + public final static int STT_OBJECT = 1; + public final static int STT_FUNC = 2; + public final static int STT_SECTION = 3; + public final static int STT_FILE = 4; + /* Special Indexes */ + public final static int SHN_UNDEF = 0; + public final static int SHN_LORESERVE = 0xffffff00; + public final static int SHN_LOPROC = 0xffffff00; + public final static int SHN_HIPROC = 0xffffff1f; + public final static int SHN_LOOS = 0xffffff20; + public final static int SHN_HIOS = 0xffffff3f; + public final static int SHN_ABS = 0xfffffff1; + public final static int SHN_COMMON = 0xfffffff2; + public final static int SHN_XINDEX = 0xffffffff; + public final static int SHN_HIRESERVE = 0xffffffff; + + /* NOTE: 64 bit and 32 bit ELF sections has different order */ + public long st_name; + public IAddress st_value; + public long st_size; + public short st_info; + public short st_other; + public short st_shndx; + + private String name = null; + + private final Section sym_section; + + public Symbol(Section section) { + sym_section = section; + } + + public int st_type() { + return st_info & 0xf; + } + + public int st_bind() { + return (st_info >> 4) & 0xf; + } + + public int compareTo(Object obj) { + /* + * long thisVal = 0; long anotherVal = 0; if ( obj instanceof Symbol ) { + * Symbol sym = (Symbol)obj; thisVal = this.st_value; anotherVal = + * sym.st_value; } else if ( obj instanceof Long ) { Long val = + * (Long)obj; anotherVal = val.longValue(); thisVal = this.st_value; } + * return (thisVal { + + IAddress val1, val2; + public int compare(Object o1, Object o2) { + + if (o1 instanceof IAddress) { + val1 = (IAddress)o1; + } else if (o1 instanceof Symbol) { + val1 = ((Symbol)o1).st_value; + } else { + return -1; + } + + if (o2 instanceof IAddress) { + val2 = (IAddress)o2; + } else if (o2 instanceof Symbol) { + val2 = ((Symbol)o2).st_value; + } else { + return -1; + } + return val1.compareTo(val2); + } + } + + public class PHdr { + + public final static int PT_NULL = 0; + public final static int PT_LOAD = 1; + public final static int PT_DYNAMIC = 2; + public final static int PT_INTERP = 3; + public final static int PT_NOTE = 4; + public final static int PT_SHLIB = 5; + public final static int PT_PHDR = 6; + + public final static int PF_X = 1; + public final static int PF_W = 2; + public final static int PF_R = 4; + /* NOTE: 64 bit and 32 bit ELF have different order and size of elements */ + public long p_type; + public long p_offset; + public IAddress p_vaddr; + public IAddress p_paddr; + public long p_filesz; + public long p_memsz; + public long p_flags; + public long p_align; + } + + public PHdr[] getPHdrs() throws IOException { + if (ehdr.e_phnum == 0) { + return new PHdr[0]; + } + efile.seek(ehdr.e_phoff); + final int length= ehdr.e_phnum & 0xffff; // interpret as unsigned short + PHdr phdrs[] = new PHdr[length]; + for (int i = 0; i < length; i++) { + phdrs[i] = new PHdr(); + switch (ehdr.e_ident[ELFhdr.EI_CLASS]) { + case ELFhdr.ELFCLASS32 : { + byte[] addrArray = new byte[ELF32_ADDR_SIZE]; + + phdrs[i].p_type = efile.readIntE(); + phdrs[i].p_offset = efile.readIntE(); + efile.readFullyE(addrArray); + phdrs[i].p_vaddr = new Addr32(addrArray); + efile.readFullyE(addrArray); + phdrs[i].p_paddr = new Addr32(addrArray); + phdrs[i].p_filesz = efile.readIntE(); + phdrs[i].p_memsz = efile.readIntE(); + phdrs[i].p_flags = efile.readIntE(); + phdrs[i].p_align = efile.readIntE(); + } + break; + case ELFhdr.ELFCLASS64 : { + byte[] addrArray = new byte[ELF64_ADDR_SIZE]; + + phdrs[i].p_type = efile.readIntE(); + phdrs[i].p_flags = efile.readIntE(); + phdrs[i].p_offset = readUnsignedLong(efile); + efile.readFullyE(addrArray); + phdrs[i].p_vaddr = new Addr64(addrArray); + efile.readFullyE(addrArray); + phdrs[i].p_paddr = new Addr64(addrArray); + phdrs[i].p_filesz = readUnsignedLong(efile); + phdrs[i].p_memsz = readUnsignedLong(efile); + phdrs[i].p_align = readUnsignedLong(efile); + } + break; + case ELFhdr.ELFCLASSNONE : + default : + throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + } + + } + return phdrs; + } + + public class Dynamic { + + public final static int DYN_ENT_SIZE_32 = 8; + public final static int DYN_ENT_SIZE_64 = 16; + + public final static int DT_NULL = 0; + public final static int DT_NEEDED = 1; + public final static int DT_PLTRELSZ = 2; + public final static int DT_PLTGOT = 3; + public final static int DT_HASH = 4; + public final static int DT_STRTAB = 5; + public final static int DT_SYMTAB = 6; + public final static int DT_RELA = 7; + public final static int DT_RELASZ = 8; + public final static int DT_RELAENT = 9; + public final static int DT_STRSZ = 10; + public final static int DT_SYMENT = 11; + public final static int DT_INIT = 12; + public final static int DT_FINI = 13; + public final static int DT_SONAME = 14; + public final static int DT_RPATH = 15; + public long d_tag; + public long d_val; + private final Section section; + private String name; + + protected Dynamic(Section section) { + this.section = section; + } + + @Override + public String toString() { + if (name == null) { + switch ((int)d_tag) { + case DT_NEEDED : + case DT_SONAME : + case DT_RPATH : + try { + Section symstr = sections[(int)section.sh_link]; + name = string_from_elf_section(symstr, (int)d_val); + } catch (IOException e) { + name = EMPTY_STRING; + } + break; + default : + name = EMPTY_STRING; + } + } + return name; + } + } + + public Dynamic[] getDynamicSections(Section section) throws IOException { + if (section.sh_type != Section.SHT_DYNAMIC) { + return new Dynamic[0]; + } + ArrayList dynList = new ArrayList(); + efile.seek(section.sh_offset); + int off = 0; + // We must assume the section is a table ignoring the sh_entsize as it + // is not + // set for MIPS. + while (off < section.sh_size) { + Dynamic dynEnt = new Dynamic(section); + switch (ehdr.e_ident[ELFhdr.EI_CLASS]) { + case ELFhdr.ELFCLASS32 : { + dynEnt.d_tag = efile.readIntE(); + dynEnt.d_val = efile.readIntE(); + off += Dynamic.DYN_ENT_SIZE_32; + } + break; + case ELFhdr.ELFCLASS64 : { + dynEnt.d_tag = efile.readLongE(); + dynEnt.d_val = efile.readLongE(); + off += Dynamic.DYN_ENT_SIZE_64; + } + break; + case ELFhdr.ELFCLASSNONE : + default : + throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + } + + if (dynEnt.d_tag != Dynamic.DT_NULL) + dynList.add(dynEnt); + } + return dynList.toArray(new Dynamic[0]); + } + + private void commonSetup(IRandomReadAccessFile rraFile, String file, long offset) throws IOException { + try { + efile = rraFile; + efile.seek(offset); + ehdr = new ELFhdr(); + this.file = file; + } finally { + if (ehdr == null) { + dispose(); + } + } + } + + //A hollow entry, to be used with caution in controlled situations + protected Elf() { + } + + public Elf(String file, long offset) throws IOException { + commonSetup(new ERandomAccessFile(file, "r"), file, offset); //$NON-NLS-1$ + } + + public Elf(String file) throws IOException { + commonSetup(new ERandomAccessFile(file, "r"), file, 0); //$NON-NLS-1$ + } + + public Elf(IRandomReadAccessFile rraFile, String file, long offset) throws IOException { + commonSetup(rraFile, file, offset); + } + + public ELFhdr getELFhdr() throws IOException { + return ehdr; + } + + public class Attribute { + + public static final int ELF_TYPE_EXE = 1; + public static final int ELF_TYPE_SHLIB = 2; + public static final int ELF_TYPE_OBJ = 3; + public static final int ELF_TYPE_CORE = 4; + + public static final int DEBUG_TYPE_NONE = 0; + public static final int DEBUG_TYPE_STABS = 1; + public static final int DEBUG_TYPE_DWARF = 2; + + String cpu; + int type; + int debugType; + boolean bDebug; + boolean isle; + IAddressFactory addressFactory; + + public String getCPU() { + return cpu; + } + + public int getType() { + return type; + } + + public boolean hasDebug() { + return debugType != DEBUG_TYPE_NONE; + } + + public int getDebugType() { + return debugType; + } + + public boolean isLittleEndian() { + return isle; + } + + public IAddressFactory getAddressFactory() { + return addressFactory; + } + } + + public Attribute getAttributes() throws IOException { + Attribute attrib = new Attribute(); + + switch (ehdr.e_type) { + case Elf.ELFhdr.ET_CORE : + attrib.type = Attribute.ELF_TYPE_CORE; + break; + case Elf.ELFhdr.ET_EXEC : + attrib.type = Attribute.ELF_TYPE_EXE; + break; + case Elf.ELFhdr.ET_REL : + attrib.type = Attribute.ELF_TYPE_OBJ; + break; + case Elf.ELFhdr.ET_DYN : + attrib.type = Attribute.ELF_TYPE_SHLIB; + break; + } + + switch (ehdr.e_machine & 0xFFFF) { + case Elf.ELFhdr.EM_386 : + case Elf.ELFhdr.EM_486 : + attrib.cpu = "x86"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_68K : + attrib.cpu = "m68k"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_PPC : + case Elf.ELFhdr.EM_CYGNUS_POWERPC : + case Elf.ELFhdr.EM_RS6000 : + attrib.cpu = "ppc"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_PPC64 : + attrib.cpu = "ppc64"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_SH : + attrib.cpu = "sh"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_ARM : + attrib.cpu = "arm"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_MIPS_RS3_LE : + case Elf.ELFhdr.EM_MIPS : + attrib.cpu = "mips"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_SPARC32PLUS : + case Elf.ELFhdr.EM_SPARC : + case Elf.ELFhdr.EM_SPARCV9 : + attrib.cpu = "sparc"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_H8_300 : + case Elf.ELFhdr.EM_H8_300H : + attrib.cpu = "h8300"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_V850 : + case Elf.ELFhdr.EM_CYGNUS_V850 : + attrib.cpu = "v850"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_MN10300 : + case Elf.ELFhdr.EM_CYGNUS_MN10300 : + attrib.cpu = "mn10300"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_MN10200 : + case Elf.ELFhdr.EM_CYGNUS_MN10200 : + attrib.cpu = "mn10200"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_M32R : + attrib.cpu = "m32r"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_FR30 : + case Elf.ELFhdr.EM_CYGNUS_FR30 : + attrib.cpu = "fr30"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_XSTORMY16 : + attrib.cpu = "xstormy16"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_CYGNUS_FRV : + attrib.cpu = "frv"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_IQ2000 : + attrib.cpu = "iq2000"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_EXCESS : + attrib.cpu = "excess"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_NIOSII : + attrib.cpu = "alteranios2"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_NIOS : + attrib.cpu = "alteranios"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_IA_64 : + attrib.cpu = "ia64"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_COLDFIRE: + attrib.cpu = "coldfire"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_AVR : + attrib.cpu = "avr"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_MSP430 : + attrib.cpu = "msp430"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_XTENSA: + attrib.cpu = "xtensa"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_ST100: + attrib.cpu = "st100"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_X86_64: + attrib.cpu = "x86_64"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_XILINX_MICROBLAZE: + attrib.cpu = "microblaze"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_C166: + attrib.cpu = "c166"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_TRICORE: + attrib.cpu = "TriCore"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_M16C: + attrib.cpu = "M16C"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_STARCORE: + attrib.cpu = "StarCore"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_BLACKFIN : + attrib.cpu = "bfin"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_SDMA: + attrib.cpu = "sdma"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_CRADLE: + attrib.cpu = "cradle"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_MMDSP: + attrib.cpu = "mmdsp"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_68HC08: + attrib.cpu = "hc08"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_RS08: + attrib.cpu = "rs08"; //$NON-NLS-1$ + break; + case Elf.ELFhdr.EM_NONE : + default : + attrib.cpu = "none"; //$NON-NLS-1$ + } + switch (ehdr.e_ident[Elf.ELFhdr.EI_DATA]) { + case Elf.ELFhdr.ELFDATA2LSB : + attrib.isle = true; + break; + case Elf.ELFhdr.ELFDATA2MSB : + attrib.isle = false; + break; + } + switch (ehdr.e_ident[ELFhdr.EI_CLASS]) { + case ELFhdr.ELFCLASS32 : + attrib.addressFactory = new Addr32Factory(); + break; + case ELFhdr.ELFCLASS64 : + attrib.addressFactory = new Addr64Factory(); + break; + case ELFhdr.ELFCLASSNONE : + default : + attrib.addressFactory = null; + } + // getSections + // find .debug using toString + Section[] sec = getSections(); + if (sec != null) { + for (int i = 0; i < sec.length; i++) { + String s = sec[i].toString(); + if (s.startsWith(".debug")) { //$NON-NLS-1$ + attrib.debugType = Attribute.DEBUG_TYPE_DWARF; + break; + } else if (s.equals(".stab")) { //$NON-NLS-1$ + attrib.debugType = Attribute.DEBUG_TYPE_STABS; + break; + } + } + } + return attrib; + } + + public static Attribute getAttributes(String file) throws IOException { + Elf elf = new Elf(file); + Attribute attrib = elf.getAttributes(); + elf.dispose(); + return attrib; + } + + public static Attribute getAttributes(byte[] array) throws IOException { + + Elf emptyElf = new Elf(); + emptyElf.ehdr = emptyElf.new ELFhdr(array); + emptyElf.sections = new Elf.Section[0]; + Attribute attrib = emptyElf.getAttributes(); + emptyElf.dispose(); + + return attrib; + } + + public static boolean isElfHeader(byte[] e_ident) { + if (e_ident.length < 4 || e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' + || e_ident[ELFhdr.EI_MAG2] != 'L' || e_ident[ELFhdr.EI_MAG3] != 'F') + return false; + return true; + } + + public void dispose() { + try { + if (efile != null) { + efile.close(); + efile = null; + + // ensure the mappings get cleaned up + if (sections_mapped) + System.gc(); + } + } catch (IOException e) { + } + } + + /** + * Make sure we do not leak the fds. + */ + @Override + protected void finalize() throws Throwable { + try { + dispose(); + } finally { + super.finalize(); + } + } + + public Section getSectionByName(String name) throws IOException { + if (sections == null) + getSections(); + for (int i = 0; i < sections.length; i++) { + if (sections[i].toString().equals(name)) { + return sections[i]; + } + } + return null; + } + + public Section[] getSections(int type) throws IOException { + if (sections == null) + getSections(); + ArrayList
    slist = new ArrayList
    (); + for (int i = 0; i < sections.length; i++) { + if (sections[i].sh_type == type) + slist.add(sections[i]); + } + return slist.toArray(new Section[0]); + } + + public Section[] getSections() throws IOException { + if (sections == null) { + if (ehdr.e_shoff == 0) { + sections = new Section[0]; + return sections; + } + final int length= ehdr.e_shnum & 0xffff; // unsigned short + sections = new Section[length]; + for (int i = 0; i < length; i++) { + efile.seek(ehdr.e_shoff + i * (ehdr.e_shentsize & 0xffff)); // unsigned short + sections[i] = new Section(); + sections[i].sh_name = efile.readIntE(); + sections[i].sh_type = efile.readIntE(); + switch (ehdr.e_ident[ELFhdr.EI_CLASS]) { + case ELFhdr.ELFCLASS32 : { + byte[] addrArray = new byte[ELF32_ADDR_SIZE]; + sections[i].sh_flags = efile.readIntE(); + efile.readFullyE(addrArray); + sections[i].sh_addr = new Addr32(addrArray); + sections[i].sh_offset = efile.readIntE(); + sections[i].sh_size = efile.readIntE(); + } + break; + case ELFhdr.ELFCLASS64 : { + byte[] addrArray = new byte[ELF64_ADDR_SIZE]; + sections[i].sh_flags = efile.readLongE(); + efile.readFullyE(addrArray); + sections[i].sh_addr = new Addr64(addrArray); + sections[i].sh_offset = readUnsignedLong(efile); + sections[i].sh_size = readUnsignedLong(efile); + } + break; + case ELFhdr.ELFCLASSNONE : + default : + throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + } + + sections[i].sh_link = efile.readIntE(); + sections[i].sh_info = efile.readIntE(); + switch (ehdr.e_ident[ELFhdr.EI_CLASS]) { + case ELFhdr.ELFCLASS32 : { + sections[i].sh_addralign = efile.readIntE(); + sections[i].sh_entsize = efile.readIntE(); + } + break; + case ELFhdr.ELFCLASS64 : { + sections[i].sh_addralign = efile.readLongE(); + sections[i].sh_entsize = readUnsignedLong(efile); + } + break; + case ELFhdr.ELFCLASSNONE : + default : + throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + } + if (sections[i].sh_type == Section.SHT_SYMTAB) + syms = i; + if (syms == 0 && sections[i].sh_type == Section.SHT_DYNSYM) + syms = i; + } + } + return sections; + } + + private Symbol[] loadSymbolsBySection(Section section) throws IOException { + int numSyms = 1; + if (section.sh_entsize != 0) { + numSyms = (int)section.sh_size / (int)section.sh_entsize; + } + ArrayList symList = new ArrayList(numSyms); + long offset = section.sh_offset; + for (int c = 0; c < numSyms; offset += section.sh_entsize, c++) { + efile.seek(offset); + Symbol symbol = new Symbol(section); + switch (ehdr.e_ident[ELFhdr.EI_CLASS]) { + case ELFhdr.ELFCLASS32 : { + byte[] addrArray = new byte[ELF32_ADDR_SIZE]; + + symbol.st_name = efile.readIntE(); + efile.readFullyE(addrArray); + symbol.st_value = new Addr32(addrArray); + symbol.st_size = efile.readIntE(); + symbol.st_info = efile.readByte(); + symbol.st_other = efile.readByte(); + symbol.st_shndx = efile.readShortE(); + } + break; + case ELFhdr.ELFCLASS64 : { + byte[] addrArray = new byte[ELF64_ADDR_SIZE]; + + symbol.st_name = efile.readIntE(); + symbol.st_info = efile.readByte(); + symbol.st_other = efile.readByte(); + symbol.st_shndx = efile.readShortE(); + efile.readFullyE(addrArray); + symbol.st_value = new Addr64(addrArray); + symbol.st_size = readUnsignedLong(efile); + } + break; + case ELFhdr.ELFCLASSNONE : + default : + throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + } + if (symbol.st_info == 0) + continue; + symList.add(symbol); + } + Symbol[] results = symList.toArray(new Symbol[0]); + Arrays.sort(results); + return results; + } + + public void loadSymbols() throws IOException { + if (symbols == null) { + Section section[] = getSections(Section.SHT_SYMTAB); + if (section.length > 0) { + symtab_sym = section[0]; + symtab_symbols = loadSymbolsBySection(section[0]); + } else { + symtab_sym = null; + symtab_symbols = new Symbol[0]; + } + + section = getSections(Section.SHT_DYNSYM); + if (section.length > 0) { + dynsym_sym = section[0]; + dynsym_symbols = loadSymbolsBySection(section[0]); + } else { + dynsym_sym = null; + dynsym_symbols = new Symbol[0]; + } + + if (symtab_sym != null) { + // sym = symtab_sym; + symbols = symtab_symbols; + } else if (dynsym_sym != null) { + // sym = dynsym_sym; + symbols = dynsym_symbols; + } + } + } + + public Symbol[] getSymbols() { + return symbols; + } + + public Symbol[] getDynamicSymbols() { + return dynsym_symbols; + } + + public Symbol[] getSymtabSymbols() { + return symtab_symbols; + } + + /* return the address of the function that address is in */ + public Symbol getSymbol(IAddress vma) { + if (symbols == null) { + return null; + } + + //@@@ If this works, move it to a single instance in this class. + SymbolComparator symbol_comparator = new SymbolComparator(); + + int ndx = Arrays.binarySearch(symbols, vma, symbol_comparator); + if (ndx > 0) + return symbols[ndx]; + if (ndx == -1) { + return null; + } + ndx = -ndx - 1; + return symbols[ndx - 1]; + } + /* + * public long swapInt( long val ) { if ( ehdr.e_ident[ELFhdr.EI_DATA] == + * ELFhdr.ELFDATA2LSB ) { short tmp[] = new short[4]; tmp[0] = (short)(val & + * 0x00ff); tmp[1] = (short)((val >> 8) & 0x00ff); tmp[2] = (short)((val >> + * 16) & 0x00ff); tmp[3] = (short)((val >> 24) & 0x00ff); return ((tmp[0] < < + * 24) + (tmp[1] < < 16) + (tmp[2] < < 8) + tmp[3]); } return val; } + * + * public int swapShort( short val ) { if ( ehdr.e_ident[ELFhdr.EI_DATA] == + * ELFhdr.ELFDATA2LSB ) { short tmp[] = new short[2]; tmp[0] = (short)(val & + * 0x00ff); tmp[1] = (short)((val >> 8) & 0x00ff); return (short)((tmp[0] < < + * 8) + tmp[1]); } return val; } + */ + public String getFilename() { + return file; + } + + protected long readUnsignedLong(IRandomReadAccessFile file) throws IOException { + long result = file.readLongE(); + if (result < 0) { + throw new IOException("Maximal file offset is " + Long.toHexString(Long.MAX_VALUE) + //$NON-NLS-1$ + " given offset is " + Long.toHexString(result)); //$NON-NLS-1$ + } + return result; + } + + /* TODO: not used in EDC + private ISymbolReader createDwarfReader() { + DwarfReader reader = null; + // Check if Dwarf data exists + try { + reader = new DwarfReader(this); + } catch (IOException e) { + // No Dwarf data in the Elf. + } + return reader; + } + */ + + public ISymbolReader getSymbolReader() { + ISymbolReader reader = null; + //reader = createDwarfReader(); // TODO: not used in EDC + return reader; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/IRandomReadAccessFile.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/IRandomReadAccessFile.java new file mode 100644 index 0000000..02fac0e --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/IRandomReadAccessFile.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + * Nokia - split out interface + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.symbols.elf; + +import java.io.Closeable; +import java.io.DataInput; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; + +/** + * Abstraction for the file reading used by the ERandomAccessFile and Elf classes. + *

    + * This provides endian-aware streamed read access to a file (methods ending in 'E'). + * The {@link #setEndian(boolean)} call must be invoked prior to calling them. + *

    + * This interface permits clients to interleave calls to the big-endian {@link DataInput} + * methods as well as the mixed-endian methods in this interface. The endianness + * may also be changed at will. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + * @since 7.0 + */ +public interface IRandomReadAccessFile extends DataInput, Closeable { + + /** + * Set endianness of file content. + * @param le true for little-endian, false for big-endian. + */ + void setEndian(boolean le); + + /** + * Set a base offset from which seek() and getFilePointer() measure, + * and seek there. + */ + void setFileOffset(long offset) throws IOException; + + /** + * Get the basis for seek operations + * @see #setFileOffset(long) + * @return offset + * @throws IOException + */ + long getFilePointer() throws IOException; + + /** + * Seek relative to the pointer set by {@link #setFileOffset(long)}. + * @see RandomAccessFile#seek(long) + */ + void seek(long pos) throws IOException; + + /** + * Read 2 bytes and construct a short according to endianness. + * @see DataInput#readShort() + */ + short readShortE() throws IOException; + + /** + * Read 4 bytes and construct an int according to endianness. + * @see DataInput#readInt() + */ + long readIntE() throws IOException; + + /** + * Read 8 bytes and construct a long according to endianness. + * @see DataInput#readLong() + */ + long readLongE() throws IOException; + + /** + * Read content and swap the entire range as if it were one large + * integer, according to the endianness. + *

    + * This assumes the incoming data is big-endian, so only swaps if + * {@link #setEndian(boolean)} was called with 'true'. + * @see DataInput#readFully(byte[]) + */ + void readFullyE(byte[] bytes) throws IOException; + + /** @see RandomAccessFile#read(byte[], int, int) */ + int read(byte b[], int off, int len) throws IOException; + + /** + * @see RandomAccessFile#read(byte[]) + */ + int read(byte b[]) throws IOException; + + /** + * @see RandomAccessFile#length() + */ + long length() throws IOException; + + /** + * Get a read-only buffer for the given range + * @param offset absolute offset (not relative to {@link #setFileOffset(long)}). + * @param size the size in bytes; may not extend beyond EOF. + */ + ByteBuffer createReadByteBuffer(long offset, long size) throws IOException; +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/README.txt b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/README.txt new file mode 100644 index 0000000..df03177 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/elf/README.txt @@ -0,0 +1,6 @@ + +This is a fork of the Elf and related classes from org.eclipse.cdt.core.utils +which is intended to to merged back into CDT core for the 7.1 or 8.0 release. +Don't add any new functionality to these. + + https://bugs.eclipse.org/bugs/show_bug.cgi?id=315420 \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/BaseExecutableSymbolicsReader.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/BaseExecutableSymbolicsReader.java new file mode 100644 index 0000000..0f3ce6b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/BaseExecutableSymbolicsReader.java @@ -0,0 +1,205 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.ISection; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSection; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.ISymbol; +import org.eclipse.cdt.debug.edc.symbols.IUnmangler; +import org.eclipse.core.runtime.IPath; + +/** + * Base implementation of a symbolics reader. Subclasses populae sections and symbols + * on construction. + */ +public abstract class BaseExecutableSymbolicsReader implements IExecutableSymbolicsReader { + + protected final IPath binaryFile; + + protected Map executableSections = new HashMap(); + protected List sections = new ArrayList(); + protected List symbols = new ArrayList(); + protected IAddress exeBaseAddress; + protected long modificationDate; + protected ISectionMapper sectionMapper; + + protected IUnmangler unmangler; + + /** + * + */ + public BaseExecutableSymbolicsReader(IPath binaryFile) { + this.binaryFile = binaryFile; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.IExecutableSymbolicsReader#dispose() + */ + public void dispose() { + if (sectionMapper != null) { + sectionMapper.dispose(); + sectionMapper = null; + } + sections.clear(); + symbols.clear(); + } + + public IPath getSymbolFile() { + return binaryFile; + } + + public Collection getExecutableSections() { + return Collections.unmodifiableCollection(executableSections.values()); + } + + public IExecutableSection findExecutableSection(String sectionName) { + return executableSections.get(sectionName); + } + + public Collection getSections() { + return Collections.unmodifiableCollection(sections); + } + + public Collection getSymbols() { + return Collections.unmodifiableCollection(symbols); + } + + public ISymbol getSymbolAtAddress(IAddress linkAddress) { + int insertion = Collections.binarySearch(symbols, linkAddress); + if (insertion >= 0) { + return symbols.get(insertion); + } + + if (insertion == -1) { + return null; + } + + insertion = -insertion - 1; + + ISymbol symbol = symbols.get(insertion - 1); + if (linkAddress.compareTo(symbol.getAddress().add(symbol.getSize())) < 0) { + return symbol; + } + + return null; + } + + public IAddress getBaseLinkAddress() { + return exeBaseAddress; + } + + public long getModificationDate() { + return modificationDate; + } + + public Collection findSymbols(String name) { + List matchSymbols = new ArrayList(); + + // look for exact symbols + for (ISymbol symbol : symbols) { + String symName = symbol.getName(); + if (symName.equals(name)) { + matchSymbols.add(symbol); + } + } + if (!matchSymbols.isEmpty()) + return matchSymbols; + + // try for a decorated symbol if no match + if (unmangler != null) { + for (ISymbol symbol : symbols) { + String symName = unmangler.undecorate(symbol.getName()); + if (symName.equals(name)) { + matchSymbols.add(symbol); + } + } + } + + return matchSymbols; + } + + public Collection findUnmangledSymbols(String name) { + List matchSymbols = new ArrayList(); + + if (unmangler != null) { + name = unmangler.undecorate(name); + + String nameNoSpaces = name.replaceAll("\\s", ""); + + // remove full qualifier + if (nameNoSpaces.startsWith("::")) + nameNoSpaces = nameNoSpaces.substring(2); + + boolean nameNoArguments = !nameNoSpaces.endsWith(")"); + + // avoid unmangling a lot of irrelevant symbols by filtering out symbols not containing the base name + String undecoratedBase = nameNoSpaces; + int idx = undecoratedBase.lastIndexOf(':'); + if (idx >= 0) + undecoratedBase = undecoratedBase.substring(idx+1); + idx = undecoratedBase.indexOf('('); + if (idx >= 0) + undecoratedBase = undecoratedBase.substring(0, idx); + + for (ISymbol symbol : symbols) { + String symName = symbol.getName(); + if (!symName.contains(undecoratedBase)) + continue; + + try { + String unmangled = unmangler.unmangle(unmangler.undecorate(symName)); + if (unmangled != null) { + String unmangledNoSpaces; + // remove any 'const' which is in front of '(' for now + unmangledNoSpaces = unmangled.replaceAll("\\bconst\\s*(?=\\()", ""); + unmangledNoSpaces = unmangledNoSpaces.replaceAll("\\s", ""); + + // remove full qualifier + if (unmangledNoSpaces.startsWith("::")) + unmangledNoSpaces = unmangledNoSpaces.substring(2); + + if (nameNoSpaces.equals(unmangledNoSpaces)) { + matchSymbols.add(symbol); + } else if (nameNoArguments) { + // try to match the name against a function + idx = unmangledNoSpaces.lastIndexOf('('); + if (idx >= 0) { + String unmangledNoArguments = unmangledNoSpaces.substring(0, idx); + if (unmangledNoArguments.equals(nameNoSpaces)) { + matchSymbols.add(symbol); + } + } + } + } + } catch (UnmanglingException e) { + // nope + } + } + if (!matchSymbols.isEmpty()) + return matchSymbols; + } + + return matchSymbols; + } + + public IUnmangler getUnmangler() { + return unmangler; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/DebugInfoProviderFactory.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/DebugInfoProviderFactory.java new file mode 100644 index 0000000..404e256 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/DebugInfoProviderFactory.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProvider; +import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProviderFactory; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; + +/** + * Factory for creating debug symbolics providers from executables. + */ +public class DebugInfoProviderFactory { + private static Map providerMap = new HashMap(); + + static { + initializeExtensions(); + } + + /** + * Create a debug info provider for the given binary (usually the executable being + * debugged). It's up to a {@link IDebugInfoProviderFactory} + * implementation to determine how it maps a binary to a symbolics file. + * @param binaryPath path to a host file + * @param exeReader the reader for that file, or null + * @return {@link IDebugInfoProvider} or null if nothing supports it + */ + public static IDebugInfoProvider createFor(IPath binaryPath, IExecutableSymbolicsReader exeReader) { + for (Map.Entry entry: providerMap.entrySet()) { + String name = entry.getKey(); + IDebugInfoProviderFactory providerProvider = entry.getValue(); + try { + IDebugInfoProvider provider = providerProvider.createDebugInfoProvider(binaryPath, exeReader); + if (provider != null) + return provider; + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError("Debug info reader " + name + " failed", t); + } + } + return null; + } + + protected static void initializeExtensions() { + IConfigurationElement[] elements = + Platform.getExtensionRegistry().getConfigurationElementsFor(IDebugInfoProviderFactory.EXTENSION_ID); + for (IConfigurationElement element : elements) { + try { + String name = element.getAttribute("name"); //$NON-NLS-1$ + IDebugInfoProviderFactory formatProvider = + (IDebugInfoProviderFactory) element.createExecutableExtension("class"); //$NON-NLS-1$ + providerMap.put(name, formatProvider); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError("Could not create executable symbolics provider extension", e); + } + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ElfExecutableSymbolicsReader.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ElfExecutableSymbolicsReader.java new file mode 100644 index 0000000..901b5e6 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ElfExecutableSymbolicsReader.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.io.IOException; +import java.nio.ByteOrder; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.ISection; +import org.eclipse.cdt.debug.edc.internal.symbols.Section; +import org.eclipse.cdt.debug.edc.internal.symbols.Symbol; +import org.eclipse.cdt.debug.edc.internal.symbols.elf.Elf; +import org.eclipse.cdt.debug.edc.internal.symbols.elf.Elf.PHdr; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSection; +import org.eclipse.core.runtime.IPath; + +/** + * This class handles reading ELF files for the purposes of detecting symbolics. + */ +public class ElfExecutableSymbolicsReader extends BaseExecutableSymbolicsReader { + protected boolean isLE; + + public ElfExecutableSymbolicsReader(IPath binaryFile, Elf elf) throws IOException { + super(binaryFile); + + Elf.ELFhdr header = elf.getELFhdr(); + isLE = header.e_ident[Elf.ELFhdr.EI_DATA] == Elf.ELFhdr.ELFDATA2LSB; + exeBaseAddress = getExeSegment(elf).p_vaddr; + modificationDate = binaryFile.toFile().lastModified(); + + sectionMapper = new SectionMapper(binaryFile, isLE); + + recordSections(elf); + readSymbols(elf); + + // TODO: better selection. We assume for now that all ELF targets we know about (ARM, Linux) use the same mangling. + unmangler = new UnmanglerEABI(); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ELF symbolics reader for " + binaryFile; //$NON-NLS-1$ + } + + /** + * Determine the executable format and record the sections. + * @param elfFile + * + * @throws IOException if file contents cannot be read + */ + private void recordSections(Elf elfFile) throws IOException { + + // start from zero so that we can use it as index to the array list + // for quick access. + int id = 0; + Map props; + + // Use segments instead of sections in the Elf file. + PHdr[] segments = elfFile.getPHdrs(); + + for (PHdr s : segments) { + if (s.p_type == PHdr.PT_LOAD) { + props = new HashMap(); + + if ((s.p_flags & PHdr.PF_X) != 0) + props.put(ISection.PROPERTY_NAME, ISection.NAME_TEXT); + else + // There is no clear way to tell if a segment is + // data or bss segment. + props.put(ISection.PROPERTY_NAME, ISection.NAME_DATA); + + Section section = new Section(id++, s.p_memsz, s.p_vaddr, props); + sections.add(section); + } + } + + // remember how to map the sections + Elf.Section[] sections = elfFile.getSections(); + for (Elf.Section section : sections) { + String name = section.toString(); + + if (name.length() > 0) { + if (executableSections.containsKey(name)) + throw new IllegalStateException("duplicate section " + name); + IExecutableSection exeSection = new ExecutableSection(sectionMapper, name, + new SectionInfo(section.sh_offset, section.sh_size)); + executableSections.put(name, exeSection); + } + } + } + + protected void readSymbols(Elf elfFile) throws IOException { + // load the symbol table + elfFile.loadSymbols(); + Set symbolAddressSet = new TreeSet(); + + for (Elf.Symbol symbol : elfFile.getSymtabSymbols()) { + String name = symbol.toString(); + // Multiple symbol entries for the same address are generated. + // Do not add duplicate symbols with 0 size to the list since it confuses + // debugger + if (name.length() > 0) { + if (symbol.st_size != 0 || !symbolAddressSet.contains(symbol.st_value)) { + // need to get rid of labels with size 0 + if (symbol.st_size != 0 || !name.startsWith("|")) { + symbols.add(new Symbol(symbol.toString(), symbol.st_value, symbol.st_size)); + symbolAddressSet.add(symbol.st_value); + } + } + } + } + + // now sort it by address for faster lookups + Collections.sort(symbols); + } + + /** + * Find the executable (text) segment of the elf file, assuming there is + * only one that segment. + * + * @param elf + * @return exe segment header or null on error. + * @throws IOException + */ + private PHdr getExeSegment(Elf elf) throws IOException { + PHdr[] segments = elf.getPHdrs(); + + for (PHdr s : segments) { + if (s.p_type == PHdr.PT_LOAD && ((s.p_flags & PHdr.PF_X) != 0)) + return s; + } + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IExecutableSymbolicsReader#getByteOrder() + */ + public ByteOrder getByteOrder() { + return isLE ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ElfExecutableSymbolicsReaderFactory.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ElfExecutableSymbolicsReaderFactory.java new file mode 100644 index 0000000..f43aef0 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ElfExecutableSymbolicsReaderFactory.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.io.FileInputStream; +import java.io.IOException; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.debug.edc.internal.symbols.elf.BufferedRandomReadAccessFile; +import org.eclipse.cdt.debug.edc.internal.symbols.elf.Elf; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReaderFactory; +import org.eclipse.cdt.utils.elf.Elf.ELFhdr; +import org.eclipse.core.runtime.IPath; + +/** + * Factory for creating readers of symbolics in executables. + */ +public class ElfExecutableSymbolicsReaderFactory implements IExecutableSymbolicsReaderFactory { + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IExecutableSymbolicsReaderFactory#getConfidence(org.eclipse.core.runtime.IPath) + */ + public int getConfidence(IPath binaryFile) { + Elf elfFile = getElfFile(binaryFile); + if (elfFile == null) { + // treat the symbol file as an executable, if existing + IPath symbolFilePath = ExecutableSymbolicsReaderFactory.findSymbolicsFile(binaryFile); + if (symbolFilePath != null) { + elfFile = getElfFile(symbolFilePath); + } + } + return elfFile != null ? IExecutableSymbolicsReaderFactory.NORMAL_CONFIDENCE : + IExecutableSymbolicsReaderFactory.NO_CONFIDENCE; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IExecutableSymbolicsReaderFactory#createExecutableSymbolicsReader(org.eclipse.core.runtime.IPath) + */ + public IExecutableSymbolicsReader createExecutableSymbolicsReader( + IPath binaryFile) { + + IExecutableSymbolicsReader reader = detectExecutable(binaryFile); + if (reader == null) { + // treat the symbol file as an executable, if existing + IPath symbolFilePath = ExecutableSymbolicsReaderFactory.findSymbolicsFile(binaryFile); + if (symbolFilePath != null) { + reader = detectExecutable(symbolFilePath); + } + } + + return reader; + } + + private IExecutableSymbolicsReader detectExecutable(IPath binaryFile) { + try { + Elf elfFile = getElfFile(binaryFile); + if (elfFile != null) { + return new ElfExecutableSymbolicsReader(binaryFile, elfFile); + } + } catch (IOException e) { + // this class elides actual I/O errors with format errors; ignore + } + return null; + } + + private Elf getElfFile(IPath binaryFile) { + try { + // quickly check the endianness (Elf repeats this) + FileInputStream fis = new FileInputStream(binaryFile.toOSString()); + byte[] e_ident = new byte[16]; + fis.read(e_ident); + if (e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' || e_ident[ELFhdr.EI_MAG2] != 'L' + || e_ident[ELFhdr.EI_MAG3] != 'F') + throw new IOException(CCorePlugin.getResourceString("Util.exception.notELF")); //$NON-NLS-1$ + + boolean isle = (e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB); + + // If this constructor succeeds, it's ELF + Elf elf = new Elf(new BufferedRandomReadAccessFile(binaryFile.toOSString(), isle), + binaryFile.toOSString(), 0); + return elf; + } catch (IOException e) { + // this class elides actual I/O errors with format errors; ignore + } + + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ExecutableSection.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ExecutableSection.java new file mode 100644 index 0000000..e626b89 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ExecutableSection.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.io.IOException; + +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSection; + +/** + * + */ +public class ExecutableSection implements IExecutableSection { + + private final String name; + private final ISectionMapper executableSectionMapper; + private final SectionInfo section; + private IStreamBuffer buffer; + private boolean deadSection; + + /** + * @param section + * @param name + * @param elfExecutableSymbolicsReader + */ + public ExecutableSection(ISectionMapper executableSectionMapper, + String name, + SectionInfo section) { + this.executableSectionMapper = executableSectionMapper; + this.name = name; + this.section = section; + this.deadSection = false; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return name + " @ " + section + (deadSection ? " <>": ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.IExecutableSection#getName() + */ + public String getName() { + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.IExecutableSection#getBuffer() + */ + public IStreamBuffer getBuffer() { + if (buffer == null && !deadSection) { + try { + buffer = executableSectionMapper.getSectionBuffer(section); + } catch (IOException e) { + deadSection = true; + EDCDebugger.getMessageLogger().logError("Failed to read section " + name, e); + } + } + return buffer; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.IExecutableSection#dispose() + */ + public void dispose() { + executableSectionMapper.releaseSectionBuffer(section); + buffer = null; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ExecutableSymbolicsReaderFactory.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ExecutableSymbolicsReaderFactory.java new file mode 100644 index 0000000..bbf9b7c --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ExecutableSymbolicsReaderFactory.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReaderFactory; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; + +/** + * Factory for creating readers of symbolics in executables. + */ +public class ExecutableSymbolicsReaderFactory { + + private static final String SYM_EXTENSION = "sym"; + private static final String DBG_EXTENSION = "dbg"; + + private static Map providerMap = new HashMap(); + + static { + initializeExtensions(); + } + + public static IExecutableSymbolicsReader createFor(IPath binaryFile) { + IExecutableSymbolicsReaderFactory provider = null; + String providerName = null; + int highestConfidence = IExecutableSymbolicsReaderFactory.NO_CONFIDENCE; + + // find the extension with the highest confidence for this binary + for (Map.Entry entry : providerMap.entrySet()) { + IExecutableSymbolicsReaderFactory factory = entry.getValue(); + try { + int confidence = factory.getConfidence(binaryFile); + if (confidence > highestConfidence) { + highestConfidence = confidence; + provider = factory; + providerName = entry.getKey(); + } + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError("Executable reader " + entry.getKey() + " failed", t); + } + } + + if (provider != null) { + try { + IExecutableSymbolicsReader reader = provider.createExecutableSymbolicsReader(binaryFile); + if (reader != null) + return reader; + } catch (Throwable t) { + EDCDebugger.getMessageLogger().logError("Executable reader " + providerName + " failed", t); + } + } + + return null; + } + + /** + * Get a symbolics file which is associated with the given executable. + * @param binaryFile + * @return IPath or null if no candidate (or already looks like a sym file) + */ + public static IPath findSymbolicsFile(IPath binaryFile) { + + // Check to see if there is a sym file we should use for the symbols + // + // Note: there may be for "foo.exe" --> "foo.exe.sym" or "foo.sym" + // + // Note #2: there may be BOTH. Pick the newest one. + // + List candidates = new ArrayList(); + + IPath symFile; + symFile = binaryFile.removeFileExtension().addFileExtension(SYM_EXTENSION); + if (symFile.toFile().exists()) + candidates.add(symFile); + symFile = binaryFile.removeFileExtension().addFileExtension(DBG_EXTENSION); + if (symFile.toFile().exists()) + candidates.add(symFile); + + symFile = binaryFile.addFileExtension(SYM_EXTENSION); + if (symFile.toFile().exists()) + candidates.add(symFile); + symFile = binaryFile.addFileExtension(DBG_EXTENSION); + if (symFile.toFile().exists()) + candidates.add(symFile); + + if (candidates.isEmpty()) + return null; + + if (candidates.size() > 1) { + Collections.sort(candidates, new java.util.Comparator() { + public int compare(IPath o1, IPath o2) { + long diff = o1.toFile().lastModified() - o2.toFile().lastModified(); + return diff > 0 ? -1 : diff < 0 ? 1 : 0; + } + }); + } + + return candidates.get(0); + } + + protected static void initializeExtensions() { + IConfigurationElement[] elements = + Platform.getExtensionRegistry().getConfigurationElementsFor(IExecutableSymbolicsReaderFactory.EXTENSION_ID); + for (IConfigurationElement element : elements) { + try { + String name = element.getAttribute("name"); //$NON-NLS-1$ + IExecutableSymbolicsReaderFactory formatProvider = + (IExecutableSymbolicsReaderFactory) element.createExecutableExtension("class"); //$NON-NLS-1$ + providerMap.put(name, formatProvider); + } catch (Exception e) { + EDCDebugger.getMessageLogger().logError("Could not create executable symbolics provider extension", e); + } + } + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/FileStatistics.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/FileStatistics.java new file mode 100644 index 0000000..c04d184 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/FileStatistics.java @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; + +/** + * Statistics tracking for file operations (used for debugging and unit tests) + */ +public class FileStatistics { + /** if set, dump info to console at runtme */ + public static boolean DEBUG = false; + /** # of executables opened in session */ + public static int executablesOpened; + /** # of executables currently open in session */ + public static int executablesOpen; + /** amount of memory for buffers currently allocated on heap */ + public static long currentHeapAllocatedBuffers; + /** amount of memory for buffers currently allocated in memory maps */ + /** amount of memory for buffers ever allocated on heap */ + public static long totalHeapAllocatedBuffers; + public static long currentMemoryMappedBuffers; + /** amount of memory for buffers ever allocated in memory maps */ + public static long totalMemoryMappedBuffers; + + /** Log interesting information */ + public static void log(String line) { + if (DEBUG) + System.out.println(line); + } + + private static String now() { + Calendar cal = Calendar.getInstance(); + DateFormat sdf = SimpleDateFormat.getTimeInstance(); + return sdf.format(cal.getTime()); + } + + public static void dump() { + System.out.println("File statistics at " + now() + ":"); + System.out.println("\t# executables opened: " + executablesOpened); + System.out.println("\t# executables still open: " + executablesOpen); + System.out.println("\tcurrent heap buffer allocation: " + currentHeapAllocatedBuffers); + System.out.println("\ttotal heap buffer allocation: " + totalHeapAllocatedBuffers); + System.out.println("\tcurrent memory mapped buffer allocation: " + currentMemoryMappedBuffers); + System.out.println("\ttotal memory mapped buffer allocation: " + totalMemoryMappedBuffers); + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ISectionMapper.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ISectionMapper.java new file mode 100644 index 0000000..fcc11e8 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/ISectionMapper.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.io.IOException; + +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.core.runtime.IPath; + +/** + * Handle mapping sections of an executable into memory and caching the content. + * This may hold files open and consume heap and system memory. + */ +public interface ISectionMapper { + /** + * Get the associated file on which content is mapped. + */ + IPath getMappedFile(); + + /** + * Get the contents of a section. The buffer may be cached or may be fetched on-demand, + * so there is no (memory) limit on its size. + * The buffer has the appropriate endianness for the file. + * @param section a backend-specific object representing a section + * @return an {@link IStreamBuffer} for the contents + * @throws IOException if contents could not be (re-)read. + */ + IStreamBuffer getSectionBuffer(SectionInfo section) throws IOException; + + /** + * Explicitly release a section's buffer. References to the previously-returned + * ByteBuffer may become invalid. + */ + void releaseSectionBuffer(SectionInfo section); + + /** + * Free any cached content and close any open files. + */ + void dispose(); +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/PEFileExecutableSymbolicsReader.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/PEFileExecutableSymbolicsReader.java new file mode 100644 index 0000000..55a2a8b --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/PEFileExecutableSymbolicsReader.java @@ -0,0 +1,276 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteOrder; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.edc.internal.symbols.ISection; +import org.eclipse.cdt.debug.edc.internal.symbols.Section; +import org.eclipse.cdt.debug.edc.internal.symbols.Symbol; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSection; +import org.eclipse.cdt.debug.edc.symbols.ISymbol; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.cdt.utils.coff.Coff.SectionHeader; +import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.cdt.utils.coff.PE.NTOptionalHeader; +import org.eclipse.core.runtime.IPath; + +/** + * This class handles PE-COFF files for the purpose of supporting symbolics. + */ +public class PEFileExecutableSymbolicsReader extends BaseExecutableSymbolicsReader { + + static public final String CODEVIEW_SECTION_NAME = "CodeView_Data"; + /** .CRT is another initialized data section utilized by the Microsoft C/C++ run-time libraries + * @since 5.2 + */ + public final static String _CRT = ".CRT"; //$NON-NLS-1$ + + protected boolean isLE; + protected Map sectionsByPEID = new HashMap(); + + public PEFileExecutableSymbolicsReader(IPath binaryFile, PE peFile) throws IOException { + super(binaryFile); + isLE = true; + exeBaseAddress = new Addr32(peFile.getNTOptionalHeader().ImageBase); + modificationDate = binaryFile.toFile().lastModified(); + + sectionMapper = new SectionMapper(binaryFile, isLE); + + recordSections(peFile); + + // TODO: better selection. + boolean isWin32 = false, isEABI = false; + for (ISymbol symbol : symbols) { + String symname = symbol.getName(); + if (symname.startsWith("__Z") && symname.endsWith("v")) { + isWin32 = true; + isEABI = true; + break; + } else if (symname.startsWith("_Z") && symname.endsWith("v")) { + isEABI = true; + break; + } else if (symname.contains("@") && symname.contains("?")) { + isWin32 = true; + break; + } + } + if (isWin32 && isEABI) + unmangler = new UnmanglerWin32EABI(); + else if (isEABI) + unmangler = new UnmanglerEABI(); + else + unmangler = new UnmanglerWin32(); + + + } + + /** + * Determine the executable format and record the sections. + * @param peFile + * + * @throws IOException if file reading fails + */ + private void recordSections(PE peFile) throws IOException { + // start from zero so that we can use it as index to the array list + // for quick access. + int id = 0; + Map props; + + SectionHeader[] secHeaders = peFile.getSectionHeaders(); + long imageBase = peFile.getNTOptionalHeader().ImageBase & 0xffffffffL; + SectionHeader rDataHeader = null; + int peSectionID = 0; + + for (SectionHeader s : secHeaders) { + peSectionID++; + String name = new String(s.s_name).trim(); + if (name.startsWith("/")) //$NON-NLS-1$ + { + int stringTableOffset = Integer.parseInt(name.substring(1)); + name = peFile.getStringTableEntry(stringTableOffset); + } + + // Remember how to map this section + if (executableSections.containsKey(name)) + throw new IllegalStateException("duplicate section " + name); + IExecutableSection exeSection = new ExecutableSection(sectionMapper, name, + new SectionInfo(s.s_scnptr, s.s_paddr)); + executableSections.put(name, exeSection); + + String sectionName = name; + // Convert the name to our unified name. + if (sectionName.equals(SectionHeader._TEXT)) + name = ISection.NAME_TEXT; + else if (sectionName.equals(SectionHeader._DATA) || sectionName.equals(_CRT)) + name = ISection.NAME_DATA; + else if (sectionName.equals(".rdata")) // add this name in SectionHeader ? + { + name = ISection.NAME_RODATA; + rDataHeader = s; + } + else if (sectionName.equals(SectionHeader._BSS)) + name = ISection.NAME_BSS; + else { // ignore other section. + continue; + } + + // Well, PE is a _modified_ version of COFF, where + // section.s_paddr of COFF becomes "VirtualSize" + // (memory size of the section) in PE, while s_size + // is raw data size (file size of the section). + long size = s.s_paddr; // not s_size ! + + props = new HashMap(); + props.put(ISection.PROPERTY_NAME, name); + + // Note the s_vaddr is relative to image base. + // For Section we need absolute address. + Section newSection = new Section(id++, size, new Addr64(Long.toString(imageBase + s.s_vaddr)), props); + sections.add(newSection); + sectionsByPEID.put(peSectionID, newSection); + } + + // load the symbol table + // + /* + * Note this "rawSymbols" array contains both standard and auxiliary + * symbol records. It's assumed symbols in the array are in the same + * order they appear in the symbol table section, no sorting of any kind + * is done. + * + * Actually auxiliary symbols should not be treated the same as standard + * symbols by Coff and PE in CDT core. But fixing that would break API, + * which is not allowed for CDT 7.0 at this time......... 04/07/10 + */ + org.eclipse.cdt.utils.coff.Coff.Symbol[] rawSymbols = peFile.getSymbols(); + + for (int i=0; i < rawSymbols.length; i++) { + org.eclipse.cdt.utils.coff.Coff.Symbol symbol = rawSymbols[i]; + + if (!(symbol.n_type == 0)) // Change to Coff.isNoSymbol for CDT 8.0. + { + String symName = symbol.getName(peFile.getStringTable()); + symbols.add(new Symbol(symName, new Addr32(symbol.n_value), 1)); + } + + // skip auxiliary symbol record(s) if any as otherwise they may + // give us bogus match in any symbol table lookup. + if (symbol.n_numaux > 0) { + i += symbol.n_numaux; + } + } + + if (rDataHeader != null) + checkForCodeView(peFile, rDataHeader, imageBase, id); + + // now sort it by address for faster lookups + Collections.sort(symbols); + } + + private void checkForCodeView(PE peFile, SectionHeader rDataHeader, long imageBase, int id) throws IOException { //$NON-NLS-1$ + // figure out the file offset of the debug directory + // entries + final int IMAGE_DIRECTORY_ENTRY_DEBUG = 6; + final int DEBUGDIRSZ = 28; + NTOptionalHeader ntHeader = peFile.getNTOptionalHeader(); + if (ntHeader == null + || ntHeader.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_DEBUG) + return; + + int debugDir = ntHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + if (debugDir == 0) + return; + + int debugFormats = ntHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size / 28; + if (debugFormats == 0) + return; + + int offsetInto_rdata = debugDir + - rDataHeader.s_vaddr; + int fileOffset = rDataHeader.s_scnptr + + offsetInto_rdata; + RandomAccessFile accessFile = new RandomAccessFile( + binaryFile.toOSString(), "r"); + + // loop through the debug directories looking for + // CodeView (type 2) + for (int j = 0; j < debugFormats; j++) { + PE.IMAGE_DEBUG_DIRECTORY dir = new PE.IMAGE_DEBUG_DIRECTORY( + accessFile, fileOffset); + + if ((dir.Type == 2) && (dir.SizeOfData > 0)) { + // CodeView found, seek to actual data + int debugBase = dir.PointerToRawData; + accessFile.seek(debugBase); + + // sanity check. the first four bytes of the + // CodeView + // data should be "NB11" + String s2 = accessFile.readLine(); + if (s2.startsWith("NB11")) { //$NON-NLS-1$ + // Attribute att = peFile.getAttribute(); + long start = debugBase; + long size = accessFile.length() - start; + + String name = CODEVIEW_SECTION_NAME; + IExecutableSection exeSection = new ExecutableSection(sectionMapper, name, + new SectionInfo(start, size)); + executableSections.put(name, exeSection); + } + } + fileOffset += DEBUGDIRSZ; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IExecutableSymbolicsReader#getByteOrder() + */ + public ByteOrder getByteOrder() { + return isLE ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.IExecutableSymbolicsReader#getSymbolAtAddress() + */ + @Override + public ISymbol getSymbolAtAddress(IAddress linkAddress) { + int insertion = Collections.binarySearch(symbols, linkAddress); + if (insertion >= 0) { + return symbols.get(insertion++); + } + + if (insertion == -1) { + return null; + } + + insertion = -insertion - 1; + + if (insertion == symbols.size()) { + return null; + } + + return symbols.get(insertion - 1); + } + + public ISection getSectionByPEID(int peID) + { + return sectionsByPEID.get(peID); + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/PEFileExecutableSymbolicsReaderFactory.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/PEFileExecutableSymbolicsReaderFactory.java new file mode 100644 index 0000000..0073026 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/PEFileExecutableSymbolicsReaderFactory.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.io.IOException; + +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader; +import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReaderFactory; +import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.core.runtime.IPath; + +/** + * Factory for creating readers of symbolics in executables. + */ +public class PEFileExecutableSymbolicsReaderFactory implements IExecutableSymbolicsReaderFactory { + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IExecutableSymbolicsReaderFactory#getConfidence(org.eclipse.core.runtime.IPath) + */ + public int getConfidence(IPath binaryFile) { + try { + // If this constructor succeeds, it's PE + @SuppressWarnings("unused") + PE peFile = new PE(binaryFile.toOSString()); + return IExecutableSymbolicsReaderFactory.NORMAL_CONFIDENCE; + } catch (IOException e) { + // this class elides actual I/O errors with format errors; ignore + } + return IExecutableSymbolicsReaderFactory.NO_CONFIDENCE; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IExecutableSymbolicsReaderFactory#createExecutableSymbolicsReader(org.eclipse.core.runtime.IPath) + */ + public IExecutableSymbolicsReader createExecutableSymbolicsReader( + IPath binaryFile) { + + try { + // If this constructor succeeds, it's PE + PE peFile = new PE(binaryFile.toOSString()); + return new PEFileExecutableSymbolicsReader(binaryFile, peFile); + } catch (IOException e) { + // this class elides actual I/O errors with format errors; ignore + } + return null; + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/SectionInfo.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/SectionInfo.java new file mode 100644 index 0000000..2c59874 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/SectionInfo.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +/** + * Information about the range of content for a section. Used as a key in {@link SectionMapper}. + */ +public class SectionInfo { + + public long fileOffset; + public long sectionSize; + + public SectionInfo(long fileOffset, long sectionSize) { + this.fileOffset = fileOffset; + this.sectionSize = sectionSize; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "section from " + Long.toHexString(fileOffset) + " - " + Long.toHexString(fileOffset + sectionSize); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (fileOffset ^ (fileOffset >>> 32)); + result = prime * result + (int) (sectionSize ^ (sectionSize >>> 32)); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SectionInfo other = (SectionInfo) obj; + if (fileOffset != other.fileOffset) + return false; + if (sectionSize != other.sectionSize) + return false; + return true; + } + + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/SectionMapper.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/SectionMapper.java new file mode 100644 index 0000000..9791720 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/SectionMapper.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.io.IOException; +import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.edc.IStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.FileStreamBuffer; +import org.eclipse.cdt.debug.edc.internal.MemoryStreamBuffer; +import org.eclipse.cdt.utils.ERandomAccessFile; +import org.eclipse.core.runtime.IPath; + +/** + * Handle mapping sections into memory and caching this content. + */ +public class SectionMapper implements ISectionMapper { + + private final IPath hostFile; + private final boolean isLE; + private ERandomAccessFile efile; + /** all sections loaded for any reason */ + private Map loadedSections; + /** subset of sections loaded into memory maps */ + private Map mappedBuffers; + + public SectionMapper(IPath hostFile, boolean isLE) { + this.hostFile = hostFile; + this.isLE = isLE; + this.efile = null; + this.loadedSections = new HashMap(); + this.mappedBuffers = new HashMap(); + } + + public void dispose() { + for (Map.Entry entry: loadedSections.entrySet()) { + IStreamBuffer buffer = entry.getValue(); + if (buffer == null) + continue; + if (mappedBuffers.containsKey(entry.getKey())) + FileStatistics.currentMemoryMappedBuffers -= buffer.capacity(); + else + FileStatistics.currentHeapAllocatedBuffers -= buffer.capacity(); + } + loadedSections.clear(); + mappedBuffers.clear(); + close(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.ISectionMapper#getMappedFile() + */ + public IPath getMappedFile() { + return hostFile; + } + + /** + * + */ + private void ensureOpen() throws IOException { + if (efile == null) { + FileStatistics.log("Opening " + hostFile.toFile()); + FileStatistics.executablesOpened++; + FileStatistics.executablesOpen++; + efile = new ERandomAccessFile(hostFile.toFile(), "r"); + } + } + + + private void close() { + if (!mappedBuffers.isEmpty()) + throw new IllegalStateException("cannot close file; mapped buffers open"); + if (efile != null) { + try { + FileStatistics.log("Closing " + hostFile.toFile()); + FileStatistics.executablesOpen--; + efile.close(); + } catch (IOException e) { + // ignore + } + } + efile = null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.IExecutableSectionMapper#getSectionBuffer(org.eclipse.cdt.debug.edc.internal.symbols.exe.SectionInfo) + */ + public IStreamBuffer getSectionBuffer(SectionInfo section) throws IOException { + + ensureOpen(); + + IStreamBuffer buffer = loadedSections.get(section); + if (buffer == null) { + buffer = loadSection(section); + + loadedSections.put(section, buffer); + // TODO: flush data occasionally, before #dispose() + } + + return buffer; + } + + private IStreamBuffer loadSection(SectionInfo section) + throws IOException { + FileStatistics.log("Loading " + section + " from " + hostFile.toFile()); + + IStreamBuffer buffer = null; + + // If the sym file is too large, it's useless reading it + // into the heap and choking the memory. + // Just read it on-demand from disk. + try { + if (section.sectionSize > 4 * 1024 * 1024) { + buffer = loadSectionIntoFileStreamBuffer(section); + } else { + buffer = loadSectionIntoHeap(section); + } + } catch (IOException e) { + buffer = loadSectionIntoHeap(section); + } + + return buffer; + } + + /** + * Load section contents into a streaming buffer. This is a little slower but + * does not allocate any more than a page of memory at a time. + * + * @param section + * @param buffer + * @return new {@link IStreamBuffer} + */ + private IStreamBuffer loadSectionIntoFileStreamBuffer(SectionInfo section) throws IOException { + IStreamBuffer buffer = null; + try { + buffer = new FileStreamBuffer(efile, isLE ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN, + section.fileOffset, section.sectionSize); + mappedBuffers.put(section, buffer); + FileStatistics.currentMemoryMappedBuffers += buffer.capacity(); + FileStatistics.totalMemoryMappedBuffers += buffer.capacity(); + } catch (Throwable e2) { + EDCDebugger.getMessageLogger().logError("Failed to make buffer for section " + section, e2); + } + return buffer; + } + + private IStreamBuffer loadSectionIntoHeap(SectionInfo section) + throws IOException { + IStreamBuffer buffer; + // try to load the section into memory because it will + // be faster + byte[] data = new byte[(int)section.sectionSize]; + efile.seek(section.fileOffset); + efile.read(data); + buffer = new MemoryStreamBuffer(data, isLE ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); + FileStatistics.currentHeapAllocatedBuffers += data.length; + FileStatistics.totalHeapAllocatedBuffers += data.length; + return buffer; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.ISectionMapper#releaseBuffer(java.nio.ByteBuffer) + */ + public void releaseSectionBuffer(SectionInfo section) { + IStreamBuffer buffer = loadedSections.remove(section); + if (buffer != null) { + if (mappedBuffers.remove(section) != null) { + FileStatistics.currentMemoryMappedBuffers -= buffer.capacity(); + if (mappedBuffers.isEmpty()) { + close(); + } + } else { + FileStatistics.currentHeapAllocatedBuffers -= buffer.capacity(); + } + } + } + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/UnmanglerEABI.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/UnmanglerEABI.java new file mode 100644 index 0000000..aedc1dc --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/internal/symbols/files/UnmanglerEABI.java @@ -0,0 +1,1824 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc.internal.symbols.files; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.WeakHashMap; + +import org.eclipse.cdt.debug.edc.symbols.IUnmangler; + +/** + * Unmangler for the ARM/Itanium/etc. EABI (http://www.codesourcery.com/public/cxx-abi/abi.html) + *

    + * TODO: + */ +public class UnmanglerEABI implements IUnmangler { + + private static boolean DEBUG = false; + + enum SubstType { + PREFIX, + TEMPLATE_PREFIX, + TYPE, + QUAL_TYPE, + TEMPLATE_TEMPLATE_PARAM, + + } + public UnmanglerEABI() { + + } + + static class UnmangleState { + private char[] symbol; + private int index; + StringBuilder buffer; + private Stack pushes ; // lengths of buffer when pushed + private List substitutions; + private Map substitutionTypes; + private int lastTypeNameIndex; + + private List templateArgs; + private int templateArgBase; + private Stack templateArgStack; // length of templateArgs when pushed + + private Stack backtracks ; // grouped entries: index value, lengths of buffer, and substitutions length when pushed + + private final boolean nameOnly; + + public UnmangleState(String symbol, boolean nameOnly) { + this.symbol = symbol.toCharArray(); + this.nameOnly = nameOnly; + index = 0; + buffer = new StringBuilder(); + pushes = new Stack(); + substitutions = new ArrayList(); + substitutionTypes = new HashMap(); + templateArgs = new ArrayList(); + templateArgStack = new Stack(); + backtracks = new Stack(); + lastTypeNameIndex = -1; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + String remaining = getRemaining(); + if (remaining.length() == 0) + remaining = "<>"; + return "state: at [" + remaining + "], so far: " + current(); + } + + /** + * Push when entering a new decoding context (BNF expression). + */ + public void push() { + pushes.push(buffer.length()); + } + + /** + * Pop the current decoded string and restore context to + * the calling context. + * @return decoded string + */ + public String pop() { + int oldpos = pushes.isEmpty() ? 0 : pushes.pop(); + String str = buffer.substring(oldpos, buffer.length()); + buffer.setLength(oldpos); + return str; + } + + /** + * Push template argument state + */ + public void pushTemplateArgs() { + templateArgStack.push(templateArgBase); + templateArgStack.push(templateArgs.size()); + } + + /** + * Pop template argument state + * @throws UnmanglingException + */ + public void popTemplateArgs() throws UnmanglingException { + try { + templateArgs.subList(templateArgStack.pop(), templateArgs.size()).clear(); + templateArgBase = templateArgStack.pop(); + } catch (Exception e) { + throw new UnmanglingException("template stack empty", buffer.toString()); + } + } + /** + * Push all state, when entering a possible backtrack scenario. + * Use #safePop() if an operation succeeds, or #safeBacktrack() + * if it failed and you want to retry. + */ + public void safePush() { + backtracks.push(index); + backtracks.push(lastTypeNameIndex); + backtracks.push(buffer.length()); + backtracks.push(substitutions.size()); + backtracks.push(pushes.size()); + } + + /** + * Call when a #safePush() branch has succeeded to discard backtrack state. + */ + public void safePop() { + backtracks.pop(); + backtracks.pop(); + backtracks.pop(); + backtracks.pop(); + backtracks.pop(); + } + + /** + * Call when a #safePush() branch has failed to reset backtrack state. + * (To perform another backtrack, call #safePush() again) + */ + public void safeBacktrack() { + int oldSize = backtracks.pop(); + pushes.subList(oldSize, pushes.size()).clear(); + oldSize = backtracks.pop(); + substitutions.subList(oldSize, substitutions.size()).clear(); + while (substitutionTypes.size() > oldSize) + substitutionTypes.remove(substitutionTypes.size() - 1); + buffer.setLength(backtracks.pop()); + lastTypeNameIndex = backtracks.pop(); + index = backtracks.pop(); + } + + /** + * Tell if there is any current string (length > 0) + * @return + */ + public boolean hasCurrent() { + int oldpos = pushes.isEmpty() ? 0 : pushes.peek(); + int end = buffer.length(); + return end > oldpos; + } + + /** + * Get the current constructed string (since the last #push()) + * @return + */ + public String current() { + int oldpos = pushes.isEmpty() ? 0 : pushes.peek(); + String str = buffer.substring(oldpos, buffer.length()); + return str; + } + + /** + * Remember the current constructed string as a substitution. + * @param substType + */ + public void remember(SubstType substType) { + remember(current(), substType); + } + + public boolean lastSubstitutionIsPrefix(SubstType substType) { + if (substitutions.size() == 0) + return false; + String current = current(); + if (substitutions.get(substitutions.size() - 1).length() >= current.length()) + return false; + return lastSubstitution() == substType; + } + /** + * Remember the given string as a substitution. + * @param name + * @param substType + */ + public void remember(String name, SubstType substType) { + if (name.length() == 0) + return; + int num = substitutions.size(); + if (num > 0 && substitutions.get(num - 1).equals(name)) + return; + substitutions.add(name); + substitutionTypes.put(num, substType); + lastTypeNameIndex = num; + if (DEBUG) System.out.println(num+" := " + name + " --> " + substType); + } + + /** + * Replace the last substitution. + * @param name + * @param substType + */ + public void rememberInstead(String name, SubstType substType) { + int num = substitutions.size() - 1; + substitutions.set(num, name); + substitutionTypes.put(num, substType); + if (DEBUG) System.out.println(num+" ::= " + name + " -- > " + substType); + } + + /** + * Pop the current decoded string as in {@link #pop()} + * and remember the string as a substitution. + * @return String + */ + public String popAndRemember(SubstType substType) { + String name = pop(); + remember(name, substType); + return name; + } + + public char peek() { + return index < symbol.length ? symbol[index] : 0; + } + + public char peek(int offset) { + return index + offset < symbol.length ? symbol[index + offset] : 0; + } + + public void consume(char ch) throws UnmanglingException { + if (ch != get()) + throw unexpected(); + } + public char get() { + return index < symbol.length ? symbol[index++] : 0; + } + + public void unget() { + if (index > 0) index--; + } + public void skip() { + if (index < symbol.length) + index++; + } + + public void skip2() { + index = Math.min(index + 2, symbol.length); + } + + public boolean done() { + return index >= symbol.length; + } + + public UnmanglingException unexpected() { + return new UnmanglingException("Unexpected text at " + getRemaining(), buffer.toString()); + } + public UnmanglingException unexpected(String what) { + return new UnmanglingException("Wanted " + what + " but got unexpected text at " + getRemaining(), buffer.toString()); + } + public UnmanglingException notImplemented() { + return new UnmanglingException("Unimplemented at " + getRemaining(), + buffer.toString()); + } + + /** + * @return + */ + private String getRemaining() { + if (index >= symbol.length) + return ""; + return new String(symbol, index, symbol.length - index); + } + + /** + * @throws UnmanglingException + * + */ + public void throwIfDone() throws UnmanglingException { + if (done()) + throw new UnmanglingException("Unexpected end of symbol", + buffer.toString()); + } + + public void updateSubstitution(SubstType substType) { + int num = substitutions.size() - 1; + substitutionTypes.put(num, substType); + if (DEBUG) System.out.println(num + " ::= " + substType); + } + + /** + * @return + */ + public SubstType lastSubstitution() { + return substitutionTypes.get(substitutions.size() - 1); + } + + /** + * @param arg + */ + public void rememberTemplateArg(String arg) { + templateArgs.add(arg); + } + + /** + * @param num + * @return + * @throws UnmanglingException + */ + public String getTemplateArg(int num) throws UnmanglingException { + num -= templateArgBase; + if (num < 0 || num >= templateArgs.size()) + throw unexpected("template argument in range 0-" + (templateArgs.size() - templateArgBase)+"; got " + num); + return templateArgs.get(num); + } + + public String lastSubstitutedName() { + if (lastTypeNameIndex < 0) + return ""; + return substitutions.get(lastTypeNameIndex); + } + } + + private static WeakHashMap unmangledMap = new WeakHashMap(); + private static WeakHashMap withoutArgsMap = new WeakHashMap(); + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IUnmangler#undecorate(java.lang.String) + */ + public String undecorate(String symbol) { + // symbols may have @@GLIBC... type suffixes + int atat = symbol.indexOf("@@"); + if (atat > 0) + symbol = symbol.substring(0, atat); + return symbol; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.symbols.files.IUnmangler#isMangled(java.lang.String) + */ + public boolean isMangled(String symbol) { + if (symbol == null) + return false; + if (symbol.startsWith("_Z")) + return true; + // this is used for enum constants + if (symbol.startsWith("__N")) + return true; + return false; + } + + public String unmangleWithoutArgs(String symbol) throws UnmanglingException { + return unmangle(symbol, true); + } + + public String unmangle(String symbol) throws UnmanglingException { + return unmangle(symbol, false); + } + + public String unmangleType(String symbol) throws UnmanglingException { + if (symbol == null) + return null; + + if (unmangledMap.containsKey(symbol)) + return unmangledMap.get(symbol); + + if (symbol.startsWith("_Z")) { + UnmangleState state = new UnmangleState(symbol, false); + state.skip2(); + String unmangled = ""; + if (state.peek() == 'S') { + unmangled += unmangleSubstitution(state); + } + while (!state.done()) { + if (state.peek() == 'I') { + // unscoped-template-name + state.remember(unmangled, SubstType.TEMPLATE_PREFIX); + String args = unmangleTemplateArgs(state, false); + state.buffer.append(args); + unmangled += args; + } else { + if (unmangled.equals("::std")) + unmangled += "::"; + unmangled += unmangleType(state); + } + state.remember(unmangled, SubstType.TYPE); + } + unmangledMap.put(symbol, unmangled); + return unmangled; + } + return symbol; + } + + public String unmangle(String symbol, boolean skipArgs) throws UnmanglingException { + if (symbol == null) + return null; + + String unmangled; + + if (skipArgs) { + if (withoutArgsMap.containsKey(symbol)) + unmangled = withoutArgsMap.get(symbol); + else { + unmangled = doUnmangle(symbol, true); + withoutArgsMap.put(symbol, unmangled); + } + } else if (unmangledMap.containsKey(symbol)) { + unmangled = unmangledMap.get(symbol); + } else { + unmangled = doUnmangle(symbol, skipArgs); + unmangledMap.put(symbol, unmangled); + + do {// for break below if conditionals succeed + int paren = unmangled.indexOf('('); + if (0 < paren) { + String unmangledWithoutArgs = unmangled.substring(0, paren-1); + if (unmangledWithoutArgs != null && unmangledWithoutArgs.length() != 0) { + withoutArgsMap.put(symbol, unmangledWithoutArgs); + break; + } } + withoutArgsMap.put(symbol, unmangled); + } while (false);// allows break above to skip default case + } + + return unmangled; + } + + /** + * @param symbol + * @return + * @throws UnmanglingException + */ + private String doUnmangle(String symbol, boolean nameOnly) throws UnmanglingException { + /* + Entities with C linkage and global namespace variables are not mangled. Mangled names have the general structure: + + + ::= _Z + ::= + ::= + ::= + */ + if (symbol.startsWith("_Z")) { + String suffix = ""; + int idx = symbol.indexOf('@'); + if (idx >= 0) { + suffix = symbol.substring(idx); + symbol = symbol.substring(0, idx); + } + + UnmangleState state = new UnmangleState(symbol, nameOnly); + state.skip2(); + + String unmangled = unmangleEncoding(state); + unmangled += suffix; + return unmangled; + } else if (symbol.startsWith("__N")) { + UnmangleState state = new UnmangleState(symbol, true); + state.skip2(); + + String unmangled = unmangleName(state); + return unmangled; + } else { + return symbol; + } + } + + /* + ::= + ::= + ::= + */ + private String unmangleEncoding(UnmangleState state) throws UnmanglingException { + state.push(); + + String name; + + // ferret out + char ch = state.peek(); + if (ch == 'T' || ch == 'G') { + name = unmangleSpecialName(state); + } else { + name = unmangleName(state); + } + + if (!state.done() && !state.nameOnly) { + boolean isTemplate = name.endsWith(">"); // HACK + if (isTemplate) { + state.buffer.append(unmangleType(state)); + state.buffer.append(' '); + } + state.buffer.append(name); + state.buffer.append(unmangleBareFunctionType(state, false)); + } else { + state.buffer.append(name); + } + + return state.pop(); + } + + private void unmangleSpecialNameCallOffset(UnmangleState state, char ch) + throws UnmanglingException { + + switch (ch) { + case 'h': { + // h _ + int offset = doUnmangleNumber(state); + state.consume('_'); + state.buffer.append(" _ _ + int offset = doUnmangleNumber(state); + state.consume('_'); + int voffset = doUnmangleNumber(state); + state.consume('_'); + state.buffer.append(" ::= TV # virtual table + ::= TT # VTT structure (construction vtable index) + ::= TI # typeinfo structure + ::= TS # typeinfo name (null-terminated byte string) + ::= GV # Guard variable for one-time initialization + # No + ::= T + # base is the nominal target function of thunk + ::= h _ + ::= v _ + ::= + # non-virtual base override + ::= _ + # virtual base override, with vcall offset + + ::= Tc + # base is the nominal target function of thunk + # first call-offset is 'this' adjustment + # second call-offset is result adjustment + + */ + private String unmangleSpecialName(UnmangleState state) throws UnmanglingException { + state.push(); + + char ch = state.get(); + if (ch == 'T') { + String type = null; + ch = state.get(); + switch (ch) { + case 'V': + type = unmangleType(state); + state.buffer.append("'); + break; + case 'T': + type = unmangleType(state); + state.buffer.append("'); + break; + case 'I': + type = unmangleType(state); + state.buffer.append("'); + break; + case 'S': + type = unmangleType(state); + state.buffer.append("'); + break; + case 'h': + case 'v': + unmangleSpecialNameCallOffset(state, ch); + state.buffer.append(" for "); + state.buffer.append(unmangleEncoding(state)); + state.buffer.append('>'); + break; + case 'c': { + // c + state.buffer.append(" result adjustment "); + unmangleSpecialNameCallOffset(state, state.get()); + state.buffer.append("> for "); + state.buffer.append(unmangleEncoding(state)); + state.buffer.append('>'); + break; + } + default: + throw state.unexpected("special name"); + } + } else if (ch == 'G') { + switch (state.get()) { + case 'V': + state.buffer.append("'); + break; + default: + throw state.unexpected("special name"); + } + } + + return state.pop(); + } + + private void appendHexNumber(StringBuilder builder, int offset) { + if (offset < 0) { + builder.append("-0x"); + builder.append(Integer.toHexString(-offset)); + } else { + builder.append("0x"); + builder.append(Integer.toHexString(offset)); + } + } + + /** + * @param state + * @param name + * @return + * @throws UnmanglingException + */ + private String doUnmangleFunctionWithName(UnmangleState state, boolean expectReturn, String name) throws UnmanglingException { + state.push(); + + state.consume('F'); + + if (expectReturn) { + state.buffer.append(unmangleType(state)); + state.buffer.append(' '); + } + + if (name != null) + state.buffer.append(name); + + state.buffer.append(unmangleBareFunctionType(state, false)); + + state.consume('E'); + + return state.pop(); + } + + /** + * @param state + * @param expectReturn true if a return type precedes argument list + * @throws UnmanglingException + */ + private String unmangleBareFunctionType(UnmangleState state, boolean expectReturn) throws UnmanglingException { + state.push(); + if (expectReturn) { + state.buffer.append(unmangleType(state)); + state.buffer.append(' '); + } + state.buffer.append('('); + if (state.peek() == 'v') { + state.skip(); + } else { + boolean first = true; + while (!state.done() && state.peek() != 'E') { + if (first) { + first = false; + } else { + state.buffer.append(','); + } + state.buffer.append(unmangleType(state)); + } + } + state.buffer.append(')'); + return state.pop(); + } + + /* + ::= = N ... + ::= = number or St ... + ::= = unscoped | S ... | I ... + ::= # See Scope Encoding below = Z ... + + */ + private String unmangleName(UnmangleState state) throws UnmanglingException { + state.push(); + char ch = state.peek(); + if (ch == 'N') { + state.buffer.append(unmangleNestedName(state, true)); + } else if (ch == 'Z') { + state.buffer.append(unmangleLocalName(state)); + } else if (ch == 0) { + state.throwIfDone(); + } else { + // must be unscoped-name or unscoped-template-name + + if (ch == 'S' && state.peek(1) == 't') { + state.skip2(); + state.buffer.append("::std::"); + } + String name = unmangleUnqualifiedName(state); + state.buffer.append(name); + if (state.peek() == 'I') { + // unscoped-template-name + state.remember(name, SubstType.TEMPLATE_PREFIX); + String args = unmangleTemplateArgs(state, false); + state.buffer.append(args); + state.remember(name + args, SubstType.TYPE); + } + } + return state.pop(); + } + + /* + := Z E [] + := Z E s [] + + := _ # when number < 10 + := __ _ # when number >= 10 + + */ + private String unmangleLocalName(UnmangleState state) throws UnmanglingException { + state.push(); + state.consume('Z'); + state.buffer.append(unmangleEncoding(state)); + state.consume('E'); + + boolean isStringLiteral = false; + if (state.peek() == 's') { + isStringLiteral = true; + state.skip(); + if (state.peek() == '_') + state.buffer.append("::"); + } else { + addNameWithColons(state, unmangleName(state)); + } + if (state.peek() == '_') { + state.skip(); + int num; + if (state.peek() == '_') { + // >= 10 + num = doUnmangleNonNegativeNumber(state); + state.consume('_'); + } else { + char ch = state.get(); + if (ch >= '0' && ch <= '9') { + num = ch - '0'; + } else { + throw state.unexpected("number"); + } + } + if (isStringLiteral) + state.buffer.append("string literal"); + state.buffer.append("#" + num); + } + return state.pop(); + } + + /* + ::= + ::= [n] + ::= + */ + private String unmangleSourceName(UnmangleState state) throws UnmanglingException { + state.push(); + char ch = state.peek(); + if (ch >= '0' && ch <= '9') { + int length = doUnmangleNumber(state); + while (length-- > 0) { + state.throwIfDone(); + state.buffer.append(state.get()); + } + return state.pop(); + } else { + throw state.unexpected(); + } + } + + /* + * [0-9]+ + */ + private int doUnmangleNonNegativeNumber(UnmangleState state) { + int number = 0; + char ch; + while ((ch = state.get()) != 0 && ch >= '0' && ch <= '9') { + number = number * 10 + (ch - '0'); + } + state.unget(); + return number; + } + + /* + * [n] + */ + private int doUnmangleNumber(UnmangleState state) { + boolean neg = false; + if (state.peek() == 'n') { + state.skip(); + neg = true; + } + int number = doUnmangleNonNegativeNumber(state); + return neg ? -number : number; + } + + /* + ::= N [] E + ::= N [] E (args = I...) + + */ + private String unmangleNestedName(UnmangleState state, boolean allowCV) + throws UnmanglingException { + + state.push(); + + state.consume('N'); + + String cvquals = allowCV ? unmangleCVQualifiers(state) : null; + + state.buffer.append(unmanglePrefix(state, SubstType.PREFIX)); + + state.consume('E'); + + if (allowCV && (cvquals != null && cvquals.length() > 0)) { + state.buffer.append(' '); + state.buffer.append(cvquals); + } + return state.pop(); + } + + + /* + ::= I + E + + */ + private String unmangleTemplateArgs(UnmangleState state, boolean substArg) throws UnmanglingException { + state.push(); + + int origTypeIndex = state.lastTypeNameIndex; + + String typeName = state.lastSubstitutedName(); + + if (!substArg || state.peek() == 'I') { + state.consume('I'); + substArg = false; + } + state.buffer.append('<'); + boolean lastArgWasSubst = false; + if (state.peek() != 'E') { + boolean first = true; + do { + if (first) + first = false; + else + state.buffer.append(','); + boolean unfinishedTemplateSubst = false; + if (state.peek() == 'S') { + char ch2 = state.peek(1); + if (ch2 == 't') { + state.buffer.append("::std::"); + state.skip2(); + first = true; + continue; // more of this arg to come + } + lastArgWasSubst = true; + if (ch2 == 'a' || ch2 == 'b') { + unfinishedTemplateSubst = true; + } + } + String arg = unmangleTemplateArg(state); + if (unfinishedTemplateSubst) + arg += unmangleTemplateArgs(state, false); + state.buffer.append(arg); + if (lastArgWasSubst && state.done()) + break; + lastArgWasSubst = false; + } while (state.peek() != 'E'); + } + + if (!substArg && !lastArgWasSubst) + state.consume('E'); + + if (state.buffer.lastIndexOf(">") == state.buffer.length() - 1) + state.buffer.append(' '); + state.buffer.append('>'); + + if (state.lastSubstitution() == SubstType.TEMPLATE_TEMPLATE_PARAM) + state.rememberInstead(typeName + state.current(), SubstType.TEMPLATE_TEMPLATE_PARAM); + else if (state.lastTypeNameIndex > origTypeIndex) + state.remember(typeName + state.current(), SubstType.TYPE); + state.lastTypeNameIndex = origTypeIndex; + + return state.pop(); + } + + /* + ::= # type or template + ::= X E # expression + ::= # simple expressions ('L') + ::= I * E # argument pack + ::= sp # pack expansion of (C++0x) + + */ + private String unmangleTemplateArg(UnmangleState state) throws UnmanglingException { + state.push(); + + String arg = null; + char ch = state.peek(); + if (ch == 'X') { + throw state.notImplemented(); + } else if (ch == 'I') { + arg = unmangleTemplateArgs(state, false); + } else if (ch == 's' && state.peek(1) == 'p') { + throw state.notImplemented(); + } else if (ch == 'L') { + arg = unmangleExprPrimary(state); + } else { + arg = unmangleType(state); + } + state.rememberTemplateArg(arg); + state.buffer.append(arg); + + return state.pop(); + } + + + /** + ::= L E # integer literal + ::= L E # floating literal + ::= L E # string literal + ::= L E # nullptr literal (i.e., "LDnE") + ::= L _ E # complex floating point literal (C 2000) + ::= L E # external name + + * @param state + * @return + */ + private String unmangleExprPrimary(UnmangleState state) throws UnmanglingException { + state.push(); + state.consume('L'); + + try { + state.safePush(); + + String type = null; + String suffix = null; + switch (state.peek()) { + case 'i': // int + suffix = ""; + break; + case 'j': // unsigned int + suffix = "U"; + break; + case 'l': // long + suffix = "L"; + break; + case 'm': // unsigned long + suffix = "UL"; + break; + case 'x': // long long + suffix = "LL"; + break; + case 'y': // unsigned long long + suffix = "ULL"; + break; + } + if (suffix != null) { + state.skip(); + state.buffer.append(doUnmangleNumber(state)); + state.buffer.append(suffix); + } else { + // show other types + type = unmangleType(state); + state.buffer.append('('); + state.buffer.append(type); + state.buffer.append(')'); + state.buffer.append(doUnmangleNumber(state)); + } + state.safePop(); + } catch (UnmanglingException e) { + state.safeBacktrack(); + + // must be mangled-name or something else + state.buffer.append(unmangleName(state)); + } + state.consume('E'); + + return state.popAndRemember(SubstType.TEMPLATE_TEMPLATE_PARAM); + + } + /* + ::= T_ # first template parameter + ::= T _ + + */ + private String unmangleTemplateParam(UnmangleState state) throws UnmanglingException { + state.push(); + + state.consume('T'); + int num = doUnmangleBase10(state); + state.buffer.append(state.getTemplateArg(num)); + + return state.popAndRemember(SubstType.TEMPLATE_TEMPLATE_PARAM); + } + + /** + * Base-10, where _ = 0 and 1..x = 0..x-1 + * @param state + * @return + * @throws UnmanglingException + */ + private int doUnmangleBase10(UnmangleState state) throws UnmanglingException { + char ch; + if (state.peek() == '_') { + state.skip(); + return 0; + } + int num = 0; + while ((ch = state.get()) != '_') { + state.throwIfDone(); + num = (num * 10) + (ch - '0'); + } + return num + 1; + } + + /* + ::= S _ + ::= S_ + + ::= St # ::std:: + ::= Sa # ::std::allocator + ::= Sb # ::std::basic_string + ::= Ss # ::std::basic_string < char, + ::std::char_traits, + ::std::allocator > + ::= Si # ::std::basic_istream > + ::= So # ::std::basic_ostream > + ::= Sd # ::std::basic_iostream > + + */ + private String unmangleSubstitution(UnmangleState state) throws UnmanglingException { + state.push(); + state.consume('S'); + + char ch = state.peek(); + if (ch == '_' || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')) { + int num = doUnmangleBase36(state); + if (num < 0 || num >= state.substitutions.size()) + throw state.unexpected("substitution id in the range 0-"+ state.substitutions.size() + " but got " + num); + String val = state.substitutions.get(num); + + SubstType type = state.substitutionTypes.get(num); + switch (type) { + case PREFIX: + //...? + state.buffer.append(val); + break; + case TEMPLATE_PREFIX: + state.buffer.append(val); + state.buffer.append(unmangleTemplateArgs(state, true)); + break; + case TEMPLATE_TEMPLATE_PARAM: + state.buffer.append(val); + break; + case QUAL_TYPE: + case TYPE: + // ...? + state.buffer.append(val); + break; + } + } else { + switch (ch) { + case 't': + state.buffer.append("::std"); break; + case 'a': + state.buffer.append("::std::allocator"); break; + case 'b': + state.buffer.append("::std::basic_string"); break; + case 's': + state.buffer.append("::std::basic_string,::std::allocator >"); break; + case 'i': + state.buffer.append("::std::basic_istream >"); break; + case 'o': + state.buffer.append("::std::basic_ostream >"); break; + case 'd': + state.buffer.append("::std::basic_iostream >"); break; + default: + throw state.unexpected("std:: substitution"); + } + state.skip(); + } + + return state.pop(); + } + + /** + * As a special case, the first substitutable entity is encoded as "S_", + * i.e. with no number, so the numbered entities are the second one as + * "S0_", the third as "S1_", the twelfth as "SA_", the thirty-eighth as + * "S10_", etc. + * @throws UnmanglingException + */ + private int doUnmangleBase36(UnmangleState state) throws UnmanglingException { + int num = 0; + char ch = state.peek(); + if (ch == '_') { + state.skip(); + return 0; + } + while ((ch = state.get()) != '_') { + state.throwIfDone(); + num = (num * 10); + if (ch >= '0' && ch <= '9') + num += (ch - '0'); + else if (ch >= 'A' && ch <= 'Z') + num += (ch - 'A') + 10; + else + throw state.unexpected("BASE-36 number"); + } + return num + 1; + } + + /* + ::= # ... 0-9 + ::= --> template=T... args=I... + ::= --> T... + ::= # empty + ::= --> S... + ::= --> name M + + left-recursion elimination: + ::= + ::= + ::= + ::= # empty + ::= + ::= M + ::= #empty + */ + private String unmanglePrefix(UnmangleState state, SubstType substType) throws UnmanglingException { + state.push(); + + boolean any = false; + boolean lastSubst = false; + + while (true) { + char ch = state.peek(); + + if (ch == 'E') { + break; + } + + String part = null; + + if (ch == 'T') { + part = unmangleTemplateParam(state); + state.remember(substType); + } + else if (ch == 'S') { + part = unmangleSubstitution(state); + lastSubst = true; + } + else if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') + || (ch == 'C' || ch == 'D' || ch == 'L')) { + part = unmangleUnqualifiedName(state); + } + else if (ch == 'I') { + if (!any) + throw state.unexpected(); + + if (state.hasCurrent()) { + state.updateSubstitution(SubstType.TEMPLATE_PREFIX); + part = state.current(); + } + String args = unmangleTemplateArgs(state, false); + state.buffer.append(args); + continue; + } + else { + throw state.unexpected(); + } + + lastSubst = false; + any = true; + + if (lastSubst) + any = true; + if (state.hasCurrent()) { + addNameWithColons(state, part); + } else { + state.buffer.append(part); + } + + if (ch != 'S' && state.peek() != 'E') { + state.remember(substType); + } + } + + + return state.pop(); + } + + /** + * @param state + * @param name + */ + private void addNameWithColons(UnmangleState state, String name) { + if (state.hasCurrent() && !name.startsWith("::")) + state.buffer.append("::"); + state.buffer.append(name); + } + + /* + ::=

    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ɝcNGp6 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�|~ucw|S` zNr}l>(2LM1GV%=9VOVvVN%{GxNm_>ILEJoV2g*;N@jZ|RB2%R_pyDzal3_qZ6pHIb0ED*i zUm`QYiW|RaylKfvA-o2>Qw`e)8H2!v(BevK8{z3q#J{6Q$$N1@=K|JVxcW9hh$hd##mc-4k2YTkGx^m2v09~lj`j1{c? z(n#ZrZ)E8|(&ZL7lHUu!8 z%L}|8KQP~%Kg8#QxEp4d?@N4wvd=QLr*_#G#^)0FWjmUp2o$TdR}O(h^1OwmX}Cop-(f|}cY3|yypxIQ3%=4xy2PxVM*`TEzIjj zdH8-V7O&1!bRdv!`ld%b`i$WhO@n3K%(g`6mk0OsonZ|s7jGT=m)Q&Ms)aLK^$#LL z+$z%=Y!DkjS?(T77UsA?fuA;!M|x6SL2B{?Yz=ku)*IX}zLrdJ{QaM%a5dO8no4An$3yX7yI8<2byM{yx|G&&9Ybn-`@w+h;UZ2Aj3K;9?jnY^<7^Fq0A`j z(ATKBzx@V|7m_)EWN@BYtXjlT=OE{uavr6965D2Mxs_Gjnv(r3p{EYtC=rjZI<(TA z#dIF@{ihgFPtCEy^>DMxgTEW0zM)z<)hE_MwmiNG(i!jixre=&TCYH8V zCYC@jj5AQ1#Kz2v@xMpqpZ5HRjQ5|dZWVcl?@Y*k_Nt4Y0z=b80_hJ;kT%3gh@5DN zTGVOLNrbFhBDV1?47W-VWxBh5&WY@c?)M|@N)nISlQFskX zb9{-|nrSdKrliSWfNNQK*!TA%y3vCKdhTFV zy2EL$43B?fD=XF*5~(6iuY;3Ou*~u`d?0g}w4c(h@*Dbe@(L;c5b;~CGWmiuZ7Xf^ zY_YraOiwFUg`wWRlsgeMdp;vZzSVcUwyDQ;Ac*G!?sEjAB^WNm2n6l z24&AZf|vPXKd=Aj%PpDX1T8I@WY1)rv{qnCrm?D?&i)iy#$`uun#FXKPQ}Cp4kuJ^ zPJu@=^KSU(E7U#i8*S(3r=6geBTsRz%cJ3C69J#%FCXw?AGk*XPZ{vtUAnuU7=9D@ z@QP%wZN{WKl^CsBV`;z5ArELye-KA>AJAh8{wC9$1H=7nQNu)m)pO*c;k0Jqgu31L zi2GO9=&C)}f&nILXrOk+zlMSM$58tR*Z30?^QU@7>6YD;`=Ni;E~GGhYGZ&@2+6oQ zTqqF{)K`iP_hQC`o_xSkU1WV$iN9+A~mb|rPXDfLGBp>r5-Cmd39Ebar%S%BJ z1S5H2QW7`Ie$vq40AyuiD0E9K6(BqqGM@Qt3{`LxjS5RsDIAvASVZpmdODsOihD-> zEh2CP+c!DPjH~!I?4=F6xWhJ!m5mG`x(@w5nXj*eQht$*vXOdgbNMEWD?K$Snb|fB zKr+M5o5~!kHac z2(^VE4Rm=+4d&Qm8v7#I5xdQ66NwSJqt^`0h5&Iv{c-@9o}{X}MCY}Qf#(hrIM(-e zv+LI!X_QS2aeDZMB9g%NDD`HR7z1AD;QRcBW0WAs^OA{{@E4o8+79h0D%X#VZD(1Bu#ALpJKAEfwx4JxHN;Z`L1wJG{#`UMYe9D zpx5=2T=}qirEVcizE$Ajk1Iuj#Q2gu;t;b+ZQtC0dD=T@7xp_WHCf`jgcMEDJKqNQ zb0pY#$W0Q9LjgfHTb!oaxlLow2*~z=!DElkge5iZMbX$VyW-947^;iHbY%39h47av zm1>zC(X$Ovp2QkL#jT472z%GvztNY-Zvz*ffO&Tnn1lbdGWs8bOwrNo5Am+Q)<`AF zf1YOXVkXV&1_hkI29~}8(9z(G=Ytnt%vm#9&Pz?drM=TB20;TS6v^aBFnTLR(ed5$ zZ)Y2sZ*LpugW?t77DmP*=OSklw?YK{D0%jlS9O4c)5v*4AgY9$?K$uKtgqDApG-R|R6+r5x(Us*k2Kl-EA zQh;bur9^TJY{8D1n*Gys(b+xY_8T<2I`cXVgu?rh`mSZiYunGgoi)O@`e3Nby!6p< z3$KrVYLWEjtagEZ@I= zvi*-H%~hI_8D_%D`Kegd(%G3eoXmM=cuN8w1)bUhxGng}FE3!bxt>;h-WY!5I?pCBa3;@4?2@_{$bdDN$e?Kc#;G%)^`GmZ+ zU~0lo=0c)`oA#~vI}IVV#qq1^&+nOcV8O!)w>(odvu8273eIw@TGW?i63-R%_J0*I8Lb1G1uXsC}~+Q?E_}jS8*Qy zbu9dG@vC4CTfP9=^Z&5|`%`M}pH^T~GQ&d1)!Q=^IA3Ys1A__(@al@%PX_f7^uPBg zQp94TQnDno|FrP>%=ZZDpTZSMzz1v0iKZuh7wrG<71#`xXtm^O1QSI_+4{**4AbUD zK5CFvE~`HEq& zD@TJZ>zk4Ar_G)0B^5fXEp)iOKMrHK=Za|*VXobJ>Z2?=v%7ApUas^7CLlm1LM8+` zQR6;1_9PiwnXl@82Khew@P*|?=7E0=#++|rgo@w`>uHZhkDo{ft%`WLZ`n@u{oC{c z55BahQ=ma3fsXqBaL)dhcHdvaKUZl$=8t0b+aJYjv;`wS%o(tnMMpySwz@Lj_#^(= zok-Wd&(EC!T@|SPvQKfQ{O`r=Hp2A3DIUVdh}>5~oJ+~40_~9ykWj~n$ zI|RV()f1%9r8iaKI%HxPmFuKlKkh}ESKJ~`WBYZc zCqt%cY4Jy??Q{+&>k(TbO+NBqm$M#q-l_Y+0%PwD^b;MaCl)fphhHqwd&Zlzr^)SR z*E-3{MX%@%^MaG1<2~4VXJL4M;ZEe(suPwUc71ex^rc(v3F?2j%@khkLm{(z=S!ZGeJw2=_CpqY_u(u>8r^fDts$MnwIjO>G zmZ^$rRv5sjSF3OW`$|Q8>Y9a{t3jR0JrQ%{T$xjadTMRra9H6iv9mgj(bAKX#9#K5 zK^2)g8wU|oWvpS1lP$g!OW5t>aV8vkGKk9cuBjO~)OXltisV1%e;zL1?D^2mCJ?ea z#>({kpE3VM8(@5k;{-nyvlk8us*&Zn+ODzlw@eyL#axjAH0?TY{nOEqf4L+4lPC|3 zY4|kA1k`SVj37ow7gaJOlK?3xEHDHc6F{NF5OXJ*v_?bdSAv0#j0$4hN>{kN;5T@H z4q#^iC1yg;KxsTUJYzpzW;SZLtJdCj$!EExg{Yvzo+x-h^AT{aVK)+)jIzSY-DDvK_;~B`{nlu! zO(!767jM&}e&0~taFmRtt_>m&n)%5qrIOdp$(91PVzpL2m-icX*}imYGRMmpb3V*>+yP}S1i@59HZrr)BU7h%(Ca@S7TX6$#uvxm*u`kdXO&N+6KGq3^!-! zjnQ7EYYz<}RpdrZWZ$z4h=w`k-ay+&1}LDvs0!7_ev*wyP173tG`V6hb6uJTkv8OS@aj@DIUEa+4S{E)!$yd4I(3#)q z>%(iVDW%I*uS|JkW~3{d3lKBW~8N{M^?wP_tse< zUKAzPajS38dAaoERxXw?82t(Ks95vpP~TaS@{(h7DP>~}c16is- znW_#<{_WaOV3+fm*Ab|;12=PL2t9>v)J4+lLnw5fzwioswFUO6UIXH|lP{r{Jn{E5%b{U>fx z)>?-qj3|Dsv{&4VdY?348=IXpv*ko6tAu9o2>PnDZ;MljE^LxU*3`t?m-%7-``1f) z9msS0wgmjKFWqi;Jbe4fUQ+lJ!7@y=c#&P3Vmp5fce8TR85Q;CSyjZH-+Y^@%d`9Q zv&~+ph|U_2f`?D=W?Vh8mhndt9GEEZzk8ALs5lb^00=Uh|u|>Evnq_FYpr=l_`vMOrL1&_H8+28Z(JE zAA{5UAQacofNnDXZ*BrVI4U@XtbtVKSACE{UMDz7;WZrJoV?DhdoiQOt`5pa2YKZ* zGPDG;GM}mlFyPv2{~B76G;(~P7gzkgy)#8* z$gg@ZWhn0-0C}1!-l4gb-h)&yGiUh@@n|3DOqWPcTz1c?fozeBMmWLc7qG$bmHg)e z4@Do*35YOyQ6TH#dlQ#3McPM+?%3aMgP9@i`>?>5xIkbw`KMDu|L2qT-;W-)|9FPW zRo$}x{D)Slaa%R6Y{PqVl!kbTVHZ5PcOf$~8JW6DBs=@H{c7&`cQ*|WcX5J|F{bOX z>p^JC?~h`mtU?fs-2u`^IoyISvmWNN-0yF9xFATp+;n?Iv3OA&c)E>F*ti_P)Iz)x z188*I8vF#$iH(t*_q`-5lm#3sN3TR|6QN^Sgq3YQ(6MC)zGO$%n*=fRMFnAV#qt6iQ1>4*-<0fXyYQv5`akeEmfd&z(;?1@!8!yT@FGb|?yWc)K9SDE7 zZ4OA&@d5_2g5}ld)bKY4(?ac_8Tg>tO)5;Hx19<25WJE{KXGRgdLV`7E3Kg}C972^ zuidQ;srmt*?w3nCkC|_eUJ5c97jS)=wljscn3Z^&M9B+|*0y6~k$6Yhqk_}WjD!-F zKOD>eu_M`PC&lPb72E1_#c)OM_0oB&Z8j*2eS9!wN*sJhxNH&JS=8C?1Gli(eAAQj z`o#EmXt_9KxUqT_{$N$U!bd~%7O5vB(*S}4gj{@=QcDXbM01Tf6Fa;>RL)lGL()|g zjJSli7}QJUoHWc2I1J!?D@ar7b&nrwNN8({YO8e>u1ijx2+QHOU<#iuO~(baWl8V< zmWM337H$8S@*NK(i~O%@8@4|m^HP5OF<5jof1@WQb#hxtOc|{#CeW2gDrS^1nsih` z8DTU&{bCed#%A3<`9lU(`D>&>tS{U34s)IlXE;$(3`Lg%|AR;VOU}1nAJ4DoLg=*E z2zyz!GEgk-_PbD}ZYiINnM?|TwD4Vc?9VbRnASIG-E{jq}(dl;XGYIja0 zXzkn`lt$=<6XSDkm8+QnnsEoCa!QYRqRvA>&6#8@fjQ z_E4z(=I*v01w?!J9`C=T%-AxK*$9g=ncA&j#_RBAllabZ@@rH7!4vre>w?U9CfN)zJ!A-n7Hiqj;qJFv4cD(!{`h!mD=|QPXsQASUHV) zlAwY;>{{t3gq_pRywi{3SEUS@x5?AblDyGxsA{o%c99r|#;bQ51FiMcd9E>cuH`y{ zHc!3P-s`cnw~7gcm7E2IL``A`tO<(36t#k~i;UrXGw^Jkq6@HRO{r`A^^=O z%)|G}rh;fUx*i7c)RLIY!fIi%e$S00^UGfw{og|k{UFYX!yK`bCqMP8ND+yHt!<#% zr<0J9m)fL-RaNE=X0WJ`T0Tg-b?yB1zK0$P4rPu8OqIZy0382|D*aDC<_3c253gAr zIA1ujB^$Yk0s;b*ML#ElIFn*ITN0&*&=T!WUC1`puf;lWhU@}61=`|hXy|H|b{|oJ zwn4(>+6~*1HOtm^Eyju));2wr?-soe_tQZ_{(Zj3x;xXptUKL)dtH=>AVL+cDm1oZ zc=lmD<=CV0wcz0gFxZllo=M=Qcq22G(Cwbh_+#Uqjo@f_mjN7nQesR~xhBp2K(m#=ATYuo>eS ztxazjh&$#s#9>HjSO8^pLaAdkcmHOpyC1;qJI~#ol5I9!9Vt15EpA)Ad*sVoYuXK; zAyR^`IpJ9dj!{5k(gdz|VlFlVij(%6Sf|~p#RRub?tmZ3q%O@V7CddgT+Oj8<{nUr1S$=zREYrehW=u(6KoWWnHe;n{BrZZQ$&t><{ z6P%ON*#-5cJ2P7cYgdC{Yjh?a5V2v_JtSPZJ*->0UKswuoB3)U)=T^8a+H44)@_&H zvo2->uO9o-1&FN$A++wo_h8x${#k^yc5RgALwWhr*y6Dv28onw(q<9|S92+KNrS|6 zsaj*Dl3agjMSBtJJAd!87EDDa#+Anz1APF~BFG7XcQ-lw%%NAVK$|9M|Lyu&r}`%` zJFAh(tVte-Y6&criwDS{O2&4vJ9lf0PDzdsxwhpZckf_ze?6O}H!+X_s|1a%Ao4^1 zIs?ie;7sg-T8(mHH)drV29V`ch)${6q^HC8d&EA)8%Wss?INoS^Q9K3!t&9YR0v%= z{rD>S)zVY_8q?Tiy~RQ(Fg<(Jw#g8RY1@|M0$<^H*-zfDy-+}EElMdqcw*x~gczgv zH@CjH1XM=b*mb&Ae1V!OVWrFnCK>{X>K8YURLPr8SPoJ++If=($`N}-mbP!Cv`5Se zxV{L%nk9AecO7gV0BgzB;U#pKj%#Cj5>h5STH5$>8=iblr9Ig48U0v<@Tmz&oG!oN zz~(@vr9<+1zP2>XF`js~3=2yp#e`Yf6?XP=`uR?ICsvd0x*RKH*$vzHInj4;$BeoOs2mb6bbyTX8x_pW2-g@AUG{@Z+N*_SGZevRqe$<(TwPELr;`DnCl~}HHBatMWXU2w!N|%ZO6Qw^V;7pL9Q{cu*#Z8o>AB;GQNK~H1Qh-;|gw=&Sy#)+nwf}w!_ zR&_&~WC{mESDP7WZ`y?Ehl;$OsAMcUQEoS{0(=}?jp)kBe&b7Nq@E}uPe_%#3o|GN z2^2Z`mk~Y<$4c5x^Fk^NL|F+b-OE#|ih1pBhynjVfqnGE5I$x}B~H%~R7Q(^1xDTm zi=Ly}B{0yIRE0jKk8u=_dU%9ZI~50+Qzf?+et}I%-vI>zRVxT)A0igHFF@8lm^a>G8{$8R}YuDS_99GMXZddihdIPzAJk4E2_~D}T zAB0G)?N)f{Bx6KgcKAFqM3g@>G!%*t=S{X4 zwE&u1#26+z;sS!17zDt{&!(@kyP_ zoN|;ie5Ov&)Rswxj}t$I4SZ@x!#d(0TrqmKVDWpgO<$4IjgxS) z;LcNmiY?QcMngXd)`z@zzTp?QZB`N*&8K>VnS?R^$PO1SVU^TbhX+Ip$~7?iIZyos{L&k37A?!n|4%#fMDoM-Gu%1b*Myq+g7h z(|)|HNheX&gf;NJk5_^b4j4@eDxar^8d#Xm6ZEZOp8PzyI!`$n9TjvPYqc5R=<~s& z{m>ly@i{V5eSmW!;7ano+-O3zAgC{F2(DNB0$Onp6mrM>8$n^ z((Q|68(4n7;0d;27SqXt>gwW?Iy%2Odk?xc`@M~C`gB^xkg2cYz|P(a+-*MrPHmL@D48m_e3R>7;8c^BqvA#jVr}R3&@Y4 zFX~qgzVniM%-&oCQ$sp|epe7yMvf%~LNNDAas1Bx$_4qvVHAFqq;lMa&*Zk_SS8=f zx84;xtG|pXDv&wKsaz30DnfpQ=F>c4zv~Qq?1sbn$6eAq8fg5)d_0Vt&!s!ig!7Nx zp?Va2)fl+E@(~AvMVC&ZgX@N2q)t+oQ6|HcC)a9JRf}L`obXhsB;h`JmbH2;0W%m_ zX)LB%M4qUXI=zaaGowmUo#aEgo;5wwYD}q-;$BpO^hZ=APU&pf=VBQVD_wPU6)xq< ziwWXLLASz!E?YcE6;5<6*@OET0F7=H!p8EmXF+VR&c9Eea(lI6pZTjh6x+2_qzHrc zw>Ldqxe@Y@6B@7eNYh2~(HnYQ8D%v&PkE?`WYSa&Cu|^7o?&n6Vz>xl@AlQCVk>5) z41BKN!lqTHqiC*i&p$M74u`|pE>CIr?e zbdcHmPM4!o4>Or@aVb}13kF8>TCkC)oOZ6yyi1rNqVr63;N5#tudiAPqX`Vfs~sfR zGz!cl=iYX_6R=ZbCfyRiAG;c*9TuIbZc)I5_Lzor?8{Y(eCEo=`i?-e+^%1F z@8+7+YD@200%jNHjPVp)*_M}X)|QAf6V#YR_#{xsw)eRsDD%o8nM$i%5B+v}Acm}{ zmTRuy#vBmzD}|t$8NcCnv;)x+@5tZfj1hbxF9JYe@#1UdK%~Vmz~-H2x0UkF3Ev z8*8&Iy|JJDaO)=ZvdUWMrDTSqLZmq2?PE$cD;Q`Nr8=}m$3kVio2~6l92_leG0rJy zzUVV2Qt`QlJB?zeantC>1yb4yd(g*pl6+7BB-dmn>GB@whBAy4OyWkVt2brZC@uY` zrwj-Xr6i_jqMV?v+2wun3x7Q$-W4g#Ji?(o@Uw9WHiW=ikm~fFPRMN|{0Lhcr-K}O zx9X1orQnU;mR5ZD7T;h@F6$f;OS{HRGxj4_DpTK$B-MokTfkmokR(*3Q*5+7D#^%D zNd&z=?5A`;#DbAM{q6$0M=_oiLgj#h0!XLC!#Ft@1LS+LAjegi8tW}4A@?Tb3m(*g zA#XcKKP>6fmgv_+UF0Z#%AZAW_hW2nyOaqdW))bf{6yZ~Ezx;0fCbf4BJavcaYB}3 zzoYJ*oNw^@w`x}^f;m%o`!2|jbF-Jd*;mm}}l?O5_!G|hA ze=8)IECfYF8D5v@5DBu#%updgMtub$^{*sz(KHyuVY5w?`^FwCsbGi;}%czAEzZ!R-`Wg4o39AyzM{LdLqsc zV%@Y$pfAS_7%XLd4p8tL#TZ9p8ZpXXeJ(UDb;Fd)%Ov5T2;-c7`VsP!0&|VBj4X%l zD+%yG>TfQsKJ{ZdF#I&dDjOh#ql^kmG9p1AB zAgmyV;~JuGij8(+ckW>fSdrS2o^mW)_iS3-u^zxJ-!?w6b@0oouWX}BjDb_t|ftPKP(z`FzVQak$ZW2|KT4r#_@y_oUb5r$DelC?M2zP#cBFQPD8b385DFIFrQ zy)u%mDwj9`-12@*nwvdM6QEPxhT9tBMaoYYh!)>~DpZEbdx0sfZ}-S*vnVfX-Ga~W zSOLgtvF>?2;LcEn=BO`w+^a~(_riArGlU?`DD4dry!K|#y$9ai6DpI zh`W@!amq8%c_q=1IrxFW7a@jCNDVoJUxbNAh+}w`o@C9u6SRbAg|AIgmU)Uy2qVI6 zy;lhZnMq4nLE`b0^KU71Pg)3D)e%LFB(5KyKA2C_GN?&IPZ$)`hE|xjvp;v}=MR06 z|Did~P+epequY*J9e=ZnTn z#)i@N%*zaM;COorN7dHG)fROCWMyqEcYl!+;sm(kJbP1DNIIUK7F>W{eXAygz{FmJnd!6ES~z?5%h8NGo^lPm(Ys`v_<8(nu?>dny%?(J?! z{ms!0rgo2==d@*?d>MKrbl2PEG>kNtQ6k*+R1WIsCf4f;bq+rW_uyI;D?cJ1Z1-NXJt;gp|1*C~P!>nrIUGsBE;~gQ*-#C0PqM`!xWL3v$ts24TpG z39(ERWj4Ty3-xH9E+f9lh&c}ub6@w$2wOL5$q{!p+{Y1=FNl3UxMe=vt)B3FkJ>h1 z<%-V}33rc)AxP1Y*%wGPh1Z4K*=I?qhh=r*jvKvcK-1i(>jpVKpwW%M+*eVvYRS~b zbT7bV9Kh(t(YZFa9okq3_Sm!D46|{B_P$oW-4h7%##q^#T8+Kj^?n6m9F2!Pcj-p! z8~CIGrO$Ay&(pwM~7uXKp39P0k zxNiW-nmgP$FBOrXl({z-g~O3Vkv0Q~bFEwzqC+^nAKWKma0if~p4Ywu~Ww@9@0;o0rS~lBsn2W4@^n zLg<6k6Oy@cA$rYlP)dUyvN{B~Z2DBLsDk{@@#FGXdP4(kIZPwV6NXb{)iX|48~Jdo$^At=ulk zISY0-!ydh}_`)HHRm09NT6Qiwc|@OI^*ZJ3D@@QRXp~q=CU!^f{yk_4w#ZPC$NVSZ zLJ?0uO(70Cc)ieA&`mj8hsoA&p$i#`2CzKedCxqw-3dT6@ndCfP^r4fjSY>!rMD3f zqI-1kj%sT%yz2S$O9agUNAchrmkxa*mZya~vL|wMKYIl67`}LcR~Y*(h5mKYm284S zr=j&2+ZE)0y%GOmX@8255GA0cbAXoq*VsINMRNR=o)oJxpa8~<+>?BTbf5=|d}r8* znbLz52@Cysu%wH(%kD&B#hs>c^h=vrplK==ebG08coNh?0BH79Rri5a`~8I#(Ml#RLfx9v|t#EZ`kfF*$V*tcGn} zbt!NL6g$xiC1>hKKVQU-js$$1x}GE@O*+C>1@`)`kqi2%&Ssg+fmG&`WZWlOQRy8A zVyvaax&^br`%KHpzKWXgnzmo;-vvYzslP|TxyJn1wPy)k%Nxo~1i;~Qy!7yW#Cv+0 ztTBDB8I?%|grc*(L?fn}td8b`rXuy3{gN$g@wq8yzYld5rmezaoXl}??Lc76RL6?4 zkI)g=c!v6~Z}kU$i^=0OdKefDaKP`y^e;ulUtw={ie2`DLdZEI5WHl3V#59dN3||E(Os4mYp#bK2V7yyeB?^$GGSOh4in2zJ#IX+CnU z#n%~RB9P~NR{cW#WqeE9FXztV`mySmyw?J|21Zz!d!YSdV@gjQEAK}dY%Z)zmSvM) zO>&6SvUm#Uuo_k{Pl9x|9Wp0CvyPHDEQDIo*$+G?|>!_Lt{mQs+v z4d%(%u0dehkn^|)zsmh!8i2}E_^U;xz9^7A1M&BrK;ig*4Hqco=4=ZTkJq%aH+As% z5A*y-N4P|NM-^8cI7OCD%U!EjzVNeUC`}D<%ct)$C5EBDMf>NAh)R}PZ8_Q|l4k5X zy8?gzNOr#+!1QyHc+v24FBKbw9<%r$x4@fQD-J1K3eS+6<$vG>4nEj&nd^AEx!m!G zW(rag1w*By(CQxB&x#Z1t}}uA##3t|F-CV}th%1rw`|UMdzLW<9m6%I%1Z;k92#Qzptv(>rz}8Z|j*N0cZ-d}zleeIPkr&i$l2s9+gSD*cvIis- z+QFXK?lf%Ww2?aUHJRCGTe(om?L-wsb_O4Bcx|8qN5lZGZ8^z&=;&4l<|Fz&DJZ`M zsyo_N2`%_ZmPR{s>Tv`cQl=wX#`}5~?(?!O2hGW5PGxB%2FtD2;_IWfr`z&OF2eta zPr}#7R5I_zD=DNk>G~~El9KwKmFWf(X~8$;x-7qQ_)grTST%!+uO5F*DW z>tdM_w_&DT_^X3<@yqTLc_u2B6vz0a-D%kA>9|?kT|~Qi+GHHQMn+Etx+UutpQ`N_ z0CRNn4Aek$?5SN=(%ttjq3BA$8E4=W1$Ex&J4rVjV?TYU@1pT0`*E>Y9O247AsEj0 zV|Ux{(s8J5ayUZgS3XYn>ust!?etT~p=*I-I75*UV2w9X5tR*c)Q3(%MbY7vQ{ z;x;k^2z4K4r^Gs;JF~Tz*XQ@1`qKn2>}5FZ0$%PMZtnxNXBlK~vq01dOaoYiMba%v z`5h!kr&_l~1Mn~Vy0_uxYH#7@-*KRuFrITqxU>4C*YUJbzBUND`6H3Aw}+>xiL8m* z&@8k-YV@-Q}pJ;wKWgb$FOV{-{a@{-SsP1t?SpD{^i5iF>jL>uH`DGBEF&Pv1Lw^ zUomcYhEAhwaogXvzp6VGwJJZ%VR0FV&k=HIja0=n_@MW=xg5BfoRE28;#{cGa56^% z72!l|7r{{$zg=l^zgZ(gpLc z>P7yKY2{DxG4&6XKavVZpLCm$WptISE+;MF;^x-J_Kf%#k2jOZ!{1XS zk)c1)NN^=;s(3NrYot-gJdHq}?Phb_9D zCLFU7+Bn|+oMv^Rvz_KBm$-(pG#z);`EnT3mI*jVfd0TpFlisr||*Hi=>^mBgg8bkE{_=3W(M8ao`0 zqIvZc;v&x?V^kewESfyy>`TY}=f``C>hdpQplIb@Q=b)~m3G zV=d*aYYUHS_-EKAU5eHtV(s76Z+x~r{!Tr!bDt$Wz`Z{K%b%AM zXL|NSt@#B*HQBbZmXgM_@RA2HdAu!$Q%)6;RrY9{kH@EKHjn6)2h%HfCFvt~{v zxk&m?_*Zk-`;bfYdrIt{*G2swob++_x+0V>NA%X9x~1D&#RkHd-i|G`eWGt$6g}zQ z2Fd=h-d~d633z@KJMIvVjT&&Xy=VPif$`(!OIfM#3u5vR(&_A>4Lpv#s=DtW4e|dy zVE-5boArvbw?ir0j_dN8uCrEms^PFjiV&#f?J5mkJ>dr zO7R(a;SyQ)0gq%^YB3z^&~I>t$%x=r#v%R8HOGMp?yME zKwt75)LU*f*YL-JcaI>l;GkO!nT{02JJ>OtXkWvAp=kLHqoeVtDH2c zcgkYFNv0s3VjGGP+Fw@&e<$g_;Ejo3_K&eh@(J5+TxP0(?5j(TcpNqTb{_In%`(CN zk!1XccHkBvgimsH@FgIF3thy^B?5%PFLNYoNBtGz(f#$)U&|qU8-RE=urNFau79nV z|C6NpKVthsV}yYk_gJAj0Pe#|KMzaW6;P1~3cmblsIAjp>N#dihzs1$L)hT7e)A?Y3$ zAOGd}=-=B*AJnB&RlY`dMs*r zpCSMBX`eNDt)|ar4RT1u%Jx9WJ%c4E3`Cc9@|ps+LbVrL$>p=C0;v)YrO5+yWHUk? zXAvoP5}~XMPGaj`6&=C7mSvY7N`v9IJ5~Bj`||wQlaOBIhhl-^AEuWcjfIg`k{#V? zA8~fy8o)g>kakUmhH^pNHV+l#v%mHynS@rjN^X%x)%1_{iN>qhM^4c&eRHg^S2$KO z6rkMTpfDLcE6zgQ!M9n>m^708F!dFfkn)$ZS(Xv~O5L9-}e^LHf8>jgJ}O$4erOV4W6e z&fAyTecg4lop{T3Yjg11rrK9NM${c!+Fd?PjnFHnB#b%yH4Sjen?B6}y#xwa!u&71 z^L-pX7Ak|x`BAX)qZXmInQ96>){=uFSt*H zbRZV)gyNFsc$G>y5I1?_g!aS4t`~yPeYN{wqLd|vkF-5FGO;EUG4w_kSFf9hPrnvk zdyS--V=)4j)z9wn?V^p?f^dlmWlmS{lX_zbi`{W*lUX!Hz-}LVSW~RnE?wSTRtN7n ziHUw@!VSrcfE8-VfpAXTr@aLOS3Gdf;Zm5%N6lqANH#AuWQ}*;uzE+1U%2?oS;5l{Wc1xpm+JEiF1&c$=hD?wwckGb6`k+92VNvqLL}xUG1d9?tkI~FYDksD@ zdlCM`Z}OTrSebNel(&2slW4`@L7R=^==79Z)vkiq-l1%E{}uuJjoUg71WUiAN_ewN(Xo*}@7F3W7bG&5a zQ2^yLRfRBnRkcY2%i^PhIsd>H1w8Wqa{0qUw*0-5LSN;89&#ML#it~CI53a`jX8y= z!B;()uBfTWW;EIuB(_#E02;31bG%dX;HqDr(>AWxRK$5sj^RXuHq-H?j~4%-_CGx& z0WmX$*#b#^+itardT0c4gWs56Ow|6`l|vwqCx79Qs0oT;^4n+-hLg1I-1=uudbSO( z8$daXB8^Db4NCJhSi$lF$AtFF_WQxFlp>ryQ+GH5 z=)6Yru)n;I<~_X~A2Wgoyg~xn4G+i|)&awvu{;cG?J=|xx-E_~K{k6lqTKi}zwEWz z2SA`KG^z7`jtkk;Vz+joJh*Ztkl+=A=Sf}k?2}$bYz~co6D`#DR*Y-+o|fzpayo6j zWTyKWj|N#rLiYF~5_tG%IaJ+Lg9#qtbR(+O};~+O}=mwsYsVdv*8M>-5>z+NV!k z@&1TEalP-15o69d<~^QgnZC|`bKeT-T0fQ|7S8@pJHCn75NA(U<_Sp|KmlpNED`*8JM`Y#cWc-irAUR&%9WEJ99%Conq->Hb zu{T0-Rg|hp*1^=N!X3y&)IOGUOy$fkq&PjPIi3F+NwxADMvh#^zS@< zocWhQ2uk4QvUY=(vKz1vicqyU#ZaO+v+yoDiox1nz6-W38A}01Ne+z_@5Xm=A-uwW zQT4oC_(oiSihaV^IVq>Z8v9JwLv9nVkCz8fK1|jb(e2nb6xe**0bMcZ|@dgNIkNac~FpEkySvSyBYTe(ucsb)^5jDa9rE@i-KbNC`x>hS7cME!=teiJWd(grX%eK|f03F?DmM z-Xr_DmJVDxnonVvJEM@s)9=2GIM0IQn8=b{v}rRpT~5e6p1-UYda7h8;?D2&Dv0Xs zdyB-~h1@Yuf0i8wE2*p`t#<0m;dS?sGm;AHrVjPY$gx!WLt}E3_w>XPYtB|%(}X#6~SPub0sAYWIY)qS^Ax(&_o8tK8U6v5=;D5 zKFPFDSXs8pT3lw3X-2w(PaFMc^ln8G3^<775@gg z86J&?6Sj4$9hzp7X-});5VkC2>V#2NUkXru@m&&0ouL=rB;GrBjj%nDAg1XTOAl<5 zk7Ju1EJqT|b85Q_0m?%9jO>E}A?f7bG>90fSi;U<(g?414s|U>Uo;unP?JPT*k1G2 zRsw_Orapb=0mJ^GiXYSCDoMrqm-7M`lp%g3yOwWwd~&857H#PzENOfU)=zht+{L$l z+Gt$1NYAi+Nz#uId^u?U-)uDg_wxH6IK3*2N4iqNXV$O*>Fggf4zaWja+(DesTpEV z`IVViGO08s5(>{LwB#`lsX%Gto-tyxY-ryRY&BWgIm+Bzs@7FB0F9uYij$fOIO^5; z4v(g@Be?Urt|e_e;wD`&$|MXJD4w)jH!F>}RDp@8W@@<%aBwj>~i?Yy1gs-LnjWR|()x+0p0B z`GjaI1VyhGMl+(mtN|&gO zV+saO8Gll5TD!t%+xTTh_#3Hjaz)-3sL@>w8RiqixSN6sN03Ki3sy99N7w!cY!t52 z%^sY$a6c!x+p0cW6Y_Q(C7{aZjf-3UYObC$Q}_c`R=1cfMZ_FKif}Py;E_?8G++8O z$=xLJsF80WVwEj*bicDu41pV>DZdu zx(eP=iT#%MF;KHWy&%D>bEVcOV40B&||zSXWwSKgdY_Jj=KRLl$xIKfg~@4 zoa4=l6e{fWN@T2Ra|{k?mN`;P3kf?zav*K5DVtGrm5s@^g3K*kiVXNt2nSPYM$!84 zk`OIvkI|L8c(KZe9Pq^@0N^NoE;*oSxa}oZd6Ysm#6LhX!zOpf4{XfkI5tShxgsF& z9V-^m+WpCHV#Z)ytq5yV{b6H2%*qIf2RV%0vUU%930T6bWW%51t-@62AoL)`2uN@Xg)dtHwCNe*; z$Gm?X@a!N2i0I$VYr3Aw2xT1ln}99NYxZjSQ*<+9*$lNDV1%D zhW!RfF*=XBeB9c_(54HLGqiyWo%|j~)haR2CWHP_${Q0YS2-?LZ6F8Xp>MHKp)` zAD8>BC28V@M8P767=Sg9G$-`L5&#%5;AoYiAYh?(!~`VM8Lw#9jE9gge*|VgM146B zM-#A`+AF42`9sc`MNU9&4{%Hn2oNGO8>(6{5eEjru0=ZEO1DLyu6Mn=;BVXgO3>Tl zS(B3GaUMDpu_#4DEdR_4CEBof{y4gc5)nZT>?2`#KhiN63JymeDjGByO2z>gYFaVw z8M9jraT<0-JCD!=u9Y5M(KcJYw3IuJo(HyRY#0o=@52jR#J9pWYg{nwX%B$&ghyf6 zWvy8cy)sGSAr@}?rD`IWX}9ZG0c_A@TK7Q%xysF>wg?(MrlJvs^JW)~GQN!mt@qII zQlfk^JU98I*=klfy+k)HcCaY)qkX5lM3bSXoT}xv%COq$@C4KR$U@Ew%Q}N_O?9 zrx62wAt}V@5Z>?@W$Ymg-ipfU5Kg0YmwFMboSfL2*t&nl9D z3UEB1wgC#p{e=C1Cm7Tv@b-p9+KHDj`XF^5H-YQ1Y$juPA(3W1$H>u|(P3m7vZ!m8 zQ-_z`QoK%soNO$OF^#~d{mSD#8BB2jG_FHMAr^gwLBc@xvMS$J)P+o$D!JcZvhZr- z5flU81{_c=psEjB-jP1N;}B5ShDK&38Br-Eicpl;#R>+aIbs9t@ddV>Jt#Jzs*T|o zjp2LqLt7dHc6#+bn=sEJr>>DIWGp)FL6gr-kLd&S*# zt8h2sT1ie=Nqr?~miAFbtP`BdMP(fuJ-Ao*fx_HDn^^lSOufC-`5!J8+!x*(DVchzU1*$osHhq!pDiR=BcHlw0gR1I zJ)g<98bj%zcodd8vhpD0`cShA9$-Vw$>i*|V8zL{4yFJhHK1>9t-p8?#Po&NXX!P! zbd8bsC%p62#1tiUA1KVD5USe2@EVfxk_#rOErduK^pIMrkk^;Iwd!gi5aRSJ+W~mp z5YJlv`%j2?1=_SUc{uMZHpD0B?nFAa$O&Y#oC)gY?TJjih4%SSJfYts!y!bq`YsD+ zi%%;5Na#=GC10j#SUXZGUYRM9F}T_5XOqw@?aH7y5jClCVrI1?BS}0=7|%MOEn-YJNhlhET#PxP9&p`@06A8#xN zOI)dT9u`Zxu+(xisXjAwJ~yL&tPss54N2I6J+%uelkXK{!ntD3{5fmCRtx|Wv6tBmj~;&s3s!r!&?0UZ-AAK&s`jR;4} zR0FM%es@HC^MEkF*0Sh(tis(S!+MV*pKAePI_`}2z0NhUAZzXMzcO~K zaq$i22~l=hC7qhEf@oE_kxU=9lD0G{viJ374Z%ITNbeeho#aoQV+^58VkigLT- zS<2{B!fAMQo6MbT3^G%W@0%Apn-}BMdNfmsvx!RZmq_0|FP+_;H#W$?ql}u{O{eIm zLaFQk0^dUQHndAED0G% z&Wj{N)pwJyP|b}sajNp(92Bc7h)#KomgzF z(ANzLQ)30mlRAm}|KtO3!?e4G)1@gQIjK8QzVK(z5FnrX!7o*&;XqVHSI!dZ`=(GZ_dFmuLT&O`ddw7eYoMiF>cNA?eJ#Nv}UoVM)k0EEVSnP#%g4Zqi)R#EJL38Zn7*RM0P1$1ZjKu z7BOPYnwd!zH%7~(bR(!YHB6%j`AS{`heLD)T3%8m)*}hDG3S-bGso&bIJHLeN9)B~ zw6G16%**bY)QuX=TQ&Dj617$S+%>-#MV%I(jiZ28qReGQCsCVjmrc)y($(-Oz`CGK zvM1|u6o@m&oDW>Qpv%hXyfW$2&hf(WWHSC>NV)=I_eO61W@LwmY6oe*zf%5^#{q{i z|0MB-%1XX1RX&xY;YHC-Vx)SPz%?t#+U>N*XZem9PRfwDT&XFxhi2tW$(4DFsuNp<9UGwop@GDa+yU3K7-WJx0sBSNN0Z*}MEe!S zmn7zY{@l{elr|?fCcdBAb_8Wy2ERZ56Cj!}nCe#ZwFAfhDp3AwdRu=lPX0{~-cqI= zx`z*T1I9C`DJ*-7&;eNs>>60Jvi;9PRXdJY=*xrl{Lk)v3DJ(MeCpV%=yHyG8)$we zNHvI-ou4$Lt_o;IG3h7cDn%t#PmlC~hn&IOaT~+cTa5RMjUQ@Ts<@<{8?uH(Ykukv zq-fC7%y5bV>$_a9EYNQvv^JSPVr8BQ{8o9-vJJ=bal^*VFy@QDRU}cB;(yDyfk>3G znr(LZxuCqN^7!H^i34ykArB+_&)V8w{H7^ms`uL0K=^$P#J?ut`1gVMCwepLZ>X$D z@ekE##;F}NAKbIfxzgIxjA1o)+cr`m5Og7{7O(!&;XYK$94Ga+*GT_i=cL_u5G*l_=Bx#6EiHjw!0pA7oRERC zIJQ8Z?4S1Yxc9kxsAaMK3dJboy_Abb+&V6|I?LKwTiQ5$k%K>t?7!qhzdkyd85-FsiTwleQPxmc6-N0$ zGaQ9P^~*s?ZD^h|i(p{MkpfMgLdHf$9`xZi6?6MO)uLR-8LFp9WouG<|roD{!u_~3HlmHV;I*x)uvPe^WZXz{6vG=is*Qo zS+cS0mp`(-mVNWjEjh-m26J^1GINd5LMEoa0k?*y?)GjEUWt zJ?yo8w+Z9SR&+4@urcWc=KZMSEd3kk;#S=b7?qzvg6ZO6YAOGI z58}5Ho3?8PNq5br7+?9yzfG9YMR0aJu42wqiMQ<)3V{e1>4fP$!A8SocnsFp zmmmDfRRk@1);*d@WgLq32+KMM4@=b$>J8(VnL>PAz_Zobf-uh*uwh@Yk;Eh}zLO0@ z`?cEKV{^RsbHnbiTzoirecDxxsj-NC3bS=-EwbxPeAP2qj60s}F&ar)Q8-I9j*qMf$yHhl^GgHHv$p ztz$Qn4wJX^35pj$JR#4C+R3L-{Y@(XxRNj=K2+iUC6eF2+AD)w$XJVU}c`6w2*&X~N=RwI|$&#g*vi(oSVzt?N zKCEvr^PjgB94>OwNbvG*At`^hKdybh$H_InRAqSs*?tp6U5|?m)?=i{$kviUjd>c< z-2!U&i)HhKO=wWMQ@Z}Jt=W+^ZHv^Foc;I)9#a5hH8b8M^a*xgHl~N`L~pCg64PC>StZh~*hSvj9j zzQiT^HV8F$VDhg3htTvYQXNzmDrm4A_{lY--zZk`TtwrKLQrK7ilG3x% zGx>MV-wZ_!``NGL#Ue+op>(1jq%qPS$PuW@Cy~RJFJ(_QAe9CKcODj zd9lwr#oHx;?>!MM2~fb}oW<|AQI^MDW$2aVKC7Hyf9bG)R{rdGJGBN%y3Pp1ep2k0 zLM4IoOO76;fg5Cq=`(~Lyi!BXGOv>v-VY-#EU+aFQG>HjP8#)v)tR%wmY^J=yfDRx z;Zsx0Ka@ZnrR>m8uKQJZd1#S&Tk&hWy7Xs47}n%_SED`LP2E}grrp~3TFuo-gtxSW zN7{r&N zE$fw9c7c|&rnZ^#%|re9HXR~~!ZS5v%XO4UkEjT7Sx1k+Q=>F&EeecyU!($Ee+rBY z<_!id`#6|V()M9LBLy4QrqiZ|Mg5_J!Q9euWnDpG%)`flh&=@V;WxFi^#)oX%RpAJ z#xd_z|AVJ<2ei`&b=5cSorB6vl(xa5ah^K1c6Zu@)L``q8=g&u^aMUx7qjxowr_aa zdTfiQ#V+0Hiw@^34j8U#4bMQ7MpZk^0sV(K%eMxe9BT3SB~R*u(7_jDX-gQ==Rt~X z^rnHl!M^@i{*el76$Ys0bH`pca}1%6m{v<|OUzG%a2*(5Z}^TSoi&d2ekzUy+obIy z^SzSY{5|q^aFIV9N*;N;T(n0|h_1Lv^p*MogWTZ&&2y@iqgzPJf$M?^&R3R|#03!6 zbF9br28D++4P2pg~GH1(Uv4un3lZh;$K{`_Rwic3Fp zqvf&)o)KnJ=4k68cw;=m!PGK$Gx&vn2kITWvD(1}RqEMs!% zk4I1&bT)t|%;IF@0wJP}_%XdP@g_Ocxkc|)!0^7{!-JKFO#u2HW@dO77VJt{H%bUl zWOtX}=>1_!j-F+3B=l6zzYp(V>a>h5 z$Zy?W3&ioSe8KlGom>4qSN!K%=imDzGGbSySNRYFKOOnkFp7MN`Pl3Bzq)}HlQ(|; zY!C4V6GX9X*<>qo>n_i$|2||u0G!aY1?&Pe*C9Etwg^Hy15*=g;{3IvPk;EBJjeA$ z^`O>=R1lWrB-b72=4@-c?j9(QVE@)Q+WSjGL~9v2Rj*_kS^Eqk=gyB9kppF;X zgTtIm{(T9ly?x9zBgbV*VJ|^6D<>L^v9glh<2=grmW{{S^_pGo2I|rdz1K#ojelAQ>O0GU7In6`00tL& zAd=q$zqIsb8d;A_F{(`Ad!+oQdNqeB;x8x8_G0ty??0Vk(>^g>HmjK>IndR@&pBKL z#f$w1Le$(&z*8gPU{GfWnJSG|E3il8BaN;o7{T4)&)Tu zBF#xFcLPIMIOalbpcuGl&)lL*8~zWQ&ak(qDp!w_Wz#&0px zX>2YGzU=iP?FHFHrYO(2OBJZ!_!)1ObfAt`txc7E3b!?-CwEcK!{U{`YI?JDrUk#Y zPQu^+DbtiG;)DGE5=#Fd%>E;knpplGO3H274IqNV*@!>q`SEWKIH)Xa78B|IBb2%$h{n%jo%8EQ{w6Lt{=bXuW%WJv}rWkoe&y@o2pAoCm3WM^r-9*XlueGg^avLy% zf3%KnHJ0_h3BYA=fBVl+;$1o%hH>U44q*=FVqLS3`J$0vW}b zh`qZb69~EFdzDMW0m)iww+JEdLEGB*-&W0qHZK(KO-%a&c3j86%`ouZNm7~t0Gy$+ z-x`4~Gh}h1HZhhCflOUcGPm>wy1k!fU08|72`6{KsH!!cOxEA_Y79qz+d+H6rT^#< zD{|a1uWL-dKpAUh57?ai879~NO_FcjnWILM>T3_q9i>o5C$EfUEK#I075d+W(rxk1zS~z;Qv8~< zr2i+A7QeN%g^`|>yrY$sp1y_Azirqn zMRmY-4`5Ap+yfmlkt2}%GDt&U)<63Zji}U>ICy)|&N?$Oar$}-<4rk2YM0EEV=&WI z=Yt7a3(K7ojLd7Ss{+Q7AA3zIP+8+LoP7yasf$rAK@u6e8VEV*`i0_@;IXZB?&U~c zo5)3RW5&2~LV9%1o8>A7RXrpiZ%0n%iAHZ_UqEx(ap`bqpM^}JKSY?W(&S!hakeC# ztnfhjttv|{=a?#Zk!c}mpV7UUY60j6fdVVUAGuY29m~}RQT7h#w9unWtb|%rJ7A2} z{(!=*rkVwo{IpWHy5Y3SK?euDg?0aAMhnzmS$<$wi^P`Np1M!$kl1XwznC1YTB%T@ zn5J{prM3cIcTOyC%Y?_)@s8F3|JS9nC+&nCRE-Ke!YStiZZ#cK+ zkt%Yl<&cwxHpL$y&fFrJCuBuk)X(UcA}q0{Di(HY8$7~XYO^cvdQ>RRN>e}?QM#^5 zLzO8xx>lF2JYRw_i%*2#Z3Ud8Je?4Z9WW zP~q{(=1_N{_Pf7a$T(M1s8hLGx%h%b^;70B1d2%Eatqorh*15 z`}2Vpt?_!Pd;i>l_JN;y9J*kSiq;WAZ{6HwP!}x&D-{}+A#cH$aQ#Hum>xbPxKYob z^A%2yEiO~&^sey$#Fg5?@O*JGe5wj7#Y@#+2MY}=3k_Nt>KdsHb<9lGYx4_JikmeR z5qxQoaVPxUrelx;4cIcOOOMB_iNh`$--ken1ZU)M}V@tjY{v$Rn${PBH&uLtYr;cV*$t4(!6z$ zR$8O*WaD#*`-(}-}&)Sh(~aN_3l0{Y{}Wi)vF64#YlnG;5ySA z2m~zPPCCCr%m?C!H8Hv~1_NzLD%1u+eXos(`;TJ8kR*vk2JD81ZhDV5U{JgR-mlybwQw4d1Wc8-8eox_RNDR?v)MRWG z!#qna>-?Uwh`iji6kefLM`sRf6V`1-x*n}vKMr<$PJv_IrPnf+gw6JbJNj<^B(xh| zQw?D_9O($AvJ~tH9`Q~c*UGseHWah57CfE82J|88ScY^L@a0zgd?zTBLtor6Xdakg z#=J5qykszNGE>}KV=+8PaOe=WbG!oW8kmSuSc#GJ!BmN+wxYnCP<3Ic#;(a+=^Cr* z@l&y6w7jClf^Y=IeP_cn18pdo9qCC&c*oVQ`ReAgdv}MW*S4 zGkhnO)obPS$CvZGoql2AkI!rP2}xf62!h@sP3CJ%GQEan0oCX)KZa0C$m&a(DObl* zS%DwA7Yrb1kG0Th8ynU`t%d|5<*d|)JmryQ`a1sdDM=~ETvYH)JrCb=^g#r`eUXe5 zWMq6fk(Kt#)rRCBJ#(*?a;#pKI!c*n=AwMXjlS#k3i6fgKP&;POASI~r(g%-X<**E zlQBd3dMV$`G6H!Kqpn!SrSyny%l5M|k74~=PKjcomu7~=1i27*pSE$=NA}k8j2^XT zvA;i>KlBj}xDgqP`X?vA!Ii;&*#nZ~22bObSv}Uao*yK|Q40`LSJ@JxHPMzqxpdz2 zB<{}g6SXjNhB6}G{s`-j;LA?>%lO`CR+0`IREGNaOxcoW<#n0%!=~%Z3~J%eA(N@G z8fnjPa)QC)5A{Sqlr?5qg`u=Pl}nUb0Ru<{%nb z-P%c=zlRA|XAqPl;221OOas=qh}2h8HeR2j-xcy=0Ns(xuZTS?&2($t7DH#j7G&`G zNrt-g?KS+Zl{2%dsjDTi9=tU?W@7Nw%eDH;w>w9Df=_Lc}) zo)7Q*U1bm9yj8~+E>EAX#yL)hmbeRXJ)wi>Sjt$2Y#Z^X>h?3c?U8kkFQvpchF{7@ zE-;Uu3|O=a*UW2wrqLZ=ka6({n$#W7MH{R#KwcO2N+_;nX8jWEj! zSvz@n;ppaXHG3@QCOOFYln}{jQzX1OcWirN(5dS#p`9iz1DQ&8tihp;$TX?voyYG2 z3zX48gOwEfq$euKWKx6Q<)QXX9WSb<$(u|#cNz9;0V+|K> z>SNREvW<{FnxpI3A&*3&y-iV~NG(-WNC;>bKQ~Z1@SMBWVE+MnM}4^c-TBCWAHO-U z+JKT25yXLm;;!Y2D5P{cTe`?J*gzR=;-pEfZOF_`x=7D06N<%6%9=I8Qw4jPwxja2 z35Jy-&Z{l&XL4+&*j4Nx?v+sY{HKl@hEApkh>U>53_MC9IICC|e~huC&sb8jnn@pt zPO&6>3lwxw-}L zTFB`BW=Ox;KIkd`u`jlg%LA1PJ8qNMN}wN8=L)5KR9#)%*~=UIK^nbEqaGw~QF1U| z)WgL1$#md3KR@-nzG57192--okj|X2&W#wy@aaf+Xdj+mOKoBLaNU;}nbD|az#eMy z#@5J}wb6CCeV5r*fd@hQTI9Re%*OQ^%ze!l66y=@^8<)h~HHuCQjYc4~kUI{|s6IKn< z5}QSyuCM{eJCWd2dc&|A>)7#|cd`}KlLPzt)N; z9B)*0(M~~$a44n)u702x1-@?z0vC^^EzwMhbPiQ&mA(}lp2V$;L3O4~lKWjNc9z@k z_|q2JM0$;JP+LIh#Z-WqVT>-~`iQZjd+xJvWlU|2Ke)E-^wMdrM{v0PRLc0UvT2qY z_FX;p$5Mmt&dbFnjh?RZK-mGQ97pe$hH$zd38Tcst^T!XsX${&p3s<0*H!7C0!K$o zb|OJ+0xcz{T%!-YpWmXIYND{xAKXD{1zFwrj`~qFe>h`#pQfFs#%U|vt_#d(^&hG} zuna}PW?XGKdGK7nfqPA+P&aDDRu=PgFyFk=mEhai?O`Q<9aL~CZ5k{-uH1W;W|A~> zN#M)P&<<04m#J;)e^jN#-zy4hK7c{G8IkFB7?-bid_yR44$1RrU_$I>s%a!*`1WWZ6wiMgy5es*#DgR?tz z@CTK?;p|MzdK?nw=F-_U_W5-`tkDa5gOc1eqH(&SXiYmxR%X~ zN^3OFUv=UJdLdrA5h6twfdURdO`+je_bp|yuSMDjj7svffVEid*>$9{En@@z zfl|*F=9b=T+!oH#) z=aB6TLPtM>y=?Ie4XDtkKbA+c>9%$5gWdU$A|!x(**Zlm&k0gzFFyOL?E+^;eVQKBbft zLxHM9Y7T_tUHFH0zT<{ zlj7(uhrMr7XH11NH;W!YmgTcGFWt?sJA+=`5Amiq#MuzKz<9sry)J$`eJE62_Twc{ zp`+~Prc7f!vV<;)THEM@?4*NjPYKo_@Zq!Vx0pwx%r-@qTQjfq(Jk_pPs;7XlBMs%crR%gJT~CwP4K-%TsoA`)>L#N?zh z$u6liGr7z`i$X7>&sTd^S%b}AWZ7m$3#}7k@CMB+#)VoD31yIWk_Yt|a>sk^{FaPu z^;-*SJP{Y&Zm278q2$>DP*S6NjN*C{_(LOz@>Mm?xO{z~<*8L^PyUombEW167IK(S zfzQs3QLNE(yRxv}D2>Mb7WV&QO$%H7YWspxerOZwKPd2^iduf(gQwo=pi2IsqK7uG zk5ti1St@{AG5D=igvgSQN^5)%5ia6tmN{6K>idp57atFoBkUDk%pl))Af zpoh{7TC9PINWHV2iq>tEaKP9K5!blc8L76BJ8#>etm+=N?=l0BHGcZq?DW(7&G8Wq z{}<|Z*()TK7~77UP*f#TR~#vB#vBGoc1&m6qrF?~GQ6wHyWNL1#{l(Ky3vi%Uw+=KWDI`wrweYHDMs3{`_j)p z)%efAk{1Y5*he{8#OZg&8$+ziu7~88SEL_eLYvyCcEtAYG#j<{$HttuufbW}q|fZ*?TyATOMm$I>@ffZqi20(W}O=;CRy#4s` z#al>djQ=Q4EQ^r*X%4Lo{k7KBJfNL0^Z79WRN_nU zlnGCAGI zq(qe5-ag3Rid=u)c8NDRhRN6MMt)tw|AX89uejEKd*}Dkf&kTwov>GK(O;na%+J1h zZ9QG4paGTM7id^8yLM71J-km0aEp~tQmTkiG7sZ)oi7f*t)P)yo(Pf5b#S6Y)J}?+ zWolgS$k5RWdOVSmC|OS{bUHyf_-{yA!2(%4d($Y+v_@9 zfn1OE0|Do4hOMgVg?GTJ3N1Y@x`kJ5SiXY&XGH%so{i}9KYvJkK^W_9?YehdAOJBC z0uxlBs3PSmcv>=(1sL@loKdPg(poOzx_)VO7CO|^%u7Wa`J^S*pDZCh1Qskd(>QGG zuc;@ZBGkxjJPN;b*q}da2&>9)n9T?0s|~jhoqeo!FcJ9tA2eH<&ZKGn5+K<7s_y@5 z-Q_Aqdgfo`ija$e(HDqkZS@cEPF~}yD;R@&Hc`1@o=}#~#SdK}lugi;ia@T7OLa~b zbaHl`?!2qY(%7W`<&VeA(-y*&2xjN96-vRc;8*(1^E39%^sz8*V-* z3DmXXtwKImiNO_1m?7gs*>)vH$CV*&@xT(eV_Phdz?HZVIa?j4jCtG6_7*zX6-;4b z*~_D3?ZQFs8f(Q#8kN&&H)X9MYx@yTS}W6AaF`K5a*wAK7n*EyDP z75UZH8!7bK_=6a^WQCK#bGm-bh{Np*ip}ok8E4{>$ieRleMS)XPxC`HL}l5%q?1m< zC5w1DzJM~V3p93R4fDr7vfwCkkF6SS7>{o_KBR+6V|EQ(K6YB;#ihmDgtO0Q$S2{M zqc7T9cC<{U*;imbYs}BNg=&l$OF)MwBX~ z#rTv)Ua*b_h+Nm7n(y%c_0QpalqLE46(pr!LBjkmC7XZKbyRXNv#|enSRp}S(;E3F z;s=^3!XK0BrP6x!5}^PzO;eBFCw?XdcJp0?;HXiC0Lw|gHC)XXlV|-1(g8C3x4iIL zK8uQy!p7$Ic5CC#lxL@h!O2M-;5pg)nEuoVjV4RI^&VVoOcV=?t;zr?7$KNPumk*4 zzCjtVnF2eBAG0_PVm}T~yq!cYIZ-;~aI<3CIIrS2<#Sj*0rcM=9f^T}4_y&um+q8M zkcb=`B^YmBIv!qZv-q?22yll9(&8$^k#X+~H6Yf1-molqDVDQ>p#^R0it2gHot0$| zo~4mI@ zR7QyS1BwlUcERc5jSORN+}X7PcFi6OYo^m6hTDfM%2o<0Hf zJURjFs(C!n9MHlM8Y1&k_kB|zlKPH(qaeTF4GFznld{zWw3?o(pi?f-<(}WDs%zwy zJT$a^C9*4THea}EQ=fU{P`xRQ#>&`7Vr`ki>seBA_FDWVi4)OYV-OLa^k9^0Ql^U% z&DE(8euw~JwoIj(YxRs^98`7vBY2KAUq`Wn=n*`{Il*Aev&ZArpMElFP;k_a7XGBk zCj-h=Pn@2JwG36$;DtKTCZk=ROPP$C6_X(arm~-F`Jae6kRavU-(M00eb7KafdAWQ z`nPP8@P+w)H^K1Yk@j&U!O11hRu)S0!>C&j=vM|eixDMB`3Ty$cb?XCu>&3e(QR44Ky@QCJYr>T64Z`}ykRMov707_xRUByfB)T3!kzfw2xro>|IR7Mg z&a0G${p(2*E-(;fMw}xrN1i~5{~LW}4yGq?GVmITDHet#ye3u~hf^NeGBcM$$?Jfr z^>1f8#cTrG*<|J&wcgZV1lLG2sdUt(4I_<86V;92n2Z<@N44I2x3jx&_x`GIsAI@8 z+8O&j7Z2IUuSw8M?Eb~KX)HWdc_8z9aVm?;Ig-1k7O~`FTp|cZGN`y%uiY+aBsUGN zb&h##lbuv>v{FW)k=rG7d=L>42&$G-V4E-0Z0tKgf#O(`SzfJVt$J42sn15TeiC2V zC9aSPQO3}4O-jai{4SrBBBMNfGZyCBtk?07(bhS#W6<6qh#PP^^UH?c4V34SnH8%y z21mzWViZO}Iv^e{ZrB$<83SNuM$7;HUaD#s=y*^XHdK4iuv@GPDxL#=tciHnnm zq{_^P8CKVuHnWLZb$aXjUq;ht2lL(3Nmg}+p8ADXN@3l zT{e{PtN32$u-*_ExeG$pqp={nhdQssvPmEdsMBQ#${Ze2aW1TVKA8$U!z80|mrQtQ z$u-1Na^ZmA@s4CgT9^(51zwwp0S84|>rxyP>vK#O;sTNgiZH`%+y>h^xuPeUx?yaW zGh3sSRs3e`m@cpUuCt9WtpgselMox#yD zz@2z!uH>-F01SE5j%HpPCUqiCTKZm3kFnsm8CR0VIG$;>La0$Ll9)_+zTVEq@C`N$#i0~orD1UwL*XQVT=;6T zxSdFIM22}&`^0ISZREkY`TLSic!SWNdJemh%!IT~OOT@80-38%m+z?U>%ye9s1~>- z)-E`|bRIa-)qWqp(5>FjbQPo1vzt`tHF?oWaHjD(RJ?_N{&r8TMt@Z`vbIqPbTci5 zYFbddeYV%|G7hn?%t7Id#X`E+*r7&|zM~jH^9(Mg(;T>lrM!aI*F0t?!1>8}2pLJ3 z3GtLt8+)$B|4iwNlO%V|Nr|7se<$=QXalbF3%>lv6uMNOay9D%1SLKphKBIHfZ`ze zTk>gYUmp5rIiI`c4=WLsMaGR*7xK6b)$4){0Uo6sCS;>j5*FRRfjDM zv4AU<$XQ;YN3ccq7Ie9bR^-si+y~5th-qsrTTkDchzo=~BqE`Upc@zFllqZep*L*Z zSLg=1pL-rEw84bgOcBOSyh@O-GF)=3>k`HHj=rA%i?VkPuB_j-hC8Xwdh^_K&s*m{-#NG5uWIkwwf|ecwbmR{V~$B(Dm9Sboo^U7e{U}I zj*Oi=gE>Yo7;YVDoU`x7Y{>nVrM`|>Ln8*$m`e7(MsmUAh96;={B#F90Nn3Zg2)hs z#Wx`xfKA@YClow!N;=8Bk>VQrvexQf?7UR|7SRs6eV2;ywWfU}~zd;lsbl zeC+1q(d67Cbo6mp`YFXHY@ME9Ua9|Chj53k@Rd4^pL2*Pxr-N+6%`rQ-F zw&(tPz!a~fP-6%0aAK*t=r!FYag=0!=8>dGb5@X3oD(bW<)g_w{{T~tn+hPZR;xM7 z=}2CotwLSB+`+@^v*N~w&@-!{l&^{ki6{kyEZ%Kun&%OfR&KgR9a6c99`EqyION(L zNcS9Sdq=Y=O71t5CuXX@{D_-_6XmES2+Xd_l`aU8Y9z`;Br4L&lnnkUr-|@y7!Z=$Xc&*UIFM{jQJt2g zugYJ**W4pTs9JbZJr*wtS#&q=3}I`rh{|Bo+=pXT4(iX6QHf$jf5G`<7-HCKT-i;I zDGNvT$CHX?R2u&NemMaBAnFQFmNZ@fum4g%pdR5$l7PQ&fBMI#Jk?^3WejPEO~kqi z+=I$adX2~&7a5nEs&hk?sYYpa`9gj}G~%Rc+Ob^WqSihYmF=*B5Xc6{_~+|O92?-jJNOo_cH z9~9t@Ix98C2sVrm=^1(=H<77tu^e(vaw%csje;(EDI6iT<%h#i#?1&|z~Wv<<@U9hqNB<-FKRIw5w`w4 zbdi)`XAh6=a=G(U#=%J~2XFYnQxRm3-&$d^44tkR8U$ShE$jAn^C$9ZWN02m8V#^+7CxyXY#FU%fQ^46PhbBC}k?7Rjf#|`Nd;zUNlG#}R?hg)GCQlmt)=wjkc z#&lGC;w_{j1~7Z*R(-ga(qzf9Xz1Dl9RBZEn!X<9J0l6L8I*X$`?~u%;{tRz1(XFW z&I2#5FgFw?#$4q0FtSHaAq7|;7CQ=(C=t;n!aCLBEWEtP6Td@+nVE?dnz@l5+=vt= zjjd}lYA5g)<7g)RbszgAc%c3)Ly+GYa|D(2l<}bLBA}uloAGB3&FQn5^`G$IO>Se^ zlT8J3W`a0zVjMc)XAahHTW7-^UE^}39QC>LARIdJWlr50_=426?IbtKguKHK)tMPR=MZ;4~?qpJ2_(1sJj_0MoasocRx3E9nPj{hi?Tsf$#e|0)*Q){QZDy7Ct!m+wZu$gsHozxQ7OAp$NTmF90|2 z93X@{12?i9sHxrh?G-OJo{%ZOqubVN9zJ?xG%mek-HVXG%|##eV~Y#1K>P*W@As*X z1%e1x^r#-%uZ(%*jTlh81@A4>^{aA_yhZPY(-Er?LAujElE<7EB|(?7KBC9A7o>tu z7W8Nyf}Uy9ysKkDx(hz4$E+7efx3%6y2rE^7=fE#i@5KrA0q@2EW1hWV;{!^)hxP+ z0F93of=lMzWG_n=UxMEztJFdGGd@Dc?iVV8zs!H3dnmoi z(e&GNJUdZq9>Mc)8n@87syh{qQy;lGf*#wKi{7)Rt5&ZfT9rM8Bb|7O4e6Gm!zJc6 zNs8rPK^Pe?Qd8+JCJa{_n?u9Qe^QWD^HP~+JgPFTH4YD)FXCg=OL=Cb!e3k%W}bBl zNjE);8ICscqbrqnDveuT=zI+gH>XNo@ESgvU!l#Fy@#b{t-cO4SX^NwOn)ek^Ic30 zoG*N6OGi9n7{;&ag`doPNJ{^D1Y+D+)r+WY>_$Ra_)r~(zqlG`up~f5S^Ur)_qiY# zxVQMEAQO8fXXLxc8PqQH79R&&?G9~Ke^p~lG5;hx^t$NZ<;wR46J92Q?DDwtx7JMyi$#i~8Y^h%0qphZHmWhdkRw=%;;= zp^m-UOcGn-t#zAq_0nD2&~O#ns`yHm>|>m${in1sQ><#s-3|QOjdmcRD|GZ)4+LgG z%;Dze-+Zi8x!4H(SFZGzY}>!h!2h$4wRg0$H*o}5m^h7%Q`1R|Q;$f~NXXPa2=7vm zn315Pl_XOr7OOFB?Lupf_Ps1>p(;`5vgeilA+2`3|?nwGb{c7ANG>OIBi>2(2z z8jMCzJ)+zG6GnU_3QtAkmh`R4F$5Or_Y(G9&6rVZr_Ec zfD^tXs=7eTj`mNkWTLV`T0PI<9g=pUX zEN#*IPz5{n%wD5Z*e(z}=0tT)*R9KJ$cFZ530a<}kq9QM1M4hu*qQM3&Ozb8s&JH2 z1%(hRrs|4gq3%c^v;fR_2caPuwEoZv%-+&)(4hf)sX-1hWoe?aT{a5Q;aZ&E({HXA zO-DL`pT4qa8nNP#_@L3aDSvWLxLh+AqcP*yJZOf(*cS2ZVFwBu4#%%eqC&0d6xQDT zJU#Q;&HARFe<_(!)5bmw$qv1m! z$yetc;foIzzn#{`g7pT5308h!<{^NtNnla+%l^JEAC6Y)7OF&2W-JMA-lLID%Cf6H zv*Ie4GRuSY2H6xAUnY+~`^8Q;Quu>@3qHEoUl?yy)3~@n{8G4j>sksEH%eV}D}Pud zqg>hiTF5j1@}#xJCg0kXAPI`b!Y9ayucTvD=;_bw7S6^a^fen9fq~g0)rS9zA$TcB zxt%hLjb&y_I!w`UuyF8{$2k;D6~jKxFp)S~RXZP<$Cx-@m+aG5u$0OpS5D~9-?XDG za7wL3z6xn<;QxOON#tvZ=D!%yniGl&?uTsM2-%sSmSiGTaz2<7rHnbFp}^uIn(gA0$dZ42nPVcgDUQ^ws@;0BJF9rUSZ^lfE$dJM# z2mVlv791b_a&*PVTiGiEixnZWbp@q8#eSuwr|FOlUG>0?CwhTpg+Ro~g8o?f*(84k zN{jW_4ozG;Suz=dNs61&ha6N*9~%yiLwY%rWzXxk?&l2_@5ArW*KYUC1d{fCJ zQl*<R}Ii%w(C6)n3vHW%#RNKnjzuqi4Qw_o)$(SC|jxv zLtAIKVbmm3?cJFoz}ELu`V_ISzZBU=_~H0FUR3C&@Os@lEWl)qiKK{{#Q8uzGSUH; ze_JTlG8(OEKUt*MGb4~kuce(Ia8&`B>4i=U%0zuJs9MlkN5=5-6IRl;JZd@8$;89w zShV_T5Zotn@1@8a)oVQLrmNZH!6RHBj^A9;j@c1ZmLKUY(Uy0x5#>d5hY~QhsoBMq zidW+P8F@{$tEYlQ&9^`g6otzz%PV#P-3U5GJUB~_I2dp75k4U2upHq<0Cq*u5Z8w- zy*?y0FI~(8M1Bn|2S-@SuU*4zR3>0rlmwib(XYvdF9;v8VV-y~y)hcmE4R6AjS3QW+ zMaTvL!S3(JJxUA?@@puj=S1qCqH9NPSm?zy(d_yKk#M@Dc-sABn)WSY-lET<;hzE} zdYLEpLflG?bIrf9PJWiVT~1(Q1;Tr^dR}r)xlgWjx_)}Uyl#DyG{?jg4x+Colhv2) z7l&ScpBgAhWp{vElA+lS1|JUe6M<7f0eNdL++hZ{nR(JgcxMx8Ll^N`gW8ZCzKYGm zCJpvmIL-RwuhgldqiduO-=8}d&Q*&ucxJo&fE78BwVZR4PM22%2aKtmy`vdC5583D zB!D__2RrEHz2?2UnulYv64inytW}Q#QJUGu6>u&O4J-8U{WhgNhW-69y&Wr_Ov}#Q zw&k)3q)RSwyx@AmHxL`jAVMGv1%~qAt9YuD@DS3qag%Pa&AL~-1@Fxbt;r_WvN!w~ zj`3PMw>FOKhtV1%($UORh~8?j9d4S%lM4*KVI@+FBMi!spxntme?}2RPoWj_qXd4K zAvNw(4Dhj5B4qa!z*jE^9tcsA3r^@&nI$Io>n+(Ta98(4IgbnP_c~EG(oGpY zzTpyx(SR5YwT= zF^us5L+t*Lc`OhtLryV{peLX`4g^RGV2n~J?NKH8_*gf3r9=ZIfD)M}QbMQh?35rf zMZq)f>b}!4|HGIP*i40pki^D*&Eyu7}FadQO; z3+$>+L^3?#`~h9qN~*3Nrek zxXBewy-Lt*claY9KO;s^k=2r1B`37_MnLl^=H-{}BGXk+?1cMQP>Cu?8-gwEo2h*9 zyGVWyJG%0Q)iqR5lv1_y_Skq2(_q4FJV@v4sJm?uul2(UUYC+;aA{S{)I083KWGV=Li6gqA?-56PJYf&e zf$2FNFYhzRA2B%O7{S27``LhPF+@I)rx;v*)&=g2=gC8qN8K~zv~-Ya%qZRCWULLm zWao$EV|0NZ0*#dsjV_!v-fG%3_E%MF)rtR+ePL*Ca|W-YW-WyZQzJ5#i=j@@R{P8@ zWvTQu*-_vzV}6Q;Eq!Mxo1q?t=p=IAXmHJJYasyGKfS(;Z=b~STAEAalJON)=6R~z zar0x6x>|57_Yx*yrQW6Dv3OtEkSok=kfmi4$oG7zD~dFOE(GV}U!5FkPWuw`0(VF# zxrdXvfm*ECHb{*f<~c)3yAXPBanx^*>>1h|tA7m9vJ4grsS{?@ln~QRF-=j$Kj_mxEqaeNA5|j0 z_}Kfzc#C;shDq96I~>~Kw&PJ9#2B2TkT=1RaFb%fm#y!w$TZhSt*~CKR35bV)##Uh zMLii022X$pN67hnzkVqQ5R^_x$^9X>jq9FW@{N^d?q_SbtA#4sHHd_dFk|Q`i@Q&V zA(xm3(yS)g24^^R2)4yhfHE5J{>#t5&C?RGF4~lS;lQ`AF8II211HxnZVkPFp%cK- zzz85@XJcq5Xy+#AXy@u=;`o1C;E{iAwt*Gpzf;rXvi}ASe%OTTrz&V@xD9F%YF;rd zE|F``3J%|shX`&8Zmsbro3?xS&IKZt5FQaU6mn)Vvr_p?le*7Zh08AJK8Q1!j6G#N zeUdVRWtRqW=W_LrxyWL71BmU>fjVt(O*@SRYD2I~7jMw3d@bRXvd|Lp!Fa$kEbeP#ZHUsx#q@38QH zKl?xLg@~~Qz|QdtAl=;mfsR#4Hga?FU+ZsNL5A9F6QD{%b2&^<3zZZUrUPZ9LnBi4 zrw1^K&#JX*tt7sLS5(u*QT3jI-sFdzq}U%pgO7FBJw5S#-gBI;E_~iUZcu*UPwmRv ziwOYVITn%sc2Vo)T~Db1yUy4$v1sj;SuUm-f6R2v>vMr!+x^HFRo1V-oYw1FGS~YojPJ-?{e6dFRhW@ zrO}Ee&1S4TnuOt!+8!qp(wnKW4+e}lK38OUqQ3NCE#>dwa*7^JsAU-k0bVX|vN? zVpVF2JsM@93hYiYG};Jeb}8m?BWAKP&0bkJ<+^fQ(&bvJYMw!Q-u0E|WNzc-O_Pn+ z{8+GEnukF2U^F#{%O5}eRQ?=X%NT?7^{09m_qN8NpPe?HvY6i5`|OaR--$D%De<(h~*^tqtU&&g;3vM{~^iS)olG)(1zHn**3e6>6(VG9!Txuz&0LT{V zGvp>5nl3v=d04spYQQ2XhNDt0kong|Ghm+dwa72KNEw8g8bIwcp!}Ye1siJj;{zH@ z>wz>4$mG<9uRGqJ`?*DG{PDN48IrdO@yk~raq^{b_HTK5|GV)>TQ~tsZ2wt2D^j&l zLlOImCjzb2Q&L1_yn9*9%O!rq|45Ro1P0Ptg;Zssy&tq?1JP((k#S}B7J zWX~VYiFK!rC@ayIUn6DsB7mAB`78~aLh41g1A|3OA*z7>nD<=y8*`{UPz<>%@mjqP zTWFx_OqOaYmVU`?a^^I+dSQdB8Sd7_*@>E6&ske*VLg7KR1;=#)8FQTYn_e>wvv|} z>hu)*W_>|sqjQ)c>oSQ#$pA8?659-u?u<;&g0+0zCtnpVJuHb;1rR( zXgRGf;kF5eDKIQ6g4{lVvj~r{4AIzTX?vr&jlgPCAyL9l?|uin^tR`uQk^b)ITN=q zc``EhBeBv~V}D)H{y|SQ4ubQ~{vt}wbA1(=xd`VkPmpYRVbIo>BCW8>RY=KG=`Q!>vraViDYC~n#ESn^s@Ss%iA&!!d}n#xi*cznhCku%JKTB4y? z2Q&gfmZ`Ir8Pil^YRvoRAeo=_D3-v;K^`#g=WM~tu(mZC`x;1N=X?*V zVDxW=1j`lIoI(5&22V;LQ*pQh2i5xNl`X%CH2h+WhY@-!gnJjPw|jO-g?cty-|O zxiHmA0Z&m~3s-Fbj`wW6IY)Uv{ zi@vH=_(Xf+y%uog=0M#f<&+V<)=4pF!}MIu;`-Y@K-44*W^dt~>Ot%l?nw^j689FNVNO9T0@cpIGTFdPSeoJs>Qe zV-Y-fj2%KAnhb)tLj?r<1lkywRe}>Y!QmKZp0Yi1?A%`S=-~-tBbr3XG)g$qsIbY$ zfp}p#C6aVm5;YPOUM&_k&HS%PbIU?^G~!3;s($IW`C3~}XDmi~S#$TOWZUp*gRS~blz@H&vEsZVpstQB@E7zME+J>FZKwkg7fV-8tklNNNi zpSR#}xE8b`>ZF;$i-B#ZEGS9N!+;KvfiC@;3GZ@jNE1GfGhh@`9}u0`)xnb#o5Hm? zb<&)VK*!n4LNACoirjA{;=JG7BS7}e2HQ#1VePO9yEI5!;ofk&r|nNaHEM%~ zmB5p8XL?$nYy67LnQD+L+~B26knrSi+`z?P-;ld!Ym5{9gIirNpILp3wwv?4V6s`S zaifo)v;2;3{DUoqM;gE61>-_k4(LjFf%JFnvQEXvxAYkA; z*Pp+m(lK5GWm;^ro^(b_r8+wDsb{tpEH8E|f9vpL7unQ>$6#we#BlBU*5AW_ z6CT|R+Y$8>OP!2pvJZk)S#122$4Zsjxk9X_*iUYc2}De!_H>4mNRE}dPD6P?nMGmF z^fnnKLf2f!(NgThsJMGqU}jv?(}!pU`;??zkdrei?-KP@1;pue6rKq&&fS8Qy`mTQ zeFeYj^3*Ga;L&B^E{la5B||#c21BR2NCE9&J?o{xfGUu6&Ng_rEPdyRGAyX$#zb;= zUf`*d@TsCtIofTN@vKBrRkc@Vq0->RGaVE*4c#Zmhg$I z74e9UUkMz`{CZ=Af0sx^oo-xuzacBhPTUDa%?doh#CySTXsLvI-o(#kfzxOMZ;UD< z!wkVyg(@#E7@9V+c$Ev8C>Eo@+!6~)ag4p9$dJojB)_8F%9#bN5g#Y1d^JfGp85y5 zcYWLa{)Qd6Dy_SUI(y0O4ozw+cdHRwOWlrycpS28p-7SGjy5`@(o7-NNbx`ufMO%d zadO)ez(tdAx}H+HE+w+#;e(!KeqV1!B%_GU6X1@Z9C{P_NVcjMizm`T zU<+#AR+_-8moL$N@`@*PmM`*3NF&!0A-oY>ZNXr?^0Ytjok9mizod`=h4aicu9&KR zi{P63y_)i!;&)jq=-#pm$`)Dpr2yeCK_h!YGJWdeZKCm^!O|hpQX}PYBL!}}6h<<- zk|TbhLH-cu7R6pIbIR->jC`T=!~;QqL;^5DzR{#HDk}1|*tLRxl@Kl8Q1){=2K^eW zoxR9Ww@EJ6Xuzxd32b-!42&qInFTTbf5~**93Qw zNP^W?NgF)D>WIeO!yE7<=k>z4xf}qT6CG|qZsU)O@K5$^0^#eV z4mKd-&8sMNQh35IjOnL`z%7eUlo(MNoN&tO%i3#_wFP{>XHL(wF$nC70W5K=;^ zljZB0>T|jGYxR5QadBH)n*1cJRO$UBbC#cnHUCz zt9m1yu`@?`4#=tR5<|}*R>h*2xlI_vZUq*;()~Oifz54Vq8 zV{T11+rI7+0ijoe(gLBUOwLEVC-r=L&4hcUJv3Aq8Pz}95-u_tPuNRxBwZ5eW8NQ; zY8z)Pa;$;LCBo2F7ulU26#yp5AYThp!V_q?Rp#lin!dqd!o8k((tom+%Z$Yh<5Hkl zXz8wqSDBkXvTzP^koXgPu0ovR;Pd_diwhaC^GfhPi)FAG60+f6#j=Ah4M&>)Tr3l@ zH8-#|GBN%i`=Fzg|C*sf{V1l@X`@L&SME?oq;4pxQ@(-D5B||JFQo`F(`>?hLZ{(6 zaXB08=6y~6+?No;_wpm3bY_5HJK=+HFKs1VlxS7P^e~h8DD!2~)%0=guVI<-T~%o8 z$+F|&!f?ucPegAhG%!>Z=>n3%c>g;p#Z;v5YJF7!jb5-|WAhaO+hl_}#XS#w&1f6V zyg~1fhT@CG2a_cx?Sv(KOgh&?EX4)96kNfz!eg+t#(t4t!LIh}J}x1{kqU?4-tdcC z&ow!=*3ao>!0-4nx8j{joG#k?CPu< z29+b$;4m+fF>}ne8Cd7dZQIgcACDU7<-()KZ?&J#NKgRF2`i>T?rNM_;SBE?(}mk~ zI#RFkT-8pSt$peyniqr`W+L7G@4+m__6oh3!BQ=i+u^|#Eydey!R|B+(s+s+EPi#PLS;yUbXVu;6g2PiPsiK2 z{j@?S)1VNqKboQT?&V)kuo0$zhvLtrC)=@#5(gN}iixKa>!{D~-jmnt@)>&09zjk> z+yZ&w7HK5Zg&T1I-SEinDs%Tk+k!;G{Sp(hSn7d~`Z z*?9?^#;Mo0ix(wbUByXL^FQV_O)mj4`01t#`ETU{XB(hS#SOyj-^BaS{HhISN7iNp zo(3l`q>)AGP)KAHRUQzh-+?`dNbpiUoZ4xj3DxzuM|k~PGmMTXZ9V=HFj`CGSlYzV@Q z{dxq#t3p`JZF7vu^tA&&pP!t^4JE(n-I3huHI~mi%`g5QE^_rp0iRb~YOl=*`sZ56 zVQ;t49KHP=1N^T2;glORe&EVxteER-3It+ZuZ5UjJ7>C?_eQMI%#-XLZsReryf4KF zTZSVFx}1ak7Wk8HH!T=)*C{M09Q_eSN$Mf>JUk=iaxV;%jL&Qca?C+ay3%eAy16{I zxLk#4z!6;V6=DnaqqBPkx^pNYeR#K8^}fhoGd;=E;)MrNIj{8L&=b&fr*q{@@QkFLLr@3gC z@*z=)jao9L=MPuOSypBMLxhvp46 z8Ve_A5QR_Bh0=O@95_1p6}16d0h4lxb;;-lvk4QDF70ECDhN2}3E}`i->O!9%S4nT z-sQoiiStPlCYxV^IBHQ$(rFon<5G5<60t2Kz}7aCH8h}9*ljGBT*d2~fq4$5OjJ&eCKB$+DO-j_nE5W``%hgK=YvJmSJ$V(DiD&(%Nzh%{dF>cH|qRh?N z!IDw5aV15%Ey^$Wq~xu^<1Z579-o%|;eIezCiZn~kCzW}QaZ1dzO`Y>;RGu;Hm~Zr zeM86!ZtNE)&0h;4TK$GWL)jW!F@&l-sv$*ksZ9JcCXR`C6<#MfHPdnCce<{&{59S> zx%{0b8JO+wZ~(SqsY=9(V6jCi^y*B>cKb7a_l06jNXf7rH!7J+JsEhSqftn0p&BJPyV*-xeB6yaxYLR^rkPZ zvd^uO5r($kC|&zGL#e;nH4TCqDo;p-?wfM&)OCkHY5?3Fq7Xl8WJkf(;1t>$aQFCx zBo+P@(|ur3T3Q3;a<~mJb@7ZoT7v;M>q_ZjDoUGZ*#bo)wo`Pzzo$cvztwY+zuuj` zf6Sh9_Tlt>5gP0^K3I3J9ok!Tz?~<)W|~V4xyDseCK;HrA0I!&{>d`LAa+|8#@*kZY z+IX1L$TK{jF!Ov*C+3qVIl}aGm-Vooq&c?5_^KG~p|j3pqE9tEA!JyOoEB3yl`g(* z%5$xT^Q{?neTvSWaw&?2&}_x|HenY@YrF|f$rZgTYWwbu&R`jGNt&e&6DlxG1uqJ; z5}j1(Wy!qBmPPSQMu4k_connPI&X5(sKGh4W5*bidypN~KUvD6{Bos;vup3#0mmnM z36cxm5YKw77h}hibi!%JbBu_N3%JrCnZ>KRkO3XF=H&`YUb6oN= zh2I-yCF-%YaGUd_`c#kyEz;+29d+(3qE6b;u-M=&e zz&EaPnGf-l7%*b;@)3(gQyKesltJsoz(W{camP(LLjvzG{CR*8kWnRs1gV;8Ks5R; zI6(H}woC(u6k1ba6Io1+d*9+CB)*~0C_%l`ldM#ya!;9D(PhW$V<#qM8+Le6g1pi`wKJ#a@bK}*RdSs#o?=}n}J})3b+I5 zc8Fj7>;-;XNZLP*T(HDVR3*2W0qYx??jMLTX_qtF;XqdqMu$i)>=kGuj9MyE5V9MS zmF)CTi$&)a&_v3=8WWTMG7;jH8dHf?0naf1M|SIhEeDtnf#HW70OY3#_tlp04L{xN z2G;C`ux0``qp0UnF^-Fism3vl|4K*VT|R}AO+FKZDbkiD?tzO~D;EICZyKzUM*xC1 zN~K*?*PRl8PhIckm=Xc449#C2xZ7719NoX2v8P3`$9Bm`9!&d?vi!NQ|MNol*kN8L ze?5v=`0fw6{4jONj6GC6FnhMh-X^m-rT}M^{C?kxJuQ*lcmM0qB>4fVx^8UtP)(Ky zF11umCIid7xzyNfEG*F{uE_LarrS&pR(z{lckA!?IAOzNyAI5U;ii>nv~>6~Sbu#0 zPL6J+0|5o-rWqKu<)tSqi`il*?@`HoQO+-6<^gIA#3WqWVUXOxV0vJ9P7t`w0S{nN zJd#J`Q4a-Pp}IMC1u!ro>|kxf2igpK+K9>4*!W#^+{5>bC1j1QAQ?k4?KqQ3BJA|u zh%#_e8R3X&b2al$zHd5epCoLF+v+D{#J{vhxS4is9bdnB2@YC2#2$;(=nB^+ZMuf5 z7f+7&bKyFlN^1q%XE?c;8liwQ?w2$7f4V}jp*wBkJNA%3#P9oxz!(1ZEBNad_B{sv z`8maR??;Ie1&A`-fcY?oq(yr7qIRWBu|kULw%_Dn8vyzIE>s#XZnQ)t-8Qc z3UY_k(7BJ7uutBW^(_9!-+KJw4t*ZnU)+YEuhiw=QXl`(QZR8bu?5ioSJEP2Y+w)g zXJax-K}M?oOT~HZmwDCWoQDdiMFl2(HkE(qE@7#B*^v!XD(#6V+uEb6J2KBR$eY40 z$%Vkpw65vl#CQgK{p-W~4b(QQr^)^dVA`?fESFZkO?x!TMT=x~bK=~W2mdBtoT2|E7Bq5Zq;&IN!RX);S%ACTjl$XnB!UYVJ96FhNB zr@r2Kr%;DOY(My#V)FVh+1hA6kco9IMr3o!{#_-(XIKbUZ6^g?m_e^ zsK?^g^WS(TcHk*sM_x(Yyzvs9#oDlj&Yj4ci17x5-3=eE7iLei08zesNV!~BGiXD|r7X8DaXJC}(h z`^Gq#olLvZUM9z%^m6z>FozR;Wg}l4Bz$2;Tmat>hFg9-nE>f(Gt#Q9*;m0Wy|)m4 z_x&ok`K%isFSe3}Ifhxa6;egC!h&QN9j7XwZ6Kl*kc`4zdUtZ%d}N*7Xa#Qqe8{x4 zDR?xfj&9Qg-OD(%D2^y8j=y*oI zoU2C)ZNw#MlT=Rg6?YcI^7{@(*3H9unF~}og_b%Buf2?%)2v{2>!g#XJ2dllMJ)XQ z!^e!L@skW5%D`QdXv8MHW-<=(qq7Uas(H&hdn$w5@#U~tthT6CU+O`K5qN123_Vcc zG6@3g%2hO!D$W5rBtgGI&kQBk85Eo1csi}v-1KGU2Nv@4kZ^^j2=p{a0Be$y{yI}2 zBgXj^3&ykea76xEumM#qnKXCl6eW$CUwfzO=&8LXas?Q8?I0Mx`QviQiV0}<$RlDf z;tqWG!1_~odXH3({4$lmONzQ!PFpo+ojz#HDzkto8vT+pV3RNaaPO@RGJ-g!qWN_l zZh(-&ZJM3;Q_mrLu{Z&JJZkP(kR39W1w&9+7QrLKBlTVh;-1ez|#(6ItxyhPfD8oZrc_pmLb3f)!QNUj!@3d`>j zjg2-MHVX8#P5JOz?|F|Gu{E6`-;mJP?G9m)UVE4gcR3$E{7<|Ro1p`fC0SW#46CG(!riTwcJU}$la5L~oLC1*Tvs9Bh=~)d?bGxyHL8RkDYpEjD z$OS69$di%3pl#^=udK6{rN&HEipNIc7~WV{jyX)Pknv`A-2J<4Fd^;?K^B5mW?2VU-d7V zTz_?iIY`vRX}*{y*I$((Vs&mH9H{A_V7n90o`0(`6LzUylu+xd`HTG3N&9pq6oh1XMDs z4b8mgHmiGu??7|PQQ2pxrN_!+Tu<#=@Bh{Ny~z3W+yrHaG{gm=@?d31rHbSL-@}~E z{a#|I9!cD{uM%0_Lbc5bR~L)Ei>bs|Z73*&Aq~g-dyo-p7&V}eAUJtWf0}7*5V^DH z!xMHkQ|$n@1j9OI3;xXH@~24>o?$$U?x5qPW*6wdW4nc-MyGJk~R-2(Q6dCmL5$S8hNiJaTw%Ge_<$KVJ%6Ia|WL(cjSN%bS!YgNa=9oxdoR2JYVW^Cs%2TYHx zCG6npz3GSpR$VB}`|-XJu43VOG%N3{c9k}%Pja^q%LUm9ITOh%4Hb}IgA4$(%>|h} z1TG!^n}$3*vm3&VL#J<6f`XaLYAZR@tq@I#)@vfxTRfQ(hUik>A&<&UtwFuKzok6o zlUM{L|hd(qLaNCp50GmljF)F6Ztbe!gEq6HLIk(DYO*#0iroi zN+^XtI(crEQD!N?mT_V!Fhi=dDVRcsLE=A3HaXY?hM0-$a7(to{AhIYBPBbRJ7cy8 zqQF#hc_N_OXl>SIKIzVQY#u}3*TZlZ6+CVL(Ic*({2u2SnYbl}r>mEuYf!~22H0l+ zGur@{p206Ab$~v#?^o)O9f0=dFziPU+*=sYM<4D-Z^<*pow!1AjB#zK!KoY2g5=DlA*K@+uFcy_8_ zKP)*ke02KvGy!G(ufMrzjvuExg9{^fwb~pkPzhQU`l7)SY7MB34ypLj`ddJl8o8-apz zvdJ+{WHF0aeExRgvurJ=nJ<7)31DaQb@+dPPL`sK-Pckg?>+1z zkh$a^TDf47jDrr}AP|w|DFlMhZ2mf|mz{q?|*i$X#8eF=h6orUNo z2=zypx!YeiJJMG4x_`cbPK&hrVJ}v;t_tHVRkqqrw6U^VE|>0*<@rzma#a+NH9HY@ z3MloP2P|TCt z_SRquc#_6au|?4htnZhVvbaKCC&3Z#6O_Yx@c`72-!&V`Nm26}Jy-uuiW<(SP8vfa zDaap(PfgnHW)eLNLl+@@Ii4B!_kTq}ryG&`)RoWSm@(xLxoj{+KC*tSSI8d4Ga;?c zoCHkmdOdR-75Ej$d~5a^H<}x^3FK3?54*nR2cYz6C{!vImeGW73#1HtKM{a0$+p}W z7?vD_^==m}1{PVoyT>^DWH|d&z-u-sB2M=C&}zMrI6mhL0}n@Zc>EvA-YLHFcFPt{ zr7AX7SgF{yZQH1<*fuM+ZQEwWww;P?J2`oG?{m8Q-Mzo>oQrjp-28vfmVTj=@s?huX*dS_VH(2gGVffVPT6mw6Z!(fN>skh&#-9nXDwz=te)#0_e7~B`{ z9mYP=V_5Y4hKq0D{v1H181vU_BT;2(VWBL|@0Ef;sFuEzsp(leo1M~v{?|k0zp@Zv zk-UoCr;X@*E(`yU6pR1PPX6XB;-9?*@N-}IKa8e8S<)I?8TCDq`z|8GbhePhbQYul zu7VMsjXbLUR$LI8oJ1Xi0)U@Cyjz;dkP;2*Bb~HBbJ98QVSa5 z-IevFgVQNv?#pno&Kl>z82iT4g!${>Pu>quUF0f&4anqys}wq2@GLYfs_s_$bUNz= zO>$8fbQ1K?jsq|Jwy?dHN;3H-td2r5wQd)ij=YQd7QpAxSMRQ{?N}u>1XpPv8K+Gg zH4CuI%^EJSVgI#Tca+Gc7dt@%`DF_ZYd5xa10xNUZJt=$)a9=0;aFUI(8tPWd=0{+ zWzIoQ*Zd-oNx~xv^5At!mIjh0(Jg36+VC~CD>WpsUN`$V$gQKLy?AGFy`K;J7-_w# zrN(-h?9$37S(q+lS1V{TIWqrzvm(l`wj1bB`w$j(Bx+2%a@{T*E z1B4b_;iOPg{h7-oPpXz0(bjMjlr8!(#*BWlXQE6w28HKxkQ2J-Zlq|M!)PA2pUf~w z-re_cg^p?_&v<_e*l@^cdu4K4xvaDOmdEl*f#ga-sRfXF_+HqS@bW_mV<FomPm)4!~P5-P>o;rF7 zY*@=JJXF{6I%M1L7kI?>EK~Qgq$eMl__a%$qnP#mdX0Ri-mS9EwV4c7?rnJ0hp>fo zKYS&R_Xzy*^j-J~G-!7e$6s^>DKwl%re}?tvF%I^2}a*V3W>`Z{moaCZC`Gv9<^~( z_4K!&C-$MF{qxJDqbQlhqPc%pv?kLV^x&R3n;o{{6L{S9S)@=AM~IArZpk=cxvYi2LfhJg?0QC`_@MUH#-$B(iI^E%MGQfL zG2{YPCTynkhw>q{vWrP|D9L= zN9OyxGn-q_ilK7HH9Hbfj~vCpvpsa+~grTlgMMuKo_*dFhp@4WWJZVN%bPvyZ{RXK2?MN1N8hZEvXe#G_r#WqO9$rq42J~= z?!`u_q8yD~eA5TOha(i~3L5>`N+nLFK3mpdre2xkurN6BNdj9h-yf$Z0Y}4-m!>h| zAfl^w(c`c}>o8BnV#r0zXY6k+(Jw}aPq1zijxAY^V|bemUajU;BprsiY=A*{0iahJ zY^fom+9oqcBuVT8)XB)W4Z(6C4Hfr(;*gsEB1U9m#_rl@_$mbgT_?&~3v@e-t|Uy{ zX?)y0JGQyEVqN9?nZfB^Z#rjIJ&|Qb6okw$>C;hrnFP&9pJ6qo%bw9XEy6g?)}cA@ zUuQp)v17PimRf=1Yj75Z2#0o784ayH1?7w8ASg7&r}%?Unx5jEEliU#)iFjl4*jVi z#s$G3tUfZazS?D|av9gfCEz^JGI}RXsA)Z0qr}B)NHQSw5FWH1U-oSfULWJs0$|oC zJ;`D#@^DmiPfrOrPb@YIu{>W!lPBy}Y7lA?DefvXyuwRPo{&qEI?HB^QxEhEIdyIi z4$u*taZS=-wXRkaX;`6|vHZakKHbYM)ntm08ypsxzEB02dmw!Z-Qb@pfRILoe=PS~W;z5W(@#eCbXmHcH$q;QUhZ zwg&ysxGGw&$~JkI&_O1j%{Oo65H)g(ZMYaij755KgxeOQ%)kcF#={d($`yp{xxRe? zfV>y6JBD+Ji*tjBlP-i{Ak$T<#&`%m@3@Z6P4-IL=mH6#e-uB4pDD`k9A2aCF)G8* zGY_tF8$Dsu6N~8t+^As2YF`Le@gY(k>i@weq+ zl)PH%IO9Qu|v7^kyGl6GLMVMLxnixL__4wH5b#Y|Z`r<8^W;)Ba)pqvH|zm&)sW(A{G*ZdMl|G7tHdqL+(J zXprnn&6gq~kAWzGbiEqUHztq7pvkLC*UT4Rf7)mH9!-i%HGG+y!JYQI5CX1{&;JZD z>>R`WN!~N-61dT!;a_#NI{V0hVEjoC{(3JBwQ-#XK8dzP)iK`dtoF{1#zwm3%6sf` zCZ2A51cR(|Nf>PVp1gS^$t6{L%ZRLV8|PExlDxgu#^q6kcsBM@AfRPbLuv6mirhiF z1%d2E2J*#Kl&TObrx-b^%+|;CcVSL{t5j}OeP@SrWt)p1YhOk%{ zcQGtfyfcn!U_zpQiLj=dW3Lk7`p6Wx4_HHaHytxK+QreUS}nBGD8VBGiQ`Y2UbfEn??4T;IdaYvVIw-v#G}}=V+ehX{e#9^4L)~o&S*fRC-Y32J-?E&dK7MBsR;%QKy z-`@lepQ7JKB_~UN)mLHqyo4`@v7ld=+i#-j+8U|tIXF+ZY)=;9>UqdRS@LGc54!&1zK2InY;OJW~Z z2zM47%bNzuia6`1-jQ<8I}RhQ3-mhqoxd?d8~|aGHvN%vVq;SsC~ubGx9x#I^^9eVHk=d%D3l2 zI#b*y%~-tp=;i=Ro4A_6Jx7$a=_o|a;KW1?XPZG+yiq}ba;sVbTBWJ+PxfrdA*vOu z=-KS~#XO3L+Iry?`2>w7(Z-m+frDWD@BD~~dNw~X>KfI!oi-C~((d1>Sf7a-spxOZKr6g2mY))<# zL@XvSg-i#1iA#0EcyaqE-AJV~@e&)evmc1r*^ABK6_v*jxl`O#VIMdt^7i$eOh1{t zGKF!VRF1&v*iR+xlKo=rQo8ZU5tH;XF!j_U)f!ui^)IjAzKE?r{5z)IAZTu;RS7=a!c9&Hd;mLOFbm=mRXihFyP-#M4zw zIQ(VdFh&wF7qt+QM+Jox{O>bI-~7*@Yw0%H`IPZKz$*tyt+M-e(c0NBDzpusa;Tav zqo@0|_UH5HR+SDuty6LRpG zMc&F&&vh9ek_Xt=)xTeb24gM4GH;`f=_t~p*p_FHo`JV+yUPvSW&9awzMQFx4Wrh! z-++4uTz_%uC_OrZKh3WR>p1ttrg2MzAjJbKl5^1o?FhSsD5DkNl7*ph(Cqqw)il-Y zL-T=8Ma0a_q!_anuDxXGlcXu+U$8Bs*)OiJRd{giL4j4(gKqI%boxEMw*PWwNuP36 zc*H4A*jW$rUQNP0)+TahuTjBkRnVSB(vz0^pj>A{-n&o5o3?~k;uxT?!CLnGdshzq zUj63B>EJp`$la}htg9c~4jIqE;kCxg^Q^~_qs?zNK9e5)JQ6eaTYsGT#G7PiEMmAt zIi>*QTJv{9^TJyEN6_!ZYgs9w|sBqn)Uu@YYw$u|$gGbRiTzr$byZ1I2wn)D$Qq`d+1j zp7dcDLFbr{UL$duu{y@C?{z>9%a1W1g~*s1D$d~-h{tC^5?^| z^EgeEq0JnX7#(1d1jv6TS)w7tFfFc%IJ*mq=-e?aYoSp=v8YQ8*xr0SGp_vb6h}kg z2MD;xQ9zs2q4VRbbNPyE1&QXJeMPUpm}5v5W!~-^vZPPFA5HTopSF)`^MrO3pKKom z&Svfk0JSfmR9uUDDri41`$H2>Yf617CW%0;%$M8pN8I6J4`8{h_C1LsoTDeW`UJMM zBlYBcplcv0g@})Z0jd3Z7HIQ_Xp%LWRCN~1GT|(F7$mMUlH=7#P;NKbKN^%=FKTmZ z25TIm&TP>=NvWv|NlI1|;U}q^j_vIvzZnl#00)D#`^ZpSq519hzGcmD4dF22T{Mhd z53RAW?h`mq_PF+Ky+YdVhnwy+%Vt56o-<3T0pmQ0QnhX`7yv6xb_&;c0r!Xj_jCdG zKgy9rXB2A3bEfydnMI%!|3V>q-q2IjOj?#n1yi72n=B0Bc@$!^mdx>HW*MO*8V;#t zWQ$C!3_SAB6rgOFRbD@rhAWxVd5+fP0&AgP)>6H&-c|Zp$J=sr`^hZ!qvl>qU9)tB zW%emBIEU{rnN%ir8N9!bsOwwC5YVn0av@CKzYn7^?1j42JY+&zO=vydz6G@GN~b;Q zl43gaK{05Tqjr`h|JPb?B$7ja-iOw`cHZDbVC^Px^Ms>xw_qXa)bC#RWjnvYQrn}u zn(<)>+LmKKC2yBTSOgRZwxl71t=`7KIp$wnG1?ZZ43%FHG=+-rdA5bD^MsL#xuY~I zbMj9YB-NZZL9N)o(vFAkG|oCvXm@c%mJLm9_J~qf;P#TZRT9Oq%mBie=caF*G)i&~ zjLOQtp!Ds^kgz$nt8@c~+HT54&oP@Qhm4mRAqvc=t%m1PGk5K#%)XtpK zHm*6J`VACXT2Tz8sn4G>7zP@`U?hjk_s@6dfF?VO-E#SN=rtc0i0EL%@0$}*0%KNE z$`lmQdrvMqpTiT&kH@Dw>|dHD%Je}I&=y+C`xQRU&~u`iBjZu9x4N8Fj1Ai$v3N&cpmK4)X9PGr#pF zM-%hH`MDq(2<(BG42y+huDl~X3;Q?Gia>7YfvB1A2YsIHkbI-M zb#{YdVh;kCXkg2FifOptZp(v<%a~xvVj3NjY{`Z!!ZjVm%5z+FCz(kpglT5LtB)Lo z>csJ3DHQy^Z7)B786uKlRL!Nv;+he#^ zF&s}^NeMjHxJy?pJk6q0%z5c+#|OsbHqL;pb7`O#(NLGKRoxKFkkxcE3A2^HJYj3Z zG5QxAa;!o^VFNj-Ao(e-`Fg&^w{JTzRDp|2O7!dd*yU{_xH4fYluHYoYWpuJ0K@h5 znXw5Ah3>IAQ*|e+K|Y{i%fu|9=5*B@;VCpn;V2C*&(~A5rTNOphZuK3X6Z`k#^*a|PHNmz%#a_uaXyok1vf zp<=&b;&aYbsJ7E5LdE6XQ;lj@EutpEo2+bJoeL?f z9#+TSPPc(ecuFdt{?ht6kN+Pz7ysce|HC(nSzG)kO`E*5Y!4r5x}}dmg}~+4zNk0| zqJf_NKHc_c4DsL}cxy?uHRcN}%Z(!5iKHk9?;zgsSC;rXw;-0+I)BE}hELBI9|lQ( z(L`!5nY5B+A7$@t{>s7VQ;%n;#uq%25MlUjRJ~fH7}$fC2@`lMCbCWAo(jdi#V9Q1 zi3*`5-I8de;~T&f59PWxU`E5_#~MzM0})CZg4fQP3d0K}KW?8PPW`%=9%F+Mz9|Jc@Q67_hg{09}~x>m@8#8vuUfhEBjbJ1QJTr&*bd*fK-oT z_C?pAyTnEV{p>+6I6b#50t{kpY0Qgs+$;5BNn&QWMI516}_L$siSZ%%sx z61~zPxMJBh4GHgN`jbES+U?MhZ>JZD!tRq#&X-eh!>B0xf$d|NapLPfi#wnrHPBL`L22$(UMxu^njxSV6z6)0sQCmW5~X- z2`+_Ho7PGNJ_kS#U=DrdTWiQJiO*G6R+<-|d3Y?)ZbHj_7s7aNf_Uy?a{fmgO1 z`k1I>da2rufYxdGq`Pi(IPt! z&*Vq+_YHINNrr#J&!5WoRkh#x!WECi#7Naw$(N3FW2(`~?UN2t#=QQsJ*x;57M!>&J^E7c~L=`_hrrFEA-htS)X?~xYjzdxnCL5c5e7~m-I`NSH&=waFK{9$=8>cMICR(786b@I z%C=eBi&FANU}BU*RGqkiqJ!lx0S-h96@s#k7T?qM583?PJ{^_!PTwo_(*UOuoFL0t z#>WAbZry%7+k@Ky(-3D|`nblm_`LB=(rcW%Kd?US7U z+?wCJu!F@&yaVqdnu!}E-ub-SD^9-WyLcK?wM_qui+Cad%>~@MeRj z(x;~;edaf&e`^YMhQ@|2wEx9trGXCmCjWawGeOb(uiLUueJ&cRFlB!*)GHr7+?fhr z5o&pq+<|-oai|clRhl@bA*UuQW9c{5R5A?dIct)4vYm`G1rleId7&kKba<^k;_ z2JZLXd~g|w+OasVOHZ{gnwZaoT}qPE*Mc9CI*g8-O^fxi7UMZUlLTu%Ji@B!BzI6H zc+TFgfuSdU2+$$TKYfxP&Tl;r^6AZjoKI=lDjlVm<%0*nvBItOr23Gj>#1=Bu0d-% zucH5$XF2@xHKLaz5q52W06z-RbQ3fYW8~ujl?iI_6pFQXBsg(#!)@lAc&^~)7%9-e z5_ddr|M5&_E`B~P@Emuxv>{5UFimTlVf;5guYaKkbEFI=$AJwNd3w$&+ci=j<(>^Oy40^Cj1&PK$P@bX`|3p)ZjOij2x79v z2-&}}b&Uxpdm%>;Mf=sH;P}EX$yCfx5$N7=Pzt^tdh2sZAJT)n!D{spUo)CDg?3*5 zEnuB|Aa&+_TIb&9@84HpZl*T00zi9HeGO9^5mO7p|IDHPn;H#WgQE)$15uB_1}r){ z8Kbo(KzCY6z9bbDDsrIf3mYmyKmd|vVu$hQ#ZxOU2vsyBq)#$p(Lw9XU;RN|f}O~P z^ztT`D!Op+jQJMhy$B2}WF4Vo5u>>ST4REty1V|~c>MK)Yc0{QXp1o4vIgae8bVm? zg8EXn;dOlDGpN}Q4-5!Rm<_Wak!<)@+{m83Et$iBIq$#i9nN&GC<%W$CD*4@^8Z_> z{Fl$=*Vq3?XJjC5W#j1ZIUY3xTK;p#K}pm6uj@~e7KX1ndg&`{+- zg$nWvv3f3I4O_{;Ob3pd>vZXPC#%*NWb;x_O;@`}d~NU3*+ey{(9S{+z=m$|tu)>5 z9$l($(!+F0iXH8<%O*oM%a$(w2If9CzX7aDD;r>N+C+k0I>FgHgS9P(O`Nve@C9w% zy0p(7u;^T@p+sk`e~fYZd28gI+c|#(8i=Ett-BE!aH{y=rZjg&w-$LUDyGf!32Rh9 zWXOq057Nzy^3dDfFXq*`y<@?%KEI#K8wAX--n zt90<%*0AsWWJpw`(6a z<{*o1p!1f9?39E}CX0UvDi-CXS2D~Ba9Fid@)+?a9 z6TiQcP>^HP`<7@NN5U?pzMl&HW^nOcfj0hZ=Z@kE43WLRv!$$)YjH$2`T2H+K(}Nt$FJQ?Wk7vi<$(`Ge=dY07w*s_X|u zbieY~A}KmHl9gyn5#){Ht@;rBbn(|)w-I4A-3S;gbh!k1B=`Db zT~Xizn8*adr4Ja-VK+Tczhh~CD<~l=|72?rd!7g_XJa)qRQS|h+|1EJf~A_AVj}p8 z89^Uj80NgzR!KN2!&5w$yIf4MR!H#%~I`m0999D$~Qi%DW4M=7(8AK%2oO3HS82>48^`aJUCIt=) zfn8X5Tunx4FcTo#+^$7GX9ar(3u?LRn6v5Z!ug``8YZ?7Dc zvwWAEdSbqjPQ6%~Dd&q3+jf_sfQ7Nr5bp-wV&0N7i^dTn-|HXX>=Gc16FjydC=BeIYSWIVZ|9Ri?D<#FYT{C8$E;TBH{jC?# zkvxbVlR{baVqt55Mf#t384vLt{8Vb+S@gqth%BG=B>@W<+m}A@=Jnq`eXW6qGlQns zA7E%70P%Nhh1W0eifey(BCDppnpB~CeyijX{yv+TtI{`@hbrH<<3J;`Q0smwD)!oR zL7%#CY#|Np^HGVZfYn>dsCGCAQh`gD6~`^ZYxeSa8A%t7$7$)@wIpPJ^9Es};rTZ6 z$F~K#uK0A*K6f|G1ha`1$lZ+&i^A>s;4L!9c-mR>dtqg^Dd6kmBC~5*rB*1i_&o6n zUC0Ll#Sn$YlVJS~ZwVQ~^!P^)$Okt3&tCO+gu=&8jtHHM^II9LuS(FGMO#zau(9YH z339NcOq1ds(kgE-L`U-%B8z`ZoN;?Tm&l*@9&VpgdA|R9FBSg_UvmOl{7WLqP+tFw zhx}vRz?wyUk$|5E6>+W@ktrv50YQkb9!{YqSFO5&CJm;X2HVJ4zaM>72FH?f7L)T< zvW)gDoVNYZ$AnW6mvff4^nOhmmj6tu5TWH^t?pp$<>l?1oz?r}<|PY+17ELr5FZZi zFkt}*@WevB9qs@1J<(KZlTTm@&|(*hJvkDug2$J=!({D&icd9f$V)`*KcGp zL*YoDjPgFAiWDN4dX>q{RD*Vfm`jL)CT5ZRthLMCucxQ4UG20(yxnqfbX>B{9SQdB z{G*H{mN5mV)2@SANF9a@La&&kk`4^@aK^$bjK&tD={ZrA)HALdwX>=fEw{h6)c5_F zoyThX`A3d&^4@d;wE?7Xa1BxPWTJNJ0xHZF?AtZF`&yXwvV-6j zbJM{Q6cfjfa)rz}>Vuzx9_h1JNIVNQC~X*xl@{@~wc8_Ne{fTrF+i8PD@YkteqCWwO43y zFe+>hPs!T?M%&hO)T!1hfvG(=$m+hFK0%Y!mT9o9AdiGAb^Iu5G!OYE;LEHEnc*X%@iGPeKtuwI>?Slx0d2k{nNh@jy zA2xw$nr7ggpm7h+*t0Fyd`mo46FJ21X_8;Z(tHFnfB(hM0sGE%*?$tRJYkSg>n~R8 z2zBhYd1=XH6~B6QGxZ2&u?_BYBYt{7;^vCBdgM;obIo?j$MDM@11BB@no3**Uw1Bg zH|8?&Yi!r@u6}h<@C<4Q^_nmoW=&QOaj#@>0J>mUzy+4{F=IJYUb7c?#*dx>&SKff zS<-R5@|jQ*-)vTzL|tco(j`W@C*ks)B)LgTrYrSax*(PFoVXXZzMI2?B-?cFP{vm? zzM@KyDzO7ZBr$wxR1Q<(l6IV_BZ?_tT1ez8Z`-s7`uw<0yt(*DQ)UqQPkgnXc#kT4 z)p_I|8u+o}i+cwF?!m)PMi<`E=O$)effQiw2^xDpu)gj$jNBnR*Al;I7zVsU%^|*- z%RL$gUr&nr(jp!#*7$66p?RU4y;9~sE*@@gWT$zD{eDGzespFVK>w^s2AMv-uzVn? zKFU7EZb0Q9(a2G+-@=`e;KG!16Dg2Y-^T(5nC1geWyn$BT_9dU4OgV685m>pW5X(x z(ny@QK4IYvU&cEDr7Nkxw*rY)p|+8cRe2JJpZo?5!i>)v3;Htp}E_1tEL+U;2T(H~xZ^-!>+D(EU{camFtjbO^u@!XAfX%2E;dJAI-I{$hjQ zC$a+mSs4lZKg3(R&kozs0%#{|Wb~HaBQBly`|H$6-JUU*>5K_i&= zM;;9YgTn9kRa=TMJ{)qXN_jBb;#C(5?(0FgB#nN=*`6Sr2^K~POL=kJUt@IMf7-c% z>Owa1FrZ%xfDeZZhYCk&XNzIMpMuY^R}SJ(Cp3`cyb-lv$yF3StT>W8W2Tjj=Z+^0 zWc=Dd7QHW~akhP7z*2IOOxJE%!C{SM`Y<`6mvA~FBB(9^#!6w99xU6GnXXD>nVQ7m4z$ zxr|1;n?S{mhq9BI2REUpjbq z->H8lVc&Yksk9Uj0`@o!La+CO=)l}AsD-wJ#B}j0jOmiMgPOVNVvezeS=Ur?_m&2U zH1Qsw{u43zYYRQQ%%VQ%^NFE8pZMQjEBs4y_OCCSp)e}Z%ZJL%YALN*wy^!O93Tc@ z0>~rw2l(oiw908Urwx?gV8+Gf=f20msQSY2b|D~kinOB;hBlKK(K9}**-xZ%?(V%E zVe$d?xD=9y2qU1d6hcQF|Z-Qjf<6>w+Up0 z@}+QmnU$9e@b8hY!yGx}t6yc&Vh=m;3 z!AUXlijWWNK&6UH&YIpI*~-{JP3ad^L-44M-kYzFaTSi743GuAJ`96>*Qyk=(v#V&_`4?;;CSf>9q5c)e1iz2McT?ow zV>DOr2E2b8%;Dty*~0j2z5n7>{`WTq|MI$W*47q(bu~s7z|YF*U&^Ke1?|83Z|*p$ zHtE)y!iH3mnnvb`rzxvrbK!hp{A!b&*dX5?14ews#x|fcp~5TSJ80Hdi7rG1QXjp?? zN#l63jTSk<1G&BtPUT+Jk)(u{Xb4zx0A2YcDu243BmbOQ8nAoFSZuMr{&X}d^E(Lz ztR74h84r|b4Cx(H;OqF7JJzzmxCjm$_Nd9q5T1G7FF5R|tG)jk%CKoj4mc^rDSAe6*%^mQMK!+XVbYvJ+wO8MCPTMrz!9vO? zWXE_pmiyHH$o)w$sz3e67x;rOLpNWbwQ_`!29dc&)K+lxhnoQ`>==-_O1EYmHCkSoXl8tHPrpdN;oNXtZ=>zJ+I9rNc`S&8!&r=- z+Ym?%FJ|hZCF-a$iNYas zeKmM#`-4Y5Qg&MrD|1dhs7UR7cFZw!k|%G=6emLLYM%)q%kb5Bj?~K78}^!=#4~gJ z%{P*ETeAEjJdpNgpOS;%(G2k?C1GYAzZBgCJI=wCBOE%DhoBGdejh3ow#yioUZXJ= z=d@RkOw&WSdQGpDkw=&>^rB28N%{Fs=6nXG{3hp;w1Sh}u2o6Lu2|14RZu=?AKtPu zSE1@y!-03-nMq{JNP%UUX zh4#q-hKD1MDp2lg_hJh*T4DRp`xqnnv*e`iRW>ktiZg3%0SeW zMErQH!kmWULqS^QB67DL6XJ6>~Lgh1HSo@`%{5<(z}=&G|Ja>zP4r#Q1pw$(UJ zV28mP2TSr5xM-_liox2rJ?7z{JF|ys?*pvVHv89&!RSC-j7R)T#p+{fK{H+GN$f`? zFN;m>LxxL~rMWNXeAZdC^E!j#?BIn!?B=0f;&$E5uaDV2m}6LU^u@r5E<-K)OM*%= z$WB*Ju_Sa1+k}XvNb_AGc-!UzZ4s`unRuxf(E~!O&7$T?UF|h9&Ftm~KvT?iV^1`8 zvrm@kV~fwv%Yw#t-o4UnE1vy6As-E!#&UP4pW*feiPIc4J++hL^q>%>Fo#EDf+ z6O?(nB*UnbPiYG3dbf?_IF1o%XGuwM3UXY0b?5LhEm;kfweb`Ua#qe$4ARKqs%+Om zOWnZ=GMtcizxB1~eRWP4^$RC@PQ5$LPQ4*OULvU`Ix~R+ZvL4UV@%GfS^b(}Siccz3u`AG532+!gn{(=(piHKwNkJ+Bse~3oHeoy3fJ2!{ zdy7AL%Ru8vn!$#@T9m znzKH8DLC~#Lg*k{sIrHZ3*rM-NJtB2f-gc#L>F8m-^aOI>;!hCu;3Vni6xdEu`__e zE24j!wHVMTnCAj!-d`3RypfmWLZE)P6v6|Ay9Y16*{;Xv`AL!jF^q`otcSH+jZ<%2 zc{~I&HJQ6jF%nc3!LGE{?AICWg7*$0{feZ#UD(H1tH9pAehZl!KU)XkZr>`MOMkus zNv`^)hZYvtB!fri`mzuTqec~iU25}kB@VfvgtV3=NB$mec7+b58mAoZ$9TA7hoCJ? z4*FvRl(Gt$T8y-cRSL0B$pAiKI!Vq85H@_G%zBLdW1Z|6TPCn?`0y?|IE!o2c;2CL z7aX&JNn?X9Y)XVVKT{BZRBz%bmLWV&RGNGD?x_yFUKpr)`|XWOD@*w7a-a)L94+=c zv{pBR&+uxMRIaW4FHcSMDzmfS#BCU!dK~D|3vj6DulGrjHiVeEr$(1*_4teGX{G8*oaPT4Xv~ZB2ID%Ql zHbRi6YB$pmR?-Bs{SL4%Y0NN*XD$vdkFRM)YY(5FJW!L7E5>8x)`*ud z>fo`8*`gTFTYg5IjVVxL3~Mknrm-RDL_=bnTK-6?iM+OWBQgUIHI<(ztyTBO-5hK7 zMFU%>RLx)yD^NwkoX8YbtxOf91Y|@pG$oFtNODjdoB~>pve4(iP0R>=kIkr*7qeBg z!`vKk7K%@5bl?aDUf@@(bKh8)eRY^a`5O{)T@Xa(oLt{Xj*6z&?%ZoquYId{#g>us z61;r~x2x@NPQ6T_0E-SWs+=(GrMtgNb%oH11>|lz+G!Wf9hMEww@4K8&Gq@MrzLL_ z>6h5;H43a^?_~i;OIq2zNwY|O`Ub)(4686c`(Y;TPzm#ANz?QmP?m9!h=ynnGIDu& zk-MG#&!(<%?N(O|!#@(;K4rivhn;7#rkwTvMZ8EXC6I352M7qV;Q!a+=ilq)f3~)o zFuIC+cf1Fq(pIs5I%Y_irV{bMBoxUe(O}5r$WTWFq4lOia#{*vn2usmzhp#xxjA!S z064HEs28!xi@>OK52E6x+1p#qay!^_ILaKXeV>5%us{FZB0Y=FmoXXqfr)T6cBbxvf!hcIx>U0m61AD<#HBZw=j0J? z%Tvi8PbH~h0+&X;Tur0iy^%HLb~~xhB$Hmf6W1Q=_xeQIzF8E@6rdqU^25nv1P29;tW#9l~>xSWd4odzt1?Ok<)j{|x#r{13;|EypdjZPNo}acShF-54 z0~>5W%J)Plof<4G(#WdowGC5(Q--5dx6Y(11ev8sZ-bRZmtDuqXHv|MQ-8`UILwc2 z|FSD-%niGqhQ~sjj}am36H0tTOv&q*g+D;03!|-#%imP5oE?)<2nMe~C{8;;4DWF- zxa?ajujnZ6oG`otA2tuo;aO~3GVPH???FKyCw;P4jD^o@kw59`QFbRl4SZypquQk* zN!KQ=!>EYV)naPM;9`QY%3vV2ZJ8rCt%CdK;4-%OEL_dawWO)w92|=22_(-(dIIIx znhJd z-z$(~4&0VX|64o4 zCM>fiI+Y~DVf@xdO;Xb&E|jj3zF4JSbEPLIu~8@u3#Lpt$3&TGMWaCh?pu;*kLIx; zFrm;um~$?;l1|U`Vsqe`&eq03NL<}*b-_x_>6x!F^|2x+veebbrP$E2*bg(Qzzsy4 zoJ>C{gjm49=PAeKS2MVHi@CVeY$BwsguezNh2~P-h_9JCFOnfuZn#i^4Ko%3JtLYj zwF?;)5Wz?SVy2+8c!|ZEFEUgRni?_q&ek(JUXP9g%$k`Z8q8KEjy}ME4p^2(YWf}V z580j^V)xf=y^8+*d7m~R-SIGIJMjW$XnrHc6?ApJ-&1F!m}YAjF+!z~ z+_UAu)6N#+x#_-^5B<_T)0Ntd&P>7|!$MBx$9!TG$BEbYHVjkVo!#hn+Wyh&NFS=Z zfc8lhsh75+3I)w#AyJLsUR=q>Tpj0iQCsou1SDaKpB7weUaP+-b=ch(KdqWG}H#~jC&(V9Wu~H+b4Roh182GPt+cYK_enZhQ(!_zr*Z#^&E>TAD$3OhEz~5 z`AMbZiFRq5h)F1$f5gKbP;p1UCno&pGC_vs5sFa}%-|KiHK_KfzAf4^q-X=WtQJ0q zC9DMLjjTKHT^X&<);C#Ml9j% zt6wUrJ`<_Avrs(nvs4`6+jW{tV}>C_vZ&1wX_Tgv9JrO^j^AF6{by#>?pSnr&iN~5 zbV8kycXu?qL>tw{2_-02xg)l|T%B5Pdj%J&D>B)JT)fa3g?p0LibL8}szW^5(F|r` zV?Q!e;}(}A58)$bh7V(~htO-_KyB+8onK(Kz7;qnd23WAx*A3uIpwcArgP2P39ZvL=;%3l6eKPf;3_NaOjuuwekBQMkD@o{VN) zc)7QL)34a3vP+Waad!@aNW~$=n6=sn6R6MMISIp#qE!fH6o#akrXqehGV?1UP`kwk zFdA``YLExFTJE3**7DhFa)HPidm>02j4FXpEeBwtS>YPGLpq^n+50a{pk)#cVbC27UxoYfM)gbN%IVI(dnW za}!J6PAXb7oczL{P;-V?JRU9}YFlg>n|+*ZO4wGGkt0(I6TpoWDK!MKBsy_O#rI^iR>l3n zS!UH+qOJ&YqKcgwi&waawgNF7Kv8?<%|GJ%*(&r41EWNL7*>etxjfl<7{0tufYaMLriWZe6X~5&Q+cT7&v+xyM3T{IZdj} zu%jk#q<2FUZ>%0XX3t(7-@luNmpc^N7yIXDg(y+Gt@bGHiioY!JJQ)rMZBJRqnVp6 zBg?PmWj0FYualLuHMxOlfO@RPF_z6+wItf5RpJc(4JG_b$g{Ve$5}&GK6IV}n`Ww@ z6x5K$5$gx3!~f-Iz`+9?3k>`{{O3>Mk{?bE!-t$=E}ZxmWIVjSr`JBF`^skyI33+v z)APf|=I~SAN-404mr`>@cX`kJPA|)jGWC3C*ahRk3-(p3GcT&)Fr4|V=p)qi4;7FtKjp3?k$Vjb6;H{JQ6;8 zQa^_$)GNpxM=%LckU+q2QQ(6GkMwS#$UNLJg8%p&kl&JTQ;YmAP;LJOOCsVw$S-Ss zFX6>Oy|OD3KG9n;Wn_4<&lG=?=V`d#e^{4cN@Si{3!Y8KURTmnGA362#al>5n9IKRE&dm z7pB7=JAw8k2HSH2c_vNN&igAKQNBUJu9 z=$)$g#z|25m$qJ!ilt6ROtVV@YJ)vgAwi=zT@g_G;OxC7hQd~`rgdjD#t*jMEx&Ym z|J-+5*v(L|ejk=S>Xqjn{f&X5f)_|bcIKZ@h?=}Dzp(~-9jbq1J67$T!S8XFcw-*? zO#qQWju)!XX{_3+Voi`$&vk2=h9~@smz^AahT-3p8cVR^8uA zpLPeX+8uo8PPPr=#$U>wUOR;U53W1AcC?N??hdruzE4JpT0&+^9NIT5e&Wf&QJCii z(^$xNpTjhqmkjqM>s6iFrkRix=~bPZJU76*(BgI6y5QI&Mi*mLu*QT&V=v;K4hEL$g3rJK6AC3z1piKt|MkaFeYVj zs>J=KH=ZVccu$3=#y;hCdgV{#hId{)cSF0hT;UGgY2eT82Os5l`tn^+UNtAL!K)RI z-c*N;w%o>Jy*!cK>R&i;NMz+IXko)fucO6WUC%a}c{qI?GHlhwDIU(I_OYh|H;4pX zwN96P_D-})+m6NUD(Dh1p)IAMvOuUVw&5t{H5NA6+4ono-;yT~F9b}3>ur8!Tff#m z&U>fE>yG#n1It;iWUwM9XEqST532YT`05Fr^57e|WM7H_+7A@=m5JrRP9OCPZKhvM zU|7w7_$#L665jy32aNsTV(4ym?nfa1@0ARvuXPWi2R8Pw^A_d{HfQu@PsSU6XB2)< z_!Hba2LFIUNIvF!#Nw54WzV5%P_7P-e>nLSvu1>z;SV_j1p+$+v?~PU;XnvFBqlu~ z+-HfredyRQbr7^2La=+}?cU1}LzfiFzRy4;e7NByBI#=x#c=5mz*{4#pM6OEvlAl} zKV0%tJ?YSaQFl!wcnr}up1veZ={B`MJByAioU=f5DKbo*;=nMzrE?eTKqh?n^cEEK zOPo@fXO>pejyNlihbL22N4$Rzax9-!6R|uw61NCju$rd}f=&Rs`JNJ|Mm(I!CACfv zO<{uoJT?&BqzO6I>DIy-AzK>D7bSbCAu-2`;^`xRXo9T^w~@k_Q(|{_1ulhV;eEJF zpAD2Df^_^$n3nifA#yN#PV>gxf0mHV5Y8bbPl#qj`@lNb!VvC6VbXMj`ikRcO!??; z;uBIf5kBbvC#ra7n|5BR->?AeTU%rY6mFyty=+7qL>3`#Yg<(kG7!yr|`M4z?zM^n=JI1P!LlbLsT73ZAOHLgqaxy(HN7JYb zKl|WLN-Gj`>m`0B@-tzwsJ$s0-{I3v%ida&^|dVh!)J|$&PUQ9{V`tk+{b_^MRtnqKn&T7-8=l$oSSMynb zZs;QO#=0M-2Q%Odqt`5n&_0UNK8nwY1{$YQOCcBiz+)&gX-Ja!tU;q;euj0^rb^wb zLB_M$FI|@x6t2aOFiTF)mboX0H5yxcixMaFjdzgcsA%Kabb};5kf8!4-5_!iLe#>cgBMWEKc_6E9DKh;c0w+q}+c&%VO2f8=WFQ;HAXc1}}RBZib^T05O zepLrPZzb!XN)ZfOw5vKT?O(gdTKQ7i5b$AkeFhGUJVbQCrNbt-Rcm1M;a9g-ceL(0 z+HiJZ)ceQ|sG38~WnmW#YTB`)2VgjawnIz~$T8^bM#*iURzq~!B(|hQyQ7W6xG2Im zLuG4`j1KI&6dkvQ4)D5kzJPis{%bUN#Y>()Zjtzh@S^O)GlQ>b?ijhq;D1Ov< zgR8@bDEzrU#5}oMkUNy&nbKecdWg!`;JQe?aGE&ybkijx~AaswHreMXK>p@q5ei}o#bXnM$j1S6a zSVzAf5v4eC7=$4hit~WzI{&dbC}G;LL4`DBL7h#*iX^5;m2Q19n9uS!akz>jLK74v zU$0-O?0AIe6Emh{g@I;pw3)eIYDKRon`m$xTy~I2hymE}fCxv}S>uS?ZBJbn+hdLn zN1QhO^GuPZG$oL@0rM#~Q{lVq=Z3AYOU1Wf*u6wQAoa=2F%6J%Hp)61Swzx_bcz#E z>rEASG%D_|i1>JHQEZbcYILx$M#=8eCw>jJHM+MDnI^K|^J}Rv>bq-l3kS!S}vT+iq@?lyaa+q$J?B>_r>BxPZ-Er zVlP=>NS|UJ6ycfW&stI*WKl8kvG^-Hd0x5Huo}o5&W7ge#89BSuDN}n-`aC;;Gad_ z!0!s);7n?evUE&A&;>!8aR|#4NXv2{%Oc1LWz7sV1y^rhj>znObMKA zP0)z%cEirF8lnj0W{;_oc(-#s^OLdaElF#gqh{Xz=_>9IU{#*f2WyLa2PRG^=RT>o zzn|!k^Qh87PEi*}rP6Z-sjXCkXi#fj;&tjaC6y?z`qmWCpH~*}u5>BZW{qNgc|6jc zyu=7ZH@l+`bthC~m)r!r^YoZ2ILAlbF8s+UXaEeiQO${%dNn}rGX+$+qo#wE*}fRB za&(r_pB^&=C!X3p*e~eLL2qXM6YB+c#aRaSC-isqqn*bKuv0Pf$Zm#$*Y(XU(FK^h zE_`QKV&dhs8KaYa%-FUSpx0PGQ(af#wNZEos*8AMzi^SXOX=*lqiRnN+I9!ltTqBkibYJIwZ1ywn{49VU=Umrdr<0 zTA=OFPLBvLXnTt-#8zvKq2~V4tSU{C@Nex4gl=ZJVU`3(SD2JIeuwBT*2%)4lcO~< z+kaTgE7f1BSX8WwZK$vu^4%B591d`>`19x*N&*fFr&QZev4^2_%lN2CNK8=Id@btdt*q6TCXzEHrvXLB}4+5Eotf9IMC-u{SYX{tstHD1aA6R8XH%9~Ej9N_ z2tU@=He0*Vb>xkKa>8L<0K^vMC>c4$T}aoY>EEr9;jH(!rr>R&qU4a_oQHI}Ev@m0 z*kiAC5Nr~ASo>p@Uko+kmDAT!lEx750;7dj5S~LsrN$(z;02a1<>wV{4g9|8@HfCIiniI%XZY29jH{k)s=p>W&cfRVcb4 z$FbrWR}C##PZ!{A1p?DZ$9PpTC#DpQ4-)}KBJKKx%`AMvBwSK?fH3xf?bRnBJ7B!Qk9S0KAwP7v$bCG0tC+8f6;LV-ja{ zzq6#EAP&O`i{MLg9rpe<(bNYpeQ=F{(WKM#_(4o1&>W;Os4HWK*DB6SgC1y}cLo0W zkR6baI9%eSDBV*#Y6}0bU0o&2P>3OGih)Fy6L}Jv|uzPkgsM zKIcvkh`ks6mRvPH?w?FNmTu9=P7)WERck{|BN=` zuO9gTH@2QHbMaltJE0J>&5wN23MZDH{L(kn=iAVO-~Ypu!1)Gy()F`Hs`gX5`Tth9 zk#lkWf7+TPnilpVCjVI?{m+a%Tk${Mm6@DvT{S9E%lbXke3}hW1-b|lG41lbFW# z)X^-qQcCe7N$s2#*8nHAj5m^N^7_8K_5*=7m?=YfUITUt@BX;YOU@p8O_*@h(&N`k zm@b}130AAC5dE>`tQ7b4?M=iTEw9mH>7JFE&FhjY&U+kEmELn_j0UZlFXZ}*jh3Hut=92|46Y39i&NB zEI`b0C7x+QqK5v86$8k&q*H+Aaj@HiF07zI9;c{jjYY za>AUCNic^3Z{#I;$bw0f@%h@h2?OE8uBwG7Vv10Q$RO$aH|9mlyQaqs#8*xgse>wozk~)! zfRHar^!z(g<5x!k6^O}0%0~Y!N8oo{#B%X!miuA(fTI8^QF(Eda^UvC9yn^igE+~R z<=nn*STr|^5pG01+%O=Nh4)$}Lb)S%z_}_6iF%;-h4S7xkLcK6zZqW}8zLvXclodm zj~GuS_y&;(im({UJ>M1x$vZkb)pZ@LTd1 z=mpbM7fIouG#9gA9i4fxsFs`Pp>C&0WlI=SURl{vvE{aA^G1h?mR5Cj%Sv(cg44BE zBT1BM?`|mnEVmo?i}edlqBwu|h3>D#Gb8xu5-M^P?(z{3>}W*$IB>Ojb@-YR2ic0J zK2f7B9_AehWS-lMz}hu|Kl(1fWF6)S-tcJhH$~%kNtxK#SxaaA6j+Buy-}GwEWssQ z78&41=2@w5`RBlMcsdoo0xjQ>^SED=bJ(>y6SX8Okp zME%HZm{ORa$Hs{&e~%T3@OVv?DZ z=4#-X`t~fc%u^`h-KT|@GamYEIdq6Nd0B0eJ;QbHaG63<$^2BPHt9Y#pwvwf(3XGz z(n;EfK0BxTG1a{|5Vd)>eBWUG(#QnxVbA6i`~7Q+=!2SbYc0tummG{Wgmm=pf^MbG#5?<@ z7X~2%Et(7f*pH6cf9#K-J=h2ET~Iv9TEHDa{s0e49E^BL4$^h*MoWRsh%=uVG$wBl zXEvdcCD9r>B=|>yj~I`ku^Sx($$;RA{klMdAHg^}mj9CrCk`{Bm-+TDrTG|*K6j!0 z8GY-2p2QO`=vC|qKJ^Ix9Ud8_2L_~SaKcg`|D=a;p-4cs#|5(B=M4j>F*H{e3ytlc zf(rLVatW1Jn8x)Z8duOlko{c{2~V$g zP>v7B8K|vIOvHAjwrAlSwWvLyo?h=s63rmaj$fzm<8=w z>|(IIC+k8)=l0+D!*O^tC-%ru$c=DqqBmfMQWyVgJmQP<*(o65h=XB1y<$zcn%Acp zQoA>KN_^=4?M37bWi_VC-!9C;$2mH?Q3!Go?JiJs7)>WC^EO-c&O_wGnA;!@a`DCm zk8CB?*+m}DTs9`|)$HL@THhbWkTI6`{0^t#EHXt{4`aL2w&W>%ErLcLhB3cmoQss4 zD<#NLuTM}f0s9txR@FvlWTZI|c+nfiVK{;f@uX+|plPs#7Rf+e80aH*OLAN$9zr}q zM2x_6U?|YCFn(vhfKgwRmb93U(W$YR>I@=2$5OB4VPn{HL`n+l4DQfk1*+Ef`s+W$RNa2Q=ETU}eT z`<*COCUa1!L_unjs5M+EShQ){*u*+EH9gbAjHWlH*=rOi>kkFwyK|*=1m-_GqtHQwNXtet zC0fa3drYHRDW}B@ud7&n5KdDmx@m#k7O_wC zco4o;wFl?v%{l`L)A~`HXM-nv3qrn2@)Ty#)~w#?0cT% zu;LSJbUnT;r4#D<_E4N1^4v0mMV1nr7dW25j;6!9D0U1pSSYlh3b8aIp# z?ES;YA%;1ZaB|x@R`z8<7q@r#fonT7HOskI7QT+8DOSCNKLP=ML72-GdVXFbds=Q) zpag$$&^`QNx#CP>er#;$$cCHeq%W^TlvpFR&sQv0! zh(_xgeUjecDy1YZwmKExe(G=qYiG#$n-~dACSBlZqOqvsGwjFmQ zH9WOO8?x395Czj8tmJ5Rim7N@Mc!Nb{*a*g+45=otp~{+J7mXeu7lx{&+Azi_2~yLm9A(M@mgA}gA(bv3a=$MNmRG1L zy%p&yCs(q^MnfQNWEd;`zkG?Yu=2}!(%IR)@7uBHg!#RelcS2CMp;!BnxyiBT{KlJ zb~;ig*NG@QNr_6>Q;elfAC+bP9n7}tZu~jUf?FqDsgz8>ma-#qo6+5+CCy@JWulon z*7Q{(vH+B#;e?I8$*$M2;DiJCkEM&?*U~{Kfj^41GLpr&^_G4SWub(blq9JJNu)|C zZkFCHfVie1rL76(Ch~EoFq4K%GsoKTdy-07c^eTRNH{-=895Zv63~;@vbM?Cmmky% zyU;>iT}MiQ(EXblP#;hZp|)Y7L;Sm1!M?x8rGY|HJ)^d0((Fv0o|0`Ku3SEg%o-&> zfQ16{7^)1dn^Q|Vg|dfxQoT}(DXOuC=Uv0w`*uJ-?LzGxZ&P3qS+15e&7+}9(y|I!pGKI3Px><;|>}{8I46SwC z6O=Rlw)tzT>P4zJZnX?->^+HUb4H6SF z2i9aF@Y7Jgw+g*o?Syxx!ulu&&>62|@K2q48h3s3_BnI7)&Iu2- zVOeE1KA0Q4sDt^lZrGlR?6Mvi#^%(0=b9n^AFHW+k^x$y0|wc?J&OUJX&!9jyniqU zVx&D%iV?3Wam2@~Nbxw{^(aWhzrrE}6GS}Yt(jc~$*fQsha6)E>rdFv-mnLRtS_8+ z@8T~M%NWaBc;qU~U>La%`~Vv<@|hvYtY9O1HrYNjQtj$-Yq7RJq*?k0j2TFce|igV z8F&`>?kXU-@c)8)MOn7t8-Z!GeK42;)Nvb24A9{=atvw(Y&I)u7N?2-A~AeX;5ClP z9M@KHVqFV7jSZq7jh+y3exktlGV@MpAa_XuiDR?91sKTcdc~2E0 z?*f>(AO0Sxy*9hNLPVwqgowFTSGBq?U2c1yi&~ITFdk-HC)1F!>mSK<26nbCQdLS7rWuf{(VGx^c+l1A z`eyEv4#cX~+^)hD)RYXl;Er7P53zbNgy*jH_q?N!F^9rZvRnuF*$GdRev&j^zQ3}x z89eOCNDt-ChqXGcJ)5mPJAJaOf8pvj*zzU4K&a`Oc82RoK`Ghd_J4YDPW=ekdZX0t z+s>8Y;GPNBY=~KZ3UTbT$F6Uz)FRW(L^X~1^Em@eh%I|PC4a0rg*cgoI91|i#d>xh zzPExijoZB(89?%&R<;SFDWz{LlUlO|VDP4R`mu042U5_yio0>9Q*|RHycnpfJvjS2 zUZzdu$Gw}WpmADKPfuAksV_I4F8L^N=w7D>WEu}PKh>&n;M0Z#U&6pPWv6h39@41y zl@A#$vu+wZV5lxFoGK?z9z<)zw4k7mOxv3kT$}F94LCRGyOHq7-j`9(#s@Pd>T85^ zypVfeh6`FCt7CB09Z4lCaNs34E{{G^uBWLuV;HN7>g$wfw^$I7%kZLEFm;xKl375l zEU0AjEI5)&jF_kU&@#fSmjZ6)X|w^24w%gcP+VDB<8N!?(6hYVJQlnv}z;TLnoPizHc0-cAaUIHmW1ijZkFkT1Gw2s4>=A^w(-R*5q`C zw_rC;M`^pn{K4wFE-4uxC-rol(xRvlBR-QN^*rr7ZueFzM-f}&w&_!rmNZT zLZH=Rw79`wTv(wCSX0H#oVt9o6?_X>(}qx6ADLMeULG|8ls1a4cjJp599Ec^uA20Y zl-TW3mpu)`{q`!6iTn3x?1QMZx-;EMnoy(Aqk&~*&S_z~=PV`+_(o3kG*vy1mP=y+ z1U(Z%$PPDs^MU6+q&-v*qE!}j)f9L^l|!TtsKtTysT~BbC#Jct_nN&oX(&C{wG{C> zGQt#WFRAeT3I`JV>VCm;d9RgEytdT%aXP5JnK;vb2&3*}Q$_uXH$UBviEsLkN=lli z^i*8w7cHtNWTBG>?y8Sd)KX8+X7p6(xZebz$Z!7`6y744R~@m`*9fw-Aoo{Ev^vcF z#vMK30a`|h>(xBehbjmcN)rS#Rf5lKLBCoG#f#YUmNbk5v*)%Mu;oI1S-^aS%??hr zfc^q#-LZ4Q-z>hprqT74IuoMK4HqqvDvPBmvg!zeFA~V)SDr(3g!G85F3dmraK-on z2(b!~&&B?hW||ZK6KP*Sr9dOE&k<$Cwd0M1yma+DkgsJdrEc@ynVBsJ=iR z%+2DVB!A$8w_`prh19%5AL*hQmF^l;CzMhO>AgRs8hPuwu!~C8k1IUwj7q-$hIhF1 z1LEVtpng5y4rAg9m~881R^_AF`3gi%f7|PsaZ>CG7fz*l+O(w8T;FSTD1(Xys1129 z*xb&+B`sWWn&i?Wulu;`6;p#dz036|VLP0HuVjDkb4vU%%XlOAolCCU9eLdnY@+-w zW1#+RWWNSNZH?n355;?;NiQxRli?%$@jZi#*NlQUz~T{TXqD?_GnfZ>8T2yIGJZjxB=^$~Jg|;}TDxyI4=35Lv*s$@f>nz- z%5ITGu3XvCL_aHB>y1fkoCagoea_q=Os;~Cg}MVlpI zcZl;2-7?SZ9>v$k{7AS{5X&Lu7v;Cu3n-K;3;Gf^I#;@PN?)sLr_4i*&qq~Kr_T4S zP6A`m8!;-KCwyfGM>E{@M$IkDbB0Tu_*M`M|JQ$?TeWI_kKL+LL3_e!5z<{E4Xwzr?75MfjxJ~Aa4O+)%~L*e@sdr~E=HOIbwl9oTmORjB}qO=m~=lUEhhVB z+}x4YjlW^e(L@!sV96kh9jN*I=4peI(WE&wH)7Pn2ISNnezyFnUMnLil<6P6A)Qr& z8*yV!%b}MUJlUjL+>ZJe*1FO8aIa?p=I&|hZzf?6qyhENtiT-9U86%4>cOew!*>kS zUH4WH0O1ABEA@k!(V+8*SpeP2{wmLWVJ2Lg%1Ej>8#bDX({_d>%dH_%zx-P^OEe2} z0t@2qoPM@8(YfMb`=zsT*;CHJiUwi?uz$t48hOFk*=wSvaQbH zlbVN$PT~M(b%)CI*xF$VTGoSS8fO_H6p*wAVPnZ8cH)Ogw+2P|2 z%r@PhR)C^Ov0k`k~Gh(x*}<3cgipyw0YWu1%a| zQ)RhOXAGGIyL{p^aYp_&ps_jAqQ*7yK1zuM$^Jay8tg>Ft{{UNgFL`BCc-s`8tcR< zMq0Kr{B$BM@p?*0;=7{Jq=yF!&z4Q|^4@~7ELrwGW1sIh;mh%9OvBAYFh@f!I1={k z1CLw%YQ?m+Ei;G#Pjy4f`EKyBF0Z(3V7OW`_(QVIm{4a-O2@Z}VMTG{j9ad&2ItgC z--;%k`dWE`M80eAcXLD0pQd&g=-=;jQ`TiP$&j6SJ&{%GMl$mI(*u$^9_}Xb-W(0u zTbi0GmRz*N7Nt+Ds&7eZYHuO!`>~Aa^V}Tnmm=vY1L`*Df19>(IIf47uIMl}@ZgHw z4r#9Nw2QVQ32pFg=Y3;vH;C7&c|*E4klp3IuwpHGP0_vaW-aLtM6XD@3c4fs&F%JV zu4KAOyMy7I+-}34>EfUHIGf=mR{07PuXb4^KZ4*Eo|Up;m&_aI3E8+=H*uCMsqbh*q!0TW?FD?{Ghimo)x5Rp3r9UaOzZd#H8S$&skxlJZo~VPG zZ^LPSF+}*NU5@N!Y&yIlK)I6zQ!nD4T&WZFNDN*tlqnvSDzu^9U!c@S*9@@Ue*PEs zBmEBo2QB&Y1my>iGW;{-`d{N%g%yRFnMB=+SviH5VHUv2dowm}kfkfCUqNEc!bd1FjH=m`aQo!T^9XGQ>oel1eBo zVxEh#UaKr!o@QEh$i2CB+n(+K3)V7*umam#wt2sWvdSCV*>jB2r7^jHl4bZ!UL9~O$G9bzv`zO`qq3Hzu6?OtAkP#tj`_Dy)&Dd?>tag>EefMRV|4Bc zb-Q_}{Yd$<>zI+GkxWkQRuWp*;vl)^NR(utYp=7D(?=@cOEhr*n(XCt0<}`&G0qgL z-OSb)S{G_yPNO(AhiV$!6%2#RR__SMZ-)|X$}z-0+c#vc$RKs8;JrxNc$~5WEVotU zP$t=?_;*FbDwgTo^xRi15sVExA*VRl^nLUs!K#ZkZ1vgVEf}W3w57RNRQ@rU#mV1H z%3$&NqWv6o&D%eO2KUOt0*ZzNlvsd@g!T|RXREZqF6sAPN~R`Bvei|q71wo>f7Q>J zOR%HeS?=oQ8S{~N>psVcS~Hz9;CCu2FgGKUbJ{j@ENN-uypzW#%_LGi*XX>Qt*ku7 zr)vN?&HQW;qDsLt5wA!D)JF^gUqZsIr}C7qYIne?xUo;cCBc=>_>R(V`21_a4Ll{j zoBV5>{AHye`h=^|FcPB)#=meBOn*k3Mo4BDs)>WxBFHg>$w%hJc1R46h~73#hUpA9 z1fPOP-NA}T)2NPoLfpfpGHgYZZSJv&^lGF)i=8xutWtqU%{>WK5-)7Y>6Inm!e;{u zL>yyW`>8T`Kt3{f#bI4)9&_@Zg-$4vP|F0Q0YeyX0YRApv5#WqFK`>R&NrfZ;X6e` z;0K{|z6E@qr!a16v3Xa}^UcUhH-ak9`Aay0ym8gZtA_4$+>-zPhfT--c1gkf2QlUM zGe~CsUsA+GesDv|7B(ircDAl2j{il9k{mxP`@_&5=`9W>D$gr>{XPL=QS5e?HYI4V+ijn&HEdhW!9J*Dw30)d4zRk#*i!| za}y@04WkbztK?jRe>7#|2rE@LF!28{O6&`{=69fcOM+ne@2|i${KRW3MgN; zt(1fM`2+1a|3)m-~b76B;^CK{bWssfQCV+>oR#n zJEGK1gRR6GVyf#y|A0^^JjSMrkVE@TRMJTa=uveB4}bq@W|rd>+SW0hcr%FNAkr;H zFh3f;NrW^CR1RShYMQT#u76H5rPOCMcdliE|TBuMU7|oG}HeLfsKmti4 zXpZx}sM1knkZ~rDhHG&87DDBC)BZhX{Q$Y-3Rdx`jgNcMzV^c6p3^OLF zu|4eRe7U}|Fw{1Tj`$zW`UcAtrR7@;Bdi?2J<8$2ReA`;2CFoIjuQ*46(y%G_E?ck zsx@q4n&BDs?NGQXDG4AzGnpeXE#%ZapP&WS9WF(whH|hjK6CiR+dPW_21?fsC?iGe~QvthdH6qI@(NlSb(@B*^jZx9n zeM6mnSaH4@CjMX%5PI)8`3Sr!msBt*;zA{ACoj3l2w^7y$)OxRIEQQ%Cjb&UMu~W= zyBAaEkM_`bei~$1%7J+zn^=tDg38rkDMsqhhiN!h#ir%<{UZ$K7Zz_ z@Xc(ul}mO>id@_|q;7}UA0E%tjMNsl5r5S_TOQ=c%&YQ<$n}p&aqptMiytp?zj7pw z9hbKV{!q31Gsz6(jC;`!uZN@;O1#Hfxd3JT!3nieS0YyU)m zMoARHBP2ZAq;ckl!YDB_lg^9t2jcIk2=)UCV#$0%?w(Ocd`f81_XRVYPqKV8yso;{ zKAvVr<$m3#*$IQ&mI3UG-JoGF*wBeWqal$$n9`0U2we}$S)HobKL1Kpz$rzA=L=fQsF zKV!fD>mz(ttzxNem8RgwgYDHuFHFvwB}y**4K$s8qI&AxE7`AvRdOdVD9mFx#>L}i zOvI@{ERH;mOI&OK7K@6)GG!R^+rGkp=@Ca>v+8xrv0z&ibj7NzoUhLM9x1&}{ZU8@eD>b!Z~qWJW;m1Ij<-p*i{&xdl04 z-vvdXk5&#JuQ{m~J}wz~=cpY^vJX6(#>llzFyOc%j6Lj`d8No1s+mKgZsfM0N!Xy( zAPPqEX9Rka9setW`p6VRZ%^oPSZ6ZHMQrokK*bHwi_^CUQ(Cc$BzkV_P?|mZt zUujX(a$8zK{emm3AHgz!9%W0@=jkJv!nmyW{|$^{X$=@*Bo zeZ5Ofzy+Gp(kZ*Miu)aBi!SXCFxwRLFQFTpI&uO6bkVWDszTE*jWzYWJeOE|As!7NiH z8XLL@feEP`x(^D|oJx@gQLIF!MA%Sd7xW%+ zGG%bWHD_&bf0D1rbUC$7dYz2dx_3O~gO;etedC+Ct~p|-{D~F{iu65O-S^ib*_K`Y zF9Wy`>8ukks?A#Aft!0WlLumW))vjLiiE1eG~HiTCzuzksGEY~n%q}xR+}ezwyhq4 z!N?_tvtiY)bm(4CARt*olW!-;-lve%x%OjQtzuJGkf^nXu$bs7UE!_DUD0l9r=3)I z!-A->`*9Ic?sCH>UG#C+g;|nqAmJMNY}rFnufiRPYfBpqtn({~1G)K3hMM~8`H5DT* z7q@;*KJFV3`NdR%YW7cU9bYqdFCKFRE;W0<5IV6eA(iEeHR>bZZc8NpT?)Wrg&r34 zS3Qx*9h~L*pxr!So0^VdBU+;KNRUy|>&^`M#&sr{t(aG4!zO^65iN29e!9;9-Bor1 zfvZgru!3c_^C)3d0r39(jtMpSTEKSOvM*+K!cfOT z0RFn{P%4Nlwzdzo@D7sYk=6^);EANWBoC-HAT`()N5g`Xp6>`fiE`*9gt0@bhkXbm ztsWYt9-CUyl-g{<`KwZ$Y3F2szB}q#E}Iax=vi$m&CM=5M0QbR-mS`9q7ow|#t^-1 zwUM^MfG6GL-i?-pC?3zr58m~`tkYgd%S{RU%t0aa-+1(?++#|wo zyHDvIh|?1sdvlA^Gg|oyq;^aE6}8zGo@@Ss57Zbvgi+5le0lYUTkshTkC2ZzC;^%y zWsJD{O_Fn#D{J6xq&F{1+b{4bR~A$S&HA5{Sjng`ctQ}~BN%Zvf1pso3z!Du|H0Th zg;&;X-NIqTso1t{YsI#0+eyW?ZC7kpRIzQ_HcsAuf9Lu3voH4fFXpuR*w`e?oP z){NPswMkW?*$MeBG6aImQ`t}uyHNGTo&BXuJ=|HY<)y4l_Df^o=>kA}LF8sRG%Dm| zP)~P&@RuJk6@LLtR9?xj-l~aRP)!;Y2STLcNU8FMT`DtrL>;%BaVL<6|At zd2Yrb!Wsje(1)~lnxUo~`qywYwwbXpPG~XAucSR6`X<%5;K)w5Z!fZ=b*}_`{y%si zt>J4PQGG1-oUzocT+pCSx2>kzo_Or~CuPUAm{ERSv~=rSpiY?ewDdO^OlM=T#6SCG z(`XRQ+mcz^a|UQ98D=24-#zTS0wY!Ih>41p!+hv9??foJ-t^g^`sn(F3jbzT`0%mT}S5AgE}x*8VW*h>1@#j-YZjNOJ?6_ z$9zI!w$1E2vv$P21E=>TdsG%O4p?0NrahPkI6lu+%n;N$56#Kjsi5AU(Ap3zb7R{tGt0e zj+@=`_wZJnb2;!RT)9m!YEzT4r2(X?+=T_05iAj=3YS)Y$ZW!;OQlefjVrvLQ?Fa8 zyhQq>_Ir#-Ela9|H{a2+FC&?>m0?qT|3d=$9xwp1`mXQ5zw0}y|61Su=gEy$wNk@g zLft@z5)I2A#L$LqrbgO@yphBja)6Vy)D@)EAJXUEZk%LjPZ-2wab~HnTRWT~u}S1h zxYuE~$k+$f!}X%IPOaw1U2S@GdIfE7p9%{F@*vfedYa_@HXVOlIa+7_9(4NHg8`D; zZs5=~z#hh!b`Xh6CPWv@tVEC=}G3;C5jj`g|&r^bU@i&aH=!j4s|#W-tr>? z!Ib<_jn#@a0Lb}cVH$&&15({e`%kR`cV&k&u)IN)LkjX zZsc-}@m(5?A6@?s!?i39?=Y6Tn!%L!>v&yZD%qfHbWCl85DOy~_d?1$YcMg9$Ah)%jU{1mFS!{$~sqz^Zovb2US)EVoS; z@|MfqIymV2RXM+#Q+`1!4#V=lA>wtXkAtFs_CkA zIc2R^THFwUY_*BNNCvVHNW)%we-k_$&A{b~m zPF!j0SCX2Odh2=UO3b4lRq1EH4VD^e;s%YM{u;>swP()Qf!~M-3(`n;*wRvFNI(yr zv)CDKJ>>S!dBBJr7ExBC0}URcvdD(=E{(%JuTFT(I3P#GTWMpw0N>Lsk6RJFy+uy= z&{2i59d=!cBH%8{2Gy7wc{RY_AYIn^& zqUCp=F5xsM?(Rpn|5oNR=%@Lv+%xmYN^gMBRDYoUz3K=Ym63&)Ixf=TBo16^y+)fA zIeWDZlk-Y8#bH-Mro?{LZ!UwQCLe$q(tWo5DDS8NFdauVvUaMv%sV){$@A~$QtBVDzrVMXk?&f~cago@d-X8h zf>g#EV5nGZf}K5g>YG7Te=XjXRsj|@x=^;lRH$y-TIw&&?z-J%xaON@w-Ro-(C(X@ zF)FKy(N#{9aTO?Ut_QL*N4)rY=R?jZNfJ*s*o#JGlHfC8?X35jeW%#!lnc7{Mm7Xo zr78-dYfEcU)fnYfy6CJ`({aaDPB4;-Sz3j=A_8$w>w2iAT zEP2P+M^D_{(Ej^kHn!s#C+Dc?P%X0o*f`2hCya5)uSF*3%rF7xi9F(1+UwwG@_ptb z6yf|?qH5qBzPt~uS+av`&hoop2WYgb5f8!L|f^u+}3Zw~P$;oltI=v!Qfya*RsfZaa-zq?v`1WowE15$Yo#UlfPMu)*HP(Z_Qp~zT zB?cW}#TfoRA6U^q8i7}h2TN0|V!@}Eg;ROJh(k&IDU?O#&Cxk39G-LhM3{R$mLKAE zc3BT{z>eKGeKxbETEN!$iwLq+mfRl%-6@Gt!x*+S6UP2r_e#c3v{i7{A{-Z9-}``7 zVd6g-RJ=60Kfa3t?4Pd-30$`kB4LDH3<1nCp@FoT)ehleEIF0KPCHVKt)>?y-zV>j4eyKnk%jy!-|G?{Pfrk+^tX7t-!XJS zJomA-@Xw8>O~J%Z+RwVp?xVOifg5EOnm0X+dBAt2umUA_*t#Z??uVy}*+Ib;~igvAgh ziN;xKm4roNZJNzuu2B|CNWDt{q>(o?YYxAi{!8F1X7(z^SOdiA^c82y>uyu0`>o6C zisxg8U#$joIcy8u9$~6NybR-KPhb&GB@mv7B7h1Ab%ZHtk5i*grO4#3LcD?lh2LKe z?HFPXtR6<5nq7CGWDY{=EqMpUd0ognX!;0(s;+%8IUrVd4HDUrz0BL^6rOIKn5*rM z19$M6(LJw%rw<_7PSud5n~-tYw;NE0ds8609UH{wd>&tt8vc|Oi<{>dd^3?(a-=0W zm3QgC9ng}|#4%OWWyhRl__J$FG3n-K3rbq3G*&|kI=eg*NZmbco_?; zAO+ZvK+LIu1ni1uf|84NZ}pXcQ-(z0u@pkrG?nGZXw71CBrzqx&mylC>%KJurt%~c zZqdp!@p*A5-ub(d38N5fp`aB~sw1p1`;aE)9qC~JcfpA8uZuGKq36tY$ z`c{S)aHHFm!B&?rL0VIeOWD|X9H-qNv)QfNfS_=WkSgvJ8Cud_b5qn|soIksI(Wv7 z9j);34>qHV<|+qp%j=$MaS_=KdJs?z_-K;5aii!2(5cp(f@Om>=P1F*G!emlpOr=> z`(L%&VLx!zq+@JsGRVgyV|eoPFS4utssYf&$-eEpv^_?(h{u7>n- zE!0B&v|0{^SFFp!Lh$;dJlz^MpjzuFYkg$RKHUE*@VAD=*{CH#&nm4av;k7*MSPZV z5LWG47|!b&F`Eu7KV-sPq~ET#BP~;!XvQv`#q#JT{34e1ey1|T*Sly3Icx5ka`Ja; z-VPC6d28iP1dVKga6gKx)pNym_98}-=mQnNiitDoF6-Sh{-S1Xn zH+9Iul#S9@ryA+oTH&c8PCGgp|K3&`T(pk@sx&PVONcA;2SquR-j0s^N_r|J6TYoC zFns(lX0M|D!RX@##aG+n>fEVY@2Zw89V5AJIMoTYC6@0EutT(C0oFO4J<6l9wUQUi zJKR}h%)rL#tPix-I%oB8Fx2`9{TJ`Eb1>8DJ<2jVMY`jlWVae5VQsmmn?xzkgi8Vi zw?i+zkFJvq{1fsPovx2SVd#L~;f?!ox#d@{%yULuasy{lqms!qkl9qTpNwnf#IxpY z=LniTHhpb2tQaG#yQgXKY&OIxSMZ=Qm&UW5{KLZ9!7 z0x#^*U)IjvTZ1dEmXtWDK_%NTI)Pj);9saoI@_91ZvH@G`f#1ge)Ju$)jY2H|SoV7fwUXe^tMsVD9J-TZ45D%)03)myS=ilY*&VsAENYZ%qM zWNsVvzuN;Qpn|V;N!6~3cBrG%;dD!V?L4q-LpV_~I41N2IcBvYy(``fd~Rk=f&~7Z z!MtJnG+D+3cribhWR1$z+d@Y3S1D;SdvB4}MO3Z;%DKG}hg#~YYdqnoSNYmRnSGZ+jk_YOTeXdwfN+Hhrs;_LDq`NuZ3 z&A0M<$GD1!;>~g)MWPZL&o;O9<7%~SUVRJ&G=`a0Hm)pj{2Co$AhNP5Rh^z*=`bmh zS>(@8CUEe?P?x$Ndi{Qpwqo#aNF^6}k+|+SZ;oMeNhy$L!inbA=Wz+AlpIl)P|>+!5g$l5J(7ygavH-!UO0@eH%T(JPf1VbaxgEOn3M zHZ1(ZG4-nH=+Rtk!Zy|HZq-QxvQv|OJ~GzcmTJF2qItUhcgF^~~J9@U~nPFzQ8S5NfW%||$u?ZL-FC1@o4v$B> z_hY=_g#+_L3Pd%qGQ#nA7d!qQEBcZRHmg!UNda)q(PwQLR(y+6D2#4RNIyh5Cw*N8 zZ}rk$m-wdL5v%m_3hHgJutVwcT|oG%rFVf<1KdD#r%09c>@ywm>A@XRaqs^8Z>d2jQ3&x`#d+o&6WuLU2yF5X z9*LhRi?+sX*|6gf5OWVc3K{}|wh4UD#Qljn1eqpdz5VzeR5!YFh=2Ax=R+QXl>-SJ)kb^0% z1jO^j)2EDk&ro44B*f=5jw^bO^5jfrq^K}GCc&6icM9iqTkb>m|CL-YJel9=m40H7 zij~7dy~f2W(%_U-G6w5ox|>c=7G=epNWw%a5fDG1Sejfu8mLdcWh_a0Hllb}T4;oY zkd!hpCToIL{8>&LEMFu2R+O@OL=qfIow(4+Xe`+!qsy8}=E#4DB_C@Ks%lUyuvF?I zNI)f5BGqldJAso58`-m zw|D_`Y^ZbcV_?^Ft;a)x1Ps$D(XvN`OzsFi?@~zDXB8RAiKP zAFB4_y~m=>aOGSapcmmQ6u`6kTmNRSLxRe zyEC%3&0FP&o94YqlCg}wYzqyGDy{NEOwZbR&_g;gOm@JUV)eV)l{i-6egUybFHCzik~4@Gpm%Ek_(ZLx0_(zK3?X`_t&& zvUc@7xkvMCx;LWDXA5a4{+9cGa;dmg7OKDgP5$}^xUeG6&JCWl1OLdJ#+B@ zvu_VaZF=m?J%jDGSU_O-J8&i1O|3L+xjnMHJRGgL0TB$6i=(a_g%V>bx zpgE3-YZVPyuPC@__^v)0&Kw=J%#zw};tBDl4%r@X zc}-4LDU;oBzYY5*nP*{;VRs^0x<}yDusFyIs@EN?LyfgM6=$T3%kQ#i_H4de76Yg2 zW`TAc0ft0pHv#qk{fX%+rH9tKque^+8ceR(pG8<}(a|HE zJL94)qbr}&IZkXkk}o9Zt7vlCo9o<#cF@zuD^m*)lK%`|u7{_~e&F&_y}POsf-^LA zCO+dk(+c7Pq3{apN6xNz+_;N7$SVL>Sym&goHH*#Uzrw_?qJX6CY*_6z$MQXfU`h+_E!*To>iaW3ZT zzqS4U!39rm?&v>bGN9jMG9>>U7vCAq|AK{&l9tk(0Lo{xjD==@6^JmvYCy|h2mu8Z zfi}#jZX28;)nO3Iz#`CMRsvbsH?-yxQnx1_)90=iKR8E*ngMORKgX&2<59c&{FCeT z5x0jSXE5FmjS&CONu(hMJXD7ItN4IOQG1VIFI`e3}OO27p(P8Gn8n81Jf9fXS=|^`hW02Mwz1@DesDH&m>~l=?DAAY>{>m$i3EG;6Th^xytIgm2-4W4zBX z9@jvlKUH0%eKoQ58k(RSHq>Nc=#Lxcc8ynb?;O@yxZzz`QPkm@K-C_C3z`24HZ$j@ ze6FuHPSh>8_evy82)4rUK&LQDBQKn6t1AJdT|id{7|6M&<66A&~!S9Ujl0rKM-8cWv* z*6#R~)&Om+QHj6~+^!BfhBc`UPkK#`c}ApFLWteum~M7InDXw&E665LK2muh zScUOvMHC|0vm@2aXm`Pdo=Id_fwQDWo9-D2cE7&8>G8jbQ2zkrMREps?HeGU|8L@u zwzD<+zr^tmLcWQk#6~kx06Zij#jhox7$C1~tBEjV*b5_1#~hPbB83erK`wKByPJEx zfZq$l!Bl9+_Z;Z0{6}WYgeJ;k`TygN9Nvr1_m2l`KLef!f)HuQe#GZE#C}>#;)0mb zR@yz;?Y-PrawD3c4#NXoFopG0Mm#}oGNCkBg9yUTI4y6T;X}1UjAb6-u}YIgoCRm- zik({^tXu@sCHUZ3MO)!xCtpp^9)zrUnT>SQYjOzaMjoqV4q+=@_LqVVo&CppO_s3m z16mnY=!zEfz*T)s?64#I z-o8>B3d|vvDa=waRdbHa#GMR*gvw5lTG~!Q{$z+Q2hBDsBx{FF8Jc8L8#48nZcd47 zBr)S%bM6Z>l%(}JS?FdWDKtxq&qg}hMy<-*eO=FjA?AgR_3dW4Yu;WYv z!Nit3*Gw&_V=gFGN_7_OvAfXKO!uGUo*~V9$hoZbuoVkb>{77h`;;@e+4?_&T^}pX z)m=jJiB~F#0Y?@?sK*M8bD2QzVS6B4$M|a!!=ZG28|3zB_BiOV_CGJK!|@~1z!(da zF&BEa`If86Pl^>f3G~5`pinXZXGHh;xt7}d;?OhO=oSMVb^YOTxr7&ZJuTfozgm-C z{nfQ4F9bECrRx03gz;FN6C$L-dBMP87Ytf~54g^I2pwb*Ai}DLig_E)_uij~TbRuY zZ=eE(34=<5Zc%zcbX?=J_=ey*1+eHDLrkO%z?~@K43np^bPaHEus3NTPUxJGwF@_{ zO_wZcrZPz_4ofEiuv>M_ENkj=VhkjgI4Qbdddb`cN{rbNn9y307KD{9f2NmjKaV6Ep-1+BN~q13?MO zD+{p5tJ`Akk|NOk)EqMvXQS&V@7g|adj`?%Nuc^Bkk}jK0cHuXQGpjGv-Z*>>D=m# z+&_POK^bByqaww@{R;~jW|;!S!%d`xMCTo#+(@Ox(_r^<2rkFM^d$M>CBzmhkW+YaQmu3?s;O5@FrH_Lx7MNOK$>A}o$kYx-~#&Ag`= zm~*2wO^d(9X1kDlnHu{KUSX#4!|(5U3M1?9EK2tngJd&JOoI?iSc9dlO2-XkcukS{ zWbT-YIP1)gYE?2hAKH44UsjRaBq`|pr=5qGC_g>qDt6)8^xtA8b1@Bb#QQJOju8O- zNU&XIZjpvR8esh`0Oxp0h7mhdDHoLZu+V=MhcgN^NGq}<3{Fa}u(;RXSwtX&)|>w+|G2(Yu7LOI*@r3$$Lc zWVKDkP#j@)8Q!D&@m={2ID~gE*a`vPBV6(Z zg9g#(_W3vq+d~=t2um*-Eo+X(@w-?cRWna62SJ96-=?}KfJ6Ki4;Oq9Nhn1E_2wBw zny{qLg=7anJ0LG`iCTUAYUNW1U5hg8c6;y>86<2XX7QfT{Szo9$0EnYBJUt? z0oA_}X^5jn%Snn4wa7Ox+7R4Czy2-r`5(?u6AfCE{YC}(H!6t#D=IW4!IC&=*Prs^}Fw4Vee(idsbJhA)*!YEgBW7HOK+Y0zIV7?O&H zdr$Gh7&fc2*Y-%vjjoDTrCX&DO~mLZhaq0N zqyA`6T(im0U<_+71L9?z#XgwrMnD~JuvN1Z^^Xq$AuqPQo7*i&6| z@?jSs9-Y0#YoB=H!qL&Fo*D~`rQK}FPJtj*y@GqSv26!ospKbJ>^HCLR~otyp0dIJ z5!!imGf!aOHLv!R=+0#ENh)u_Eo(=KT}mP|AW_OHdWTz`3o{2ui$TC`!<5OA`8~_E zdjS+}6!$xAe?Oga>C9vOW=1C!f;dg1o#*Tz5OPOEbU<_lr@Y9(UO_(0aN8k#Z#!r} zt;Zba%ZY{ZL}}Y19I%NQZq~a*(hZ-J`26FzWT2(z4vF5+PRbj?I~7gL`=|F82!Gr= zegOW=Y*=b%Fz@tZ@_ZE;2ndrF2#DgpA4dy&fUUEm$G^^GwkC{s z(n2!7*(S5M2ZBE2kKt=sGXHB)j}c-hutYx+9#nhr?l^w~vh4J0`G{u$8y})FaPP{C z%le;M;8J%6w@0=p9|>H}&iSvX2sbKc{6MUo5~NiZDr{4?opE5Gw>Sge)S8 zC{s-Bfn>sY;Nnfo;`)oApgFa3Bmviu^m>N}O!Tp^@|dv+sfAtIczHADcMjsOjI&Y6 zrrLf(cVOwO~+K74K+9wCKvA;o-N0M*5xq1>kB4VwA(oXj*fO969vqbQJo$saJ zI)=oWd3ZF(9)X#&sl7fsB6I?E6Vb5PUirdem--_~{Qx`E;qqn}DnL z0DRTxhUu}XQdqMWI zM(4OZ>U4+UfH#MihUc1QtrJWeqHN+z&x*p`J*@mz+hoY9ZX7ybPYVP>V_TqRDB)u~ zJvvg|7}_$>*%ufcK$UuDMR<~92Ij1Y>ufhDr_;TEW1+V!)@W~#urPb1F0d|D>8?{0 z1&+)qFSUD{RLRSd9nCIC9n64tvree7)@U!m&PZh$3X;(hTS|TGsz$ZwOIVr9IQ4sm zSy||`wO6B!EiNwXsbmwbgtp1RO=wxFHCtQQFwE;1xQ7geMO2&fWQd~2p3kRCVzr35 z0xS*VpPMsMoSCq;*naM|8^$|}5w#&l*v##DG9mRFaz8km6=aWeb+J+@W!sFf$=j44 zKjdkf9!WSm7da0(;^Fl6rSX zqCU)0xvNO5Tn%1S9PTPWWf?X2aCn)m^kyPHV$qmNwkxrL~+Jx^IP3Rh~NZgDz7GINx= z#dc|J7U6VJrcqOi1W&FgRjj@Jo?~u6cbhPeGv4;(@>G&!&eLlnhpkHrmKH6%1Z#Y| z%)Bh9Zezy1qZ=Z|Uu**XG9o0p0Hu#;!x~K9PNfooN**@a(_5>(;U_kG*c3Oh1hGCy z3K=E+&^Ta%)ce$eYA%mrmk_EEs`sQ4ffmA`Tt&6V5SH6Sew6R9!W^-9gM0ToEK3Xs zImM(8>s_8Wt{x8RwTTRjwOOPVy~uNJvTF9VccI8Ngg@CQ1z?Fx*`z{6rIr?{E?gaf z8X|i^M)^ZUu6%q>9uZOEOo(vhyf0)rQJS^ZeXGuC1nh~+$lwhx44{P6OKcvEqb4f+lqjhA)ld8%9LMR zn)+ZJb%};?R>q42Zk7-W{vtuAPGNq0lyMg_3cd?8R=iPKuxPy6{9JJ|!Z)xe)fRZ} zkLe-pBod|yDCL@$9+$zTt}*7y^xWD7Fs-0&q;YWzA#{FlNXuOCgz-%pRHlVcw{;vj zfcsI}2rKgqUcKb>ehb0t)rJ-F!74yYu%EeZnLYhxKd4l4wiJN^|TOitv z>Qtbzf;?wqWS~}7vL!?9&jp1j;3pZeuJU1YH-Fze+~bUfVny3+`*1`ukqgta=zh{* zc<>h}nY>I_TpFtp6^DZP`q0!@q4O&(tjp(S6@&&EvLFcyS>c1a=^94=9kJP{|81>q z`HGl61&qMWK94JBqK!97qAw1UE{51CLO0LMoaqJUqmvCs>4UUNoe!P!4=QM8r zJ8dT~)o$+D6)G}*r3f$Kd_7X9@GCD;w;R+~6WQ)8^+u(An8mgUeoxHpB>&*LIR`fV zg)8*IrJVwMPbS(|@X!3S(>-=H{2XHRX1?1_E^x6$H2;*F<@ZES)eWzAOX}6aGhch& z4Pm!l;g;c=p0LtuF67~tNO+n{z8 z<~%g3K}r&Y=<%1zCuBBU1hT_9Q&caXoRv#*D9VPfIJJ|K$PRj6X2jYl`coR;(mUyU z@yd1sg8gtGr~!|aS(rtkfeahZ#a@A%t(kT=!qJgn(#RUF;rdnzj6T}A^jh0SZl&s< zz#fefwZ+Mp!+Ea?f#ilUqxqt5JLOv(;73?650kQyS6{8Hw?Uqd)N`3LAe8Zzq^$a! zG_GACpEqY2DROD@Vz<)G5bV64tEG#8w@M3zxRfVi8Rdkzww>AX7ka{v;I-nWeE#fO zs&N6Xx;`$?Y-+R`(~NgYn4y^u0*g4uyaL0&0{&5_M;un_;0rU8Ic>$ZK2~37*3w~K z8!j@xHQ9mG)Y#|EFR$24s9k?(BXhP$@M=&BviD%-6m>J#Nj+`|kfl9TrGsGagV3Al z`7jZ(+a?9V4T6g>pM4D{s0$I<8Eyq&7oIpv*F?665j&8Mvm}ZINoX8yWk;2`I8AHS z35nJT)#}K7-z;nwz#IkKO3h)T^Rfp}#C~CtmcdNr#>-(Ofo0dvSWIuQd7>YG|NK1e zVte%z@AQAvxHl8LD#fAcQ7ZRh#;<7IxIkfl1 zkNZcGw6t90m9W$z>|Phqf0JBs`VD~KDMOM^k6>^N1HgJELJaL*j$0BI_A*bK?wvz{ z<<2%UcVC3ewBT5M1jZ07eVGTYwwV{to|jZev*k9u%)|IBL0o@BSZ^U}yb8FBC2)@+ zY^)dMw#B^Q@PU#uWI;I?t$RzF8SFDJo|+9Ctf(z_PtLbrP>Mb(vj)ZCxCJpqXrv2{ zAqyEB4s=BaF=Iz1?hIVUE4I`cekB}!+?m+I`W*u_iG1%Cl2j*Iid0^mOtw)QY+k>O z63r!=JXud4|EF^Ki6a^fZgS=r&aAAHWM0^4)YIJhXEbtl-*v`s>#5JeeV1&4)H|rL z9$?{R;EKVVF)Sm0lPK`}*uhQec&iA-9fdN2TwFCDEL2fEK%+Io1BX2%p)-g=k@?WX zn+eI;Bf-egSm5+2TZUxI9MQmyq=@67w))zvee$e)&Seju%Qj|H%52l1JxM$^8OCi= zliv_V=MX|!I;^BVBQJowmoyQ3I+8PFWd8`U=@_AQZ|bQzpYptR!ndF1B4mcr2!fAR z&u8Wr>V*Zh9*r`LyW?Z`N%9bEalImMigN7g5`3E`l}1Y$LN=nPh%ARB_>uW;NP>h} z*{;w6jF5^gh2Xua4p6{p0}JQ5GofR@%JScp;2|O;sGBR{^HhS@z_3w-T?Zs0N2UUM zu3d)T)38$cn5qSw!e+@r%y4QzQE64il0O&rGtP@9K7mOiPps~v5^BXIAVYM1kU03c zG5B!_l|kN$3K(+w1d>gAXbH$RS~DUJ#p0L+mceTO{7%G`L${_whYJnaD9NmC zuQ7i8^bX5uAjGm9`GvLzD#)@&GXdKnBN7^)>4fM5gGE$!0#4wG81@MsM)&A{OlK5n zf`~fDUKQmmWKzTiI>U%X>|a{%M-jjy&jb@44@pIrgiHR*L16{mqK`8pdyIW3hlMV+ z^I$BuWgPa#4st#v>&99BX4%lM#{Tp3>Lt$f~LEM>%)Y3AGy zL)C;SH+{r2)04$x<`ZG(gV?x1t=3<+c%{{HanG_X#MhGfNmFX8NmW!!>Z_7zwdEEp zZU~y-7e4U4o(D+S&b>4cu9B+yCbysEXpAB%)2oq3v?Cx!fk!p$#Yy=52{N6Zpz~Aw z?)b}`u`9Ol4HWzE0PXOgY-SumD^F-VxW`-Jq-}gSTcj{AFhp{HSOF^v)V(^6m*on~ zgW>rA=Nf;tCsq-r4dDPic^WM!jzR&Ajvas&F?@@cVK*xL?J^p_B9U4*gl1%t@@aB! zQ%Gj=swQ=YbwJ7K)rfPkoO^U`0Ol;(5iQwKhj|f#=_dns^iXO{7`=m(nP5aqI)nwz z&=391w)0#{^S~!u02s$fF}jwM<9cWB6_8euwqlm^rdy}p-u%Yv!A`s#2R4u5l+G*7 zG&?^Y^jAsnm8jw1LWF(M`(zp}smT6K1thxzx4g>naQ6A;U~NHCZ3$vdX`{9Xs@7FB zyW|u~DhCJzC6tOJGP^%!z-vW*Dh3NeGY1$R;IR^PJhzZ9ax)2q`w$Kw3-lok>M#I| zrD=liD<989NZY99=NsDLgC$G~)j0HtqM&9>1Sd?Lh;@I%@K6J=13cW(n2j!7lW{86 z64uS>&)X0~gK90b1GvAxT9mcRVld@e-(eRHL$r|F+S+2N{wf!VbYu7ut+#jD*Zf#t z@LL0Et@`LorpcW81?c)vOWOJcX#3QH_^Jy1V%vY%isgfn@4D4fpv#j1YQ*$w2AX#9 z0pcopf7R*O4#}}=J>G$_jPgF|0^`o zSmybpzP$Le`~FEi`LGpzy#@SyRnqzSHbM@pS^ch-1#?UQwDCir1#}wM2dG^S*ps&A zE5hl+%?$4g(K4{}(`xu(tLu8p$LIOV_u$VG1W*ed{d&Kj7nnUh&^p9h@Yrofil#|L zz!_ABr#axV?zR=qPIZm_SccULw-qpCuv5?MtfKUAhf;Q#FPcSJT6R*7^Q=eslixz> z=JEH^RP+=Z-hAt=pjfr$pFF(^z$TL; zWR;asPoW5CrrSX-O3qM@4PWhkyJnTV@3Ou-@|9}ur`p8aXol~r-CMDK2$js%c;=o1=SRoN57#a*0PrU?$KulO zaHI76n{fmcFGOlts_%k~{3$#i_EGtsR0e9uzsbd+=k8%_!^(yM`f4XN0=wu}HZFQdVD!Zh!d7Cvr2*Kwg!wm5IzViY$<_5T zvmB$91mvv^F0c(@-#;GSW@vB1E)9#7-{Umd^~lKPp5gD*IL4gk!|$V^QFSO}T0r87 z#jQDDdf*m{J4Kbm6=sof2`Qgo$g##iDIcYYN5@FiTA*5M%5dW(Ql6xNbWG-T#iTn& z8li3Mr3r`PIKg>UhmhI|a*Q=UM1m)oY*2_!06pwtkvuxby@vwVl_Hyk+Ahz*jpImK$snyoR>ckX-zAyi6edV<-cDVyxus4o1 ze1SB{;#u3L1}s=WA7=5uufO1oS=1K#2gIN@AB1R)!LfHw!R$ZXrsailImt|C4S`|N zm0VFHORHhM+M{DdYpG5OUbHTDLZUuQXYR#Z zD26EiM@qgs_5avix<8uXHtZZJZeFasG2&Bg9Awq zB}5v?00*cX82HHMxqUpCQ7Q-PP;-rC)l$N=KTerv@)1(EkwaWtAx`p~0X9>@7N^aL z6%$7Ma~m4L>J&(Ey^w=1b(c*oMaBvOIoZ5ObV;u8VcrOvWR?sk1PvyJa?BfVG8wqpa2Qa zJ6&!q>jLaon<%q?L}L$;UEu`i?}DDSQ5geHv(>-tT;nSHUMVg?9=>OFxi{9WXXFG= zFwoU+Q1_^Rk(2o9^ZmZf2pkG*l#em7Fw>+Fs&{{k``Yh0Z43KiWlp5cvX3Kd<|>X3 z3UQl3K2rLZrXb@T1ic2ylf4H$V5ahA?RE0>mmg(;T$eUzAK>V+^{7=n@pEY9?DPj`V_)$eJVeU`u(hnL8#D|YI`1}=eAb=H$F|~OT25LKXFJ1UV^IdHN0(WhWCR}EC<4c!(M4UinrBRP1m?_iDl|7@LXx1y= z$^5>buS`)LKaH{&p>%A1papLXR3~8nSdLTKa<-NWEH_Z<7lupeIZ5N$V_u4ixb&P| zswHLU{9T)j3V&YNuDDg;ISOJJ>{!l~vz2uWWWUl&?I&I3_|yDbu4O-(RiY&xP^m-q3UOBR46c}i(BzkTTqGvLnrJ?PS*c^4jW2?ozP zS41TYgW?z_oUw5$DeYNxsBnra+&{1IHhhu15T6zyo&}Z?r4TFv12!FehX4`R)uGq#)uM;Uz6 z_D?>@o`X)sdl^sRE?4u5a*D9xkpm_^!;+eZ_RdUbYsL_(_S7D+Hx0uyn+I3m2%nnE z6pLoeP&2lEx2Xm@?%ZSXnkOvueP}MyT@3%;{JEp~$M7Q>+u5cr&-7_g@btO9(__rV zLWRoEgNer~TNcxU-tfhIwWfLbObFY8W37jPGAE2x=InKOYJ_kdT-Th7I}|8~$Q9-1 z{q&`h9APl~$t9DHlJf+b*s1u3NFhp0!bJIsg)u{*FBU46E=NcUiX_?)R3aDPrNjXw zkRx0P`pwyoHxm98v~hRX92ZyN+6%0{q9>MpU2|I#XtIzHs~ANlCxO#{2SI_6z*B%4 zbC9&)v)dW>gkq`Xc)%^8ph-|)0>$6s;|Q%E8- zGpR}Lh*JX*Y0&|H2;w{g!r-o5iE?C+6e1lz1c^S=2@Dg@9spTk$PRKzZ}bsw+=2s6 z?(BjCcXdRrqCEim`dxv4y(3E&o)+n-BUYLwi%>W6;7J63?G><__A9^}GyjhCag%m2 z{?}%~)NMeT%KS@+k^pay+$WHJdS`ldPsg;2(LK9!bazj;UfmZ&(ce39#@{6CA941< zs*J(g>Lw@HcK~goD`4MO2qqat!YsihDQBk)-uo?V85i0lOEsYJ1t$tMA5z3i0UYgO zIGnC15I9L^lN#7woOebLqfmV&;BkUK0|DA8BlI#$w#j3|Gv8BayR#le_7QMfDb^cR zr3&o4-eM|0o#%+tya=*ry68c>!{zIP%^Q4VydGtw`_|;Wj;+0s1cJ}d;=Rk+`x$bn z(m0cypxKkMhtMO`r>DptUjD=2vfie0mjAmWT=e~^{O|Sw-+^s%{~qA>KUABXDDzFV z2q9ZCvuPZ3P!^JiTS-7Kc@EGAzX9SDVC9N=p?P?Hz?_#6)(6Y+U7|r-1HdHE{-C?# zu|nfqs^JBStlu@k)FjW_<>dJlKff=CxjuCujj9VqYjt4|Hka*g3X=(|!iXWFiistb z?b)!tjId5%d46vXN57=kmZw>IK1$4rV?Xc{EhUdzBq8k^5ru+!RoBo&&n0)?r+H zLPtX$+(45xp1etmY00TWs`p=B4w5=^PB@Cvz7?{gi2hNlXUF3fyGmOvqBarax+!v3 zGg-1pq6y9dXs)kl z|L%yTQ=w7=)R++o2TS=6vM$u2R8hN@tt2;Df z?6$U>Vspl-JWH9HR1COxutLR1L7B=^QsswCJ*JqM{Aif9e|Ol`yiH4Hdt|%{eAxEi zMQt5_Ji2}R=U*+7mbFT{Ygu*oo`#BT_3yuEWg53Yme*so)rJ|-|D4ZU7kMc2+MU#s z!kOikP48)+_vrAQ)H9Q^Cmj{K9y4(WFOw~~b?MeA(dvN zam(eKH8LuseEj>?iQAWJe%_wlcMp))vaeD`+xJtWztY5YG za>r$lgL}VTuygV74yXT1h;4LYWq#)B+x4D~xqi3gddIn279N@F@VsW}hl;g*Lw23) zUwKWy{5=X)rtMvqHiuuWK2kL$!L;q=_U*h|SV{28zocyNl?_+3yB|K^@RiNe6!*Qk zt2&>Xw%&imVe1n%H-;IHIBA(V=J4y?eupZx$$XLaUr9w+pGjBF9EskZH=x?-O?z7> z=fvkeJu~Cc^C=PiC%DYod1BYV^{0YAnvLk6}wyK#G&!W?MnB(dLn!Kf7fg5+mLTxy>yA0BdV3Mt=9W>t0ct;??Wx*0nfh%JGwo0 zZfC!+env=z%Oe&ZN#14NadOL2v0IznJ)Kvk@9U2BE%r}YV7`Awxw30#`?ttBTJN7R z7U_-RYCDz<9w9u`dTdOE{IZt4{I+HttuW87{HrB<61L^-b=eZ!8NEYWmGr|J2s zF@2n-Cr@m8t5>HB&0>?&nqTelVDXfnH)Cd-Pp(&D%crs>KGjWsaWHPq&A0o0beWym zQ;=<9Jzj3obzIHy!<__~!rZ0tiD^9tSNmSm#C@FW)8_Afj?a8o*F0UgZe~)P) z^W*V{z3x^1UfO5&hq}$bAMA1UzUoN-s79^QkKf;4*ViQ8MEKy@w#dvI$)8it+z>v9 zGwZ(a#N?p-UX^Up@1)jsu=pHla=6mR5q8N>JnkPqa%_cLjUm&L?hSRC=9B$!@T`XR zCcVzxl$cH3IknbaE1S3d|4J^?Io&2T&ZgGUN6Ed;ExmDTV1va@wJP2(H{tX4Zn8IJ z^GAhM>^m{^lp(xvY6zKgDR>nUZr3=XA^~m0>efI?e0Y*2WJ8 z#&vUAYgJ)HlJ;J$dKaZvI%D#C4>#s8f*^6AJU+5;qhfTgo<2DAc1*c7^9M95Yje-! zjd86_v6rSFOHjR;VBKolc+HzvyF3%%f*t zzndLwRHKboK-1^fPOM6Gy?o4mxaEgxryZ-GdN9HIcKG}1Gfrjuw#fWv#?hScj+LLL zRI(Yi>$~T{)t&qLJ*qCTTeZ}|{QIiXm%g=pQn~d*hv0Q>UVS(Dk#%6oaoh9-4Xe*; z|D@F4Gd=u%tUf*TV|_=9DPik#mYsg**0%lDt;dFnmriW|p;;{_r>rWj5e@fCD!V(B zp6k2LBd+hM&LdM6fA8SEVAYPpXVRutyO?mV|D1E7F$2fcx+q(8u7Szgkd^&Zr)`50 zCVeRRyk4^#<~j2=1ujd?2(NpyZqs3A()yi!as(fZ_UtS5_C?=nvWDMsAJ;C?%}%nZ z-=2n|>9bRkV^YRxtuoBZKb_R+H${u3JQRKY|5MRps+bJ_u`p^%4MlawfF&P)7>&C( zIO~4$)gJR^bX)eW?GNY~e z*ob#Y<89}(>a*$Zd0T}Zr#w2G`t8VIQrt&nRJhg-dcK0YEF4;j0}=}Ac66^(IKtVy z(~;Hi=98|%Nts5LS2{gCmX)9qO|$y_tKY5zQ_mhL(bw;4kCqGmlDk(Q{LL<{_6A$~z{KJCSN7fic(X!$$C$5E z=e)_ByH?S<{;`IFH_G`TDA7=%=*e)72(|zaA)rn)wOxjfJ6|!zdLWlf` zzF(Y8OIwuP9c!BwWzqWQNAp36_ojVu>fz@0A7J0p{TG5RxoHss zArAm%5xGJvkC6n56=?l5BM=ChX$>9=euWqLeFAU}#jRSRT&(a|`O{mzaJoijCqNK{X1(1am43nI3^UugEx2$gbRii^$Q510_T( z70X3YGC8eDZ8xZ?!4nX`u^fOBdSu!_bt$0T+(2@XmVveHRfj@*&w&;p3(~^U9@#H< zB_g(j@91b=OE&G%)S^Zc$buk}2Zl;wXh+f>3$3MPdXN;663QF6(QfELixSBVK&y`Q zz@#UQl;rrD-$PV;Y~*Ftf{SRqFAp>wr_hF^LufGzq+AxvIj|a{D3dB=T4`7t(S|~7g0l>CR8GVz9GiX<(&{3o4C>%XwNiuj zkZMyyTFwR$7%Gx0#M~9anu5Bn4@x^ZXd4n=m@m9Y09G?$5Kg~_Xz_ZogNS3qQf~1q zHN#QI-4rG$9sky@`?PcJXT^|{siV(bg0)W8; z@FS{%Pb!8`6^D7WEBZMZ!Zc*bB7mZ1DoAWk^&0jPnLU&wQIMA=BIUA3d^1HNR%nki zw}Hzeve4#$yA4G%5iexu(hL{Hi0lzE_J#g#4=1&EE%1F`xhzH!B$ofqLF^m-?1S6^ z9hDi1d>4wt7!P%I0@76$5h0QWc}b+=-bja%sCYZi@NjX6D7?2q6e8C8#F92y>hVS| zo+IT~Dx?ZZ$)JG{MVCr>4eI0}6Ep1L z9Ye8tE)Znlu3H33tbVE$1FT!Yl7Qx^xAq|IPl)qtVUU$ENc_C$QYn|U=0Gz*+m16rD)5r>@P@$7%kob!n zD`o&9vo9ejL2eR7q$nydlza;t%I2~pI{8{A+PH@o(qf&;4>E&Qnj`aqo*j>Q+ikmiK)(8g3 z!g-~?SR5uA7A|%Pmj#BoN+L1sWrlCH*6esw1jlZS8kwNzQYo|L?C`%$INc;6Vnvi6 z(zGmsnc|1jSL+j?sDSt*--ps%Dy2s(I|X{Nf^q9U+xcDVq(}4Z5T3XIKHdxUlqL|3 z=0V^m76ti8!{f=WA!Z5I#*C|&fni&~NxN!>kH0FV=TuGt^)#o4IKHPyih3pY!&KN; zBo{@9@zF8`Q`izm^%vC0ngxBGgA=(?Yy+nK0b4+Pq__pMe5ahxnx`Q&9-}ovN-Vlm z${w?d&&bSm?Zy7F6`{vO+$h6EmrCh9S3j4Zv(R4`mpFk%(xtR7C_Lp>6>Rd+0IQTL zq*I+TTo@?4I=)kl=tBedO=}s=V&ZBNuwlzB9b-q zq$t~|4=wwFDjw|-?Z^Xn@}uJ*AWF(GmbHlk!66XPIq&;5| zfY*29I>Fag!$@>DA$rQdgY@V;4D&`&V3c#gil-Y&S0LkDi0JFBgJqQ#fFA=<$TxB| zmrD8K1q*xutV^_lE3Xjj*$x$=Nbafye7aMSywQu@S0tBWk&h!ph<5Vqzg;~73Zfy* z_lqu-vQ<7O1-?WYC6{4pDrYL{1iJs8)}FHgOD166MZhF7T;B7AE;NCVoPOXg3Rj4I zWeQ0YmZ9~CWoKbDgOv9cDDR#WcjwQ=;r5nAxyz!ZL3(H%4wkG}6Y)vrULF*!*LMSH zNo&TF)n;D})jzP|O0f2&SaW{zWp$It)lME?T#W}#oU$bn8lMi0yHJA=lq{j!H;^zZ zh=bo8$q);>HXrtFKZH(((0&x(xl+9OpyT4oo1NXQ`DE~?Lgwxi|2Gr9{C>d-gFV}A z*2R5)VU}!-kZMBlJ}bkMm%03J_%=6i76dvB|D_X|Qv;sBto?oYPR6%>!caqy3TWpr zYs4G-m!se9E_f`-HPQ(69DcieXYk^L0&J<$| z0+33xB5#Q4ULfv*1JFg%y&G?2=7m;L3T!WB&kTWI)kBeNL=D`>gA<;;_7d0*lg8g& z3%GZ<=}~|0&J8PvZRLK2E5vLCOi|JL$qk|qcv4Sl)Ngwj0$;emROm}?YHmG+WM=k~ z;r8glrlJcYE7Y1xrF8N(fLhm$h_QQjd+=~R5O3h7rxFV{xXDB1fh zS+38+O}D=@g7jni<4LF}!Zlo`5OcK(#0bV~gzqvz@&L}&m{L*IU~VGzH9ry)|9QW7 zw-R`danlW5ReWlmBS(;i!#`dTC5~XyJAv-lDDz4*EV>IrcBY10QoN$I(~VEtu{bhBqh&Cp8?uA&`okJcGXsY^lXQ}wa? z%1Pm{w~!j?h1rmFP6|(HWONjd#f^IB>IX!F;4=v5^`H9N_z~z|;UI#POT2Vk2A(_M zp}U>@?VLOXOL9CUIaBq3x+MT|Fhy9V+n+$LAIo=K^dGZX4X1OQr08jRh=D9EjS@Qnl+e zn7g?I0%R5*^x(N((WO#0z0QostVS}nCjAo3KSRg>n2635k}@S3qk>@R$#z78T_3+R z!Ge$=9J!)i(GZCSH2Z~(iO{_??kwLLm|#tXHt5_X zZNh=d4CdN#T=R3#>`81o#f+-xQYnwRFoSgqmkkqzYqBi0f~HGBGWnqEdoFH+2G*lf zr8~UGzJ^nC$UfDG{!$m^^qQG=sU9IV^ix4fZv1{(HT4+%gIcwomwBiHI2FhCmH;trF6tf z4E#E7IzC@Ym~p%N3tI~di#J;%dN9qq?h6U<1WMy<8-XVg@DdP^0^rJ8J>@5jQqS z7hNjl%!PVDNpoB@WTu!W`0KlU|1%^{I0ggQ`D* zsU1b-wA3IfA{aZ3_4${J=744pXy^{9(F%iTigd>uOB-wY-)aF4YjhlRKVz0^2oE#* ziZeFr$rg;kxaqo=yv`tW=0<>+e%`6OZHE9p5VsR<&81SdS#Jo%5WFeG%tB)KS=ncc zNvNH~O~>vt7M6m^4ePY&`pZ6NkE4i?4fyoLHfsa(u!{hR4A zy0C>C)+IVPm<@GfuYK8RDE+74B-R=QLFL}%jOI{e&B=$n97i_g) zv-q{9yQ}&@M{Ur-z!pW9N-29%Tq;j#AYSyvRv{G2!WRSmqa!2ni9MlQ&bI6qvOU%# z5w6z@S;D($7$or8zAWxQ3g!~UzWY*KB6jcG-~CA5Xt>ZuBn*0bkcM?@rsh%OooY8K@YDkL(G`dI zY2_wEV#(vN7}$;Ob)vrWCQ!H8%=nS9$DU)qwIBu@bOYk>(=dF_`Q#L*(LaZRf>aV( zj3ELey?RnlwhLoTR}5nHsWzzxoq&(|qt@H6l}Z|huV-bN*yPOBp=Z;fGu?NVR7U#A zdPavwNg~6=apE9qBEgnE_NuH*M?r1>AbNZ$hu-$rAF%P5dJ$Pu5+>Uqn+uXn1OgIP znhQIuO8)_SfH*?^sX4qXt#^}U-EF%k4MhIjhUN7D4L|;>lyA%Z9}FR$d;Uq3pq$h0 zp)uxJ+pV=<;`+C8@kgNR$?AZ2Ilh9N#FMC#QLO9e=b}7{nIL}b?kOZxqF~jolsZ3H z8A!k*R-XSnYfhf_-ax}gKf#+}t)ES^ahX|?(KincngL137ij5O&F*^ou>&y4R7g-i zIal#Wa@ka=SDmAnYR`rPwxTq)qyaY%IV&bWBzM7^#133pzV73(9uvS|SxI|=V|z1R z3|!#N(<16NMEo>H0-;TybmRrjQ9d3y4zt+`6PUonZj@@?x8;T14XP<@pSs~|sQP13 zDEGbd5^USyP;|vLX>TASvsVp0d1PlAMEQc7-lpZ=nHRzD)ru{tcUe*D!6>+GIE>zn z(wj>c!%0XsCCf#6p43;kcWpr;(pZ+xqZk|PedKCZ3jO$Z$(WTl`O3Y#b&%&fZhB7e z)rS`amB84v_iuEcgXGYsmGA)%N_(HNR?9;WnuTX6lpQ!R+Y+qFXrH|()^7pDVAYgB z9`&b-^D*0&h~6t`p4(8&qx%`otZO-v_h(oLFBo8LnP%$RfLES}iE@_^f zn)^C~k>g^herXChe1d|xINSy2vN1st_`&HqQyR++tkj#wtlXIwtnq~#12TB6w_3}fL=M}%v11QqrFdN~@u_Pbpi5y#p1qtI|7xHd4-IBB&#|xaLB_TF%yGs$|2o;5*Z)8c=kGrD@$vnW&$FBjSnT+q8%c$_4mEoy;{7a{_&e2e=+rB|2L1 z_wC&G;4p;%bh2MJRX+#Mbh5>>!C&SeIRPWn>E!JUekAIr4ID{}s4KB|MEF#&e1^H{ zC!K%K($AtdTRFV69z7VIx*8Pp6OC4Lc*1k|YWNHv&%Hp$bVbV!cjod$=k``&>>#s# zB5V^Bh@m0c4zK3(B+=ti#174pOXQZpBEe~$XSB5!@?zmid*Azp=a4BzD-h86La~Au zIEM{V&UTq}9@u_pu;_eoER`3wehVZ7*a_An73p@xPuKFIp!Cnw6%#w3^tD_>4s9?& z;-I_YCuzlCag_%;IusDIZGI%IzQOYbV_qbLL6&x~z6D z-f2rQSb6s1g!ydhqUfa+vC?RxUFBzH7|yKQNf3_SK3^=ztok&p=|YvTF^BbYs88L| zH00_8N468Ng%^q4QGb8ix*T592Xb|#_-1Aq&d0?@q|2z(cl1q2N4C|_(oMy#AbkZ+ zEgd;rL@JX6@scjMM!aM!xUR!PY3YuhHk?nNbQ`K%_{*xKK(GdkbbGt%98WfXQLvbo zWD_@qnR$cfEXp|D4c5A77?(b&*8V-LT4UJkKisqqv##)D>Md39m8-mK+3$V8R1bQj zb?9}?P&O{fi0_Au89#xviY4G3^plAn*O|G<$;g`U(zHU%`{RkXPhR&Ubpx`L8RqUZ z{;oWB{DSA_;vjB(GX8`i?^4Ja^o=ooy8qewgdHEx45dE3F>8xCwqIJR%5{5;6&&>oZhF_@zVGZD`p3TVzWst@(D-@0s6h85Hb42{ zs+$tFx=qxRvizQzGlpFq2B4MSq10cDS(x~}za#>WuDAstUf(L};bXj|A&7+Q&;pz^ zW=1bKM431Xj;0+ZbCJcl$YrrOd6%u-Ir7kGP$fA1VXT?c3&9P`7)Zffg+qo5`;wDi zYCr~BLsP2gBPe*my^lm3%QpN|TQ)x&g1k_@x^`gAG2@TUJo4)m-X{)4tK6ir_P(7? zcw?5S!v4}e88b8L=9nZivSTF2=|t~@k7UWST#1>Vw#Qp$(6ycn2at=4z!_W^dC zjfRTe4Y8>w7p(fj1VrCNE3V>j6jmv=!mug6rmbHiyh$TKplj*pvoCL&p4e;?&Srt# z(*tS_LG({*pxt%E_#4K+tSE=CeiK&0*`J|6(OpNqAZC2^q4Zuta^8ymNoD?zhUUa8 z-H?85Df5~S=YaPWMTIhtx9eG9mvj`1Na)0l0&E$k2asXAG^udY=cT;=1Pu&>1{zX` zHc=di{@55PiSrk;99n5J+GEC5L{3|bm0m+0I+6=DUK$uG$5HAd#X)*2|Kyy;_Kx6K zr?dDseJoE7ZVQqWP`btXo|j;~gCL?6ZZ?5~giOR46iyKPB$km)g<6)OpQAg`MhOgv z#>E*&SU`W7CW&+Hxtx_It>4*;jzV+I?xSfLlT$BmCwRsj-QoV2#ow@+e$ z1!m!i#%!Tou7uA`GIbsc^L3>hukLIfpz1RxoTZpqM95;qdPS&o|MRfpV8L-_T8oEg z=IUqr4ZiS$1I+qg-{N#P3955Dylz;JlIhtzy)4X--_4A6RKuVTBUv!H9Tl=&N?}Lfa?$^!g6_G{RpxPa1~hS zO~Xgm@?h~K2e`ZO}cMqJRC&ipd$Lgz>IY~i1-~B-=Y8b=>m|DGlJ?<*6y)^ zlSKXD3te-Qbo}ng{Rddh5gb9wK~J-1ZDheLvb8ghQ2sD*-1yBHZxe9P9qPt(efaug z`r7dh?WSO^TE|j5x2@gAA6-{7#COgPj=Q`TTF%E!m+F!GcwlQ1CtEsdv8-$|*-BOo z>4=Uq*?vRdivo^Wib&^K*@EXe5O4yOW$CD_s6G< z#6iD>B{TA}0Zs#&0`(DYy5s9|lLfiAG)#)4O##iZ7mn16%PIK>v9(f=2)}Wq^2zR7 zEZBwLLnAL<(lH^tYak({E9?=O^|o{1wQ;*4Q&s5A zg_7+kPJv|fCN|lAvr%tPwi3`Vz~jphaFN>RP4V6Q?~nL+#DA^vf-B8X^G{-8*OlT< zd-NyVx|$_kllXQ`ZJaYGXaz}y6r01VKVpky{dSm1c-_`Gyh`vElpYji={J8u$-QKD zXRogjPM{FfL0O^~R~zK>V?{!hMa%I8T4qgdKEFP^H0(A2`%&pyboxCvLBUdGLC}!} zZfQtVsILeQGnk3Sj?Hsh3cdXW9d@Pk*X(<7iP)_*>g$$jB=m6FuvS`W@S~V)+=l8G z^W^qrkYUwJE3I_FLD*ceUZ_XvBPwb=vW0oZ+mJ@&kPPxe@uoH)})0kZudqvdL7Tx>FCxdtc|FGqt4Eu_|QnIG`w z)8bjnHChoRi_p8+TXFXNk(=?T>lbHlGjt0eH+^!lb{8cGe)G8($d%zL#Tq_QJ_Y(wUaf@!)qp>MdzX@GL3Q3@= z9H&%~#TR$6IB1xN^&qAPZ9VhBlZ%L>JI`}S%sjc+DTp|+%>*q;_qGN!bVakY=1oyJ z^WZ5}*7$|}$#XTb(C$o`EZD|S%HLGT7T)`|JnN5F)dVJJyy#q_wEF`(UFRo>tKK{1 zh0l*K}pE^^1N;&)kgr`ABZvpArh&Q2LCgLgUTP9w4$>=Ey z8}nu=?9X|6N^HlJX-_~o6~fV`dxH5gPyhclCE(WN`3E~Dk#~M{P1n4cp=5d$N=!Gg zVaxRkL70o1UOAa&&xeqw5+8he9)Tk#1?5n4=oQNN<_6JlHU}5%q*Kp>g`7K0v#f1d z3>KEYVB>6eDKkrsV=-79nS*#yLgu|PNKQ(~La+V2Yh4VMR&1Fm#OXpfSvs4A#)H;b zZ>Qq$FiT@G$;dd^9MWKNPCrtz>R>pFE(ggC@sk7BSAq5af;4nDf8D1T9PH(OZ2hAN zz97QkI9k=$wU^;U?3JFxXN%Y;)3XqpWx+=;`M&bw!^NF$PL1=n`+~Bx7n2}5x0S$A zs`_)AN3=W~&nfy!@O98w4HcWG%`ttxaS*(DAD*AlEpESl#U|5r1){auVf}HetlAU;%uy#%ieI@o>N-}Aw91vmY)!elTXE?y+HMyrYp5Tt;EC3n6)^YAP)NBcm7Iao61@ntmv-$4!`ru=ztU9ShmcVANbHWxLUQn0yUe zP~FyS`)llS7FZ#t(KYAWc!TKBV{ecNI|S|JfUK)VDEw6^8{+L!{h7K*E)e10 z)ekY*7gP5JZjXEcHaxY|V(T{f57=0e!o~orlFV##rv3pNOM1v(ckjQEkPWX(Yb_Mt zn*IlDE;6jgi=^yF?UK55s!>;#!e8w0o3IAJ_*TG8VThLFt}Cv5F68uV_)2P6MN> zPeQf3>SY00!`1C6j->LTDx3oHD)*Vsy_=CTsrwT2zSVrV`iezi2y~9ePeh{F$1A+P zf(5TgX|3$sS;LD(-S(-E2W9K|N>1*RIt~>w3;RatC4BpJ22$u+h2;CPSxL_=(Y-b+ zuiYR2*vvp6#b*Ko@!$`iylL*~(zBIg+rop(n9+M|=$1|1ttADXUi%uh(;#%_s3At^ zk|Hhf4t)e!_@&#&2l^;{0;9y5gV*fb#2g2oNouYO7sASIu>3@mG{aXdbVBoYEm0(# zr>prIy}0rZNHSp#qBPB=QXYqJyh(H|LDZDjv32eJ0KWrpy4|{PP!Bjc;R{l zgi+Ixari%0Tycz88r57qUgsbYw#~_z!DYq^O5qSnfe;CVej}p$BR=3l!ov(bz)J4C z5Ak4zvD1qWqo4AD=JpgPyS^Sx;gqjoM;lGDz+aVe(lZ8h_1C%lJzk%ZaImu~)3hrA=T6r6N+xclA!&H@#3Q<>h3 z?Y{*PR-vl)ZkkP>`BO2AQFqnBhi_q_DG-I;1GLu2ShxPD{i(Z5B8}2}_}{67X2P|M zo^`Jj8}e^wlDZarP>;>CMAzyDkQYsHxUW`|amCmGbPriL>%pgEcT4Ag1Vv4R8oh~W zTxtFk%xb?_Z$>T&yN9^x{ByW04{R@)G=xnv1FgKf`D57Rm=k(G?Y44!p}Eu&vaEMo zvNhWu9@7NF*IX)PKn0%ox;i1}1q<)&97A@lEP%f0caMftVgr_oL&R~-e{-9jqNu=7 zwygi`XO(|fW4!<2rY%|u=c(v4TWV(?i8FE3Pk!-UH+fXgruGYmas$YVWF0YjXN^wq zSEYQ%AKN)FQ0?~mUj;duIY;FQ3)De#N-sh$wBRjD;Xzh<-#eN6pYpXSD&h_(Yea{OsJk zm<&Gh-Wy${lI!y3(@#@-b>3Zk{7XPuO1enNYzGOQDTc@b#OY7t9CV6fsc{$Go5a7Abm=^&lMixlyyO0xFPL= z>0W%0e}C`E4xx-M0;*NW%r;=f)lu=Nwo+sXIu&L67|N#0K&If9^S?bbhbLhEqLqr~ zg>W&r`nftf=vksrzP{88U-A}=gTCnXgLlKZu + *
    + * As the address expression is usually produced by disassembler, this evaluator + * implementation should stay in sync with corresponding disassembler + * implementation. + */ +public interface IAddressExpressionEvaluator { + + /** + * Evaluate a expression synchronously.
    + *
    + * This method should be called only when control is at the instruction. As + * DSF services will be called, this method should also be called in DSF + * dispatch thread. + * + * @param context + * Execution DMC. + * @param expression + * the address expression from a control-change instruction. This + * expression is usually produced by disassembler. + * @param regService + * EDC version of DSF IRegisters service for register access. + * @param memService + * EDC version of DSF IMemory service for memory access. + * @return address computed. + * @throws CoreException + * on any error. + */ + IAddress evaluate(IExecutionDMContext context, String expression, IRegisters regService, IMemory memService) + throws CoreException; +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IEDCConstants.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IEDCConstants.java new file mode 100644 index 0000000..c4a0709 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IEDCConstants.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc; + +public interface IEDCConstants { + + /** + * This is the TCF peer attribute used to differentiate between available + * TCF peers distributed with stock CDT (e.g., windows, linux-x86). + */ + final static String PEER_ATTR_DEBUG_SUPPORT = "DebugSupport"; +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IJumpToAddress.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IJumpToAddress.java new file mode 100644 index 0000000..1d3b4b9 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IJumpToAddress.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc; + +public interface IJumpToAddress { + + /** + * Whether this address is the sole destination address after executing the + * current instruction. E.g. it's true for unconditional jump and subroutine + * call, but false for condition jump. + * + * @return + */ + public boolean isSoleDestination(); + + /** + * Whether the jump-to address is a subroutine address (namely whether the + * current instruction is a subroutine call instruction. + * + * @return + */ + public boolean isSubroutineAddress(); + + /** + * Is the address an immediate value (no calculation is needed) ? + * + * @return + */ + public boolean isImmediate(); + + /** + * Get the address. + * + * @return IAddress object for immediate address, or an expression string + * indicating how to calculate the actual address. + */ + public Object getValue(); + +} \ No newline at end of file diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IStreamBuffer.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IStreamBuffer.java new file mode 100644 index 0000000..b2ffc2f --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/IStreamBuffer.java @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +package org.eclipse.cdt.debug.edc; + +import java.nio.Buffer; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; + +/** + * This is an subset of the ByteBuffer interface used for read-only + * scanning of a buffer. Its implementation is optimized for streaming access + * (i.e. not random access) and for making cheap sub-buffers. + */ +public interface IStreamBuffer { + /** + * @see ByteBuffer#capacity() + */ + public long capacity(); + + /** + * @see ByteBuffer#hasRemaining() + */ + public boolean hasRemaining(); + + /** + * @see Buffer#remaining() + */ + public long remaining(); + + /** + * @see Buffer#position() + */ + public long position(); + + /** + * @see Buffer#position(int) + */ + public IStreamBuffer position(long newPosition); + + /** + * Skip ahead in the buffer. + * + * @param amount the number of bytes to skip ahead + * @return this buffer + * @since 2.0 + */ + public IStreamBuffer skip(long amount); + + /** + * @see ByteBuffer#get() + * @throws BufferUnderflowException + */ + public abstract byte get(); + + /** + * @see ByteBuffer#get(byte[], int, int) + * @throws BufferUnderflowException + */ + public IStreamBuffer get(byte[] dst, int offset, int length); + + /** + * @see ByteBuffer#get(byte[]) + * @throws BufferUnderflowException + */ + public IStreamBuffer get(byte[] dst); + + /** + * @see ByteBuffer#getChar() + * @throws BufferUnderflowException + */ + public abstract char getChar(); + + /** + * @see ByteBuffer#getShort() + * @throws BufferUnderflowException + */ + public abstract short getShort(); + + + /** + * @see ByteBuffer#getInt() + * @throws BufferUnderflowException + */ + public abstract int getInt(); + + /** + * @see ByteBuffer#getLong() + * @throws BufferUnderflowException + */ + public abstract long getLong(); + + /** + * Wrap a portion of the buffer. This is a cheap operation whose + * returned buffer maintains references to the receiver but has an + * independent position. + * @param size the size to wrap, starting from the current {@link #position()} + */ + IStreamBuffer wrapSubsection(long size); + + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFAgentLauncher.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFAgentLauncher.java new file mode 100644 index 0000000..0c18669 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFAgentLauncher.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc; + +import java.util.List; +import java.util.Map; + +import org.eclipse.tm.tcf.protocol.IPeer; + +/** + * An implementation of this interface is provided by a tcgAgentLauncher + * extension. It's a way to advertise a TCF agent that may not yet be running + * and to provide a means to programatically launch it (or at least put up some + * GUI that informs the user how to manually launch it, in the case of an agent + * hosted remotely). Agents can advertise themselves once they are running via + * TCF UDP Discovery, but we need a way for a debugger to discover and launch + * agents that are not yet running. This interface assumes the agent hosts a + * single peer. An agent that hosts multiple peers can be described using + * multiple launchers with common launch logic. + */ +public interface ITCFAgentLauncher { + + /** + * Gets the user friendly name of the peer this agent hosts. Same as calling + * getAttributes().get(IPeer#ATTR_NAME) + * + * @return the name of the peer + */ + String getPeerName(); + + /** + * Get the names of the services the peer implements. + * + * @return list of service names, may be empty + */ + List getServiceNames(); + + /** + * Get the attributes of the peer this agent hosts. + * + * @return the peer's attributes; at least the {@link IPeer#ATTR_NAME} will + * be present + */ + Map getPeerAttributes(); + + /** + * Tell whether the agent can be launched. This is mainly used to + * avoid considering the launcher for situations where it will never + * work (e.g., wrong OS host). {@link #launch()} can, of course, + * fail for other reasons. + * @return true if launching is possible. + */ + boolean isLaunchable(); + + /** + * Launches the agent, if it's not already running + * + * @throws Exception + * on any error. + */ + void launch() throws Exception; + + + /** + * Shuts down the agent if it was launched + * + * @throws Exception + * on any error + */ + void shutdown() throws Exception; + +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFConnectionListener.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFConnectionListener.java new file mode 100644 index 0000000..3747971 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFConnectionListener.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc; + +import org.eclipse.tm.tcf.protocol.IChannel; +import org.eclipse.tm.tcf.protocol.IPeer; + +/** + * This listener on {@link ITCFServiceManager} allows a client to track the + * state of peers and channels managed by EDC. + * @since 2.0 + */ +public interface ITCFConnectionListener { + + /** + * Called when ITCFServiceManager opens a channel on a peer. + * This is called on the TCF dispatch thread. + * */ + void peerChannelOpened(IPeer peer, IChannel channel); + + /** + * Called when a channel was closed for a peer. + * This is called on the TCF dispatch thread. + */ + void peerChannelClosed(IPeer peer, IChannel channel, Throwable error); +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFServiceManager.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFServiceManager.java new file mode 100644 index 0000000..1bde259 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/ITCFServiceManager.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2009 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.tm.tcf.protocol.IChannel; +import org.eclipse.tm.tcf.protocol.IPeer; + +/** + * This interface provides access to TCF services. It abstracts out the details + * of which agent provides the services, launching the agent if necessary, etc. + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ITCFServiceManager { + + /** + * Gets the channel used to talk to a peer. If no channel is open yet it + * will return null. + * + * @param peer + * the peer + * @return the channel used to communicate to the specified peer + */ + + public IChannel getChannelForPeer(IPeer peer); + + /** + * Find an open channel or create a new one and return it. This blocks, + * and should not be called from the TCF dispatch thread. + * @param peer the peer + * @return the channel used to communicate to the specified peer, in open state + * @since 2.0 + */ + public IChannel findOrCreateChannelForPeer(IPeer peer) throws CoreException; + + /** + * Add a listener. Duplicate listeners are ignored. + * @param listener + * @since 2.0 + */ + public void addConnectionListener(ITCFConnectionListener listener); + /** + * Remove a listener. Nonexistent listeners are ignored. + * @param listener + * @since 2.0 + */ + public void removeConnectionListener(ITCFConnectionListener listener); +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/JumpToAddress.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/JumpToAddress.java new file mode 100644 index 0000000..0fe6766 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/JumpToAddress.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.edc; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.utils.Addr64; + +/** + * Representing the address to which control-change instruction (e.g. a jump + * instruction or subroutine call instruction) may jump to.
    + * Contrast to: the address of the instruction right after this instruction in + * memory.
    + *
    + * Object of such class is supposed to be produced by disassembler and consumed + * by debugger for tasks such as stepping and stack crawling.
    + *
    + * For some jump or call instructions, the jump-to-address is an absolute + * immediate address encoded in the instruction, while for some instructions it + * is an indirect address whose value has to be computed by reading certain + * registers or memory when control is at the instruction. The computation + * detail is target processor dependent. + */ +public class JumpToAddress implements IJumpToAddress { + public static final String EXPRESSION_RETURN_NEAR = "ret-near"; + public static final String EXPRESSION_RETURN_FAR = "ret-far"; + /** + * @since 2.0 + */ + public static final String EXPRESSION_LR = "lr"; + + private final IAddress address; + private final String expression; + private final boolean isSoleDestination; + private final boolean isSubroutineAddress; + + public JumpToAddress(IAddress address, boolean isSoleDestination, boolean isSubroutineAddress) { + this.address = address; + this.expression = null; + this.isSoleDestination = isSoleDestination; + this.isSubroutineAddress = isSubroutineAddress; + } + + public JumpToAddress(long address, boolean isSoleDestination, boolean isSubroutineAddress) { + this(new Addr64(Long.toString(address)), isSoleDestination, isSubroutineAddress); + } + + public JumpToAddress(String expression, boolean isSoleDestination, boolean isSubroutineAddress) { + this.address = null; + this.expression = expression; + this.isSoleDestination = isSoleDestination; + this.isSubroutineAddress = isSubroutineAddress; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IJumpToAddress#isSoleDestination() + */ + public boolean isSoleDestination() { + return isSoleDestination; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IJumpToAddress#isSubroutineAddress() + */ + public boolean isSubroutineAddress() { + return isSubroutineAddress; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IJumpToAddress#isImmediate() + */ + public boolean isImmediate() { + return address != null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.edc.internal.IJumpToAddress#getValue() + */ + public Object getValue() { + if (address != null) + return address; + else { + assert expression != null; + return expression; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((address == null) ? 0 : address.hashCode()); + result = prime * result + ((expression == null) ? 0 : expression.hashCode()); + result = prime * result + (isSoleDestination ? 1231 : 1237); + result = prime * result + (isSubroutineAddress ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + JumpToAddress other = (JumpToAddress) obj; + if (address == null) { + if (other.address != null) + return false; + } else if (!address.equals(other.address)) + return false; + if (expression == null) { + if (other.expression != null) + return false; + } else if (!expression.equals(other.expression)) + return false; + if (isSoleDestination != other.isSoleDestination) + return false; + if (isSubroutineAddress != other.isSubroutineAddress) + return false; + return true; + } + + @Override + public String toString() { + return "JumpToAddress [address=" + + ((address != null) ? address.toHexAddressString() : "null") + + ", expression=" + expression + + ", isSoleDestination=" + isSoleDestination + + ", isSubroutineAddress=" + isSubroutineAddress + "]"; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/MemoryUtils.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/MemoryUtils.java new file mode 100644 index 0000000..28ee2e5 --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/MemoryUtils.java @@ -0,0 +1,710 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.edc.internal.EDCDebugger; +import org.eclipse.cdt.debug.edc.internal.symbols.IBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType; +import org.eclipse.cdt.debug.edc.internal.symbols.IPointerType; +import org.eclipse.cdt.debug.edc.symbols.IEnumerator; +import org.eclipse.cdt.debug.edc.symbols.IType; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.model.MemoryByte; + +public class MemoryUtils { + + public static final int LITTLE_ENDIAN = 0; + public static final int BIG_ENDIAN = 1; + public static final int ENDIANESS_UNKNOWN = 2; + + /** + * Pad byte array with 0's or 1's when the byte array's length is shorter + * than what's expected by the conversion functions. + * + * @param array + * @param size + * @param endianess + * @param isSigned + * @return an array of bytes + */ + protected static byte[] fillArray(byte[] array, int size, int endianess, boolean isSigned) { + + byte[] temp = new byte[size]; + + // either 0 fill or sign extend + byte fillByte = 0; + if (isSigned && ((array[array.length - 1] & 0x80) != 0)) + fillByte = (byte) 0xff; + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + + for (int i = 0; i < array.length; i++) { + temp[i] = array[i]; + } + + // fill up the rest of the array + for (int i = array.length; i < size; i++) { + temp[i] = fillByte; + } + + array = temp; + return array; + } + + for (int i = 0; i < size - array.length; i++) { + temp[i] = fillByte; + } + + int j = 0; + // fill up the rest of the array + for (int i = size - array.length; i < size; i++) { + temp[i] = array[j]; + j++; + } + + array = temp; + return array; + } + + /** + * Convert byte array to unsigned long. + * + * @param data + * @param endianess + * @return result of the conversion in long + */ + static public BigInteger convertByteArrayToUnsignedLong(MemoryByte[] data, int endianess) { + byte[] array = new byte[data.length]; + for (int i = 0; i < array.length; i++) { + array[i] = data[i].getValue(); + } + + if (array.length < 8) { + array = fillArray(array, 8, endianess, false); + } + + BigInteger value = new BigInteger("0"); //$NON-NLS-1$ + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int i = 0; i < 8; i++) { + byte[] temp = new byte[1]; + temp[0] = array[i]; + BigInteger b = new BigInteger(temp); + b = b.and(new BigInteger("ff", 16)); //$NON-NLS-1$ + b = b.shiftLeft(i * 8); + value = value.or(b); + } + } else { + for (int i = 0; i < 8; i++) { + byte[] temp = new byte[1]; + temp[0] = array[i]; + BigInteger b = new BigInteger(temp); + b = b.and(new BigInteger("ff", 16)); //$NON-NLS-1$ + b = b.shiftLeft((7 - i) * 8); + value = value.or(b); + } + } + return value; + } + + /** + * Convert byte array to signed long. + * + * @param data + * @param endianess + * @return result of the conversion in long + */ + static public long convertByteArrayToLong(MemoryByte[] data, int endianess) { + byte[] array = new byte[data.length]; + for (int i = 0; i < array.length; i++) { + array[i] = data[i].getValue(); + } + + if (array.length < 8) { + array = fillArray(array, 8, endianess, true); + } + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + long value = 0; + for (int i = 0; i < 8; i++) { + long b = array[i]; + b &= 0xff; + value |= (b << (i * 8)); + } + return value; + } + long value = 0; + for (int i = 0; i < 8; i++) { + long b = array[i]; + b &= 0xff; + value |= (b << ((7 - i) * 8)); + } + + return value; + } + + static public BigInteger convertByteArrayToSignedBigInt(byte[] array, int endianess) { + if (array.length < 16) { + array = fillArray(array, 16, endianess, false); + } + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + // reverse bytes + byte[] holder = new byte[16]; + int j = 15; + for (int i = 0; i < 16; i++, j--) { + holder[i] = array[j]; + } + + // create BigInteger + BigInteger value = new BigInteger(holder); + return value; + } + BigInteger value = new BigInteger(array); + return value; + } + + static public BigInteger convertByteArrayToSignedBigInt(byte[] array, int endianess, int arraySize) { + if (array.length < arraySize) { + array = fillArray(array, arraySize, endianess, true); + } + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + // reverse bytes + byte[] holder = new byte[arraySize]; + int j = arraySize - 1; + for (int i = 0; i < arraySize; i++, j--) { + holder[i] = array[j]; + } + + // create BigInteger + BigInteger value = new BigInteger(holder); + return value; + } + BigInteger value = new BigInteger(array); + return value; + } + + static public BigInteger convertByteArrayToUnsignedBigInt(byte[] array, int endianess) { + if (array.length < 16) { + array = fillArray(array, 16, endianess, false); + } + + BigInteger value = new BigInteger("0"); //$NON-NLS-1$ + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int i = 0; i < 16; i++) { + byte[] temp = new byte[1]; + temp[0] = array[i]; + BigInteger b = new BigInteger(temp); + b = b.and(new BigInteger("ff", 16)); //$NON-NLS-1$ + b = b.shiftLeft(i * 8); + value = value.or(b); + } + } else { + for (int i = 0; i < 16; i++) { + byte[] temp = new byte[1]; + temp[0] = array[i]; + BigInteger b = new BigInteger(temp); + b = b.and(new BigInteger("ff", 16)); //$NON-NLS-1$ + b = b.shiftLeft((15 - i) * 8); + value = value.or(b); + } + } + return value; + } + + static public BigInteger convertByteArrayToUnsignedBigInt(byte[] array, int endianess, int arraySize) { + if (array.length < arraySize) { + array = fillArray(array, arraySize, endianess, false); + } + + BigInteger value = new BigInteger("0"); //$NON-NLS-1$ + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int i = 0; i < arraySize; i++) { + byte[] temp = new byte[1]; + temp[0] = array[i]; + BigInteger b = new BigInteger(temp); + b = b.and(new BigInteger("ff", 16)); //$NON-NLS-1$ + b = b.shiftLeft(i * 8); + value = value.or(b); + } + } else { + for (int i = 0; i < arraySize; i++) { + byte[] temp = new byte[1]; + temp[0] = array[i]; + BigInteger b = new BigInteger(temp); + b = b.and(new BigInteger("ff", 16)); //$NON-NLS-1$ + b = b.shiftLeft((arraySize - 1 - i) * 8); + value = value.or(b); + } + } + return value; + } + + /** + * Convert byte array to integer. + * + * @param array + * @param endianess + * @return result of the conversion in int + */ + static public int convertByteArrayToInt(MemoryByte[] data, int endianess) { + byte[] array = new byte[data.length]; + for (int i = 0; i < array.length; i++) { + array[i] = data[i].getValue(); + } + + if (array.length < 4) { + array = fillArray(array, 4, endianess, true); + } + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + int value = 0; + for (int i = 0; i < 4; i++) { + int b = array[i]; + b &= 0xff; + value |= (b << (i * 8)); + } + return value; + } + int value = 0; + for (int i = 0; i < 4; i++) { + int b = array[i]; + b &= 0xff; + value |= (b << ((3 - i) * 8)); + } + + return value; + } + + /** + * Convert byte array to short. + * + * @param array + * @param endianess + * @return result of teh conversion in short + */ + static public short convertByteArrayToShort(MemoryByte[] data, int endianess) { + byte[] array = new byte[data.length]; + for (int i = 0; i < array.length; i++) { + array[i] = data[i].getValue(); + } + if (array.length < 2) { + array = fillArray(array, 2, endianess, true); + } + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + short value = 0; + for (int i = 0; i < 2; i++) { + short b = array[i]; + b &= 0xff; + value |= (b << (i * 8)); + } + return value; + } + short value = 0; + for (int i = 0; i < 2; i++) { + short b = array[i]; + b &= 0xff; + value |= (b << ((1 - i) * 8)); + } + return value; + } + + /** + * Convert big integer to byte array. + * + * @param i + * @param endianess + * @return result of the conversion in raw byte array + */ + static public byte[] convertBigIntegerToByteArray(BigInteger i, int endianess) { + byte buf[] = new byte[16]; + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int j = 0; j < 16; j++) { + BigInteger x = i.shiftRight(j * 8); + buf[j] = x.byteValue(); + } + return buf; + } + for (int j = 15; j >= 0; j--) { + BigInteger x = i.shiftRight((15 - j) * 8); + buf[j] = x.byteValue(); + } + return buf; + } + + static public byte[] convertSignedBigIntToByteArray(BigInteger i, int endianess, int arraySize) { + byte buf[] = new byte[arraySize]; + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int j = 0; j < arraySize; j++) { + BigInteger x = i.shiftRight(j * 8); + buf[j] = x.byteValue(); + } + return buf; + } + for (int j = arraySize - 1; j >= 0; j--) { + BigInteger x = i.shiftRight((arraySize - 1 - j) * 8); + buf[j] = x.byteValue(); + } + return buf; + } + + /** + * Convert big integer to byte array. + * + * @param i + * @param endianess + * @return result of the conversion in raw byte array + */ + static public byte[] convertUnsignedBigIntegerToByteArray(BigInteger i, int endianess) { + byte buf[] = new byte[32]; + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int j = 0; j < 32; j++) { + BigInteger x = i.shiftRight(j * 8); + buf[j] = x.byteValue(); + } + return buf; + } + for (int j = 31; j >= 0; j--) { + BigInteger x = i.shiftRight((31 - j) * 8); + buf[j] = x.byteValue(); + } + return buf; + } + + static public byte[] convertUnsignedBigIntToByteArray(BigInteger i, int endianess, int arraySize) { + byte buf[] = new byte[arraySize * 2]; + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int j = 0; j < arraySize * 2; j++) { + BigInteger x = i.shiftRight(j * 8); + buf[j] = x.byteValue(); + } + return buf; + } + for (int j = (arraySize * 2) - 1; j >= 0; j--) { + BigInteger x = i.shiftRight(((arraySize * 2) - 1 - j) * 8); + buf[j] = x.byteValue(); + } + return buf; + } + + /** + * Convert long to byte array. + * + * @param i + * @param endianess + * @return result of the conversion in raw byte array + */ + static public byte[] convertLongToByteArray(long i, int endianess) { + byte buf[] = new byte[8]; + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int j = 0; j < 8; j++) { + buf[j] = new Long(i >> j * 8).byteValue(); + } + return buf; + } + for (int j = 7; j >= 0; j--) { + buf[j] = new Long(i >> (7 - j) * 8).byteValue(); + } + return buf; + } + + /** + * Convert integer to byte array. + * + * @param i + * @param endianess + * @return result of the conversion in raw byte array + */ + static public byte[] convertIntToByteArray(int i, int endianess) { + byte buf[] = new byte[4]; + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (int j = 0; j < 4; j++) { + buf[j] = new Integer(i >> j * 8).byteValue(); + } + return buf; + } + for (int j = 3; j >= 0; j--) { + buf[j] = new Integer(i >> (3 - j) * 8).byteValue(); + } + return buf; + } + + /** + * Convert short to byte array. + * + * @param i + * @param endianess + * @return result of the conversion in raw byte array + */ + static public byte[] convertShortToByteArray(short i, int endianess) { + byte buf[] = new byte[2]; + + if (endianess == MemoryUtils.LITTLE_ENDIAN) { + for (short j = 0; j < 2; j++) { + buf[j] = new Integer(i >> j * 8).byteValue(); + } + return buf; + } + for (short j = 1; j >= 0; j--) { + buf[j] = new Integer(i >> (1 - j) * 8).byteValue(); + } + return buf; + } + + /** + * byte array to Hex string helper replaces the Integer.toHexString() which + * can't convert byte values properly (always pads with FFFFFF) + */ + static public String convertByteArrayToHexString(byte[] byteArray) { + StringBuffer strBuffer = new StringBuffer(); + char charArray[]; + + for (byte element : byteArray) { + charArray = MemoryUtils.convertByteToCharArray(element); + strBuffer.append(charArray); + } + + return strBuffer.toString(); + } + + static public char[] convertByteToCharArray(byte aByte) { + char charArray[] = new char[2]; + int val = aByte; + if (val < 0) + val += 256; + charArray[0] = Character.forDigit(val / 16, 16); + charArray[1] = Character.forDigit(val % 16, 16); + + return charArray; + } + + /** + * Convert raw memory data to byte array + * + * @param str + * @param numBytes + * @param numCharsPerByte + * - number of characters per byte of data + * @return an array of byte, converted from a hex string + * @throws NumberFormatException + */ + public static byte[] convertHexStringToByteArray(String str, int numBytes, int numCharsPerByte) + throws NumberFormatException { + if (str.length() == 0) + return null; + + StringBuffer buf = new StringBuffer(str); + + // pad string with zeros + int requiredPadding = numBytes * numCharsPerByte - str.length(); + while (requiredPadding > 0) { + buf.insert(0, "0"); //$NON-NLS-1$ + requiredPadding--; + } + + byte[] bytes = new byte[numBytes]; + str = buf.toString(); + + // set data in memory + for (int i = 0; i < bytes.length; i++) { + // convert string to byte + String oneByte = str.substring(i * 2, i * 2 + 2); + + Integer number = Integer.valueOf(oneByte, 16); + if (number.compareTo(Integer.valueOf(Byte.toString(Byte.MAX_VALUE))) > 0) { + int temp = number.intValue(); + temp = temp - 256; + + String tempStr = Integer.toString(temp); + + Byte myByte = Byte.valueOf(tempStr); + bytes[i] = myByte.byteValue(); + } else { + Byte myByte = Byte.valueOf(oneByte, 16); + bytes[i] = myByte.byteValue(); + } + } + + return bytes; + } + + public static String convertMemoryBytesToHexString(MemoryByte[] bytes) { + StringBuffer strBuffer = new StringBuffer(); + char charArray[]; + + for (MemoryByte b : bytes) { + charArray = MemoryUtils.convertByteToCharArray(b.getValue()); + strBuffer.append(charArray); + } + + return strBuffer.toString(); + } + + /** + * Convert raw memory data to byte array + * + * @param str + * @param numBytes + * @param numCharsPerByte + * - number of characters per byte of data + * @return an array of byte, converted from a hex string + * @throws NumberFormatException + */ + public static MemoryByte[] convertHexStringToMemoryBytes(String str, int numBytes, int numCharsPerByte) + throws NumberFormatException { + if (str.length() == 0) + return null; + + StringBuffer buf = new StringBuffer(str); + + // pad string with zeros + int requiredPadding = numBytes * numCharsPerByte - str.length(); + while (requiredPadding > 0) { + buf.insert(0, "0"); //$NON-NLS-1$ + requiredPadding--; + } + + MemoryByte[] bytes = new MemoryByte[numBytes]; + str = buf.toString(); + + // set data in memory + for (int i = 0; i < bytes.length; i++) { + // convert string to byte + String oneByte = str.substring(i * 2, i * 2 + 2); + + Integer number = Integer.valueOf(oneByte, 16); + if (number.compareTo(Integer.valueOf(Byte.toString(Byte.MAX_VALUE))) > 0) { + int temp = number.intValue(); + temp = temp - 256; + + String tempStr = Integer.toString(temp); + + Byte myByte = Byte.valueOf(tempStr); + bytes[i] = new MemoryByte(myByte.byteValue()); + } else { + Byte myByte = Byte.valueOf(oneByte, 16); + bytes[i] = new MemoryByte(myByte.byteValue()); + } + } + + return bytes; + } + + public static class TypeCharacteristics { + public int basicType = IBasicType.t_unspecified; + public boolean isSigned = false; + public boolean isShort = false; + public boolean isLong = false; + public boolean isLongLong = false; + public boolean isComplex = false; + + public TypeCharacteristics(IType varType) { + if (varType instanceof IBasicType) { + IBasicType type = (IBasicType) varType; + basicType = type.getBaseType(); + isSigned = type.isSigned(); + isShort = type.isShort(); + isLong = type.isLong(); + + if (varType instanceof ICPPBasicType) { + ICPPBasicType cppType = (ICPPBasicType) varType; + isLongLong = cppType.isLongLong(); + isComplex = cppType.isComplex(); + } + } else if (varType instanceof IPointerType) { + // treat pointer as an unsigned int + basicType = IBasicType.t_int; + } else if (varType instanceof IEnumerator){ + // treat enumerator as a signed int + basicType = IBasicType.t_int; + isSigned = true; + } else { + // treat unknown type as an unsigned int + basicType = IBasicType.t_int; + } + } + } + + public static BigInteger convertValueToMemory(IType varType, Number value) throws CoreException { + BigInteger result = null; + if (varType == null) + throw EDCDebugger.newCoreException("Unknown type"); + int varSize = varType.getByteSize(); + if (varSize <= 0) + throw EDCDebugger.newCoreException("Type has no size"); + + TypeCharacteristics characteristics = new TypeCharacteristics(varType); + + // all other locations + switch (characteristics.basicType) { + case IBasicType.t_float: + case IBasicType.t_double: + if (varSize == 4) { + result = BigInteger.valueOf(Float.floatToIntBits(value.floatValue())); + } else if (varSize == 8) { + result = BigInteger.valueOf(Double.doubleToLongBits(value.doubleValue())); + } + break; + + case ICPPBasicType.t_bool: + case ICPPBasicType.t_wchar_t: + case IBasicType.t_char: + case IBasicType.t_int: + case IBasicType.t_void: + if (characteristics.isSigned) { + // as needed, mask the value and sign-extend + if (varSize == 4) { + result = BigInteger.valueOf(value.intValue()); + } else if (varSize == 2) { + int intResult = value.intValue() & 0xffff; + if ((intResult & 0x00008000) != 0) + intResult |= 0xffff0000; + result = BigInteger.valueOf(intResult); + } else if (varSize == 1) { + int intResult = value.intValue() & 0xff; + if ((intResult & 0x00000080) != 0) + intResult |= 0xffffff00; + result = BigInteger.valueOf(intResult); + } else { + // assume an 8-byte long is the default + result = BigInteger.valueOf(value.longValue()); + } + } else { + if (varSize == 4) { + result = BigInteger.valueOf(value.longValue() & 0xffffffffL); // keep it unsigned + } else if (varSize == 2) { + result = BigInteger.valueOf(value.intValue() & 0xffff); + } else if (varSize == 1) { + result = BigInteger.valueOf(value.intValue() & 0xff); + } else { + // assume an 8-byte long is the default + result = BigInteger.valueOf(value.longValue()); + } + } + break; + + case IBasicType.t_unspecified: + default: + assert false; + throw EDCDebugger.newCoreException("Unhandled type"); + } + return result; + } +} diff --git a/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/MessageLogger.java b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/MessageLogger.java new file mode 100644 index 0000000..5440abd --- /dev/null +++ b/org.eclipse.cdt.debug.edc/src/org/eclipse/cdt/debug/edc/MessageLogger.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.edc; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; + +/** + * This class performs error logging. The error can be logged, shown or both. It + * is important to log errors to clearly identify the plug-in as the source of + * problems. + *

  • 2l} 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%0Db#q*B=>0=)$ZMN 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