Global Sources
EE Times-Asia
Stay in touch with EE Times Asia
?
EE Times-Asia > Processors/DSPs
?
?
Processors/DSPs??

ARM64 vs ARM32: A guide for Linux programmers

Posted: 06 Nov 2015 ?? ?Print Version ?Bookmark and Share

Keywords:ARM? Linux programmers? just-in-time? RISC? cryptographic?

In order for foo to be able to call nested_fn, we need a trampoline. On AArch64, this trampoline gets generated on the stack at the start of main (followed by flushing the data cache and invalidating the instruction cache). The address of the trampoline is then passed to foo().

foo() has no knowledge that fn_ptr is anything special, so foo() executes a normal BLR (branch with link, to register). The generated trampoline itself looks like:

ldr x18, 0x7ffffffaf0
br x17

The relevant points on the stack are shown in figure 2.

Figure 2: GETREGS and GETREGSET.

We had already determined that the failing test problem was caused by some aspect of the test executable itself, rather than something that the test executable was doing at runtime. The key point is that trampolines are generated on the stack, which requires the stack to be executable. This requirement in itself was something of a shock to me.

The way Linux supports execution on the stack is via a personality named READ_IMPLIES_EXEC. The name is as it sounds. Not only does READ_IMPLIES_EXEC make your stack executable, it makes all pages that are readable, executable. Linux knows to set READ_IMPLIES_EXEC on an executable from the PT_GNU_STACK ELF flag, which defines the access rights needed for the stack.

For the program above, we can observe in /proc/pid/maps that nearly all the readable maps are also executable.

r-xp /tmp/tramp
rwxp /tmp/tramp
rwxp
r-xp /lib/aarch64-linux-gnu/libc-2.19.so
-p /lib/aarch64-linux-gnu/libc-2.19.so
r-xp /lib/aarch64-linux-gnu/libc-2.19.so
rwxp /lib/aarch64-linux-gnu/libc-2.19.so
rwxp
r-xp /lib/aarch64-linux-gnu/ld-2.19.so
rwxp
rp [vvar]
r-xp [vdso]
r-xp /lib/aarch64-linux-gnu/ld-2.19.so
rwxp /lib/aarch64-linux-gnu/ld-2.19.so
rwxp [stack]

It's easy to see the odd page out C [vvar]. This oddity wouldn't necessarily be a problem, but looking in /proc/pid/smaps shows most readable pages have the following VMFlags:

VmFlags: rd mr mw me dw ac sd

The 'me' means "may execute", meaning that mprotect is allowed to PROT_EXEC this page. However, critically, [vvar] does not have 'me'. When we try to PROT_READ it, [vvar] gets transformed into a PROT_READ|PROT_EXEC, which of course is rejected.

mcontext (and so rt_sigframe_t) are different
When a signal is received and a signal handler is called, the context in which the signal was received is stored on the stack in a structure called the signal stack frame. As in previous sections, we expected this frame to be significantly different on AArch64 because there are different registers.

Even with this factor taken into account, we were still encountering problems. We were seeing differences in memory in the record and replay phases, which indicated there was something different about the signal frame that we hadn't accounted for.

Here is how the signal frame is declared on ARM 32 bit:

struct rt_sigframe {
???struct siginfo info;
???struct sigframe sig;
};
(arm/arm/kernel/signal.c)

And here is how it is declared on AArch64:

struct rt_sigframe {
???struct siginfo info;
???struct ucontext uc;
???u64 fp;
???u64 lr;
};
(arm/arm64/kernel/signal.c)

The difference is obvious straight away, once you know where to look. The interesting question is: why are the frame pointer (fp) and the link register (lr) included separately here, when they are also saved as part of the general register context in mcontext?

The answer is they are separately saved to allow debuggers to more easily unwind signal stacks, including when using the alternate signal stack (sigaltstack). Once we had accounted for this difference (and the fairly large amount of reserved space in mcontext), we had dealt with all of the differences in AArch64 that affected our core technology and were able to see the same memory content in record and replay when using our engine.

These are just some of the differences that we've encountered, but they are a good sample of the sorts of problems one should expect. There are nuances to AArch64 that go beyond the well understood differences in the instruction set.

About the author
Isa Smith is a software engineer at leading UK start-up, Undo Software. She previously worked at ARM and on ARMv8 compilation tools, and specializes in building software development tools for Linux and Android.


?First Page?Previous Page 1???2???3???4



Article Comments - ARM64 vs ARM32: A guide for Linux pr...
Comments:??
*? You can enter [0] more charecters.
*Verify code:
?
?
Webinars

Seminars

Visit Asia Webinars to learn about the latest in technology and get practical design tips.

?
?
Back to Top