Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined reference to memcpy in ARM-NONE-EABI link chain

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).

like image 410
aarelovich Avatar asked Mar 30 '15 10:03

aarelovich


3 Answers

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 };
like image 52
rickfoosusa Avatar answered Oct 10 '22 16:10

rickfoosusa


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().

like image 34
MoTaXi Avatar answered Oct 10 '22 16:10

MoTaXi


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.

like image 1
DawidPi Avatar answered Oct 10 '22 17:10

DawidPi