Reputation: 5566
I'm compiling and linking a bare metal applicacation. In this case is simple standard c code (did not write it myself, but I read it thoroughly and it does not seem to need any libraries) for AES encryption.
My problem comes when linking. This is the linker command used.
arm-none-eabi-ld boot_and_link/startup.o drivers/gpio.o ../programs/aes_e/aes.o ../programs/aes_e/aes_test.o ../programs/aes_e/key_expansion.o -nostartfiles -T boot_and_link/linker.ld -o ../programs/aes_e/aes_e.elf -L/usr/lib/gcc/arm-none-eabi/4.8/armv6-m -lgcc
I've written my own linker script and my own startup code. I get three errors like this:
.../programs/aes_e/aes_test.c:41: undefined reference to `memcpy'
From three lines like this:
unsigned char key[16] =
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
Within the main function. I can make these errors go away by simply cutting those three lines and placing them outside of the main function. This tells me that the line above inside the main function requires copying the data from one section of memory to another. (Please correct me if I'm wrong). Now I've read that memcpy is defined in libgcc.a. I've even grepped for it (in the directory for the armv6-m architecture) and I got a match (Binary file ./libgcc.a matches as a result of the grep command).
So my question becomes why does this error persist? Do I need to link with some other library?
Just to clarify there are NO includes in any of my source files except to other files that I wrote myself (no string.hn stddefs.h or any of those).
Upvotes: 5
Views: 9824
Reputation: 64205
I had the same issue when creating bare-metal application with arm-none-eabi
toolchain.
I implemented below function:
u8* strcpy(u8 *s1, u8 *s2)
{
...
}
And use it in my code:
strcpy((u8 *)tp->clock, "00:00:00");
Then the arm-none-eabi-ld
always complain this:
undefined reference to `memcpy'
After I add below option to the compiler options, the error went away.
-fno-builtin
According to here:
When compiling without -fno-builtin, the compiler can replace calls to certain standard C library functions with inline code or with calls to other library functions. The Run-time ABI for the Arm® Architecture lists library functions that the compiler can use. This means that your re-implementations of the standard C library functions might not be used, and might be removed by the linker.
So I compared the disassembly with and without the -fno-builtin
options.
Without -fno-builtin
:
404: ebfffffe bl 0 <memcpy>
With -fno-builtin
:
3f8: ebfffffe bl 0 <strcpy>
So we can see, it is the compiler doing something behind the scene.
Upvotes: 0
Reputation: 1139
The array is a variable within your routine, and the compiler uses memcpy to copy it into the stack.
If you define it as 'static const', It will go to static storage and not require copying.
static const unsigned char key[16] =
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
Upvotes: 4
Reputation: 2365
Usually you should rely on compilation driver at all and not call linker explicitly, but if you really want to do so, you have to explicitly tell linker to link standard library (usually flag -lc
).
Compiler is allowed to change places, where it can optimize code with memcpy and compiler demands it's existence.
Upvotes: 1
Reputation: 31
I also meet this problem in my bare application for embedded system.
and i didn't use memcopy()
in my code.
here is my problem code main.c:
void main()
{
unsigned char arr[]={'a','b','c'};
for(int i=0;sizeof(arr);i++)
{
putc(arr[i]);
}
}
compile it in:
CFLAGS= -march=armv4t -Wall -nodefaultlibs \
-nostdlib -nostartfiles -fno-builtin\
-nostdinc -Wstrict-prototypes -std=gnu11
$(CROSS_COMPILE)gcc $(CFLAGS) -c -o main.o main.c
and when I link in:
$(CROSS_COMPILE)ld -Txxx.lds -o main main.o
the error:
main.c:(.text+0x48): undefined reference to `memcpy'
and i modified my code:
void main()
{
unsigned char arr[3];
arr[0]='a';
arr[1]='b';
arr[2]='c';
for(int i=0;sizeof(arr);i++)
{
putc(arr[i]);
}
}
it was fine.
so i think the feature unsigned char arr[]={'a','b','c'};
rely on memcopy().
you can modify you code or provide your own memcopy().
Upvotes: 3