【问题标题】:How can I force gcc to use custom implementations of newlibc implemented functions?如何强制 gcc 使用 newlibc 实现函数的自定义实现?
【发布时间】:2012-03-26 17:07:25
【问题描述】:

我正在为 ARM 微控制器 (SAM7) 开发嵌入式软件,并使用 Yagarto 工具链。

我的代码当前链接 libc.a。但是,我想使用我的代码已经拥有的内置函数 memcpy 的自定义实现。

我已尝试使用 GCC Manual 中指定的 -fno-builtin 和/或 -fno-builtin-memcpy,但链接器仍然抱怨以下警告:

contiki-crazy-horse.a(flashd_efc.o): In function `memcpy':
C:\Users\Melvin\GitRepo\projects\Amatis_Project\SAM7_Contiki\examples\er-rest-example/../../cpu/arm//at91sam7s-x/./flashd_efc.c:669: multiple definition of `memcpy'
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-memcpy.o):C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\string/../../../../../newlib-1.19.0/newlib/libc/string/memcpy.c:78: first defined here
collect2: ld returned 1 exit status
make: *** [rest-server-example-nosyms.crazy-horse] Error 1
../../cpu/arm/at91sam7s-x/Makefile.at91sam7s-x:181: recipe for target `rest-server-example-nosyms.crazy-horse' failed

使用某些 gcc 内置函数的自定义实现的正确方法是什么?

编辑 1:添加我正在使用的链接命令。在下面的代码中,Porject.a 是一个使用项目的所有目标文件创建的存档文件。

CC       = arm-none-eabi-gcc
CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \
       -I$(CONTIKI_CPU)/dbg-io \
           -I$(CONTIKI)/platform/$(TARGET) \
           ${addprefix -I,$(APPDIRS)} \
           -DWITH_UIP -DWITH_ASCII -DMCK=$(MCK) \
           -Wall $(ARCH_FLAGS) -g -D SUBTARGET=$(SUBTARGET)

CFLAGS  += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN  -ffunction-sections

LDFLAGS += -L $(CONTIKI_CPU) --verbose -T $(LINKERSCRIPT) -nostartfiles  -Wl,-Map,$(TARGET).map

$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o project.elf -lc Project.a

【问题讨论】:

  • 还包括产生此错误的链接器命令行。
  • @Clifford 我编辑了原始帖子以添加您要求的信息

标签: linker embedded arm


【解决方案1】:

如果它在 libc.a 中找到 memcpy(),那么它不会与任何“内置”冲突,而是与 newlib 实现冲突。您可能还需要指定 -nostdlibs 选项并根据需要显式链接 libc.a 和 libm.a。

在搜索库档案 (.a) 文件之前链接对象 (.o) 文件,因此如果一个符号由目标文件解析,则不会在档案中搜索它。如果您将覆盖放在静态链接库中,那么您只需在链接器命令行上将其列在标准库(或使用标准库的任何其他库)之前。

[已添加] 以下最初是“评论”,但可能应该在答案中;它是对问题中“编辑 1”的回应,以及下面关于链接顺序的评论:

-nostartfiles -o project.elf -lc Project.a 更改为-nostdlib -o project.elf -start-group Project.a -lc -end-group。开关-nostdlib 禁用启动文件(即-nostartfiles)和标准库的默认链接。库分组导致迭代搜索组中的库,直到无法解析更多符号,从而允许解决像您这样的无序和循环依赖关系。分组开关的另一种形式是-( Project.a -lc -)

【讨论】:

  • @Cliford。我的错。你是对的有没有办法选择我希望我的代码链接的 memcpy 的实现?我无法切换 Project.a 和 libc.a 之间的链接顺序,因为我的项目有一些 libc.a 需要的存根函数
  • @Mischief:或者,将 newlib 存根与项目文件 Project.a -lc stubs.a 分开。为您的项目文件使用存档是一件不寻常的事情。您可以按照规范直接链接目标文件来完全避免该问题。无论链接顺序如何,目标文件中的代码将始终优先于库代码使用;因此,libc 存根将由您与匹配符号链接的任何目标代码解析,并且任何目标代码都将在库代码之前从其他目标代码解析,因此即使在 libc 中调用,memcpy() 也将被正确覆盖。跨度>
  • 我同意您关于将代码保存在存档中的评论是不寻常的。如果/当我有我的方式时,它会改变
猜你喜欢
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多