[Vm-dev] [GSoC] Progress on the GdbARMPlugin

Stefan Marr smalltalk at stefan-marr.de
Mon Jul 9 20:04:22 UTC 2012

Hi Lars:

Thanks for the update!

On 09 Jul 2012, at 21:28, Lars wrote:

> in the last weeks, based on my simple code examples, I tried to copy the BochsIA32Plugin structures and adapt it to ARMulator/libopcodes.
Just to refresh everyone's memory, the BochsIA32Plugin allows to simulate x86 code.
And the new ARM plugin will enable us to simulate ARM code to debug it inside the Smalltalk image.

> So far, I am able to run code sequentially with memory bounds checks. The (copied) test testExecutionTrap and testResetCPU are green. The testCallTrap might also be green, once I figured out what the correspondent of the IA32 call opcode in ARM is.

Did you notice this PDF already? http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf

Especially section 5 should be interesting. Section 5.3 gives also a minimal example how a call typically is done.

My understanding so far is, that the branch-link instruction is what CALL is on x86.
As I understand the difference, it is mainly that CALL will put the return address on the stack, while ARM got the link register for that. Otherwise, both will do the jump to the given address.
x86's return will then do the inverse, it expects the stack pointer to be at the position of the return address, will pop it, and use it to jump back.

On ARM, a simple jump with the link register should suffice.

More tricky will be to get the calling conventions right, thus handling of parameters and return values. The basics are discussed in that document too.
Not sure where to find other example, guess the easiest and most informative will be to ask gcc to give you the assembler output for C code. 

> For these tests, I implemented an alternative memory interface (armulmem.c). The problem with bounds checking and especially execution bounds was the prefetching emulation: Whenever an instruction is executed, the next two words are read from memory, too. Because of that, it is not possible to quit with the appropriate error code in the memory interface.

To give some more details:
 My understanding is that Eliot used the bounds checks to be confident that he never
 executes anything outside the explicitly allocate ByteArray with the assembled code.
 To have some protection during simulating the machine code, and be guarded against
 off-by-one errors, jumps to random addresses, etc.

> The current solution uses a custom Software Interrupt (0x200000). The memory interface returns the 'SWI 0x200000' opcode whenever it is asked for an instruction at an invalid address. This is implemented in ARMul_ReLoadInstr. For random memory access, the corresponding functions are GetWord and PutWord, which stop simulation immediately.
I like the solution with the custom software interrupt, thanks for changing that!

> An interesting detail about the ARMulator is, that it is also the base for the ARM-Emulator used in Skyeye, beside being used in gdb. In case anybody wants to try using my code examples, it is very important to compile libsim.a with -DMODET (which is default on my system) or disabling that flag in GdbARMPlugin.h. That little flag took me at least two days, because it changes multiple offsets in the main struct ARMul_State.

Would be good if people try to look at the code, compile it, and report all the problems you find. So, that we can make sure that we have something that is portable in the end. Lars works on Windows and Linux as far as I remember. 

Best regards

Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
Phone: +32 2 629 2974
Fax:   +32 2 629 3525

More information about the Vm-dev mailing list