ARM Trusted Firmware semihosting broken with latest 4.8 aarch64

Bug #1267122 reported by Mark Hambleton
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GCC
Invalid
Undecided
Kugan Vivekanandarajah
Linaro Toolchain Binaries
Invalid
Undecided
Unassigned

Bug Description

Hi, Using linaro gcc 4.8 for aarch64 2013.10 when I compile the ARM trusted firmware (https://github.com/ARM-software/arm-trusted-firmware) I get firmware that can boot a linux kernel...

When I use 2013.12 with no source file changes I get a failure to boot. It appears that the semihosting code (semihosting_get_flen) returns an error with the newer compiler, that it doesn't with the older one....

The 2013.10 compiler generated the following assembly:

0000000000000144 <semihosting_file_length>:
 144: a9be7bfd stp x29, x30, [sp,#-32]!
 148: 910003fd mov x29, sp
 14c: b90013a0 str w0, [x29,#16]
 150: 910043a1 add x1, x29, #0x10
 154: 52800180 mov w0, #0xc // #12
 158: 94000000 bl 0 <semihosting_call>
 15c: a8c27bfd ldp x29, x30, [sp],#32
 160: d65f03c0 ret

The 2013.12 compiler generated the following assembly:

0000000000000144 <semihosting_file_length>:
 144: a9be7bfd stp x29, x30, [sp,#-32]!
 148: 910003fd mov x29, sp
 14c: 910083a1 add x1, x29, #0x20
 150: b81fcc20 str w0, [x1,#-4]!
 154: 52800180 mov w0, #0xc // #12
 158: 94000000 bl 0 <semihosting_call>
 15c: a8c27bfd ldp x29, x30, [sp],#32
 160: d65f03c0 ret

Other areas seem identical. I verified it was semihosting_file_length causing the problems using printfs.

Revision history for this message
Mark Hambleton (mark-hambleton) wrote :
Revision history for this message
Mark Hambleton (mark-hambleton) wrote :
Changed in gcc-linaro:
assignee: nobody → Kugan Vivekanandarajah (kugan-vivekanandarajah)
Revision history for this message
Kugan Vivekanandarajah (kugan-vivekanandarajah) wrote :

Change in assembly is due to the src changes for FRAME_GROWS_DOWNWARD. The code generated confirms to the FRAME_GROWS_DOWNWARD layout. However, there could be alignment traps that might be preventing the kernel from booting. Building ARM trusted firmware to investigate further.

gcc trunk also produces similar code.

Revision history for this message
Matthew Gretton-Dann (matthew-gretton-dann) wrote :

This is not a compiler bug.

Rather it is a problem with how the ARM Trusted Firmware makes semihosting calls.

Semihosting requires the parameter block (pointed to by x1) to be a sequence of 64-bit DWORD values, with parameters smaller than a 64-bit DWORD being sign-extended to a 64-bit DWORD.

[There is an implication also that the parameter block is 8-byte aligned]

The ARM trusted firmware doesn't do this. In particular in https://github.com/ARM-software/arm-trusted-firmware/blob/master/lib/semihosting/semihosting.c you have cases like:

int semihosting_file_length(int file_handle)
{
        return semihosting_call(SEMIHOSTING_SYS_FLEN,
                                (void *) &file_handle);
}

file_handle is only a 4-byte word, and it hasn't been sign extended to an 8-byte DWORD, nor has it been 8-byte aligned, and so semihosting gets confused, and provides an error result.

The reason for this only causing issues now is due to a change in compiler behaviour. Notably the layout of variables on the stack which was required to enable other features (Stack Smashing Protection, Address Sanitizers &c). However, the compiler code generation is correct, and even the old behaviour could have caused issues in other circumstances, so this is an issue that needs fixing in the ARM Trusted Firmware.

Closing as "Invalid"

Changed in linaro-toolchain-binaries:
status: New → Invalid
Changed in gcc-linaro:
status: New → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.