如何正确链接符号 [英] How to link against just symbols correctly

查看:237
本文介绍了如何正确链接符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想这是这个延续问题。
我编译了我的中间bootloader库并验证了它的正常工作,现在是时候写一些应用程序代码了。



我能够生成使用 $(OBJCOPY)生成的引导加载程序生成的 .hex 文件中的符号列表--swapcard --strip-symbol = main --strip-symbol = _ *$(TARGET).elf $(TARGET).syms ,这给了我 bootloader.syms



我编写了一个测试应用程序,它使用内存库部分的一些函数,并按照以下方式进行编译:

我将GCC引导加载程序/库中使用的所有头文件的位置以及上面生成的符号文件传递给GCC。我已经测试过GCC会按照预期收集头文件。



Makefile调用:

  Making:obj / main.o 
avr-gcc -Os -std = gnu99 -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata -sections -static -DF_CPU = 8000000UL -DBAUD = -iquote ../ firmware / src / -I。 -I ../ firmware / src / -MP -MD -mmcu = atmega16 -c -o obj / main.o src / main.c;
avr-gcc -Wl,-Map,app.map -Wl, - just-symbols = .. / firmware / bootloader.syms -T ld_script_app.x -mmcu = atmega16 obj / main.o -o app .elf
obj / main.o:在函数`main'中:
main.c :(。text.startup.main + 0x14):对`lcd_init'的未定义引用
main.c :(。text.startup.main + 0x8e):对`lcd_fill'
main.c :(。text.startup.main + 0x142)的未定义引用:对'gfx_draw_line'的未定义引用
collect2:error :ld返回1退出状态
make:*** [app.elf]错误1

我不确定是什么导致了未定义的引用。我的印象是它们会通过符号文件引用。

解决方案

我最近得到了一个由两部分组成的固件版本。看到这个问题和我自我回答我是如何做到这一点的:使用GCC工具链构建一个包含两部分的固件镜像
您在这里的问题有助于走上正确的轨道 - 谢谢! - 但需要执行相当多的步骤才能正确使用它。



我的猜测是,您获得的未定义引用是针对引导加载程序源代码中的函数,但实际上并没有在bootloader中使用。所以链接器将它们从完成的引导加载程序映像中删除。当你尝试链接你的应用程序时,它们在 main.o bootloader.syms 中不可用,所以它们显示为未定义的引用。



如果是这样,有几种方法可以解决这个问题:


  1. 尝试强制链接器将这些符号保留在引导加载程序映像中,即使它们未被使用。我认为有几种方法可以做到这一点。

  2. >
  3. 在链接应用程序时为引导加载程序提供目标文件。链接器命令行上的顺序很重要,所以如果最后提供这些命令,它们应该只用于提供以前输入中尚未定义的任何功能。


>

I guess this is a continuation of this question. I've compiled my intermediate bootloader library and have verified it working, now it's time to write some application code against it.

I'm able to generate a symbol list from the bootloader's generated .hex file using $(OBJCOPY) --wildcard --strip-symbol=main --strip-symbol="_*" $(TARGET).elf $(TARGET).syms, this gives me bootloader.syms.

I've written a test application that uses a few of the functions in the library section of memory, and I compile it as follows:

I pass GCC the location of all the header files used in the bootloader/library as well as the symbol file generated above. I've tested that GCC picks up the header files as intended.

Makefile invocation:

 Making:  obj/main.o
avr-gcc -Os -std=gnu99 -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -static -DF_CPU=8000000UL -DBAUD= -iquote../firmware/src/ -I. -I../firmware/src/ -MP -MD -mmcu=atmega16 -c -o obj/main.o src/main.c;
avr-gcc -Wl,-Map,app.map -Wl,--just-symbols=../firmware/bootloader.syms -T ld_script_app.x -mmcu=atmega16 obj/main.o  -o app.elf
obj/main.o: In function `main':
main.c:(.text.startup.main+0x14): undefined reference to `lcd_init'
main.c:(.text.startup.main+0x8e): undefined reference to `lcd_fill'
main.c:(.text.startup.main+0x142): undefined reference to `gfx_draw_line'
collect2: error: ld returned 1 exit status
make: *** [app.elf] Error 1

I'm not sure what's causing the undefined references though. I was under the impression that they would be referenced through the symbols file.

解决方案

I recently got a two-part firmware build working. See this question and my self-answer for how I did this: Building a two-part firmware image using GCC toolchain. Your questions on here were helpful in getting onto the right track - thanks! - but there were quite a few steps needed to get it right.

My guess is that the undefined references you're getting are for functions that are in the bootloader source code, but not actually used in the bootloader. So the linker is leaving them out of the finished bootloader image. When you try to link your app, they aren't available in either main.o or bootloader.syms, so they show up as undefined references.

If so, there are a few ways to deal with this:

  1. Try to force the linker to retain these symbols in the bootloader image even though they are not used. I think there are a few ways to do this.

  2. Move these functions to separate source files and build them into the app.

  3. Provide the object files for the bootloader when linking the app. Ordering on the linker command line matters, so if these are provided last, they should be used only to supply any functions that have not already been defined by the previous inputs.

这篇关于如何正确链接符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆