简体   繁体   English

gcc 弱属性不一致的行为

[英]gcc weak attribute inconsistent behaviour

I am using gcc compiler in windows10's powershell.我在 windows10 的 powershell 中使用 gcc 编译器。 gcc came with the Atollic TrueSTUDIO ide. gcc 带有 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.我这样做的原因是能够从 C 代码创建一个 .exe 文件,以便单元测试变得更容易。

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.当有一个函数被定义为弱函数并且该函数在另一个 .c 文件中使用时,我遇到了链接器错误(对“function_name”的未定义引用)。

Meanwhile I do not get this linker error if I use arm-atollic-eabi-gcc or gcc running on ubuntu.同时,如果我使用在 ubuntu 上运行的 arm-atollic-eabi-gcc 或 gcc,则不会出现此链接器错误。

Here is a simple code to demonstrate this:这是一个简单的代码来演示这一点:

hello.c:你好ç:

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

weak.c:弱c:

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

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

weak.h弱.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 -c main.c weak.c hello.c

> gcc -o main.exe main.o weak.o hello.o > 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 > hello.o:hello.c:(.text+0x7): 未定义对 `iamweak' collect2.exe 的引用:错误:ld 返回 1 退出状态

Now I checked with gcc-nm the symbol table of hello.o:现在我用 gcc-nm 检查了 hello.o 的符号表:

> gcc-nm hello.o > gcc-nm hello.o

00000000 b .bss 00000000 b.bss

00000000 d .data 00000000 d .data

00000000 r .eh_frame 00000000 r .eh_frame

00000000 r .rdata$zzz 00000000 r .rdata$zzz

00000000 t .text 00000000 吨.text

U _iamweak U_iamweak

00000000 T _whatever 00000000 T _whatever

Symbol table for weak.o: weak.o 的符号表:

>gcc-nm weak.o >gcc-nm 弱.o

00000000 b .bss 00000000 b.bss

00000000 d .data 00000000 d .data

00000000 r .eh_frame 00000000 r .eh_frame

00000000 r .rdata 00000000 r .rdata

00000000 r .rdata$zzz 00000000 r .rdata$zzz

00000000 t .text 00000000 吨.text

00000000 T .weak._iamweak. 00000000 T .weak._iamweak。

w _iamweak w _iamweak

U _puts U_puts

Now when I use gcc on Ubuntu as I said everything works.现在,当我在 Ubuntu 上使用 gcc 时,就像我说的那样一切正常。 Also the symbol tables are a little different.符号表也有点不同。

Symbol table for hello.o: hello.o 的符号表:

nm hello.o纳米你好.o

U _GLOBAL_OFFSET_TABLE_你_GLOBAL_OFFSET_TABLE_

U iamweak

0000000000000000 T whatever 0000000000000000 T 随便

Symbol table for weak.o: weak.o 的符号表:

nm weak.o纳米弱

U _GLOBAL_OFFSET_TABLE_你_GLOBAL_OFFSET_TABLE_

0000000000000000 W iamweak 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)."https://linux.die.net/man/1/nm它说“如果小写,符号是本地的;如果大写,符号是全局的(外部)。”

So iamweak is local in windows10 and global in Ubuntu.所以 iamweak 在 windows10 中是本地的,在 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.弱函数定义也在一些 HAL 库中,我不想修改它们。 Is there a workaround?有解决方法吗?

it is atollic gcc fork error.这是 atollic gcc fork 错误。 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完整的环礁工作室项目在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM