1. 程式人生 > >arm-eabi-gcc 4.7升級後的問題

arm-eabi-gcc 4.7升級後的問題

某一段arm assembly code,之前用 arm-eabi-gcc 4.6版本編譯。執行沒問題。

但是換成GCC 4.7後有兩個問題。

問題一: 生成的BOOTLOADER無法執行;

問題二: 能執行後,某段指令產生ABORT錯誤。

問題一:

研究GCC 4.7 compiler 升級文件(http://gcc.gnu.org/gcc-4.7/changes.html) 發現, GCC 4.7預設編譯時, 設定為-munaligned-access

•On ARM, when compiling for ARMv6 (but not ARMv6-M), ARMv7-A, ARMv7-R, or ARMv7-M, 
the new option -munaligned-access is active by default, which for some sources generates
 code that accesses memory on unaligned addresses. This requires the kernel of those 
systems to enable such accesses (controlled by CP15 register c1, refer to ARM documentation).
 Alternatively, or for compatibility with kernels where unaligned accesses are not supported,
 all code has to be compiled with -mno-unaligned-access. Upstream Linux kernel releases have
 automatically and unconditionally supported unaligned accesses as emitted by GCC due to this
 option being active since version 2.6.28.

後來在makefile中強制指定-mno-unaligned-access, 問題一解決。
STD_CCFLAGS+=-mno-unaligned-access

問題二:

原因: arm mode call 的指令編譯正常。下載到Trace32裡面, memory view顯示正常。

但是執行到特定指令時,該arm instruction被解釋成為 兩條 thumb 指令, 從而導致 abort 錯誤。

後來發現是從thumb mode 呼叫 arm call 時,不能正確找到對應的 function symbol. 需要顯式宣告.

GCC 4.7 升級文件中,可能對應如下說明

•Link-time optimization (LTO) improvements: ◦Improved scalability and reduced memory usage. Link time optimization of Firefox now requires 3GB of RAM on a 64-bit system, while over 8GB was needed previously. Linking time has been improved, too. The serial stage of linking Firefox has been sped up by about a factor of 10.
◦Reduced size of object files and temporary storage used during linking.
◦Streaming performance (both outbound and inbound) has been improved.
◦ld -r is now supported with LTO.
◦Several bug fixes, especially in symbol table handling and merging.

具體舉例說明如下。

Here is ASM code (file test.S):
===========================
  .syntax unified
  .text
  .code 32

  .global test
  .func test
test:
   nop
   bx lr
.endfunc

Here is C code (file c.c):
============================
void test (void);
int test2 (void)
{
  test();
}

Script for compilation
============================


編譯過程如下

Script for compilation
============================
arm-none-eabi-gcc -c -mcpu=cortex-r4 -mthumb-interwork -Wa,-gdwarf2 -x assembler-with-cpp test.S
arm-none-eabi-gcc -c -mcpu=cortex-r4 -mthumb -mthumb-interwork -Wa,-gdwarf2 c.c
arm-none-eabi-gcc -o test.elf -mcpu=cortex-r4 -mthumb -mthumb-interwork -g -nostartfiles test.o c.o
arm-none-eabi-objdump.exe -d test.elf > test.dump


生成的彙編程式碼如下

生成的彙編程式碼如下:

===========================
Disassembly of section .text:

00008000 <test>:
    8000: e320f000 nop {0}
    8004: e12fff1e bx lr

00008008 <test2>:
    8008: b580 push {r7, lr}
    800a: af00 add r7, sp, #0
    800c: f7ff fff8 bl 8000 <test> ; !!!!!!!!!!!! <- here must be BLX not BL
    8010: 4618 mov r0, r3
    8012: bd80 pop {r7, pc}

解決問題後的正確程式碼如下:

After changing your small test to: .syntax unified .text .code 32 .global test .type test, %function .func test test: nop bx lr .endfunc