我有数千个 struct My_Str_A 类型的全局变量和另外数千个 struct My_Str_B 类型的全局变量。它们已部分初始化。我所说的“部分”是指对于结构变量的每个人,并非所有字段都被初始化。 目前所有这些变量都已编译并静态链接到主程序。
变量在汇编中定义,类似于:
.section .SEG_A,"a",%progbits
.align 1
.global global_conf_xxx
global_conf_xxx:
.short 1
.byte 0x20
.byte 0
和
.section .SEG_RAM_PTR,"a",%nobits
ram_xxx:
.space 4
链接器脚本类似于:
SECTIONS
{
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x80000000)); . = SEGMENT_START("text-segment", 0x80000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(256);
beginning_var_A = .;
*(.SEG_A)
ending_var_A = .;
. = . + 64;
. = ALIGN(4);
beginning_var_B = .;
*(.SEG_B)
ending_var_A = .;
}
__bss_start = .;
__bss_start__ = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
first_in_ram = .;
*(.SEG_RAM_PTR)
}
_bss_end__ = .; __bss_end__ = .;
}
现在我想将所有这些变量打包到一个共享对象中,然后动态链接到我的主程序。我需要两个链接器脚本分别用于共享对象和主程序。以下是我的要求:
所有 struct My_Str_A 类型的变量都放在名为 SEG_A 的段中,所有 struct My_Str_B 类型的变量都放在名为 SEG_B 的段中;
共享库的链接描述文件中定义的 4 个定义变量表示 SEG_A 和 SEG_B 的开头和结尾,在 C 源代码中可以正常工作;
共享对象的 bss 部分中的变量(first_in_ram)表示用户定义部分 SEG_RAM_PTR 的 RAM 地址,在 C 源代码中可以正常工作。 我尝试了这样的方法: 在 libconf.lds 中:
章节
{
。文本 :
{
。 =对齐(256);
beginning_var_A = .;
*(.SEG_A)
ending_var_A = .;
. = . + 64;
. = ALIGN(4);
beginning_var_B = .;
*(.SEG_B)
ending_var_A = .;
}
__bss_start = .;
__bss_start__ = .;
.bss :
{
. = ALIGN(4);
first_in_ram = .;
*(.SEG_RAM_PTR)
}
_bss_end__ = .; __bss_end__ = .;
}
在main.lds中:
SECTIONS
{
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x80000000)); . = SEGMENT_START("text-segment", 0x80000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
}
__bss_start = .;
__bss_start__ = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
}
_bss_end__ = .; __bss_end__ = .;
}
结果:一些配置项按我想要的方式工作,但另一些则不然。 我检查了可工作项和不可工作项的地址,它们分别是0xf74a56c0和0x80845580。看来addr 0x80845580超出了数据段的范围,属于文本段。
我认为 libconf.lds 需要以某种方式进行更改。谁能帮我解决这个问题吗?