Allow to set register value using via `GDBRegisterWithValue >> #value:`
authorJan Vrany <jan.vrany@labware.com>
Thu, 14 Oct 2021 14:23:27 +0200
changeset 238 bdf011a6482b
parent 237 81a18c404314
child 239 112a40bdd2a9
Allow to set register value using via `GDBRegisterWithValue >> #value:` This is currently limited to integer registers only.
GDBFrame.st
GDBRegisterWithValue.st
GDBTransientDataHolder.st
--- a/GDBFrame.st	Fri Sep 10 22:12:22 2021 +0100
+++ b/GDBFrame.st	Thu Oct 14 14:23:27 2021 +0200
@@ -73,7 +73,16 @@
 !GDBFrame methodsFor:'accessing'!
 
 addr
+    addr isNil ifTrue: [ 
+        | result updated |
+
+        result := debugger send: (GDBMI_stack_list_frames new arguments: (Array with:  '--thread' with: thread id with: level with: level )).
+        updated := (result propertyAt: #stack) first.
+        addr := updated addr.
+    ].
     ^ addr
+
+    "Modified: / 14-10-2021 / 14:16:10 / Jan Vrany <jan.vrany@labware.com>"
 !
 
 address
@@ -335,6 +344,21 @@
 
 !GDBFrame methodsFor:'private'!
 
+invalidate
+    variables notNil ifTrue: [ variables invalidate ].
+    registers notNil ifTrue: [ registers do:[:each | each invalidate ] ].
+    registersChanges notNil ifTrue: [ registersChanges invalidate ].
+
+    "/ We also have to invalidate the frame PC because it may have changed
+    "/ (for example, someone set the PC register to an arbitrary value).
+    "/ 
+    "/ New PC is lazily refetched in #addr.
+    addr := nil
+
+    "Created: / 10-09-2021 / 15:37:31 / Jan Vrany <jan.vrany@labware.com>"
+    "Modified (comment): / 14-10-2021 / 14:22:49 / Jan Vrany <jan.vrany@labware.com>"
+!
+
 registersChanges
     registersChanges isNil ifTrue:[ 
         self isValid ifTrue:[
--- a/GDBRegisterWithValue.st	Fri Sep 10 22:12:22 2021 +0100
+++ b/GDBRegisterWithValue.st	Thu Oct 14 14:23:27 2021 +0200
@@ -22,7 +22,7 @@
 "{ NameSpace: Smalltalk }"
 
 GDBDebuggerObject subclass:#GDBRegisterWithValue
-	instanceVariableNames:'register frame value changed'
+	instanceVariableNames:'register frame valueString value changed'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'GDB-Core'
@@ -96,25 +96,57 @@
          of FPR might be returned as '{float = 0xABCDDCBA, double = 0xA...B}'
          Similarly for vector registers (SSE / SSE2 regs on x86, VSRs on POWER)
     "
-    ^ (GDBMIParser on: self valueString) parseValue
+    value isNil ifTrue: [
+        value := (GDBMIParser on: self valueString) parseValue.
+        "/ Sigh, we do now know the 'type' of the register (that is,
+        "/ GPR, FPR, SPR or some other kind. We do not even know the bitsize. 
+        "/ Still, it is kinda handy to intepret GPRs as signed value.
+        "/ 
+        "/ However, #parseValue returns it as unsigned value, so we make
+        "/ some guesses based on unsigned value.
+        "/ 
+        "/ First, assume it is 64bit unsigned value...
+        (value between: 16r8000000000000000 and: 16rFFFFFFFFFFFFFFFF) ifTrue: [ 
+            value := (value bitAnd:16rFFFFFFFFFFFFFFFF)-16r10000000000000000 
+        ] ifFalse: [ 
+            "/ ...then assume it is 32bit value...
+            (valueString size == (2+8) and:[value between: 16r80000000 and: 16rFFFFFFFF]) ifTrue: [ 
+                value := (value bitAnd:16rFFFFFFFF)-16r100000000 
+            ].
+        ].
+    ].
+    ^ value
 
     "Modified: / 27-09-2018 / 15:26:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 10-09-2021 / 14:58:56 / Jan Vrany <jan.vrany@labware.com>"
-    "Modified (comment): / 10-09-2021 / 20:00:13 / Jan Vrany <jan.vrany@labware.com>"
+    "Modified: / 14-10-2021 / 01:23:34 / Jan Vrany <jan.vrany@labware.com>"
+!
+
+value: anObject
+    "Set the value of register. Currently this is limited to integer registers
+     only."
+
+    self value isInteger ifFalse: [ 
+        self error: 'Compound values not supported'.
+    ].
+    debugger send: (GDBMI_data_evaluate_expression arguments: (Array with: '--thread' with: frame thread id with: '--frame' with: frame level with: ('$', register name , ' = ' , (anObject asInteger printString) ))) andWait: false.
+    frame invalidate.
+
+    "Created: / 10-09-2021 / 15:31:35 / Jan Vrany <jan.vrany@labware.com>"
+    "Modified: / 14-10-2021 / 01:24:05 / Jan Vrany <jan.vrany@labware.com>"
 !
 
 valueString
-    value isNil ifTrue: [
+    valueString isNil ifTrue: [
         | result registers |
         result := debugger send: (GDBMI_data_list_register_values new arguments: (Array with: '--thread' with: frame thread id with: '--frame' with: frame level with: 'r' with: register number)).
         registers := result propertyAt: #'register-values'.     
         self assert: registers size == 1.
         self assert: registers first register = register number.
-        value := registers first valueString.
+        valueString := registers first valueString.
     ] ifFalse: [
         changed value.
     ].
-    ^ value
+    ^ valueString
 
     "Created: / 10-09-2021 / 14:14:14 / Jan Vrany <jan.vrany@labware.com>"
     "Modified: / 10-09-2021 / 15:58:15 / Jan Vrany <jan.vrany@labware.com>"
@@ -130,8 +162,8 @@
 
             changes := frame registersChanges.
             change := changes detect:[:each | each number = self number ] ifNone:[ nil ].
-            (change notNil and:[change value ~= value]) ifTrue:[ 
-                value := change value.
+            (change notNil and:[change value ~= valueString]) ifTrue:[ 
+                valueString := change value.
                 true
             ] ifFalse:[ 
                 false
@@ -174,7 +206,7 @@
         register name printOn:aStream.    
     ].
     aStream nextPutAll: ': '.
-    value printOn: aStream.
+    valueString printOn: aStream.
     aStream nextPut:$).
 
     "Modified: / 26-09-2018 / 10:48:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
@@ -186,6 +218,19 @@
     register := anInteger
 
     "Created: / 26-09-2018 / 10:39:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+_value: aString
+    valueString := aString
+
+    "Created: / 10-09-2021 / 15:43:04 / Jan Vrany <jan.vrany@labware.com>"
+!
+
+invalidate
+    changed notNil ifTrue: [ changed invalidate ].
+    valueString := nil.
+    value := nil.
+    "Created: / 10-09-2021 / 15:37:58 / Jan Vrany <jan.vrany@labware.com>"
 ! !
 
 !GDBRegisterWithValue methodsFor:'queries'!
--- a/GDBTransientDataHolder.st	Fri Sep 10 22:12:22 2021 +0100
+++ b/GDBTransientDataHolder.st	Thu Oct 14 14:23:27 2021 +0200
@@ -150,6 +150,14 @@
     "Modified: / 08-09-2018 / 15:40:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!GDBTransientDataHolder methodsFor:'utilities'!
+
+invalidate
+    value := InvalidValue
+
+    "Created: / 10-09-2021 / 15:34:40 / Jan Vrany <jan.vrany@labware.com>"
+! !
+
 !GDBTransientDataHolder class methodsFor:'documentation'!
 
 version_HG