【发布时间】:2018-08-19 12:55:50
【问题描述】:
这是我的测试。我有一个由main.c 和misc.c 组成的main 应用程序和一个由lib.c 组成的静态库。
目标:我想在 ELF 部分 .modules 中声明我的所有 struct module 声明。
问题:我只能从主应用程序中看到 struct module 声明。这是我可以使用以下代码看到的输出:
Hello World
- module:module_a
- module:module_b
如果我将my_lib() 调用为main(),那么我会看到:
Hello World
MyLib
- module:module_a
- module:module_b
- module:module_lib
但我不感兴趣直接将模块的函数调用到我的主应用程序中。
-
CMakeLists.txt
add_executable(main main.c misc.c) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/linker.ld") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${LINKER_SCRIPT}") add_library(static_lib STATIC lib.c) target_link_libraries(main static_lib) -
main.c
#include "module.h" extern const struct module modules_start[]; extern const struct module modules_end[]; struct module __attribute__ ((section (".modules"))) module_a = { .name = "module_a", }; int main(void) { puts("Hello World"); const struct module *m = modules_start; while (m < modules_end) { printf("- module:%s\n", m->name); m++; } return 0; } -
misc.c
#include "module.h" struct module __attribute__ ((section (".modules"))) module_b = { .name = "module_b", }; -
module.h
#include <stdio.h> struct module { const char* name; }; -
lib.c
#include "module.h" struct module __attribute__ ((section (".modules"))) __attribute__ ((used)) module_lib = { .name = "module_lib", }; int my_lib(void) { puts("MyLib"); return 0; } -
linker.ld
SECTIONS { .modules : { modules_start = .; KEEP(*(.modules)) modules_end = .; } } INSERT AFTER .rodata;
以下是一些 ELF 信息:
$ readelf --sections libstatic_lib.a | grep -A 1 modules
[ 5] .modules PROGBITS 0000000000000000 00000058
0000000000000008 0000000000000000 WA 0 0 8
[ 6] .rela.modules RELA 0000000000000000 00000278
0000000000000018 0000000000000018 I 13 5 8
$ readelf --sections main | grep -A 1 modules
[17] .modules PROGBITS 00000000000009c0 000009c0
0000000000000010 0000000000000000 WA 0 0 8
$ nm libstatic_lib.a | grep module
0000000000000000 D module_lib
$ nm main | grep module
00000000000009c0 D module_a
00000000000009c8 D module_b
00000000000009d0 D modules_end
00000000000009c0 D modules_start
【问题讨论】:
-
“我只能看到主应用程序中的模块”,我的意思是主应用程序声明的“结构模块”变量(
main.c和misc.c)。我想将我的所有struct module声明声明到专用 ELF 部分的原因是,这是检索所有这些声明而无需将它们列出到全局数组中的最简单方法。 Linux内核中使用了类似的机制。my_lib()是静态库static_lib声明的函数。 -
BTW 在链接器脚本中,您没有说明该部分属于哪个内存。我不明白你要归档什么。这些部分在内存中而不是在精灵中。
-
您正在混合
ELF和memory。ELF sections也定义了存储它们所属符号的位置。例如,您可以在 ROM 中定义属于.text的符号,在 RAM 中定义属于.bss的符号,谢谢。我不知道您是否阅读过我的问题,或者您是否理解它,但我没有兴趣定义 ELF 部分在内存中的位置。我提供的示例旨在构建为 ELF 应用程序,任何人都可以轻松测试。我想归档struct module module_lib并将其公开给主应用程序,而无需将其显式声明为main.c。