Boris G. Shingarov uploaded a new version of GDB to project VM Maker: http://source.squeak.org/VMMaker/GDB-bgs.3.mcz ==================== Summary ==================== Name: GDB-bgs.3 Author: bgs Time: 26 May 2020, 5:24:25.12793 pm UUID: 8de059b8-c7b7-4943-80e4-f10d5993d794 Ancestors: GDB-bgs.2 Execution on non-simulated hardware. =============== Diff against GDB-bgs.1 =============== Item was changed: ----- Method: FakeProcessorDescriptionX86 class>>fakeFeatures (in category 'as yet unclassified') ----- fakeFeatures + ^TargetAwareX86 isHardware + ifTrue: [self fakeFeaturesStockSilicon] + ifFalse: [self fakeFeaturesGem5]! - ^#( - #('eax' 32) #('ecx' 32) #('edx' 32) #('ebx' 32) #('esp' 32) #('ebp' 32) #('esi' 32) #('edi' 32) - #('eip' 32) #('eflags' 32) #('cs' 32) #('ss' 32) #('ds' 32) #('es' 32) #('fs' 32) #('gs' 32) - ) - " - #('st0' 80) #('st1' 80) #('st2' 80) #('st3' 80) #('st4' 80) #('st5' 80) #('st6' 80) #('st7' 80) - - #('fctrl' 32) - #('fstat' 32) - #('ftag' 32) - #('fiseg' 32) - #('fioff' 32) - #('foseg' 32) - #('fooff' 32) - #('fop' 32) - ) - "! Item was added: + ----- Method: FakeProcessorDescriptionX86 class>>fakeFeaturesGem5 (in category 'as yet unclassified') ----- + fakeFeaturesGem5 + ^#( + #('eax' 32) #('ecx' 32) #('edx' 32) #('ebx' 32) #('esp' 32) #('ebp' 32) #('esi' 32) #('edi' 32) + #('eip' 32) #('eflags' 32) #('cs' 32) #('ss' 32) #('ds' 32) #('es' 32) #('fs' 32) #('gs' 32) + )! Item was added: + ----- Method: FakeProcessorDescriptionX86 class>>fakeFeaturesStockSilicon (in category 'as yet unclassified') ----- + fakeFeaturesStockSilicon + ^#( + #('eax' 32) #('ecx' 32) #('edx' 32) #('ebx' 32) #('esp' 32) #('ebp' 32) #('esi' 32) #('edi' 32) + #('eip' 32) #('eflags' 32) #('cs' 32) #('ss' 32) #('ds' 32) #('es' 32) #('fs' 32) #('gs' 32) + + #('st0' 80) #('st1' 80) #('st2' 80) #('st3' 80) #('st4' 80) #('st5' 80) #('st6' 80) #('st7' 80) + #('fctrl' 32) #('fstat' 32) #('ftag' 32) #('fiseg' 32) #('fioff' 32) #('foseg' 32) #('fooff' 32) #('fop' 32) + + "sse" + #('xmm0' 128) #('xmm1' 128) #('xmm2' 128) #('xmm3' 128) #('xmm4' 128) #('xmm5' 128) #('xmm6' 128) #('xmm7' 128) + #('mxcsr' 32) + + #('orig_eax' 32) + ) + + ! Item was added: + ----- Method: FakeProcessorDescriptionX86>>z1kind (in category 'as yet unclassified') ----- + z1kind + ^1! Item was changed: + SharedRAM subclass: #Gem5SharedRAM + instanceVariableNames: 'tlb' - RemoteRAM subclass: #Gem5SharedRAM - instanceVariableNames: 'tlb hostPtr shmemSize' classVariableNames: '' poolDictionaries: '' category: 'GDB-RSP'! Item was removed: - ----- Method: Gem5SharedRAM class>>gem5: (in category 'FFI') ----- - gem5: nBytes - "Answer the void* pointer to the backing store of the gem5 guest memory." - | fd addr | - fd := self shmOpen: '/gem5' - with: 64"O_CREAT" | 2"O_RDWR" - with: 8r666. "mode" - addr := self mmap: 0 - with: nBytes - with: 1"PROT_READ" | 2"PROT_WRITE" - with: 1 "MAP_SHARED" - with: fd - with: 0. - ^addr - - " - Gem5SharedRAM halt; gem5: 5000 - " - ! Item was removed: - ----- Method: Gem5SharedRAM class>>mmap:with:with:with:with:with: (in category 'FFI') ----- - mmap: addr with: length with: prot with: flags with: fd with: offset - <cdecl: void* 'mmap' (longlong longlong long long long longlong) module: '/lib/x86_64-linux-gnu/libc.so.6'> - ^self externalCallFailed - ! Item was removed: - ----- Method: Gem5SharedRAM class>>mmuPageSize (in category 'granularity') ----- - mmuPageSize - ^4096! Item was removed: - ----- Method: Gem5SharedRAM class>>offsetMask (in category 'granularity') ----- - offsetMask - ^self mmuPageSize - 1! Item was removed: - ----- Method: Gem5SharedRAM class>>pageMask (in category 'granularity') ----- - pageMask - ^16rFFFFFFFF bitXor: self offsetMask - ! Item was removed: - ----- Method: Gem5SharedRAM class>>shmOpen:with:with: (in category 'FFI') ----- - shmOpen: name with: oflag with: mode - <cdecl: ulong 'shm_open' (char* ulong ulong) module: '/lib/x86_64-linux-gnu/librt.so.1'> - ^self externalCallFailed - ! Item was removed: - ----- Method: Gem5SharedRAM>>byteAtAddr:put: (in category 'writing') ----- - byteAtAddr: byteAddress put: byte - | ptr | - byteAddress = 16r109014 ifTrue: [self halt]. - ptr := self translate: byteAddress. - ptr unsignedByteAt: 1 put: byte! Item was removed: - ----- Method: Gem5SharedRAM>>fillFromStream:startingAt:count: (in category 'writing') ----- - fillFromStream: aFileStream startingAt: startAddress count: count - | contents | - contents := aFileStream next: count. - self writeBytes: contents toAddr: startAddress. - ^contents size! Item was removed: - ----- Method: Gem5SharedRAM>>forceRead32At: (in category 'address translation') ----- - forceRead32At: addr - | x | - self halt. "I don't remember why this was needed." - x := super read32At: addr. - tlb := self getTLB. - ^x - ! Item was removed: - ----- Method: Gem5SharedRAM>>forceReadAt:nBytes: (in category 'address translation') ----- - forceReadAt: addr nBytes: n - super readAt: addr nBytes: n. - tlb := self getTLB! Item was removed: - ----- Method: Gem5SharedRAM>>forceWriteBytes:toAddr: (in category 'address translation') ----- - forceWriteBytes: aByteArray toAddr: addr - | x | - x := super writeBytes: aByteArray toAddr: addr. - tlb := self getTLB. - ^x - ! Item was removed: - ----- Method: Gem5SharedRAM>>forceWriteInt32:toAddr: (in category 'address translation') ----- - forceWriteInt32: int toAddr: addr - | x | - x := super writeInt32: int toAddr: addr. - tlb := self getTLB. - ^x - ! Item was removed: - ----- Method: Gem5SharedRAM>>getTLB (in category 'RSP') ----- - getTLB - | answer | - answer := self gdb q: '.'. - answer isEmpty ifTrue: [ self error: 'GDB failed to return TLB' ]. - ^Dictionary newFromAssociations: - (((answer findTokens: ';') - collect: [ :s | s findTokens: ':' ]) - collect: [ :pair | (Integer readFrom: pair first base: 16) -> (Integer readFrom: pair last base: 16) ])! Item was removed: - ----- Method: Gem5SharedRAM>>hostPtr (in category 'shmem') ----- - hostPtr - hostPtr isNil ifTrue: [ hostPtr := Gem5SharedRAM gem5: shmemSize ]. - ^hostPtr! Item was removed: - ----- Method: Gem5SharedRAM>>longAtAddr:put:bigEndian: (in category 'writing') ----- - longAtAddr: addr put: aValue bigEndian: bigEndian - | ptr int | - int := bigEndian - ifTrue: [ aValue byteSwap32 ] - ifFalse: [ aValue ]. - ptr := self translate: addr. - ptr unsignedLongAt: 1 put: int - - - - ! Item was removed: - ----- Method: Gem5SharedRAM>>read:bytesAtAddr: (in category 'reading') ----- - read: n bytesAtAddr: addr - | backingAddr | - backingAddr := self translate: addr. - ^((1 to: n) collect: [ :idx| backingAddr byteAt: idx ]) asByteArray - ! Item was removed: - ----- Method: Gem5SharedRAM>>shmemSize (in category 'shmem') ----- - shmemSize - ^shmemSize! Item was removed: - ----- Method: Gem5SharedRAM>>shmemSize: (in category 'shmem') ----- - shmemSize: howBig - shmemSize := howBig! Item was changed: ----- Method: Gem5SharedRAM>>tlb (in category 'address translation') ----- tlb tlb isNil ifTrue: [ tlb := self getTLB ]. ^tlb! Item was removed: - ----- Method: Gem5SharedRAM>>translate: (in category 'address translation') ----- - translate: addr - | pageAddr | - pageAddr := self virt2phys: addr. - pageAddr isNil ifTrue: [ ^ self error forceRead32At: addr ]. - ^self hostPtr getHandle + pageAddr. - ! Item was removed: - ----- Method: Gem5SharedRAM>>unsignedLongAtAddr:bigEndian: (in category 'reading') ----- - unsignedLongAtAddr: addr bigEndian: bigEndian - | backingAddr int | - backingAddr := self translate: addr. - int := backingAddr unsignedLongAt: 1. - bigEndian ifTrue: [ int := int byteSwap32]. - ^int! Item was changed: ----- Method: Gem5SharedRAM>>virt2phys: (in category 'address translation') ----- virt2phys: anAddress " Answer the physical address for the given virtual address, if it is mapped, nil otherwise. " | pageVirt pagePhys | pageVirt := anAddress bitAnd: self class pageMask. pagePhys := self tlb at: pageVirt ifAbsent: [ ^nil ]. ^pagePhys bitOr: (anAddress bitAnd: self class offsetMask)! Item was removed: - ----- Method: Gem5SharedRAM>>writeBytes:toAddr: (in category 'writing') ----- - writeBytes: aByteArray toAddr: addr - | ptr | - addr = 16r109014 ifTrue: [self halt]. - ptr := self translate: addr. - aByteArray doWithIndex: [ :x :idx | ptr unsignedByteAt: idx put: x ] "is there a faster way?" - ! Item was changed: + ThinshellDoodle subclass: #HardwareBreakpointDoodle - PPCgem5ThinshellDoodle subclass: #HardwareBreakpointDoodle instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'GDB-Doodles'! Item was changed: ----- Method: HardwareBreakpointDoodle>>hostIP (in category 'target connection') ----- hostIP + ^'192.168.75.2' + ! - ^'192.168.75.2'! Item was added: + ----- Method: HardwareBreakpointDoodle>>initialPC (in category 'tests') ----- + initialPC + ^16r10000000! Item was changed: ----- Method: HardwareBreakpointDoodle>>installBrk (in category 'tests') ----- installBrk + gdb insertHWBreakpointAt: self initialPC + 15 "3 loads"! - gdb insertHWBreakpointAt: self initialPC + 8! Item was changed: ----- Method: HardwareBreakpointDoodle>>pdl (in category 'target connection') ----- pdl + ^FakeProcessorDescriptionX86 new + ! - ^FakeProcessorDescriptionPPC new! Item was added: + ----- Method: HardwareBreakpointDoodle>>tcpPort (in category 'target connection') ----- + tcpPort + ^7000 + ! Item was changed: ----- Method: HardwareBreakpointDoodle>>testHWBrk (in category 'tests') ----- testHWBrk " HardwareBreakpointDoodle new halt; testHWBrk. " + | regs | self connectGdb; installBrk. + regs := gdb getRegisters. + self assert: (regs at: 'eip') = self initialPC. + self assert: (regs at: 'eax') ~= 16r12345678. + self assert: (regs at: 'ebx') ~= 16r12345678. + self assert: (regs at: 'ecx') ~= 16r12345678. + self assert: (regs at: 'edx') ~= 16r12345678. - gdb c. - self assert: gdb pc equals: self initialPC + 8. - self fillNZone. + gdb c. + regs := gdb getRegisters. + self assert: (regs at: 'eip') = (self initialPC + 15). + self assert: (regs at: 'eax') = 16r12345678. + self assert: (regs at: 'ebx') = 16r12345678. + self assert: (regs at: 'ecx') = 16r12345678. + self assert: (regs at: 'edx') ~= 16r12345678. + + [ gdb kill ] on: GdbChildExited do: [ ^self ]. + self error: 'gdbserver did not disconnect'! - "No need to advance, because this is not a trap." - [ gdb c ] on: GdbChildExited do: [ ^self ]. - self error! Item was added: + ----- Method: P1025ThinshellDoodle>>host (in category 'target connection') ----- + host + ^#svost! Item was removed: - ----- Method: P1025ThinshellDoodle>>hostIP (in category 'target connection') ----- - hostIP - ^'192.168.75.199'! Item was removed: - ----- Method: P1025ThinshellDoodle>>pdl (in category 'target connection') ----- - pdl - ^FakeProcessorDescriptionP1025 new! Item was added: + ----- Method: PPCThinshellDoodle>>host (in category 'target connection') ----- + host + "We experiment with PowerPC on either a physical dev board (P1025), + or on gem5. Concrete doodles must answer #svost or #gem5." + ^self subclassResponsibility! Item was added: + ----- Method: PPCThinshellDoodle>>hostIP (in category 'target connection') ----- + hostIP + self host = #svost ifTrue: [^'192.168.75.199']. + self host = #gem5 ifTrue: [^'192.168.75.2']. + self error: 'what host is this?'! Item was added: + ----- Method: PPCThinshellDoodle>>pdl (in category 'target connection') ----- + pdl + self host = #svost ifTrue: [^FakeProcessorDescriptionP1025 new]. + self host = #gem5 ifTrue: [^FakeProcessorDescriptionPPC new]. + self error: 'what host is this?'! Item was added: + ----- Method: PPCgem5ThinshellDoodle>>host (in category 'target connection') ----- + host + ^#gem5! Item was removed: - ----- Method: PPCgem5ThinshellDoodle>>hostIP (in category 'target connection') ----- - hostIP - ^'192.168.75.2'! Item was removed: - ----- Method: PPCgem5ThinshellDoodle>>pdl (in category 'target connection') ----- - pdl - ^FakeProcessorDescriptionPPC new! Item was changed: RemoteGDBTransport subclass: #RemoteGDB + instanceVariableNames: 'packetSize processorDescription tStatus why supported vCont registerCache' - instanceVariableNames: 'packetSize processorDescription tStatus why supported vCont' classVariableNames: '' poolDictionaries: '' category: 'GDB-RSP'! Item was changed: ----- Method: RemoteGDB>>analyzeContinueAnswerT: (in category 'stop codes') ----- analyzeContinueAnswerT: answer | signal textPairs importantRegs thread core stopReason stopArgument | signal := self signalNumberFrom: answer. textPairs := answer copyFrom: 3 to: answer size. textPairs := textPairs findTokens: ';'. importantRegs := Dictionary new. core := nil. thread := nil. stopReason := nil. stopArgument := nil. textPairs do: [ :textPair | | pair k v | pair := textPair findTokens: ':'. k := pair first. v := pair second. (self recognizedStopCodes includes: k) ifTrue: [ stopReason := k. stopArgument := v ] ifFalse: [ k = 'thread' ifTrue: [ thread := v ] ifFalse: [ k = 'core' ifTrue: [ core := v ] ifFalse: [ importantRegs at: k put: (Integer readFrom: k base: 16) "TODO: Missing the reserved case; this will be handled by catching exception in #readFrom: and discarding it" ]]]]. + "TODO: wrap all these things in the DebugStopped" + ^DebugStopped onSignalNum: signal! - self shouldBeImplemented "In TAM, this simply returns; processing is done in the sender after this call." - ! Item was changed: ----- Method: RemoteGDB>>c (in category 'RSP commands') ----- c " Continue. " | answer | + self resetRegisterCache. answer := self q: 'c'. "NB: on some platforms, we have wanted 'vCont;c'. I forgot why." ^self analyzeContinueAnswer: answer! Item was changed: + ----- Method: RemoteGDB>>getRegisters (in category 'register cache') ----- - ----- Method: RemoteGDB>>getRegisters (in category 'RSP commands') ----- getRegisters + registerCache isNil ifTrue: [ registerCache := self getRegistersFromRSP ]. + ^registerCache! - | answer stream | - answer := self q: 'g'. - stream := ReadStream on: answer - from: 1 - to: answer size. - ^self decodeGPacket: stream! Item was added: + ----- Method: RemoteGDB>>getRegistersFromRSP (in category 'RSP commands') ----- + getRegistersFromRSP + | answer stream | + answer := self q: 'g'. + stream := ReadStream on: answer + from: 1 + to: answer size. + + ^self decodeGPacket: stream! Item was changed: ----- Method: RemoteGDB>>insertHWBreakpointAt: (in category 'general query commands') ----- insertHWBreakpointAt: addr | answer | answer := self q: 'Z1,', addr printStringHex, + ',', + self z1kind printStringHex. - ',4'. answer = 'OK' ifFalse: [ self error ]! Item was added: + ----- Method: RemoteGDB>>resetRegisterCache (in category 'register cache') ----- + resetRegisterCache + registerCache isNil ifFalse: [self sendRegistersToRSP]. + registerCache := nil! Item was changed: ----- Method: RemoteGDB>>s (in category 'RSP commands') ----- s "Single step. Return control with signal 5 (TRAP), or if the execution of the current instruction failed, with whatever signal happened." | answer | + self resetRegisterCache. answer := self q: 's'. ^self analyzeContinueAnswer: answer ! Item was added: + ----- Method: RemoteGDB>>sendRegistersToRSP (in category 'RSP commands') ----- + sendRegistersToRSP + | answer stream registerTransfers | + stream := WriteStream on: String new. + registerTransfers := processorDescription regsInGPacket. + registerTransfers do: [ :rt | + rt write: registerCache to: stream ]. + + answer := self q: 'G', stream contents. + answer = 'OK' ifFalse: [self error: answer]! Item was changed: + ----- Method: RemoteGDB>>setRegisters: (in category 'register cache') ----- - ----- Method: RemoteGDB>>setRegisters: (in category 'RSP commands') ----- setRegisters: aDict + self shouldBeImplemented! - | answer stream registerTransfers | - stream := WriteStream on: String new. - registerTransfers := processorDescription regsInGPacket. - registerTransfers do: [ :rt | - rt write: aDict to: stream ]. - - answer := self q: 'G', stream contents. - answer = 'OK' ifFalse: [self error: answer]! Item was added: + ----- Method: RemoteGDB>>z1kind (in category 'general query commands') ----- + z1kind + ^processorDescription z1kind! Item was changed: ----- Method: RemoteGDBSession>>setRegister:to: (in category 'accessing') ----- setRegister: r to: x + self getRegisters at: r put: x + ! - | regs | - regs := self getRegisters. - regs at: r put: x. - self setRegisters: regs! Item was changed: ----- Method: RemoteMemoryDoodle>>testLowLevelWrite (in category 'tests-reading') ----- testLowLevelWrite " RemoteMemoryDoodle new testLowLevelWrite " | goodAddress | self connectGdb. goodAddress := self initialPC. memory writeBytes: #[1 2 3 4] toAddr: goodAddress. self assert: (memory unsignedLongAtAddr: goodAddress bigEndian: true) equals: 16r01020304. self assert: (memory unsignedLongAt: goodAddress + 1 bigEndian: true) equals: 16r01020304. self assert: (memory read: 4 bytesAtAddr: goodAddress) equals: #[1 2 3 4]. + self assert: (memory unsignedByteAtAddr: goodAddress) equals: 1. + self assert: (memory unsignedByteAtAddr: goodAddress+1) equals: 2. - self assert: (memory unsignedByteAtAddr: 16r10000080) equals: 1. - self assert: (memory unsignedByteAtAddr: 16r10000081) equals: 2. [ gdb kill ] on: GdbChildExited do: [ ^self ] ! Item was added: + ----- Method: RemoteRAM>>long64At: (in category 'reading') ----- + long64At: byteIndex + ^self signedLong64At: byteIndex! Item was changed: + ----- Method: RemoteRAM>>long64At:put: (in category 'writing') ----- - ----- Method: RemoteRAM>>long64At:put: (in category 'reading') ----- long64At: byteIndex put: aValue | lowBits mask wordIndex | (lowBits := byteIndex - 1 \\ 4) = 0 ifTrue: [self "N.B. Do the access that can fail first, before altering the receiver" longAt: byteIndex + 4 put: (aValue bitShift: -32); unsignedLongAt: byteIndex put: (aValue bitAnd: 16rffffffff). ^aValue]. "There will always be three accesses; two partial words and a full word in the middle" wordIndex := byteIndex - 1 // 4 + 1. aValue < 0 ifTrue: [(aValue bitShift: -32) < -2147483648 ifTrue: [^self errorImproperStore]] ifFalse: [16r7FFFFFFF < (aValue bitShift: -32) ifTrue: [^self errorImproperStore]]. mask := 16rFFFFFFFF bitShift: 4 - lowBits * -8. self at: wordIndex put: (((self at: wordIndex) bitAnd: mask) bitXor: ((aValue bitShift: lowBits * 8) bitAnd: mask bitInvert32)). self at: wordIndex + 1 put: ((aValue bitShift: 4 - lowBits * -8) bitAnd: 16rFFFFFFFF). self at: wordIndex + 2 put: (((self at: wordIndex + 2) bitAnd: mask bitInvert32) bitXor: ((aValue bitShift: 4 - lowBits + 4 * -8) bitAnd: mask)). ^aValue! Item was added: + ----- Method: RemoteRAM>>longAt: (in category 'reading') ----- + longAt: byteIndex + ^self unsignedLongAtAddr: byteIndex - 1 bigEndian: false! Item was added: + ----- Method: RemoteRAM>>longAt:bigEndian: (in category 'reading') ----- + longAt: anInteger bigEndian: aBoolean + ^self unsignedLongAt: anInteger bigEndian: aBoolean ! Item was added: + ----- Method: RemoteRAM>>unsignedByteAt:put: (in category 'writing') ----- + unsignedByteAt: index put: byte + ^self byteAt: index put: byte! Item was added: + ----- Method: RemoteRAM>>unsignedLongAt: (in category 'reading') ----- + unsignedLongAt: byteIndex + ^self unsignedLongAt: byteIndex bigEndian: self isBigEndian! Item was added: + ----- Method: RemoteRAM>>unsignedShortAt: (in category 'reading') ----- + unsignedShortAt: byteIndex + ^self unsignedShortAtAddr: byteIndex - 1! Item was added: + ----- Method: RemoteRAM>>unsignedShortAt:put: (in category 'writing') ----- + unsignedShortAt: byteIndex put: aValue + "Compatiblity with the ByteArray & Alien methods of the same name." + ^self unsignedShortAtAddr: byteIndex - 1 put: aValue! Item was added: + ----- Method: RemoteRAM>>unsignedShortAtAddr: (in category 'writing') ----- + unsignedShortAtAddr: addr + ^self unsignedShortAtAddr: addr bigEndian: self isBigEndian! Item was added: + ----- Method: RemoteRAM>>unsignedShortAtAddr:put: (in category 'writing') ----- + unsignedShortAtAddr: addr put: aValue + "Compatiblity with the ByteArray & Alien methods." + self isBigEndian ifTrue: [self error]. + (aValue < 0 or: [aValue > 16rFFFF]) ifTrue: [^self errorImproperStore]. + (addr bitAnd: 1) = 0 ifFalse: [ self error: 'Unaligned short store not yet implemented' ]. + self byteAtAddr: addr put: (aValue bitAnd: 16rFF). + self byteAtAddr: addr+1 put: (aValue bitAnd: 16rFF00)>>8. + ^aValue! Item was added: + RemoteRAM subclass: #SharedRAM + instanceVariableNames: 'hostPtr shmemSize' + classVariableNames: '' + poolDictionaries: '' + category: 'GDB-RSP'! Item was added: + ----- Method: SharedRAM class>>gem5: (in category 'FFI') ----- + gem5: nBytes + "Answer the void* pointer to the backing store of the gem5 guest memory." + | fd addr | + fd := self shmOpen: '/gem5' + with: 64"O_CREAT" | 2"O_RDWR" + with: 8r666. "mode" + addr := self mmap: 0 + with: nBytes + with: 1"PROT_READ" | 2"PROT_WRITE" + with: 1 "MAP_SHARED" + with: fd + with: 0. + ^addr + + " + Gem5SharedRAM halt; gem5: 5000 + " + ! Item was added: + ----- Method: SharedRAM class>>mmap:with:with:with:with:with: (in category 'FFI') ----- + mmap: addr with: length with: prot with: flags with: fd with: offset + <cdecl: void* 'mmap' (longlong longlong long long long longlong) module: '/lib/x86_64-linux-gnu/libc.so.6'> + ^self externalCallFailed + ! Item was added: + ----- Method: SharedRAM class>>mmuPageSize (in category 'granularity') ----- + mmuPageSize + ^4096! Item was added: + ----- Method: SharedRAM class>>offsetMask (in category 'granularity') ----- + offsetMask + ^self mmuPageSize - 1! Item was added: + ----- Method: SharedRAM class>>pageMask (in category 'granularity') ----- + pageMask + ^16rFFFFFFFF bitXor: self offsetMask + ! Item was added: + ----- Method: SharedRAM class>>shmOpen:with:with: (in category 'FFI') ----- + shmOpen: name with: oflag with: mode + <cdecl: ulong 'shm_open' (char* ulong ulong) module: '/lib/x86_64-linux-gnu/librt.so.1'> + ^self externalCallFailed + ! Item was added: + ----- Method: SharedRAM>>byteAtAddr:put: (in category 'writing') ----- + byteAtAddr: byteAddress put: byte + | ptr | + byteAddress = 16r109014 ifTrue: [self halt]. + ptr := self translate: byteAddress. + ptr unsignedByteAt: 1 put: byte! Item was added: + ----- Method: SharedRAM>>fillFromStream:startingAt:count: (in category 'writing') ----- + fillFromStream: aFileStream startingAt: startAddress count: count + | contents | + contents := aFileStream next: count. + self writeBytes: contents toAddr: startAddress. + ^contents size! Item was added: + ----- Method: SharedRAM>>forceRead32At: (in category 'address translation') ----- + forceRead32At: addr + | x | + self halt. "I don't remember why this was needed." + x := super read32At: addr. + tlb := self getTLB. + ^x + ! Item was added: + ----- Method: SharedRAM>>forceReadAt:nBytes: (in category 'address translation') ----- + forceReadAt: addr nBytes: n + super readAt: addr nBytes: n. + tlb := self getTLB! Item was added: + ----- Method: SharedRAM>>forceWriteBytes:toAddr: (in category 'address translation') ----- + forceWriteBytes: aByteArray toAddr: addr + | x | + x := super writeBytes: aByteArray toAddr: addr. + tlb := self getTLB. + ^x + ! Item was added: + ----- Method: SharedRAM>>forceWriteInt32:toAddr: (in category 'address translation') ----- + forceWriteInt32: int toAddr: addr + | x | + x := super writeInt32: int toAddr: addr. + tlb := self getTLB. + ^x + ! Item was added: + ----- Method: SharedRAM>>getTLB (in category 'RSP') ----- + getTLB + | answer | + answer := self gdb q: '.'. + answer isEmpty ifTrue: [ self error: 'GDB failed to return TLB' ]. + ^Dictionary newFromAssociations: + (((answer findTokens: ';') + collect: [ :s | s findTokens: ':' ]) + collect: [ :pair | (Integer readFrom: pair first base: 16) -> (Integer readFrom: pair last base: 16) ])! Item was added: + ----- Method: SharedRAM>>hostPtr (in category 'shmem') ----- + hostPtr + hostPtr isNil ifTrue: [ hostPtr := Gem5SharedRAM gem5: shmemSize ]. + ^hostPtr! Item was added: + ----- Method: SharedRAM>>longAtAddr:put:bigEndian: (in category 'writing') ----- + longAtAddr: addr put: aValue bigEndian: bigEndian + | ptr int | + int := bigEndian + ifTrue: [ aValue byteSwap32 ] + ifFalse: [ aValue ]. + ptr := self translate: addr. + ptr unsignedLongAt: 1 put: int + + + + ! Item was added: + ----- Method: SharedRAM>>read:bytesAtAddr: (in category 'reading') ----- + read: n bytesAtAddr: addr + | backingAddr | + backingAddr := self translate: addr. + ^((1 to: n) collect: [ :idx| backingAddr byteAt: idx ]) asByteArray + ! Item was added: + ----- Method: SharedRAM>>shmemSize (in category 'shmem') ----- + shmemSize + ^shmemSize! Item was added: + ----- Method: SharedRAM>>shmemSize: (in category 'shmem') ----- + shmemSize: howBig + shmemSize := howBig! Item was added: + ----- Method: SharedRAM>>translate: (in category 'address translation') ----- + translate: addr + | pageAddr | + pageAddr := self virt2phys: addr. + pageAddr isNil ifTrue: [ ^ self error forceRead32At: addr ]. + ^self hostPtr getHandle + pageAddr. + ! Item was added: + ----- Method: SharedRAM>>unsignedLongAtAddr:bigEndian: (in category 'reading') ----- + unsignedLongAtAddr: addr bigEndian: bigEndian + | backingAddr int | + backingAddr := self translate: addr. + int := backingAddr unsignedLongAt: 1. + bigEndian ifTrue: [ int := int byteSwap32]. + ^int! Item was added: + ----- Method: SharedRAM>>virt2phys: (in category 'address translation') ----- + virt2phys: anAddress + self subclassResponsibility! Item was added: + ----- Method: SharedRAM>>writeBytes:toAddr: (in category 'writing') ----- + writeBytes: aByteArray toAddr: addr + | ptr | + addr = 16r109014 ifTrue: [self halt]. + ptr := self translate: addr. + aByteArray doWithIndex: [ :x :idx | ptr unsignedByteAt: idx put: x ] "is there a faster way?" + ! Item was changed: ----- Method: ShmemDoodle>>connectGdb (in category 'target connection') ----- connectGdb super connectGdb. + memory shmemSize: 16r120000 + (120*1024*1024). "for Squeak" + plainRAM := SimpleSharedRAM gdb: gdb. - memory shmemSize: 536870912. "size of TAM's thinshell process image" - plainRAM := RemoteRAM gdb: gdb. ^gdb! Item was changed: ----- Method: ShmemDoodle>>remoteMemoryClass (in category 'target connection') ----- remoteMemoryClass + ^SimpleSharedRAM! - ^Gem5SharedRAM! Item was changed: ----- Method: ShmemDoodle>>testSharedToNonShared (in category 'tests-agreement') ----- + testSharedToNonShared + self shouldBeImplemented! - testSharedToNonShared! Item was added: + ----- Method: ShmemDoodle>>testSimpleSharedRAM (in category 'tests-agreement') ----- + testSimpleSharedRAM + " + ShmemDoodle new testSimpleSharedRAM. + + " + | rwAddress bytes | + self break. + self connectGdb. + gdb q: 'c'. "cant do real #c because we don't have a pdl with registers" + rwAddress := 16r120000. + "m shmemSize: 16r120000 + (120*1024*1024)." + bytes := memory read: 2 bytesAtAddr: rwAddress. + + memory writeBytes: #[1 2 3 4] toAddr: rwAddress. + + self assert: (memory unsignedLongAtAddr: rwAddress bigEndian: true) equals: 16r01020304. + self assert: (memory unsignedLongAt: rwAddress + 1 bigEndian: true) equals: 16r01020304. + self assert: (memory read: 4 bytesAtAddr: rwAddress) equals: #[1 2 3 4]. + self assert: (memory unsignedByteAtAddr: rwAddress) equals: 1. + self assert: (memory unsignedByteAtAddr: rwAddress+1) equals: 2. + + [ gdb kill ] on: GdbChildExited do: [ ^self ] + ! Item was added: + SharedRAM subclass: #SimpleSharedRAM + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'GDB-RSP'! Item was added: + ----- Method: SimpleSharedRAM>>virt2phys: (in category 'as yet unclassified') ----- + virt2phys: anAddress + ^anAddress - 16r20000! Item was added: + Error subclass: #SimulatedLeafReturn + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'GDB-Cog'! Item was added: + ----- Method: SimulationAddressSpace>>bytesPerElement (in category 'as yet unclassified') ----- + bytesPerElement + ^self class bytesPerElement! Item was added: + ----- Method: TargetAwareX86 class>>isHardware (in category 'machine description') ----- + isHardware + "Answer true if we are running on an actual hardware target. + Browse senders to see all places where gem5 differs from silicon." + + ^false! Item was changed: ----- Method: TargetAwareX86 class>>new (in category 'instance creation') ----- new " TargetAwareX86 new " Current := super new connectGdb. ^Current! Item was added: + ----- Method: TargetAwareX86 class>>printTempNames (in category 'class initialization') ----- + printTempNames + ^false! Item was added: + ----- Method: TargetAwareX86 class>>printTempNames: (in category 'class initialization') ----- + printTempNames: x! Item was added: + ----- Method: TargetAwareX86 class>>remoteMemoryClass (in category 'machine description') ----- + remoteMemoryClass + ^self isHardware + ifTrue: [SimpleSharedRAM] + ifFalse: [Gem5SharedRAM]! Item was added: + ----- Method: TargetAwareX86 class>>setReceiverResultReg: (in category 'class initialization') ----- + setReceiverResultReg: x! Item was added: + ----- Method: TargetAwareX86>>accessorIsFramePointerSetter: (in category 'accessing-abstract') ----- + accessorIsFramePointerSetter: accessor + "Answer if accessor is an accessor for the frame pointer. Subclasses that don't call + it fp must override to check for both names." + ^#fp: == accessor or: [#ebp: == accessor]! Item was added: + ----- Method: TargetAwareX86>>bogusRetPC (in category 'entering execution') ----- + bogusRetPC + ^16rBADF00D5! Item was added: + ----- Method: TargetAwareX86>>cResultRegister: (in category 'accessing-abstract') ----- + cResultRegister: aValue + ^self eax: aValue! Item was added: + ----- Method: TargetAwareX86>>cl (in category 'intel registers') ----- + cl + ^self ecx bitAnd: 16rFF! Item was changed: ----- Method: TargetAwareX86>>connectGdb (in category 'target connection') ----- connectGdb gdb := self debuggerClass host: self hostIP port: self tcpPort processorDescription: self pdl. + self runThinshellPrologue. ^self "not gdb; #new needs the instance"! Item was added: + ----- Method: TargetAwareX86>>controlRegisterGetters (in category 'accessing-abstract') ----- + controlRegisterGetters + ^#(eip eflags)! Item was added: + ----- Method: TargetAwareX86>>convertIntegerToInternal: (in category 'tests support') ----- + convertIntegerToInternal: anInteger + "Default conversion for 32-bit processors. 64-bit processors override." + ^anInteger signedIntToLong! Item was added: + ----- Method: TargetAwareX86>>decorateDisassembly:for:fromAddress: (in category 'disassembly') ----- + decorateDisassembly: anInstructionString for: aSymbolManager "<Cogit>" fromAddress: address + ^BochsIA32Alien new + decorateDisassembly: anInstructionString for: aSymbolManager "<Cogit>" fromAddress: address! Item was added: + ----- Method: TargetAwareX86>>disassembleCurrentInstructionIn: (in category 'disassembly') ----- + disassembleCurrentInstructionIn: memory + ^(self primitiveDisassembleAt: self pc inMemory: memory) last! Item was added: + ----- Method: TargetAwareX86>>disassembleFrom:to:in:for:labels:on: (in category 'disassembly') ----- + disassembleFrom: startAddress to: endAddress in: memory for: aSymbolManager "<Cogit>" labels: labelDictionary on: aStream + | prefix theseBytes | + prefix := ByteArray new: startAddress. + theseBytes := (startAddress to: endAddress) collect: [ :addr | memory byteAtAddr: addr ]. + BochsIA32Alien new + disassembleFrom: startAddress + to: endAddress + in: prefix, theseBytes + for: aSymbolManager "<Cogit>" + labels: labelDictionary on: aStream + ! Item was added: + ----- Method: TargetAwareX86>>disassembleInstructionAt:In: (in category 'disassembly') ----- + disassembleInstructionAt: pc In: memory + ^(self primitiveDisassembleAt: pc inMemory: memory) last! Item was added: + ----- Method: TargetAwareX86>>eflags (in category 'intel registers') ----- + eflags + ^gdb getRegister: 'eflags'! Item was added: + ----- Method: TargetAwareX86>>floatingPointRegisterStateGetters (in category 'accessing-abstract') ----- + floatingPointRegisterStateGetters + ^#()! Item was added: + ----- Method: TargetAwareX86>>handleDataFailureIn: (in category 'execution') ----- + handleDataFailureIn: memoryArray + | pc opcode | + pc := self eip. + opcode := memoryArray byteAt: pc + 1. + opcode ~= 16r0f ifTrue: + [^self + perform: (OpcodeExceptionMap at: opcode + 1) + with: pc + with: memoryArray]. + opcode := memoryArray byteAt: pc + 2. + ^self + perform: (ExtendedOpcodeExceptionMap at: opcode + 1) + with: pc + with: memoryArray! Item was changed: ----- Method: TargetAwareX86>>handleExecutionPrimitiveFailureIn:minimumAddress: (in category 'execution') ----- handleExecutionPrimitiveFailureIn: memoryArray minimumAddress: minimumAddress + "Execution stopped due to SIGSEGV. + Convert out-of-range call and absolute memory read-into-register instructions + into ProcessorSimulationTrap signals." + + "The SEGV could be caused by Fetching from an unmapped address, + or a data operation with an unmapped address. + While a simulator such as gem5 could tell us what caused the fault, + real hardware such as silicon i386 doesn't provide an easy way; + therefore, we have to look at circumstancial evidence." + (self isWithinMappedRange: self eip) + ifTrue: [ ^self handleDataFailureIn: memoryArray ] + ifFalse: [ ^self handlePcOutOfRangeIn: memoryArray ]! - "NB: THIS SHOULD GO INTO A COMMON SemihostABI CLASS -- bgs" - "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 eip. - " (() between: minimumAddress and: memoryArray byteSize - 1) ifTrue: self reportPrimitiveFailure -- TODO" - opcode := memoryArray byteAt: pc + 1. - opcode ~= 16r0f ifTrue: - [^self - perform: (OpcodeExceptionMap at: opcode + 1) - with: pc - with: memoryArray]. - opcode := memoryArray byteAt: pc + 2. - ^self - perform: (ExtendedOpcodeExceptionMap at: opcode + 1) - with: pc - with: memoryArray! Item was added: + ----- Method: TargetAwareX86>>handlePcOutOfRangeIn: (in category 'execution') ----- + handlePcOutOfRangeIn: memoryArray + | pc | + pc := self pc. + pc = self bogusRetPC ifTrue: [ ^self cResultRegister ]. + ^(ProcessorSimulationTrap + pc: nil + nextpc: nil + address: pc + type: #controlTransfer) + signal! Item was added: + ----- Method: TargetAwareX86>>initializeStackFor: (in category 'processor setup') ----- + initializeStackFor: aCogit + "Different cpus need different stack alignment etc, so handle the details here." + "This is for testing. On many OS's the stack must remain aligned; + e.g. IA32 using SSE requires 16 byte alignment." + | stackAlignment | + stackAlignment := 16. + aCogit setStackAlignment: stackAlignment expectedSPOffset: 0 expectedFPOffset: 8. + PostBuildStackDelta := stackAlignment > 8 + ifTrue: [stackAlignment - 8] + ifFalse: [0]! Item was added: + ----- Method: TargetAwareX86>>isWithinMappedRange: (in category 'execution') ----- + isWithinMappedRange: anAddress + | minimumAddress maximumAddress | + minimumAddress := 4096. + maximumAddress := 120*1024*1024 - 1. + ^anAddress >= minimumAddress and: [ anAddress <= maximumAddress ]! Item was added: + ----- Method: TargetAwareX86>>leafRetpcIn: (in category 'accessing-abstract') ----- + leafRetpcIn: aMemory + ^aMemory unsignedLongAt: self esp + 1 bigEndian: false! Item was added: + ----- Method: TargetAwareX86>>popWordIn: (in category 'execution') ----- + popWordIn: aMemory + | sp word | + word := aMemory unsignedLongAt: (sp := self esp) + 1 bigEndian: false. + self esp: sp + 4. + ^word! Item was added: + ----- Method: TargetAwareX86>>postCallArgumentsNumArgs:in: (in category 'execution') ----- + postCallArgumentsNumArgs: numArgs "<Integer>" in: memory "<ByteArray|Bitmap>" + "Answer an argument vector of the requested size after a vanilla + ABI call. On IA32 this typically means accessing stacked arguments + beyond the pushed return address and saved frame pointer. + For compatibility with Cog/Slang we answer unsigned values." + ^(9 to: numArgs * 4 + 5 by: 4) collect: + [:i| + memory unsignedLongAt: self ebp + i bigEndian: false]! Item was added: + ----- Method: TargetAwareX86>>primitiveDisassembleAt:inMemory: (in category 'disassembly') ----- + primitiveDisassembleAt: address inMemory: memory + | prefix theseBytes | + prefix := ByteArray new: address. + theseBytes := (address to: address + 16) collect: [ :addr | memory byteAtAddr: addr ]. + ^BochsIA32Alien new + primitiveDisassembleAt: address inMemory: prefix, theseBytes! Item was added: + ----- Method: TargetAwareX86>>printNameOn: (in category 'printing') ----- + printNameOn: aStream + super printOn: aStream! Item was added: + ----- Method: TargetAwareX86>>registerStateGetters (in category 'accessing-abstract') ----- + registerStateGetters + ^#( eax ecx edx ebx esp ebp esi edi eip eflags )! Item was removed: - ----- Method: TargetAwareX86>>remoteMemoryClass (in category 'target connection') ----- - remoteMemoryClass - ^Gem5SharedRAM! Item was added: + ----- Method: TargetAwareX86>>reportPrimitiveFailure (in category 'error handling') ----- + reportPrimitiveFailure + self shouldBeImplemented! Item was added: + ----- Method: TargetAwareX86>>retpcIn: (in category 'accessing-abstract') ----- + retpcIn: aMemory + ^aMemory unsignedLongAt: self ebp + 5 bigEndian: false! Item was added: + ----- Method: TargetAwareX86>>runInMemory:minimumAddress: (in category 'execution') ----- + runInMemory: aMemory minimumAddress: minimumAddress + | stopReason | + stopReason := gdb c. + stopReason signal = #SIGSEGV ifTrue: [ + ^self + handleExecutionPrimitiveFailureIn: aMemory + minimumAddress: minimumAddress ]. + stopReason signal = #SIGQUIT ifTrue: [ ^self halt ]. + + "There can be a number of other reasons to stop. + For example, a debug breakpoint." + self shouldBeImplemented! Item was changed: ----- Method: TargetAwareX86>>runInMemory:minimumAddress:readOnlyBelow: (in category 'execution') ----- runInMemory: aMemory minimumAddress: minimumAddress readOnlyBelow: minimumWritableAddress + ^self runInMemory: aMemory minimumAddress: minimumAddress! - | stopReason | - stopReason := gdb c. - stopReason signal = #SIGSEGV ifFalse: [ self shouldBeImplemented ]. - ^self - handleExecutionPrimitiveFailureIn: aMemory - minimumAddress: minimumAddress! Item was added: + ----- Method: TargetAwareX86>>runThinshellPrologue (in category 'target connection') ----- + runThinshellPrologue + "Run the thinshell's _start to do whatever initialization it needs, + until it stops (usually indicates 'I am done' by segfaulting or trapping)" + gdb c! Item was added: + ----- Method: TargetAwareX86>>simulateBuildFrameIn:for: (in category 'execution') ----- + simulateBuildFrameIn: aMemory for: evaluable + "Simulate a frame-building call of address. Build a frame since + a) this is used for calls into the run-time which are unlikely to be leaf-calls, and + b) stack alignment needs to be realistic for assert checking for platforms such as Mac OS X" + | sp | + sp := self esp. + self pushWord: sp in: aMemory. + sp := sp - 4. + self ebp: sp. + PostBuildStackDelta ~= 0 ifTrue: + [self esp: sp - PostBuildStackDelta]. + ! Item was added: + ----- Method: TargetAwareX86>>simulateCallIn: (in category 'execution') ----- + simulateCallIn: aMemory + "The return address has already been pushed." + self pushWord: self ebp in: aMemory. + self ebp: self esp. + PostBuildStackDelta ~= 0 ifTrue: + [self esp: self esp - PostBuildStackDelta].! Item was added: + ----- Method: TargetAwareX86>>simulateCallOf: (in category 'execution') ----- + simulateCallOf: anAddress + self shouldBeImplemented! Item was added: + ----- Method: TargetAwareX86>>simulateCallOf:nextpc:memory: (in category 'execution') ----- + simulateCallOf: address nextpc: nextpc memory: aMemory + "Simulate a frame-building call of address. Build a frame since + a) this is used for calls into the run-time which are unlikely to be leaf-calls, and + b) stack alignment needs to be realistic for assert checking for platforms such as Mac OS X" + self pushWord: nextpc in: aMemory. + self pushWord: self ebp in: aMemory. + self ebp: self esp. + PostBuildStackDelta ~= 0 ifTrue: + [self esp: self esp - PostBuildStackDelta]. + self eip: address! Item was added: + ----- Method: TargetAwareX86>>simulateJumpCallOf:memory: (in category 'execution') ----- + simulateJumpCallOf: address memory: aMemory + "Simulate a frame-building jump call of address (i.e. do not push the return pc + as this has already been done). Build a frame since + a) this is used for calls into the run-time which are unlikely to be leaf-calls, and + b) stack alignment needs to be realistic for assert checking for platforms such as Mac OS X" + self pushWord: self ebp in: aMemory. + self ebp: self esp. + PostBuildStackDelta ~= 0 ifTrue: + [self esp: self esp - PostBuildStackDelta]. + self eip: address! Item was added: + ----- Method: TargetAwareX86>>simulateLeafCallOf:for: (in category 'entering execution') ----- + simulateLeafCallOf: someFunction for: aCogit + "Natively execute the CPU code for someFunction until it returns. + Answer the contents of the C ABI return register, an Integer." + | priorSP priorPC spOnEntry | + priorSP := self sp. + priorPC := self pc. + self + setFramePointer: aCogit coInterpreter getCFramePointer stackPointer: aCogit coInterpreter getCStackPointer; + simulateLeafCallOf: someFunction + nextpc: self bogusRetPC + memory: aCogit objectMemory memory. + spOnEntry := self sp. + aCogit singleStep + ifTrue: [ self shouldBeImplemented ]. + [true] whileTrue: [ + [ self runInMemory: aCogit objectMemory memory minimumAddress: 4096 ] + on: SimulatedLeafReturn + do: [ ^self cResultRegister ] ]! Item was added: + ----- Method: TargetAwareX86>>simulateReturnIn: (in category 'execution') ----- + simulateReturnIn: aMemory + PostBuildStackDelta ~= 0 ifTrue: + [self esp: self esp + PostBuildStackDelta]. + self ebp: (self popWordIn: aMemory). + self eip: (self popWordIn: aMemory)! Item was added: + ----- Method: TargetAwareX86>>simulateTearFrameIn: (in category 'execution') ----- + simulateTearFrameIn: aMemory + "Simulate a frame-building call of address. Build a frame since + a) this is used for calls into the run-time which are unlikely to be leaf-calls, and + b) stack alignment needs to be realistic for assert checking for platforms such as Mac OS X" + + PostBuildStackDelta ~= 0 ifTrue: + [self esp: self esp + PostBuildStackDelta]. + self esp: (self popWordIn: aMemory).! Item was added: + ----- Method: TargetAwareX86>>smashCallerSavedRegistersWithValuesFrom:by:in: (in category 'execution') ----- + smashCallerSavedRegistersWithValuesFrom: base by: step in: aMemory + #(eax: ecx: edx:) + withIndexDo: + [:accessor :index| + self perform: accessor with: index - 1 * step + base]! |
Free forum by Nabble | Edit this page |