如何通过 .pro 文件 (Qt) 将命令传递给链接描述文件
Howto pass commands to the linker script via .pro file (Qt)
我正在使用 Qt 5.3.2 和 GCC 4.8.2。我想通过 .pro 文件 (qmake) 向 qmake 创建的链接描述文件插入一个段定义。
我要插入的内容:
SECTIONS
{
.legacy_vars :
{
*myModule.o (.bss)
*myModule.o (.data)
}
.everything_else :
{
* (.bss)
* (.data)
* (.text)
}
}
这可能吗?
提前致谢!
回答问题"why?":
我的项目中有无法更改的遗留代码。但是我需要重置它的变量来重置它的状态。同时,它们中的大多数都是静态的,没有访问它们的功能。因此,我想将遗留代码变量映射到定义的部分,在启动我的程序时读取它们,如果需要,将它们写回以重置程序的这一部分。
找到解决方案:
首先我在网上找到的"simple linker script examples"不是PC应用程序的correct/complete/working(像这样:link)。所以我做了以下事情:
- 将GCC的默认链接描述文件读出到一个文件中:"ld --verbose > ld_script.ld"
删除了详细命令生成的前导附加信息:
GNU ld (GNU Binutils) 2.24
Supported emulations:
i386pe
using internal linker script:
==================================================
最后:
==================================================
将我的附加链接命令插入到链接描述文件中:
.data BLOCK(__section_alignment__) : {
__data_start__ = . ;
_legacy_code_data_start = . ;
*legacy_module_first.o(.data*)
*legacy_module_next.o(.data*)
*legacy_module_last.o(.data*)
_legacy_code_data_end = . ;
*(.data)
*(.data2)
*(SORT(.data$*))
*(.jcr)
__data_end__ = . ;
*(.data_cygwin_nocopy)
}
和:
.bss BLOCK(__section_alignment__) : {
__bss_start__ = . ;
_legacy_code_bss_start = . ;
*legacy_module_first.o(COMMON)
*legacy_module_first.o(.bss)
*legacy_module_next.o(COMMON)
*legacy_module_next.o(.bss)
*legacy_module_last.o(COMMON)
*legacy_module_last.o(.bss)
_legacy_code_bss_end = . ;
*(.bss)
*(COMMON)
__bss_end__ = . ;
}
- 添加脚本文件到Qt项目
通过 .pro 文件将链接描述文件添加到链接中:
QMAKE_LFLAGS += "-T ../pathtoscript/ld_script.ld"
- 完成。
"-T" 告诉链接器使用定义的文件而不是链接器的默认文件。之前这导致错误,因为我编写的链接器文件不完整。
结果如下,可以在地图文件中看到(要创建地图文件,请使用:QMAKE_LFLAGS += "-Wl,-Map=output.map"):
链接器脚本中定义的遗留模块的.data 变量将放在符号“_legacy_code_data_start”和“_legacy_code_data_end”之间,.bss 和COMMON 变量将放在它们之间符号“_legacy_code_bss_start”和“_legacy_code_bss_end”。这些符号可以通过在 C/C++ 代码中声明来使用: "extern void * legacy_code_data_start;" 等等。因此,我现在可以读取这两个数据块并在需要时将它们写回。
我正在使用 Qt 5.3.2 和 GCC 4.8.2。我想通过 .pro 文件 (qmake) 向 qmake 创建的链接描述文件插入一个段定义。
我要插入的内容:
SECTIONS
{
.legacy_vars :
{
*myModule.o (.bss)
*myModule.o (.data)
}
.everything_else :
{
* (.bss)
* (.data)
* (.text)
}
}
这可能吗? 提前致谢!
回答问题"why?":
我的项目中有无法更改的遗留代码。但是我需要重置它的变量来重置它的状态。同时,它们中的大多数都是静态的,没有访问它们的功能。因此,我想将遗留代码变量映射到定义的部分,在启动我的程序时读取它们,如果需要,将它们写回以重置程序的这一部分。
找到解决方案:
首先我在网上找到的"simple linker script examples"不是PC应用程序的correct/complete/working(像这样:link)。所以我做了以下事情:
- 将GCC的默认链接描述文件读出到一个文件中:"ld --verbose > ld_script.ld"
删除了详细命令生成的前导附加信息:
GNU ld (GNU Binutils) 2.24 Supported emulations: i386pe using internal linker script: ==================================================
最后:
==================================================
将我的附加链接命令插入到链接描述文件中:
.data BLOCK(__section_alignment__) : { __data_start__ = . ; _legacy_code_data_start = . ; *legacy_module_first.o(.data*) *legacy_module_next.o(.data*) *legacy_module_last.o(.data*) _legacy_code_data_end = . ; *(.data) *(.data2) *(SORT(.data$*)) *(.jcr) __data_end__ = . ; *(.data_cygwin_nocopy) }
和:
.bss BLOCK(__section_alignment__) : {
__bss_start__ = . ;
_legacy_code_bss_start = . ;
*legacy_module_first.o(COMMON)
*legacy_module_first.o(.bss)
*legacy_module_next.o(COMMON)
*legacy_module_next.o(.bss)
*legacy_module_last.o(COMMON)
*legacy_module_last.o(.bss)
_legacy_code_bss_end = . ;
*(.bss)
*(COMMON)
__bss_end__ = . ;
}
- 添加脚本文件到Qt项目
通过 .pro 文件将链接描述文件添加到链接中:
QMAKE_LFLAGS += "-T ../pathtoscript/ld_script.ld"
- 完成。
"-T" 告诉链接器使用定义的文件而不是链接器的默认文件。之前这导致错误,因为我编写的链接器文件不完整。
结果如下,可以在地图文件中看到(要创建地图文件,请使用:QMAKE_LFLAGS += "-Wl,-Map=output.map"):
链接器脚本中定义的遗留模块的.data 变量将放在符号“_legacy_code_data_start”和“_legacy_code_data_end”之间,.bss 和COMMON 变量将放在它们之间符号“_legacy_code_bss_start”和“_legacy_code_bss_end”。这些符号可以通过在 C/C++ 代码中声明来使用: "extern void * legacy_code_data_start;" 等等。因此,我现在可以读取这两个数据块并在需要时将它们写回。