IceTea IceTea - 24 days ago 9
Android Question

Compile ARM binaries, run them in ARMulator

Here is my problem:

Introduction

I am currently trying to execute some basic code on an ARM processor. As I currently (and probably for a long time) do not have any ARM hardware around me, I’ve been using QEMU (an ARM emulator) for some days now, which, I’ve got to say it, works like a charm. But using QEMU, I feel like drawing my sword to kill a fly. So I looked for some lighter emulators, and found out about ARMulator.

“The ARMulator is a family of programs which emulate the instruction sets of various ARM processors and their supporting architectures. The ARMulator is transparently connected to compatible ARM debuggers to provide a hardware-independent ARM software development environment. Communication takes place via the Remote Debug Interface (RDI).”

(Source: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0032f/index.html)

“Accuracy is good, although it is classed as cycle count accurate rather than cycle accurate, this is because the ARM pipeline isn't fully modeled (although register interlocks are). Resolution is to an instruction, as a consequence when single stepping the register interlocks are ignored and different cycle counts are returned than if the program had simply run, this was unavoidable.”

(Source: https://en.wikipedia.org/wiki/ARMulator)

Environment

From there, I’ve tried several ARMulator versions. Got to say there are not a lot around, in fact I ‘ve only tried 3 versions (names are not official, thats simply a name I gave them to recognize them):

- XYZ Armulator : https://github.com/x-y-z/armulator 2016-02-20

- SourceForge Armulator : https://sourceforge.net/projects/armulator/ 2013-04-26

- Phanrahan Armulator : https://github.com/phanrahan/armulator 2014-11-11

I am not sure these versions are official, and I think I’ve seen several times on different websites there was some versions really official, probably proprietary and including more than the tools needed. Here’s some examples of what I am talking about :

- On ARM Connected Community, they talk about a RealViewDevelopmentSuite, which seems to contain ARMulator : https://community.arm.com/message/12272#12272

- …Will add others when I find one of them again
But those solutions are not free.

Now about the Toolchain. Two different Toolchains are stated in the resources I’ve found :

- Arm-elf-abi : stated on the XYZ ARMulator GitHub, it is recommended to use this command ($ arm-elf-gcc -mthumb -Bstatic -o ) to compile the binary executable.

The only version I found was for Windows… sadly, I could not find any for Unix.

- Arm-none-eabi : stated on this tutorial : http://www.bravegnu.org/gnu-eprog/hello-arm.html, this is the one I’ve been using with QEMU. I’ve read somewhere the Arm-elf toolchain was not required when compiling ARM assembly, and Arm-none was enough for this case.

The two programs I tested were made to be the most simple possible :

One in Assembly : helloarm.s

.global _start
.text
entry: b _start
.align
_start:
mov r4, #5 @ Load register r4 with the value 5
mov r3, #4 @ Load register r3 with the value 4
add r0, r4, r3 @ Add r3 and r4 and store in r0
b stop
stop: b stop @ Infinite loop


One in C : test.c

int c_entry() {
return 0;
}


Compilation process

At first, I used the same way which worked on QEMU explained in this tutorial : http://www.bravegnu.org/gnu-eprog/hello-arm.html . On QEMU, everything worked fine, but the emulation process is slightly different. I had to load the binary into the RAM first before executing QEMU.
The way to launch ARMulator ($ armulator ) being different, I suppose the binary is automatically loaded is the RAM.

I tried three different ways to compile, not sure about which is the most appropriate one.Here it is :

Assembly :

$ arm-none-eabi-as –s -g helloarm.s -o helloarm.o
$ arm-none-eabi-ld -Ttext=0x0 -o helloarm.elf helloarm.o
$ arm-none-eabi-objcopy -O binary helloarm.elf helloarm.bin


We should now have two ‘binaries’, the .bin one and the .elf one.

I still don’t really know what is the difference. Need to read some more.

C :

$ arm-none-eabi-gcc -mthumb -Bstatic --specs=nosys.specs srcs/main.c –o a.out


An extra one :

I’ve also tried the following method explained in this tutorial, which made me think Armulator was made to execute .elf binaries. Files made on this method are called c_entry.

https://balau82.wordpress.com/2010/02/14/simplest-bare-metal-program-for-arm/
Issues are the same.

From then, we have 6 binaries :


  • helloarm.bin

  • helloarm.elf

  • main.elf

  • a.out

  • c_entry.bin

  • c_entry.elf



Issues

When using SourceForge and Phanrahan Armulator with any binary file (elf or bin):


$ ./armulator asm-helloarm.bin

Error opening file 00000000.bin

$ ./armulator a.out

Error opening file 00000000.bin

$ ./armulator helloarm.elf

Error opening file 00000000.bin


When using XYZ Armulator:


  • With helloarm.elf binary, or any .elf file :

    $ armulator helloarm.elf


    Error:Out of Code Segment:0x24

    * Error in `armulator': double free or corruption (top): 0x0000000001000550 *

    ======= Backtrace: =========

    /lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f0f32cf4725]

    /lib/x86_64-linux-gnu/libc.so.6(+0x7ff4a)[0x7f0f32cfcf4a]

    /lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f0f32d00abc]

    armulator[0x40489d]

    armulator[0x4022d2]

    armulator[0x401f3a]

    /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f0f32c9d830]

    armulator[0x402109]

    ======= Memory map: ========

    00400000-0040e000 r-xp 00000000 08:01 3802861 /usr/local/bin/armulator

    0060d000-0060e000 r--p 0000d000 08:01 3802861 /usr/local/bin/armulator

    0060e000-0060f000 rw-p 0000e000 08:01 3802861 /usr/local/bin/armulator

    00fe4000-01016000 rw-p 00000000 00:00 0 [heap]

    7f0f2c000000-7f0f2c021000 rw-p 00000000 00:00 0

    7f0f2c021000-7f0f30000000 ---p 00000000 00:00 0

    7f0f32974000-7f0f32a7c000 r-xp 00000000 08:01 3281469 /lib/x86_64-linux-gnu/libm-2.23.so

    7f0f32a7c000-7f0f32c7b000 ---p 00108000 08:01 3281469 /lib/x86_64-linux-gnu/libm-2.23.so

    7f0f32c7b000-7f0f32c7c000 r--p 00107000 08:01 3281469 /lib/x86_64-linux-gnu/libm-2.23.so

    7f0f32c7c000-7f0f32c7d000 rw-p 00108000 08:01 3281469 /lib/x86_64-linux-gnu/libm-2.23.so

    7f0f32c7d000-7f0f32e3d000 r-xp 00000000 08:01 3281399 /lib/x86_64-linux-gnu/libc-2.23.so

    7f0f32e3d000-7f0f3303c000 ---p 001c0000 08:01 3281399 /lib/x86_64-linux-gnu/libc-2.23.so

    7f0f3303c000-7f0f33040000 r--p 001bf000 08:01 3281399 /lib/x86_64-linux-gnu/libc-2.23.so

    7f0f33040000-7f0f33042000 rw-p 001c3000 08:01 3281399 /lib/x86_64-linux-gnu/libc-2.23.so

    7f0f33042000-7f0f33046000 rw-p 00000000 00:00 0

    7f0f33046000-7f0f3305c000 r-xp 00000000 08:01 3281437 /lib/x86_64-linux-gnu/libgcc_s.so.1

    7f0f3305c000-7f0f3325b000 ---p 00016000 08:01 3281437 /lib/x86_64-linux-gnu/libgcc_s.so.1

    7f0f3325b000-7f0f3325c000 rw-p 00015000 08:01 3281437 /lib/x86_64-linux-gnu/libgcc_s.so.1

    7f0f3325c000-7f0f333ce000 r-xp 00000000 08:01 3672061 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21

    7f0f333ce000-7f0f335ce000 ---p 00172000 08:01 3672061 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21

    7f0f335ce000-7f0f335d8000 r--p 00172000 08:01 3672061 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21

    7f0f335d8000-7f0f335da000 rw-p 0017c000 08:01 3672061 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21

    7f0f335da000-7f0f335de000 rw-p 00000000 00:00 0

    7f0f335de000-7f0f33604000 r-xp 00000000 08:01 3281371 /lib/x86_64-linux-gnu/ld-2.23.so

    7f0f337e1000-7f0f337e6000 rw-p 00000000 00:00 0

    7f0f33800000-7f0f33803000 rw-p 00000000 00:00 0

    7f0f33803000-7f0f33804000 r--p 00025000 08:01 3281371 /lib/x86_64-linux-gnu/ld-2.23.so

    7f0f33804000-7f0f33805000 rw-p 00026000 08:01 3281371 /lib/x86_64-linux-gnu/ld-2.23.so

    7f0f33805000-7f0f33806000 rw-p 00000000 00:00 0

    7ffc24c19000-7ffc24c3a000 rw-p 00000000 00:00 0 [stack]

    7ffc24ca4000-7ffc24ca6000 r--p 00000000 00:00 0 [vvar]

    7ffc24ca6000-7ffc24ca8000 r-xp 00000000 00:00 0 [vdso]

    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

    Aborted (core dumped)

  • With helloarm.bin binary:




$ armulator helloarm.bin

Segmentation fault (core dumped)



  • With GCC-compiled C binary:




$ armulator a.out

Unexpect Instr:


Possible causes

- ARMulator does not know how to decode some instructions. This is probably the case, but my program seems too much basic to be the case… It does nothing, and returns 0…

- I am using a bad toolchain, or using the correct toolchain badly.

- Armulator should not be used this way.

NOTES

When running binaries with arm-none-eabi-gdb, I can’t run or start the program.
Only this command works : target , but it only resets the target file to the binary already chosen.

When I type start, it says “No symbol table loaded. Use the "file" command.”

Thanks in advance for your help, or at least thanks for reading,

Hoping I am not the only one who had a hard time with Armulator.

Regards,

John

Answer

a b c d e f g h i j k l m n o p q r s t u v w x y z