arm-none-eabi-ld - Undefined Reference for malloc, strcpy, sprintf, vsprintf

Asked by Vinit Shenoy on 2014-11-11

Hi,

I'm currently trying to port our verification platform software from armcc to the free toolchain arm-none-eabi- to save on licensing costs.
So far I have converted all my C code to make it gcc compatible (Eg - Replace __irq with __attribute__((interrupt("IRQ"))) etc
I have written the init code and linker script in the expected format.

However during linking, arm-none-eabi-ld gives me undefined reference to some standard C functions.
pcie_ep_bar_err_resp_test.c:26: undefined reference to `malloc'
/fw/code/val.c:40: undefined reference to `strcpy'
fw/code/val.c:94: undefined reference to `vsprintf'

I have read though the forum about any possible solution and I believe adding the newlib library should solve this issue.
However when I add --spec=nano.specs to my linker I get the error
arm-none-eabi-ld: unrecognized option '--spec=nano.specs'
Reference https://answers.launchpad.net/gcc-arm-embedded/+question/250460

Can you please provide me with any ideas on solving this issue?

Regards,
Vinit

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Thomas Preud'homme
Solved:
2014-11-13
Last query:
2014-11-13
Last reply:
2014-11-12
Terry Guo (terry.guo) said : #1

Please use arm-none-eabi-gcc rather than arm-none-eabi-ld in link step.
2014年11月11日 下午5:51于 "Vinit Shenoy" <email address hidden>写道:

> New question #257323 on GCC ARM Embedded:
> https://answers.launchpad.net/gcc-arm-embedded/+question/257323
>
> Hi,
>
> I'm currently trying to port our verification platform software from armcc
> to the free toolchain arm-none-eabi- to save on licensing costs.
> So far I have converted all my C code to make it gcc compatible (Eg -
> Replace __irq with __attribute__((interrupt("IRQ"))) etc
> I have written the init code and linker script in the expected format.
>
> However during linking, arm-none-eabi-ld gives me undefined reference to
> some standard C functions.
> pcie_ep_bar_err_resp_test.c:26: undefined reference to `malloc'
> /fw/code/val.c:40: undefined reference to `strcpy'
> fw/code/val.c:94: undefined reference to `vsprintf'
>
> I have read though the forum about any possible solution and I believe
> adding the newlib library should solve this issue.
> However when I add --spec=nano.specs to my linker I get the error
> arm-none-eabi-ld: unrecognized option '--spec=nano.specs'
> Reference https://answers.launchpad.net/gcc-arm-embedded/+question/250460
>
>
> Can you please provide me with any ideas on solving this issue?
>
> Regards,
> Vinit
>
> --
> You received this question notification because you are a member of GCC
> ARM Embedded Developers, which is an answer contact for GCC ARM
> Embedded.
>

Vinit Shenoy (vinit-shenoy) said : #2

Hi Terry,

I am now using the arm-none-eabi-gcc for linking and I am able to solve the above issues.

Now however I am receiving a new set of linking errors.

Few I was able to resolve on my own reading through queries on the forum.
        Undefined reference to __bss_start__ and __bss_end__ (Both sections now defined in Linker Script)
        Undefined reference to _sbrk (Resolved by passing --specs=nosys.specs

I still have two errors which I am unable to resolve:
 1) Multiple definition of _start
 2) Undefined reference to _end

/toolchain_porting/PCIe/Verification/setup/../block_tests/MontBlanc_PCIe/sim/comp4arm/obj/init_block.o: In function `_start':
/toolchain_porting/PCIe/Verification/setup/../block_tests/boot//init_block.s:27: multiple definition of `_start'
/prj/hsi_ss/vshenoy/sandbox/arm_toolchain/gcc-arm-none-eabi-4_8-2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/crt0.o:(.text+0x0): first defined here
/prj/hsi_ss/vshenoy/sandbox/toolchain_porting/PCIe/Verification/setup/../block_tests/MontBlanc_PCIe/sim/comp4arm/obj/init_block.o: In function `_start':
/prj/hsi_ss/vshenoy/sandbox/toolchain_porting/PCIe/Verification/setup/../block_tests/boot//init_block.s:27: multiple definition of `_start'
/prj/hsi_ss/vshenoy/sandbox/arm_toolchain/gcc-arm-none-eabi-4_8-2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/crt0.o:(.text+0x0): first defined here
/prj/hsi_ss/vshenoy/sandbox/arm_toolchain/gcc-arm-none-eabi-4_8-2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/libnosys.a(sbrk.o): In function `_sbrk':
sbrk.c:(.text._sbrk+0x40): undefined reference to `end'
collect2: error: ld returned 1 exit status

Would greatly appreciate your help in solving these errors.

Hi Vinit,

Thanks for updating us on your progress. Is it possible for you to show us your linker script? There are likely some missing bits there.

Best regards

Vinit Shenoy (vinit-shenoy) said : #4

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)

MEMORY
{
 ROM (rx) : ORIGIN = 0x0, LENGTH = 0x10000
 STACK : ORIGIN = 0x10000000, LENGTH = 0x3200
 HEAP : ORIGIN = 0x10003200, LENGTH = 0x3200
 RAM (rwxa) : ORIGIN = 0x10006400, LENGTH = 0x2FFF9C00
 /* RAM Size based on DDR Address Range (0x00000000-0x40000000) from Top Mem Bus Map */
}

/* Define global variables stack_base and stack_length used in init_block.s */
stack_base = 0x10000000;
stack_length = 0x3200;

SECTIONS
{
 . = 0x0;

 .text :
 {
  init_block.o (.text)
  *(.text)
 } > ROM

 . = ALIGN(4);
 .rodata . :
 { *(.rodata*); . = ALIGN(4); } > ROM

 /* STACK utilization */
 . = ORIGIN(STACK);

 .stack : {} > STACK

 .heap : {} > HEAP

 .data : { *(.data) } > RAM

 .bss :
 {
 __bss_start__ = .;
 *(.bss)
 __bss_end__ = .;
 } > RAM

}

Above is my linker script. ENTRY(_start) is used to define the entry point present in my init_block.s file.

Regards,
Vinit

For _end as the error suggest you need to define it in your linker script, most likely at the end of you .bss section (just after __bss_end__).

As to _start, I believe the ENTRY macro will define a _start symbol with the same address as the symbol you pass it. So either you rename your symbol or you remove the ENTRY macro as ld will look for such a symbol by default.

Best regards.

Vinit Shenoy (vinit-shenoy) said : #6

Hi All,

I am able to remove the error for multiple definitions of _start symbol.

In my init_block.s file I had the following lines:
.globl _start
_start:
These lines created multiple symbol definitions for start, so I removed .globl _start which has solved my problem.

For the undefined reference of 'end', I defined it after my .bss section as suggested above which fixed the issue.

I have another query where I hope I can get some support.
During my porting activity I had to change my file init_block.s which was written for armcc (hence containing ARM specific keywords such as ENTRY, PRESERVE8, IMPORT etc) into a file which will be recognized by the arm-none-eabi toolchain.
To achieve this I basically passed my file through ads2gas.pl script and did some manual editing.

I have very less knowledge of ARM assembly so I was hoping if I provide the original and modified files I can get help in confirming that there is no change in intent after modification of the original file. (I'm hope this is the right place to ask this!)

Thanks for the support.

Regards,
Vinit

Vinit Shenoy (vinit-shenoy) said : #7

Thanks Thomas Preud'homme, that solved my question.