I have a Problem with my linker, I explain the problem at the function stCalibrateVref out of a proprietary library called simplemac. The problem appears everywhere inside the library. The processor is a cortex-m3.
The stCalibrateVref function out of the library:
Code: Select all
arm-none-eabi-objdump -d -j .text libsimplemac.a > libsimplemac.dump
00000076 <stCalibrateVref>:
76: b530 push {r4, r5, lr}
78: b087 sub sp, #28
7a: 230a movs r3, #10
7c: 227f movs r2, #127 ; 0x7f
7e: f85f 0004 ldr.w r0, [pc, #-4] ; 650 <??DataTable15_4>
82: 8801 ldrh r1, [r0, #0]
84: a803 add r0, sp, #12
86: f7ff fffe bl 0 <halInternalGetMfgTokenData>
8a: f8bd 1012 ldrh.w r1, [sp, #18]
8e: f85f 5004 ldr.w r5, [pc, #-4] ; 64c <??DataTable15_3>
92: f64f 72ff movw r2, #65535 ; 0xffff
96: 4291 cmp r1, r2
98: d002 beq.n a0 <??stCalibrateVref_0>
9a: 7b28 ldrb r0, [r5, #12]
9c: 07c0 lsls r0, r0, #31
9e: d57c bpl.n 19a <??stCalibrateVref_1>
The stCalibrateVref function after linking:
Code: Select all
arm-none-eabi-objdump -d -j .text binary.elf > binary.dump
08007972 <stCalibrateVref>:
8007972: b530 push {r4, r5, lr}
8007974: b087 sub sp, #28
8007976: 230a movs r3, #10
8007978: 227f movs r2, #127 ; 0x7f
800797a: f8df 05ce ldr.w r0, [pc, #1486] ; 8007f4a <??DataTable15_3+0x2>
800797e: 8801 ldrh r1, [r0, #0]
8007980: a803 add r0, sp, #12
8007982: f7fc faf5 bl 8003f70 <halInternalGetMfgTokenData>
8007986: f8bd 1012 ldrh.w r1, [sp, #18]
800798a: f8df 55ba ldr.w r5, [pc, #1466] ; 8007f46 <??DataTable15_2+0x2>
800798e: f64f 72ff movw r2, #65535 ; 0xffff
8007992: 4291 cmp r1, r2
8007994: d002 beq.n 800799c <??stCalibrateVref_0>
8007996: 7b28 ldrb r0, [r5, #12]
8007998: 07c0 lsls r0, r0, #31
800799a: d57c bpl.n 8007a96 <??stCalibrateVref_1>
Code: Select all
xPSR: 0x01000000
PC: 0x0800797E
LR: 0x08004AD7
R12: 0x88000081
R3 : 0x0000000A
R2 : 0x0000007F
R1 : 0x00000001
R0 : 0xF4042000
Problem: r0 contains a wrong value. This wrong value comes from the instruction above. (@ 0x0800797a)
It reads a value from PC+1486 = 0x08007F4A (At the time, the address gets calculated, the PC points at the second half-word of the
instruction) which points to the value 0xF4042000
Code: Select all
(gdb) x/x 0x8007f4A
0x8007f4a <??DataTable15_3+2>: 0xf4042000
At this address the wished value is stored, that is addressed in the libraries dump
Code: Select all
(gdb) x/x 0x8007f4C
0x8007f4c <??DataTable15_4>: 0x0800f404
Code: Select all
(gdb) x/x 0x800f404
0x800f404 <TOKEN_MFG_ANALOG_TRIM_BOTH>: 0x07dc07d2
I use the following setup:
Code: Select all
CFLAGS="-Wall -nostdlib -fno-common -fno-builtin -O0 -g -mcpu=cortex-m3 -mthumb -c -std=c99 -fshort-wchar $DEFINES $HEADERPATHES"
LDFLAGS="-nostartfiles -nostdlib -static -A cortex-m3 -T$LDFILE $LIBPATHES"
Code: Select all
arm-none-eabi-ld --version
-> GNU ld (GNU Binutils) 2.23.1
-> GNU ld (GNU Binutils) 2.21.1
arm-none-eabi-gcc --version
-> arm-none-eabi-gcc (Linaro GCC 4.7-2013.01) 4.7.3 20130102
-> arm-none-eabi-gcc (Linaro GCC 4.6-2011.10) 4.6.2 20111004
Code: Select all
/*based on stm32_flash.ld form STM*/
ENTRY(Reset_Handler)
_estack = 0x20004000;
_Min_Heap_Size = 0x100;
_Min_Stack_Size = 4K;
_stack_size = _Min_Stack_Size;
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
}
SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
*(.constdata)
*(.rev16_text)
*(.revsh_text)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
} >FLASH
_sidata = .;
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >RAM
. = ALIGN(4);
.bss :
{
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >RAM
._user_heap_stack :
{
. = ALIGN(4);
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >RAM
/* source: http://eehusky.wordpress.com/2012/12/17/using-gcc-with-the-ti-stellaris-launchpad-newlib/ */
_heap_bottom = .;
heap_low = _heap_bottom;
_heap_top = ORIGIN(RAM) + LENGTH(RAM) - _stack_size;
heap_top = _heap_top;
_stack_bottom = _heap_top;
_stack_top = ORIGIN(RAM) + LENGTH(RAM);
.ARM.attributes 0 : { *(.ARM.attributes) }
}
analogue.o is part of the libsimplemac.a
Code: Select all
readelf -a analogue.o | grep ABI
OS/ABI: UNIX - System V
ABI Version: 0
Flags: 0x5000000, Version5 EABI
Tag_ABI_PCS_GOT_use: direct
Tag_ABI_FP_denormal: Sign only
Tag_ABI_FP_number_model: Finite
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_optimization_goals: Aggressive Size
Tag_ABI_PCS_GOT_use: direct
Tag_ABI_PCS_wchar_t: 2
Tag_ABI_FP_denormal: Sign only
Tag_ABI_FP_number_model: Finite
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: small
Tag_ABI_optimization_goals: Prefer Size
Code: Select all
readelf -a main.o | grep ABI
OS/ABI: UNIX - System V
ABI Version: 0
Flags: 0x5000000, Version5 EABI
Tag_ABI_PCS_wchar_t: 2
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: small
Tag_ABI_optimization_goals: Aggressive Debug