[Vm-dev] VM Maker: Cog-lw.48.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Jul 11 19:47:23 UTC 2012


Eliot Miranda uploaded a new version of Cog to project VM Maker:
http://source.squeak.org/VMMaker/Cog-lw.48.mcz

==================== Summary ====================

Name: Cog-lw.48
Author: lw
Time: 11 July 2012, 9:13:45.865 pm
UUID: 5ae3e465-4b2c-2349-9b88-77b8f53d5acd
Ancestors: Cog-eem.47

Added the GdbARMAlien, together with its tests and the plugin.
Additionally, introduced CogProcessorAlien as a common superclass for BochsIA32Alien and GdbARMAlien to increase code reusage.

The same might be possible for the Plugins (BochsIA32/GdbARM), because they are also identical.

=============== Diff against Cog-eem.47 ===============

Item was changed:
+ CogProcessorAlien variableByteSubclass: #BochsIA32Alien
- Alien variableByteSubclass: #BochsIA32Alien
  	instanceVariableNames: ''
  	classVariableNames: 'OpcodeExceptionMap PostBuildStackDelta'
  	poolDictionaries: ''
  	category: 'Cog-Processors'!
  
  !BochsIA32Alien commentStamp: '<historical>' prior: 0!
  I am a wrapper around the Bochs C++ IA32 CPU emulator.  Note that currently I provide no access to the x87/mmx FPU state, only providing access to the SSE/xmm registers.
  
  Here is the configure script for the configuration this code assumes.  Offsets of fields will change with different configurations so they must agree.
  
  ----8<---- conf.COG ----8<----
  #!!/bin/sh
  
  # this sets up the compile for Cog.  Disable as much inessential stuff
  # as possible leaving only the cpu/fpu & memory interface
  
  set echo
  # CFLAGS="-pipe -O3 -fomit-frame-pointer -finline-functions -falign-loops=16 -falign-jumps=16 -falign-functions=16 -falign-labels=16 -falign-loops-max-skip=15 -falign-jumps-max-skip=15 -fprefetch-loop-arrays $CFLAGS"
  CFLAGS="-m32 $CFLAGS"
  CFLAGS="-Dlongjmp=_longjmp -Dsetjmp=_setjmp $CFLAGS"
  CFLAGS="-pipe -O3 -fomit-frame-pointer -finline-functions $CFLAGS"
  CFLAGS="-g $CFLAGS"
  CPATH="/sw/include"
  CPPFLAGS=""
  CXXFLAGS="$CFLAGS"
  LDFLAGS="-L/sw/lib"
  
  export CFLAGS
  export CPATH
  export CPPFLAGS
  export CXXFLAGS
  export LDFLAGS
  
  ./configure --enable-Cog \
  	--enable-cpu-level=6 \
  	--enable-sse=2 \
  	--enable-assert-checks \
  	--with-nogui \
  		--disable-x86-64 \
  		--disable-pae \
  		--disable-large-pages \
  		--disable-global-pages \
  		--disable-mtrr \
  		--disable-sb16 \
  		--disable-ne2000 \
  		--disable-pci \
  		--disable-acpi \
  		--disable-apic \
  		--disable-clgd54xx \
  		--disable-usb \
  		--disable-plugins \
  	${CONFIGURE_ARGS}
  
  # apic == Advanced programmable Interrupt Controller
  # acpi == Advanced Configuration and Power Interface
  # pci == Peripheral Component Interconnect local bus
  # clgd54xx == Cirrus Logic GD54xx video card
  ----8<---- conf.COG ----8<----!

Item was removed:
- ----- Method: BochsIA32Alien>>disassembleFrom:to:in:on: (in category 'disassembly') -----
- disassembleFrom: startAddress to: endAddress in: memory on: aStream
- 	| address |
- 	address := startAddress.
- 	[address < endAddress] whileTrue:
- 		[[:size :string|
- 		aStream nextPutAll: string; cr; flush.
- 		address := address + size]
- 			valueWithArguments: (self
- 									primitiveDisassembleAt: address
- 									inMemory: memory)]!

Item was removed:
- ----- Method: BochsIA32Alien>>disassembleInstructionAt:In: (in category 'disassembly') -----
- disassembleInstructionAt: pc In: memory
- 	^(self primitiveDisassembleAt: pc inMemory: memory) last!

Item was removed:
- ----- Method: BochsIA32Alien>>disassembleInstructionAt:In:into: (in category 'disassembly') -----
- disassembleInstructionAt: ip In: memory into: aBlock
- 	| lenAndDi |
- 	lenAndDi := self primitiveDisassembleAt: ip inMemory: memory.
- 	^aBlock value: lenAndDi last value: lenAndDi first!

Item was removed:
- ----- Method: BochsIA32Alien>>disassembleNextInstructionIn: (in category 'disassembly') -----
- disassembleNextInstructionIn: memory
- 	^(self primitiveDisassembleAt: self eip inMemory: memory) last!

Item was removed:
- ----- Method: BochsIA32Alien>>runInMemory: (in category 'execution') -----
- runInMemory: aMemory
- 	| result |
- 	result := self primitiveRunInMemory: aMemory minimumAddress: 0 readOnlyBelow: 0.
- 	result ~~ self ifTrue:
- 		[self error: 'eek!!']!

Item was removed:
- ----- Method: BochsIA32Alien>>runInMemory:minimumAddress:readOnlyBelow: (in category 'execution') -----
- runInMemory: aMemory minimumAddress: minimumAddress readOnlyBelow: minimumWritableAddress
- 	| result |
- 	result := self primitiveRunInMemory: aMemory
- 				minimumAddress: minimumAddress
- 				readOnlyBelow: minimumWritableAddress.
- 	result ~~ self ifTrue:
- 		[self error: 'eek!!']!

Item was removed:
- ----- Method: BochsIA32Alien>>runInMemory:readExecuteOnlyBelow: (in category 'execution') -----
- runInMemory: aMemory readExecuteOnlyBelow: minWriteMaxExecAddr
- 	| result |
- 	result := self primitiveRunInMemory: aMemory minimumAddress: 0 readOnlyBelow: minWriteMaxExecAddr.
- 	result ~~ self ifTrue:
- 		[self error: 'eek!!']!

Item was removed:
- ----- Method: BochsIA32Alien>>singleStepIn: (in category 'execution') -----
- singleStepIn: aMemory
- 	| result |
- 	result := self primitiveSingleStepInMemory: aMemory minimumAddress: 0 readOnlyBelow: aMemory size.
- 	result ~~ self ifTrue:
- 		[self error: 'eek!!']!

Item was removed:
- ----- Method: BochsIA32Alien>>singleStepIn:minimumAddress:readOnlyBelow: (in category 'execution') -----
- singleStepIn: aMemory minimumAddress: minimumAddress readOnlyBelow: minimumWritableAddress
- 	| result |
- 	result := self primitiveSingleStepInMemory: aMemory
- 				minimumAddress: minimumAddress
- 				readOnlyBelow: minimumWritableAddress.
- 	result ~~ self ifTrue:
- 		[self error: 'eek!!']!

Item was removed:
- ----- Method: BochsIA32Alien>>singleStepIn:readExecuteOnlyBelow: (in category 'execution') -----
- singleStepIn: aMemory readExecuteOnlyBelow: minWriteMaxExecAddr
- 	| result |
- 	result := self primitiveSingleStepInMemory: aMemory minimumAddress: 0 readOnlyBelow: minWriteMaxExecAddr.
- 	result ~~ self ifTrue:
- 		[self error: 'eek!!']!

Item was added:
+ Alien variableByteSubclass: #CogProcessorAlien
+ 	instanceVariableNames: ''
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'Cog-Processors'!

Item was added:
+ ----- Method: CogProcessorAlien>>abstractInstructionCompilerClass (in category 'Cog API') -----
+ abstractInstructionCompilerClass
+ 	self subclassResponsibility!

Item was added:
+ ----- Method: CogProcessorAlien>>callOpcode (in category 'opcodes') -----
+ callOpcode
+ 	self subclassResponsibility.!

Item was added:
+ ----- Method: CogProcessorAlien>>disassembleFrom:to:in:on: (in category 'disassembly') -----
+ disassembleFrom: startAddress to: endAddress in: memory on: aStream
+ 	| address |
+ 	address := startAddress.
+ 	[address < endAddress] whileTrue:
+ 		[[:size :string|
+ 		aStream nextPutAll: string; cr; flush.
+ 		address := address + size]
+ 			valueWithArguments: (self
+ 									primitiveDisassembleAt: address
+ 									inMemory: memory)]!

Item was added:
+ ----- Method: CogProcessorAlien>>disassembleInstructionAt:In: (in category 'disassembly') -----
+ disassembleInstructionAt: pc In: memory
+ 	^(self primitiveDisassembleAt: pc inMemory: memory) last!

Item was added:
+ ----- Method: CogProcessorAlien>>disassembleInstructionAt:In:into: (in category 'disassembly') -----
+ disassembleInstructionAt: ip In: memory into: aBlock
+ 	| lenAndDi |
+ 	lenAndDi := self primitiveDisassembleAt: ip inMemory: memory.
+ 	^aBlock value: lenAndDi last value: lenAndDi first!

Item was added:
+ ----- Method: CogProcessorAlien>>disassembleNextInstructionIn: (in category 'disassembly') -----
+ disassembleNextInstructionIn: memory
+ 	^(self primitiveDisassembleAt: self pc inMemory: memory) last!

Item was added:
+ ----- Method: CogProcessorAlien>>nopOpcode (in category 'opcodes') -----
+ nopOpcode
+ 	self subclassResponsibility.!

Item was added:
+ ----- Method: CogProcessorAlien>>printRegisterState:on: (in category 'printing') -----
+ printRegisterState: registerStateVector on: aStream
+ 
+ 	self subclassResponsibility.!

Item was added:
+ ----- Method: CogProcessorAlien>>printRegistersOn: (in category 'printing') -----
+ printRegistersOn: aStream
+ 	self printRegisterState: self registerState on: aStream.
+ 	aStream flush!

Item was added:
+ ----- Method: CogProcessorAlien>>reportPrimitiveFailure (in category 'error handling') -----
+ reportPrimitiveFailure
+ 	| errorAndLog |
+ 	errorAndLog := self primitiveErrorAndLog.
+ 	self error: 'Error ', errorAndLog first printString, (errorAndLog last ifNil: [''] ifNotNil: [:log| ': ', log])!

Item was added:
+ ----- Method: CogProcessorAlien>>runInMemory: (in category 'execution') -----
+ runInMemory: aMemory
+ 	| result |
+ 	result := self primitiveRunInMemory: aMemory minimumAddress: 0 readOnlyBelow: 0.
+ 	result ~~ self ifTrue:
+ 		[self error: 'eek!!']!

Item was added:
+ ----- Method: CogProcessorAlien>>runInMemory:minimumAddress:readOnlyBelow: (in category 'execution') -----
+ runInMemory: aMemory minimumAddress: minimumAddress readOnlyBelow: minimumWritableAddress
+ 	| result |
+ 	result := self primitiveRunInMemory: aMemory
+ 				minimumAddress: minimumAddress
+ 				readOnlyBelow: minimumWritableAddress.
+ 	result ~~ self ifTrue:
+ 		[self error: 'eek!!']!

Item was added:
+ ----- Method: CogProcessorAlien>>runInMemory:readExecuteOnlyBelow: (in category 'execution') -----
+ runInMemory: aMemory readExecuteOnlyBelow: minWriteMaxExecAddr
+ 	| result |
+ 	result := self primitiveRunInMemory: aMemory minimumAddress: 0 readOnlyBelow: minWriteMaxExecAddr.
+ 	result ~~ self ifTrue:
+ 		[self error: 'eek!!']!

Item was added:
+ ----- Method: CogProcessorAlien>>singleStepIn: (in category 'execution') -----
+ singleStepIn: aMemory
+ 	| result |
+ 	result := self primitiveSingleStepInMemory: aMemory minimumAddress: 0 readOnlyBelow: aMemory size.
+ 	result ~~ self ifTrue:
+ 		[self error: 'eek!!']!

Item was added:
+ ----- Method: CogProcessorAlien>>singleStepIn:minimumAddress:readOnlyBelow: (in category 'execution') -----
+ singleStepIn: aMemory minimumAddress: minimumAddress readOnlyBelow: minimumWritableAddress
+ 	| result |
+ 	result := self primitiveSingleStepInMemory: aMemory
+ 				minimumAddress: minimumAddress
+ 				readOnlyBelow: minimumWritableAddress.
+ 	result ~~ self ifTrue:
+ 		[self error: 'eek!!']!

Item was added:
+ ----- Method: CogProcessorAlien>>singleStepIn:readExecuteOnlyBelow: (in category 'execution') -----
+ singleStepIn: aMemory readExecuteOnlyBelow: minWriteMaxExecAddr
+ 	| result |
+ 	result := self primitiveSingleStepInMemory: aMemory minimumAddress: 0 readOnlyBelow: minWriteMaxExecAddr.
+ 	result ~~ self ifTrue:
+ 		[self error: 'eek!!']!

Item was added:
+ CogProcessorAlien variableByteSubclass: #GdbARMAlien
+ 	instanceVariableNames: ''
+ 	classVariableNames: 'OpcodeExceptionMap PostBuildStackDelta'
+ 	poolDictionaries: ''
+ 	category: 'Cog-Processors'!

Item was added:
+ ----- Method: GdbARMAlien class>>dataSize (in category 'instance creation') -----
+ dataSize
+ 
+ 	^1536!

Item was added:
+ ----- Method: GdbARMAlien class>>defaultIntegerBaseInDebugger (in category 'debugger') -----
+ defaultIntegerBaseInDebugger
+ 	^16!

Item was added:
+ ----- Method: GdbARMAlien class>>new (in category 'instance creation') -----
+ new
+ 	^(self atAddress: self primitiveNewCPU) reset!

Item was added:
+ ----- Method: GdbARMAlien class>>primitiveNewCPU (in category 'primitives') -----
+ primitiveNewCPU
+ 	"Answer the address of a new ARMulator C type ARMul_State instance."
+ 	<primitive: 'primitiveNewCPU' module: 'GdbARMPlugin'>
+ 	^self primitiveFailed!

Item was added:
+ ----- Method: GdbARMAlien>>abstractInstructionCompilerClass (in category 'Cog API') -----
+ abstractInstructionCompilerClass
+ 	^CogARMCompiler!

Item was added:
+ ----- Method: GdbARMAlien>>branchAndLinkOpcodeWithOffset: (in category 'opcodes') -----
+ branchAndLinkOpcodeWithOffset: aNumber
+ 	
+ 	| offset |
+ 	offset := (aNumber - 8) asInteger >> 2.
+ 	(offset bitAnd: 16rFF000000) ~= 0 ifTrue: [self error: 'The offset is to far. ARM does not support such far jumps.'].
+ 	^ 16reb000000 bitOr: (offset bitAnd: 16r00FFFFFF)!

Item was added:
+ ----- Method: GdbARMAlien>>callOpcode (in category 'opcodes') -----
+ callOpcode
+ 	"The call command does not generally exist. The most similar would be bl <offset>"
+ 	^ self branchAndLinkOpcodeWithOffset: 0.!

Item was added:
+ ----- Method: GdbARMAlien>>cflag (in category 'accessing') -----
+ cflag
+ 	^self unsignedLongAt: 577!

Item was added:
+ ----- Method: GdbARMAlien>>eflags (in category 'accessing') -----
+ eflags
+ 	
+ 	^ (((self nflag << 5 bitOr: self zflag << 4) 
+ 			bitOr: self cflag << 3) 
+ 				bitOr: self vflag << 2)
+ 					bitOr: self ifflags!

Item was added:
+ ----- Method: GdbARMAlien>>handleExecutionPrimitiveFailureIn:minimumAddress:readOnlyBelow: (in category 'error handling') -----
+ handleExecutionPrimitiveFailureIn: memoryArray "<Bitmap|ByteArray>" minimumAddress: minimumAddress "<Integer>" readOnlyBelow: minimumWritableAddress "<Integer>"
+ 	"Handle an execution primitive failure.  Convert out-of-range call and absolute
+ 	 memory read into register instructions into ProcessorSimulationTrap signals."
+ 	"self printIntegerRegistersOn: Transcript"
+ 	"self printRegistersOn: Transcript"
+ 	
+ 	"| pc opcode |
+ 	((pc := self pc) between: minimumAddress and: memoryArray byteSize - 1) ifTrue:
+ 		[opcode := memoryArray byteAt: pc + 1.
+ 		^self
+ 			perform: (OpcodeExceptionMap at: opcode + 1)
+ 			with: pc
+ 			with: memoryArray
+ 			with: minimumWritableAddress]."
+ 	^self reportPrimitiveFailure!

Item was added:
+ ----- Method: GdbARMAlien>>ifflags (in category 'accessing') -----
+ ifflags
+ 	^self unsignedLongAt: 585!

Item was added:
+ ----- Method: GdbARMAlien>>integerRegisterState (in category 'accessing-abstract') -----
+ integerRegisterState
+ 	^{	self r0. self r1. self r2. self r3. self r4. self r5. self r6. self r7. self r8. 
+ 		self r9. self r10. self r11. self r12. self sp. self lr. self pc}!

Item was added:
+ ----- Method: GdbARMAlien>>lr (in category 'accessing') -----
+ lr
+ 	^self unsignedLongAt: 69!

Item was added:
+ ----- Method: GdbARMAlien>>lr: (in category 'accessing') -----
+ lr: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 69 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>nflag (in category 'accessing') -----
+ nflag
+ 	^self unsignedLongAt: 569!

Item was added:
+ ----- Method: GdbARMAlien>>nopOpcode (in category 'opcodes') -----
+ nopOpcode
+ 	"mov r0, r0"
+ 	^ 16rE1A01001!

Item was added:
+ ----- Method: GdbARMAlien>>pc (in category 'accessing') -----
+ pc
+ 	^self unsignedLongAt: 73!

Item was added:
+ ----- Method: GdbARMAlien>>pc: (in category 'accessing') -----
+ pc: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 73 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>primitiveDisassembleAt:inMemory: (in category 'primitives') -----
+ primitiveDisassembleAt: address inMemory: memoryArray "<Bitmap|ByteArray>"
+ 	"Answer an Array of the size and the disassembled code string for the instruction at the current instruction pointer in memory."
+ 	<primitive: 'primitiveDisassembleAtInMemory' module: 'GdbARMPlugin'>
+ 	^self primitiveFailed!

Item was added:
+ ----- Method: GdbARMAlien>>primitiveErrorAndLog (in category 'primitives') -----
+ primitiveErrorAndLog
+ 	"Answer an array of the current error code and log contents"
+ 	<primitive: 'primitiveErrorAndLog' module: 'GdbARMPlugin'>
+ 	^self primitiveFailed!

Item was added:
+ ----- Method: GdbARMAlien>>primitiveResetCPU (in category 'primitives') -----
+ primitiveResetCPU
+ 	"Reset the receiver to registers all zero, and protected 32-bit mode."
+ 	<primitive: 'primitiveResetCPU' module: 'GdbARMPlugin'>
+ 	^self reportPrimitiveFailure!

Item was added:
+ ----- Method: GdbARMAlien>>primitiveRunInMemory:minimumAddress:readOnlyBelow: (in category 'primitives') -----
+ primitiveRunInMemory: memoryArray "<Bitmap|ByteArray>" minimumAddress: minimumAddress "<Integer>" readOnlyBelow: minimumWritableAddress "<Integer>"
+ 	"Run the receiver using the argument as the store.  Origin the argument at 0. i.e. the first byte of the
+ 	 memoryArray is address 0.  Make addresses below minimumAddress illegal.  Convert out-of-range
+ 	 call, jump and memory read/writes into register instructions into ProcessorSimulationTrap signals."
+ 	<primitive: 'primitiveRunInMemoryMinimumAddressReadWrite' module: 'GdbARMPlugin' error: ec>
+ 	^ec == #'inappropriate operation'
+ 		ifTrue: [self handleExecutionPrimitiveFailureIn: memoryArray
+ 					minimumAddress: minimumAddress
+ 					readOnlyBelow: minimumWritableAddress]
+ 		ifFalse: [self reportPrimitiveFailure]
+ 
+ 	"self printRegistersOn: Transcript"!

Item was added:
+ ----- Method: GdbARMAlien>>primitiveSingleStepInMemory:minimumAddress:readOnlyBelow: (in category 'primitives') -----
+ primitiveSingleStepInMemory: memoryArray "<Bitmap|ByteArray>" minimumAddress: minimumAddress "<Integer>" readOnlyBelow: minimumWritableAddress "<Integer>"
+ 	"Single-step the receiver using the argument as the store.  Origin the argument at 0. i.e. the first byte of the
+ 	 memoryArray is address 0.  Make addresses below minimumAddress illegal.  Convert out-of-range
+ 	 call, jump and memory read/writes into register instructions into ProcessorSimulationTrap signals."
+ 	<primitive: 'primitiveSingleStepInMemoryMinimumAddressReadWrite' module: 'GdbARMPlugin' error: ec>
+ 	^ec == #'inappropriate operation'
+ 		ifTrue: [self handleExecutionPrimitiveFailureIn: memoryArray
+ 					minimumAddress: minimumAddress
+ 					readOnlyBelow: minimumWritableAddress]
+ 		ifFalse: [self reportPrimitiveFailure]!

Item was added:
+ ----- Method: GdbARMAlien>>printRegisterState:on: (in category 'printing') -----
+ printRegisterState: registerStateVector on: aStream
+ 	| rsvs fields|
+ 	aStream ensureCr.
+ 	rsvs := registerStateVector readStream.
+ 	fields := #(	r0 r1 r2 r3 r4 r5 r6 cr r7 r8 r9 r10 r11 r12 cr sp lr pc eflags cr).
+ 	fields withIndexDo:
+ 		[:sym :index| | val |
+ 		sym = #cr
+ 			ifTrue: [aStream cr]
+ 			ifFalse:
+ 				[(val := rsvs next) isNil ifTrue: [^self].
+ 				aStream nextPutAll: sym; nextPut: $:; space.
+ 				val printOn: aStream base: 16 length: 8 padded: true.
+ 				#eflags == sym
+ 					ifTrue:
+ 						[aStream space.
+ 						 "'FIVCZN'"'--VCZN' withIndexDo:
+ 							[:flag :bitIndex|
+ 							flag ~= $- ifTrue:
+ 								[aStream nextPut: flag; nextPutAll: 'F='; print: (val bitAnd: 1 << (bitIndex - 1)) >> (bitIndex - 1); space]]]
+ 					ifFalse:
+ 						[val > 16 ifTrue:
+ 							[aStream space; nextPut: $(.
+ 							 val printOn: aStream base: 10 length: 1 padded: false.
+ 							 aStream nextPut: $)]].
+ 				(fields at: index + 1) ~~ #cr ifTrue:
+ 					[aStream tab]]]!

Item was added:
+ ----- Method: GdbARMAlien>>r0 (in category 'accessing') -----
+ r0
+ 	^self unsignedLongAt: 13!

Item was added:
+ ----- Method: GdbARMAlien>>r0: (in category 'accessing') -----
+ r0: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 13 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r1 (in category 'accessing') -----
+ r1
+ 	^self unsignedLongAt: 17!

Item was added:
+ ----- Method: GdbARMAlien>>r10 (in category 'accessing') -----
+ r10
+ 	^self unsignedLongAt: 53!

Item was added:
+ ----- Method: GdbARMAlien>>r10: (in category 'accessing') -----
+ r10: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 53 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r11 (in category 'accessing') -----
+ r11
+ 	^self unsignedLongAt: 57!

Item was added:
+ ----- Method: GdbARMAlien>>r11: (in category 'accessing') -----
+ r11: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 57 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r12 (in category 'accessing') -----
+ r12
+ 	^self unsignedLongAt: 61!

Item was added:
+ ----- Method: GdbARMAlien>>r12: (in category 'accessing') -----
+ r12: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 61 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r1: (in category 'accessing') -----
+ r1: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 17 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r2 (in category 'accessing') -----
+ r2
+ 	^self unsignedLongAt: 21!

Item was added:
+ ----- Method: GdbARMAlien>>r2: (in category 'accessing') -----
+ r2: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 21 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r3 (in category 'accessing') -----
+ r3
+ 	^self unsignedLongAt: 25!

Item was added:
+ ----- Method: GdbARMAlien>>r3: (in category 'accessing') -----
+ r3: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 25 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r4 (in category 'accessing') -----
+ r4
+ 	^self unsignedLongAt: 29!

Item was added:
+ ----- Method: GdbARMAlien>>r4: (in category 'accessing') -----
+ r4: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 29 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r5 (in category 'accessing') -----
+ r5
+ 	^self unsignedLongAt: 33!

Item was added:
+ ----- Method: GdbARMAlien>>r5: (in category 'accessing') -----
+ r5: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 33 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r6 (in category 'accessing') -----
+ r6
+ 	^self unsignedLongAt: 37!

Item was added:
+ ----- Method: GdbARMAlien>>r6: (in category 'accessing') -----
+ r6: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 37 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r7 (in category 'accessing') -----
+ r7
+ 	^self unsignedLongAt: 41!

Item was added:
+ ----- Method: GdbARMAlien>>r7: (in category 'accessing') -----
+ r7: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 41 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r8 (in category 'accessing') -----
+ r8
+ 	^self unsignedLongAt: 45!

Item was added:
+ ----- Method: GdbARMAlien>>r8: (in category 'accessing') -----
+ r8: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 45 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>r9 (in category 'accessing') -----
+ r9
+ 	^self unsignedLongAt: 49!

Item was added:
+ ----- Method: GdbARMAlien>>r9: (in category 'accessing') -----
+ r9: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 49 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>registerState (in category 'accessing-abstract') -----
+ registerState
+ 	^{	self r0. self r1. self r2. self r3. self r4. self r5. self r6. self r7.
+ 		self r8. self r0. self r10. self r11. self r12. self sp. self lr. self pc. self eflags }!

Item was added:
+ ----- Method: GdbARMAlien>>reset (in category 'accessing') -----
+ reset
+ 	self primitiveResetCPU!

Item was added:
+ ----- Method: GdbARMAlien>>retOpcode (in category 'opcodes') -----
+ retOpcode
+ 	"the ret command does not generally exist. the most similar would be mov pc, lr"
+ 	^ self halt.!

Item was added:
+ ----- Method: GdbARMAlien>>sflag (in category 'accessing') -----
+ sflag
+ 	^self unsignedLongAt: 589!

Item was added:
+ ----- Method: GdbARMAlien>>sp (in category 'accessing') -----
+ sp
+ 	^self unsignedLongAt: 65!

Item was added:
+ ----- Method: GdbARMAlien>>sp: (in category 'accessing') -----
+ sp: anUnsignedInteger
+ 
+ 	^self unsignedLongAt: 65 put: anUnsignedInteger!

Item was added:
+ ----- Method: GdbARMAlien>>vflag (in category 'accessing') -----
+ vflag
+ 	^self unsignedLongAt: 581!

Item was added:
+ ----- Method: GdbARMAlien>>zflag (in category 'accessing') -----
+ zflag
+ 	^self unsignedLongAt: 573!

Item was added:
+ TestCase subclass: #GdbARMAlienTests
+ 	instanceVariableNames: 'processor'
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'Cog-Processors-Tests'!

Item was added:
+ ----- Method: GdbARMAlienTests>>callTrapPerformance: (in category 'tests') -----
+ callTrapPerformance: n
+ 	"Call a function that is out-of-range.  Ensure the call is trapped."
+ 	"self new testCallTrap"
+ 	| memory |
+ 	 "The address is out of range of memory every which way (whether relative or absolute and whether big-endian or little."
+ 	memory := ByteArray new: 1024.
+ 	memory replaceFrom: 1 to: 5 with: { self processor callOpcode. 0. 16r80. 16r80. 0. } asByteArray.
+ 	self processor
+ 			eip: 0;
+ 			esp: (memory size - 4). "Room for return address"
+ 	1 to: n do:
+ 		[:ign|
+ 		[self processor singleStepIn: memory]
+ 			on: ProcessorSimulationTrap
+ 			do: [:ex|]].
+ 
+ 	"QSystemProfiler spyOn: [GdbARMAlienTests new callTrapPerformance: 1024*128]"
+ 	"Time millisecondsToRun: [GdbARMAlienTests new callTrapPerformance: 1024*128] 2463"
+ 	"Time millisecondsToRun: [1 to: 1024*1024*64 do: [:ign| nil yourself]] 636"
+ 	"Time millisecondsToRun: [1 to: 1024*1024*64 do: [:ign| nil perform: #ifNotNilDo: with: nil]] 3639"
+ 	"Time millisecondsToRun: [1 to: 1024*1024*64 do: [:ign| nil perform: #ifNotNilDo:ifNil: with: nil with: nil]] 12401"!

Item was added:
+ ----- Method: GdbARMAlienTests>>nfib (in category 'accessing') -----
+ nfib
+ 	"long fib(long n) { return n <= 1 ? 1 : fib(n-1) + fib(n-2) + 1; }
+ 	 as compiled by arm-elf-gnuabi-gcc fib.c -c -marm
+ 	also, the jumps are changed by hand."
+ 	"| bat nfib ip |
+ 	bat := GdbARMAlienTests new.
+ 	nfib := bat nfib asWordArray.
+ 	ip := 0.
+ 	23 timesRepeat:
+ 		[bat processor disassembleInstructionAt: ip In: nfib into:
+ 			[:da :len|
+ 			Transcript nextPutAll: da; cr; flush.
+ 			ip := ip + len]]"
+ 	^#("00000000 <fib>:
+ 	   0:"		16re92d4810 		"push	{r4, fp, lr}	fp = r11, sp is changed in this command
+ 	   4:"		16re28db008 		"add	fp, sp, #8	now, the frame pointer is changed
+ 	   8:"		16re24dd00c 		"sub	sp, sp, #12
+ 	   c:"		16re50b0010 		"str	r0, [fp, #-16]
+ 	  10:"		16re51b3010 		"ldr	r3, [fp, #-16]	r3 <- [fp-16] <- r0
+ 	  14:"		16re3530001 		"cmp	r3, #1
+ 	  18:"		16rda00000c 		"ble	50 <fib+0x50>
+ 	  1c:"		16re51b3010 		"ldr	r3, [fp, #-16]
+ 	  20:"		16re2433001 		"sub	r3, r3, #1
+ 	  24:"		16re1a00003 		"mov	r0, r3
+ 	  28:"		16rebfffff4 		"bl	0 <fib>
+ 	  2c:"		16re1a04000 		"mov	r4, r0
+ 	  30:"		16re51b3010 		"ldr	r3, [fp, #-16]
+ 	  34:"		16re2433002	 	"sub	r3, r3, #2
+ 	  38:"		16re1a00003 		"mov	r0, r3
+ 	  3c:"		16rebffffef 		"bl	0 <fib>
+ 	  40:"		16re1a03000 		"mov	r3, r0
+ 	  44:"		16re0843003 		"add	r3, r4, r3
+ 	  48:"		16re2833001 		"add	r3, r3, #1
+ 	  4c:"		16rea000000 		"b	54 <fib+0x54>
+ 	  50:"		16re3a03001 		"mov	r3, #1
+ 	  54:"		16re1a00003 		"mov	r0, r3
+ 	  58:"		16re24bd008 		"sub	sp, fp, #8
+ 	  5c:"		16re8bd8810 		"pop	{r4, fp, pc}")!

Item was added:
+ ----- Method: GdbARMAlienTests>>processor (in category 'accessing') -----
+ processor
+ 	processor ifNil:
+ 		[processor := GdbARMAlien new].
+ 	^processor!

Item was added:
+ ----- Method: GdbARMAlienTests>>registerGetters (in category 'accessing') -----
+ registerGetters
+ 	^#(r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 lr sp pc)!

Item was added:
+ ----- Method: GdbARMAlienTests>>registerSetters (in category 'accessing') -----
+ registerSetters
+ 	^#(r0: r1: r2: r3: r4: r5: r6: r7: r8: r9: r10: r11: r12: lr: sp: pc:)!

Item was added:
+ ----- Method: GdbARMAlienTests>>runNFib:disassemble:printRegisters: (in category 'execution') -----
+ runNFib: n disassemble: disassemble printRegisters: printRegisters
+ 	"Run nfib wth the argument. Answer the result."
+ 	"self new runNFib: 5 disassemble: true printRegisters: true"
+ 	| memory |
+ 	memory := WordArray new: 1024 * 2 withAll: self processor nopOpcode.
+ 	memory replaceFrom: 1 to: self nfib size with: self nfib asWordArray startingAt: 1.
+ 	self processor
+ 		r0: n;"argument n"
+ 		lr: memory size * 2; "return address"
+ 		pc: 0;
+ 		sp: (memory size * 4) - 16.
+ 	printRegisters ifTrue:
+ 		[self processor printRegistersOn: Transcript.
+ 		 Transcript cr; flush].
+ 	"run until something goes wrong."
+ 	self processor runInMemory: memory readExecuteOnlyBelow: memory size / 2.
+ 	printRegisters ifTrue:
+ 		[self processor printRegistersOn: Transcript.
+ 		 Transcript cr; flush].
+ 	^self processor r0!

Item was added:
+ ----- Method: GdbARMAlienTests>>singleStepNFib:disassemble:printRegisters: (in category 'execution') -----
+ singleStepNFib: n disassemble: disassemble printRegisters: printRegisters
+ 	"Run nfib wth the argument. Answer the result."
+ 	"self new runNFib: 5 disassemble: true printRegisters: true"
+ 	| memory |
+ 	memory := WordArray new: 1024 * 2 withAll: self processor nopOpcode.
+ 	memory replaceFrom: 1 to: self nfib size with: self nfib asWordArray startingAt: 1.
+ 	self processor
+ 		r0: n; "argument n"
+ 		lr: self nfib size * 4;  "return address"
+ 		pc: 0;
+ 		sp: (memory size * 4 - 12). "Room for return address, frame pointer and r4"
+ 	printRegisters ifTrue:
+ 		[self processor printRegistersOn: Transcript.
+ 		 Transcript cr; flush].
+ 	[disassemble ifTrue:
+ 		[Transcript nextPutAll: (self processor disassembleNextInstructionIn: memory); cr; flush].
+ 	 self processor singleStepIn: memory readExecuteOnlyBelow: memory size * 4 / 2.
+ 	 printRegisters ifTrue:
+ 		[self processor printRegistersOn: Transcript.
+ 		 Transcript cr; flush].
+ 	"stop, once we leave the nfib code and step through the nops after that."
+ 	 self processor pc < (self nfib size * 4)] whileTrue.
+ 	^self processor r0!

Item was added:
+ ----- Method: GdbARMAlienTests>>testCallTrap (in category 'tests') -----
+ testCallTrap
+ 	"Call a function that is out-of-range.  Ensure the call is trapped."
+ 	"self new testCallTrap"
+ 	| memory |
+ 	memory := Bitmap new: 256 withAll: self processor nopOpcode.
+ 	memory longAt: 1 put: (self processor branchAndLinkOpcodeWithOffset: 1024) bigEndian: false.
+ 	memory := memory asByteArray.
+ 	self processor
+ 			pc: 0;
+ 			sp: (memory size - 4); "Room for return address"
+ 			singleStepIn: memory.
+ 			"We have to step twice, because the first step only changes the pc, but does not fetch anything from the address it points to."
+ 	self should: [self processor singleStepIn: memory]
+ 		raise: Error
+ 		withExceptionDo:
+ 			[:pst|
+ 			self assert: self processor pc = 1024.
+ 			self assert: self processor lr = 4.
+ 			self assert: pst messageText = 'Error 0: Illegal Instruction fetch address (0x00000400).'].!

Item was added:
+ ----- Method: GdbARMAlienTests>>testDisassembling (in category 'tests') -----
+ testDisassembling
+ 
+ 	| memory result |
+ 	memory := WordArray new: 2.
+ 	memory at: 1 put: 16rEF200000.
+ 	result := self processor
+ 		disassembleInstructionAt: 0 
+ 		In: memory 
+ 		into: [:str :len | 
+ 			self 
+ 				assert: len = 4;
+ 				assert: str = 'svc	0x00200000'].!

Item was added:
+ ----- Method: GdbARMAlienTests>>testExecutionTrap (in category 'tests') -----
+ testExecutionTrap
+ 	"Execute a run of nops.  test executing beyond the executable limit is trapped."
+ 	"self new testExecutionTrap"
+ 	| memory |
+ 	 "The address is out of range of memory every which way (whether relative or absolute and whether big-endian or little."
+ 	memory := (Bitmap new: 1024 * 2 withAll: self processor nopOpcode) asByteArray.
+ 	self processor
+ 			pc: 0;
+ 			sp: (memory size - 4). "Room for return address"
+ 	self should: [self processor runInMemory: memory minimumAddress: 0 readOnlyBelow: memory size / 2]
+ 		raise: Error
+ 		withExceptionDo:
+ 			[:err|
+ 			self assert: self processor pc = (memory size / 2).
+ 			self assert: ('Error 0: Illegal Instruction fetch address (0x00001000).' match: err messageText)].
+ 	self processor pc: 0.
+ 	self should: [[self processor singleStepIn: memory minimumAddress: 0 readOnlyBelow: memory size / 2] repeat]
+ 		raise: Error
+ 		withExceptionDo:
+ 			[:err|
+ 			self assert: self processor pc = (memory size / 2).
+ 			self assert: ('Error 0: Illegal Instruction fetch address (0x00001000).' match: err messageText)]!

Item was added:
+ ----- Method: GdbARMAlienTests>>testFlags (in category 'tests') -----
+ testFlags
+ 	"self new testFlags"
+ 	| memory |
+ 	memory := Bitmap new: 3.
+ 	memory longAt: 1 put: 16rE3A03001 bigEndian: false. "MOV r3, #1"
+ 	memory longAt: 5 put: 16rE3530001 bigEndian: false. "CMP r3, #1"
+ 	memory := memory asByteArray.
+ 	self processor
+ 		disassembleInstructionAt: 0 
+ 		In: memory 
+ 		into: [:str :len | 
+ 			self 
+ 				assert: len = 4;
+ 				assert: str = 'mov	r3, #1'].
+ 	self processor
+ 		disassembleInstructionAt: 4 
+ 		In: memory 
+ 		into: [:str :len | 
+ 			self 
+ 				assert: len = 4;
+ 				assert: str = 'cmp	r3, #1'].
+ 	self processor
+ 		pc: 0;
+ 		singleStepIn: memory;
+ 		singleStepIn: memory.
+ 	self 
+ 		assert: self processor pc = 16r8;
+ 		assert: self processor r3 = 1;
+ 		assert: self processor zflag = 1;
+ 		assert: self processor cflag = 1;
+ 		assert: self processor vflag = 0;
+ 		assert: self processor nflag = 0.
+ 	self processor reset.
+ 	self assert: self processor eflags = 3. "IFFlags are both set."!

Item was added:
+ ----- Method: GdbARMAlienTests>>testMOVSD (in category 'tests') -----
+ testMOVSD
+ 	"Test MOVSD indirecting through edx."
+ 	"self new testMOVSD"
+ 	self processor
+ 		edx: 0;
+ 		eip: 0;
+ 		singleStepIn: {16rF2. 16r0F. 16r10. 16r42. 16r04. 16r90. 16r01. 16r02. 16r03. 16r04. 16r05. 16r06} asByteArray "movsd %ds:0x4(%edx), %xmm0;nop;garbage".
+ 	self assert: self processor eip = 5.
+ 	self assert: self processor xmm0low = 16r0605040302019004!

Item was added:
+ ----- Method: GdbARMAlienTests>>testNfib1 (in category 'tests') -----
+ testNfib1
+ 	"self new testNfib1"
+ 	self should: [self runNFib: 1 disassemble: false printRegisters: true]
+ 		raise: Error
+ 		withExceptionDo: 
+ 			[:err| self assert: err messageText = 'Error 0: Illegal Instruction fetch address (0x00001000).'].
+ 	self deny: (self processor pc between: 0 and: self nfib size).
+ 	self assert: self processor r0 = 1 benchFib!

Item was added:
+ ----- Method: GdbARMAlienTests>>testNfib16 (in category 'tests') -----
+ testNfib16
+ 	"self new testNfib16"
+ 	self should: [self runNFib: 16 disassemble: false printRegisters: false]
+ 		raise: Error.
+ 	self deny: (self processor pc between: 0 and: self nfib size).
+ 	self assert: self processor r0 = 16 benchFib!

Item was added:
+ ----- Method: GdbARMAlienTests>>testNfib2 (in category 'tests') -----
+ testNfib2
+ 	"self new testNfib2"
+ 	self should: [self runNFib: 2 disassemble: false printRegisters: false]
+ 		raise: Error.
+ 	self deny: (self processor pc between: 0 and: self nfib size).
+ 	self assert: self processor r0 = 2 benchFib!

Item was added:
+ ----- Method: GdbARMAlienTests>>testNfib4 (in category 'tests') -----
+ testNfib4
+ 	"self new testNfib4"
+ 	self should: [self runNFib: 4 disassemble: false printRegisters: false]
+ 		raise: Error.
+ 	self deny: (self processor pc between: 0 and: self nfib size).
+ 	self assert: self processor r0 = 4 benchFib!

Item was added:
+ ----- Method: GdbARMAlienTests>>testResetCPU (in category 'tests') -----
+ testResetCPU
+ 	"self new testResetCPU"
+ 	self registerSetters do:
+ 		[:setter|
+ 		self processor perform: setter with: 16r55555555].
+ 	self registerGetters do:
+ 		[:getter|
+ 		self assert: 16r55555555 = (self processor perform: getter)].
+ 	self processor reset.
+ 	self registerGetters do:
+ 		[:getter|
+ 		self assert: 0 = (self processor perform: getter)]!

Item was added:
+ ----- Method: GdbARMAlienTests>>testStepNfib1 (in category 'tests') -----
+ testStepNfib1
+ 	"self new testStepNfib1"
+ 	self singleStepNFib: 1 disassemble: false printRegisters: false.
+ 	self assert: self processor pc = (self nfib asWordArray size * 4).
+ 	self assert: self processor r0 = 1 benchFib!

Item was added:
+ ----- Method: GdbARMAlienTests>>testStepNfib2 (in category 'tests') -----
+ testStepNfib2
+ 	"self new testStepNfib2"
+ 	self singleStepNFib: 2 disassemble: false printRegisters: false.
+ 	self assert: self processor pc = (self nfib size * 4).
+ 	self assert: self processor r0 = 2 benchFib!

Item was added:
+ ----- Method: GdbARMAlienTests>>testStepNfib4 (in category 'tests') -----
+ testStepNfib4
+ 	"self new testStepNfib4"
+ 	self singleStepNFib: 4 disassemble: false printRegisters: false.
+ 	self assert: self processor pc = (self nfib size * 4).
+ 	self assert: self processor r0 = 4 benchFib!

Item was added:
+ SmartSyntaxInterpreterPlugin subclass: #GdbARMPlugin
+ 	instanceVariableNames: 'prevInterruptCheckChain'
+ 	classVariableNames: ''
+ 	poolDictionaries: 'VMBasicConstants'
+ 	category: 'Cog-ProcessorPlugins'!
+ 
+ !GdbARMPlugin commentStamp: '<historical>' prior: 0!
+ I provide access to the ARMulator ARM emulator and the libopcodes ARM disassembler.!

Item was added:
+ ----- Method: GdbARMPlugin class>>declareCVarsIn: (in category 'translation') -----
+ declareCVarsIn: aCCodeGenerator
+ 	"prevInterruptCheckChain lives in sqGdbARMPlugin.c"
+ 	super declareCVarsIn: aCCodeGenerator.
+ 	aCCodeGenerator removeVariable: 'prevInterruptCheckChain'!

Item was added:
+ ----- Method: GdbARMPlugin class>>hasHeaderFile (in category 'translation') -----
+ hasHeaderFile
+ 	"We need a header to declare newcpu and pull in bochs.h & cpu.h"
+ 	^true!

Item was added:
+ ----- Method: GdbARMPlugin>>forceStopOnInterrupt (in category 'interruption') -----
+ forceStopOnInterrupt
+ 	interpreterProxy getInterruptPending ifTrue:
+ 		[self forceStopRunning]!

Item was added:
+ ----- Method: GdbARMPlugin>>primitiveDisassembleAt:InMemory: (in category 'primitives') -----
+ "cpuAlien <GdbARMAlien>" primitiveDisassembleAt: address "<Integer>" InMemory: memory "<Bitmap|ByteArray|WordArray>"
+ 	"Return an Array of the instruction length and its decompilation as a string for the instruction at address in memory."
+ 	| cpuAlien cpu instrLenOrErr resultObj log logLen logObj logObjData |
+ 	<var: #cpu type: #'void *'>
+ 	cpuAlien := self primitive: #primitiveDisassembleAtInMemory
+ 					parameters: #(Unsigned WordsOrBytes)
+ 					receiver: #Oop.
+ 	(cpu := self startOfData: cpuAlien) = 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
+ 	instrLenOrErr := self disassembleFor: cpu
+ 						At: address
+ 						In: memory
+ 						Size: (interpreterProxy byteSizeOf: memory cPtrAsOop).
+ 	instrLenOrErr < 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrInappropriate].
+ 	log := self getlog: (self cCode: [self addressOf: logLen] inSmalltalk: [logLen := 0]).
+ 	resultObj := interpreterProxy instantiateClass: interpreterProxy classArray indexableSize: 2.
+ 	resultObj = 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrNoMemory].
+ 
+ 	"Easier keeping the damn thing on the stack than using pushRemappableOop:/popRemappableOop.
+ 	 Where is topRemappableOop when you need it?"
+ 	interpreterProxy pushRemappableOop: resultObj.
+ 	logObj := interpreterProxy
+ 				instantiateClass: interpreterProxy classString
+ 				indexableSize: logLen.
+ 	interpreterProxy failed ifTrue:
+ 		[interpreterProxy popRemappableOop.
+ 		 ^interpreterProxy primitiveFailFor: PrimErrNoMemory].
+ 	logObjData := interpreterProxy arrayValueOf: logObj.
+ 	self cCode: 'memcpy(logObjData, log, logLen)' inSmalltalk: [logObjData. log].
+ 	resultObj := interpreterProxy popRemappableOop.
+ 	interpreterProxy
+ 		storePointer: 0
+ 		ofObject: resultObj
+ 		withValue: (interpreterProxy integerObjectOf: instrLenOrErr).
+ 	interpreterProxy storePointer: 1 ofObject: resultObj withValue: logObj.
+ 
+ 	^resultObj!

Item was added:
+ ----- Method: GdbARMPlugin>>primitiveErrorAndLog (in category 'primitives') -----
+ primitiveErrorAndLog
+ 	| log logLen resultObj logObj logObjData |
+ 	<var: #log type: #'char *'>
+ 	<var: #logObjData type: #'char *'>
+ 	self primitive: #primitiveErrorAndLog parameters: #().
+ 
+ 	log := self getlog: (self cCode: [self addressOf: logLen] inSmalltalk: [logLen := 0]).
+ 	resultObj := interpreterProxy instantiateClass: interpreterProxy classArray indexableSize: 2.
+ 	resultObj = 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrNoMemory].
+ 
+ 	interpreterProxy
+ 		storePointer: 0
+ 		ofObject: resultObj
+ 		withValue: (interpreterProxy integerObjectOf: self errorAcorn).
+ 
+ 	logLen > 0 ifTrue:
+ 		[interpreterProxy pushRemappableOop: resultObj.
+ 		logObj := interpreterProxy
+ 					instantiateClass: interpreterProxy classString
+ 					indexableSize: logLen.
+ 		interpreterProxy failed ifTrue:
+ 			[interpreterProxy popRemappableOop.
+ 			 ^interpreterProxy primitiveFailFor: PrimErrNoMemory].
+ 
+ 		resultObj := interpreterProxy popRemappableOop.
+ 		logObjData := interpreterProxy arrayValueOf: logObj.
+ 		self cCode: 'memcpy(logObjData, log, logLen)' inSmalltalk: [logObjData. log].
+ 		interpreterProxy storePointer: 1 ofObject: resultObj withValue: logObj].
+ 	interpreterProxy pop: 1 thenPush: resultObj!

Item was added:
+ ----- Method: GdbARMPlugin>>primitiveFlushICacheFrom:To: (in category 'primitives') -----
+ "cpuAlien <GdbARMAlien>" primitiveFlushICacheFrom: startAddress "<Integer>" To: endAddress "<Integer>"
+ 	"Flush the icache in the requested range"
+ 	| cpuAlien cpu |
+ 	<var: #cpu type: 'void *'>
+ 	cpuAlien := self primitive: #primitiveFlushICacheFromTo
+ 					parameters: #(Unsigned Unsigned)
+ 					receiver: #Oop.
+ 	(cpu := self startOfData: cpuAlien) = 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
+ 	self flushICache: cpu From: startAddress To: endAddress!

Item was added:
+ ----- Method: GdbARMPlugin>>primitiveNewCPU (in category 'primitives') -----
+ primitiveNewCPU
+ 	| cpu |
+ 	<var: #cpu type: 'void *'>
+ 	self primitive: #primitiveNewCPU parameters: #().
+ 
+ 	cpu := self cCode: 'newCPU()' inSmalltalk: [0].
+ 	cpu = 0 ifTrue:
+ 		[^interpreterProxy primitiveFail].
+ 	interpreterProxy
+ 		pop: 1
+ 		thenPush: (interpreterProxy positive32BitIntegerFor:
+ 										(self cCoerceSimple: cpu
+ 											to: 'unsigned long'))!

Item was added:
+ ----- Method: GdbARMPlugin>>primitiveResetCPU (in category 'primitives') -----
+ primitiveResetCPU
+ 	| cpuAlien cpu maybeErr |
+ 	<var: #cpu type: 'void *'>
+ 	cpuAlien := self primitive: #primitiveResetCPU parameters: #() receiver: #Oop.
+ 	(cpu := self startOfData: cpuAlien) = 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
+ 	maybeErr := self resetCPU: cpu.
+ 	maybeErr ~= 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrInappropriate].
+ 	^cpuAlien!

Item was added:
+ ----- Method: GdbARMPlugin>>primitiveRunInMemory:minimumAddress:readOnlyBelow: (in category 'primitives') -----
+ "cpuAlien <GdbARMAlien>" primitiveRunInMemory: memory "<Bitmap|ByteArray|WordArray>" minimumAddress: minAddress "<Integer>" readOnlyBelow: minWriteMaxExecAddress "<Integer>"
+ 	"Run the cpu using the first argument as the memory and the following arguments defining valid addresses, running until it halts or hits an exception."
+ 	| cpuAlien cpu maybeErr |
+ 	<var: #cpu type: #'void *'>
+ 	cpuAlien := self primitive: #primitiveRunInMemoryMinimumAddressReadWrite
+ 					parameters: #(WordsOrBytes Unsigned Unsigned)
+ 					receiver: #Oop.
+ 	(cpu := self startOfData: cpuAlien) = 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
+ 	prevInterruptCheckChain := interpreterProxy setInterruptCheckChain: #forceStopOnInterrupt asSymbol.
+ 	prevInterruptCheckChain = #forceStopOnInterrupt asSymbol ifTrue:
+ 		[prevInterruptCheckChain = 0].
+ 	maybeErr := self runCPU: cpu
+ 					In: memory
+ 					Size: (interpreterProxy byteSizeOf: memory cPtrAsOop)
+ 					MinAddressRead: minAddress
+ 					Write: minWriteMaxExecAddress.
+ 	interpreterProxy setInterruptCheckChain: prevInterruptCheckChain.
+ 	maybeErr ~= 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrInappropriate].
+ 	^cpuAlien!

Item was added:
+ ----- Method: GdbARMPlugin>>primitiveSingleStepInMemory:minimumAddress:readOnlyBelow: (in category 'primitives') -----
+ "cpuAlien <GdbARMAlien>" primitiveSingleStepInMemory: memory "<Bitmap|ByteArray|WordArray>" minimumAddress: minAddress "<Integer>"  readOnlyBelow: minWriteMaxExecAddress "<Integer>"
+ 	"Single-step the cpu using the first argument as the memory and the following arguments defining valid addresses."
+ 	| cpuAlien cpu maybeErr |
+ 	<var: #cpu type: #'void *'>
+ 	cpuAlien := self primitive: #primitiveSingleStepInMemoryMinimumAddressReadWrite
+ 					parameters: #(WordsOrBytes Unsigned Unsigned)
+ 					receiver: #Oop.
+ 	(cpu := self startOfData: cpuAlien) = 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrBadReceiver].
+ 	maybeErr := self singleStepCPU: cpu
+ 					In: memory
+ 					Size: (interpreterProxy byteSizeOf: memory cPtrAsOop)
+ 					MinAddressRead: minAddress
+ 					Write: minWriteMaxExecAddress.
+ 	maybeErr ~= 0 ifTrue:
+ 		[^interpreterProxy primitiveFailFor: PrimErrInappropriate].
+ 	^cpuAlien!

Item was added:
+ ----- Method: GdbARMPlugin>>sizeField: (in category 'alien support') -----
+ sizeField: rcvr
+ 	"Answer the first field of rcvr which is assumed to be an Alien of at least 8 bytes"
+ 	<inline: true>
+ 	^self longAt: rcvr + BaseHeaderSize!

Item was added:
+ ----- Method: GdbARMPlugin>>startOfData: (in category 'alien support') -----
+ startOfData: rcvr "<Alien oop> ^<Integer>"
+ 	"Answer the start of rcvr's data.  For direct aliens this is the address of
+ 	 the second field.  For indirect and pointer aliens it is what the second field points to."
+ 	<inline: true>
+ 	^(self sizeField: rcvr) > 0
+ 	 	ifTrue: [rcvr + BaseHeaderSize + BytesPerOop]
+ 		ifFalse: [self longAt: rcvr + BaseHeaderSize + BytesPerOop]!



More information about the Vm-dev mailing list