3

I am using gcc compiler in windows10's powershell. gcc came with the Atollic TrueSTUDIO ide. The reason I am doing this is to be able to create an .exe file from the C code so unit testing becomes easier.

I encounter a linker error (undefined reference to 'function_name') when there is a function that is defined as weak and that function is used in another .c file.

Meanwhile I do not get this linker error if I use arm-atollic-eabi-gcc or gcc running on ubuntu.

Here is a simple code to demonstrate this:

hello.c:

#include "weak.h"
void whatever(void)
{
  iamweak();
}

weak.c:

#include <stdio.h>
#include "weak.h"

void __attribute__((weak)) iamweak(void)
{
    printf("i am weak...\n");
}

weak.h

void iamweak(void);

main.c

int main(void)
{
 return 0;
}

Creating the object files and linking:

> gcc -c main.c weak.c hello.c

> gcc -o main.exe main.o weak.o hello.o

> hello.o:hello.c:(.text+0x7): undefined reference to `iamweak' collect2.exe: error: ld returned 1 exit status

Now I checked with gcc-nm the symbol table of hello.o:

> gcc-nm hello.o

00000000 b .bss

00000000 d .data

00000000 r .eh_frame

00000000 r .rdata$zzz

00000000 t .text

U _iamweak

00000000 T _whatever

Symbol table for weak.o:

>gcc-nm weak.o

00000000 b .bss

00000000 d .data

00000000 r .eh_frame

00000000 r .rdata

00000000 r .rdata$zzz

00000000 t .text

00000000 T .weak._iamweak.

w _iamweak

U _puts

Now when I use gcc on Ubuntu as I said everything works. Also the symbol tables are a little different.

Symbol table for hello.o:

nm hello.o

U _GLOBAL_OFFSET_TABLE_

U iamweak

0000000000000000 T whatever

Symbol table for weak.o:

nm weak.o

U _GLOBAL_OFFSET_TABLE_

0000000000000000 W iamweak

U puts

From https://linux.die.net/man/1/nm it says that "If lowercase, the symbol is local; if uppercase, the symbol is global (external)."

So iamweak is local in windows10 and global in Ubuntu. Is that why the linker cannot see it? What can I do about this? The weak function definitions are also in some HAL libraries and I don't want to modify those. Is there a workaround?

vonPryz
  • 22,996
  • 7
  • 54
  • 65
Tomi_Stack
  • 31
  • 2
  • Try to use this other kind of syntax `// function declaration int __attribute__((weak)) power2(int x); // or int power2(int x) __attribute__((weak)); // variable declaration; extern int __attribute__((weak)) global_var;` (They are explanation lines terminated by ;) – Sir Jo Black Jan 29 '20 at 09:40
  • I use attolic studio for years and I do not see anything like this – 0___________ Jan 29 '20 at 10:11
  • @P__J__ Have you actually tried what I described? – Tomi_Stack Jan 29 '20 at 10:19
  • @SirJoBlack I don't want the declarations to be weak, only the function definitions. – Tomi_Stack Jan 29 '20 at 10:22
  • 1
    Does gcc even support weak symbols on non-ELF platforms? The gcc [manual](https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes) says nothing about it: "Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker" –  Jan 29 '20 at 10:51
  • Windows binaries are using the PE format, very different from ELF. –  Jan 29 '20 at 10:53

1 Answers1

0

it is atollic gcc fork error. It does even worse:

          main:
00401440:   push    %ebp
00401441:   mov     %esp,%ebp
00401443:   and     $0xfffffff0,%esp
00401446:   call    0x401970 <__main>
36          iamweak();
0040144b:   call    0x0
37          return 0;
00401450:   mov     $0x0,%eax
38        }

the complete atollic studio project here

0___________
  • 60,014
  • 4
  • 34
  • 74
  • Thank you for taking the time to do this. I am not sure if I understand though. The call 0x0 shouldn't be there? Does this mean that the weak attribute is not supported on windows binaries? – Tomi_Stack Jan 29 '20 at 11:51
  • they are supported - it is just a bug (IMO) in the atollic PC toolchain. For the windows PC stuff just use recent version of mingw – 0___________ Jan 29 '20 at 11:52
  • Unfortunately I am getting the same error with mingw :\ – Tomi_Stack Jan 29 '20 at 15:05