`--defsym` 链接器标志如何将值传递给源代码?
Posted
技术标签:
【中文标题】`--defsym` 链接器标志如何将值传递给源代码?【英文标题】:How does the `--defsym` linker flag work to pass values to source code? 【发布时间】:2018-11-12 21:59:47 【问题描述】:在LJ post 中,--defsym
标志用于将构建日期传递到源代码中:
#include <stdio.h>
extern char __BUILD_DATE;
void main(void)
printf("Build date: %u\n", (unsigned long) &__BUILD_DATE);
通过与以下标志链接:
gcc example.c -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
根据ld manual,
--defsym symbol=expression
在输出文件中创建一个全局符号,包含表达式给出的绝对地址。
我正在尝试理解以下内容:
-
构建日期的 9 个字符的字符串 (
YYYYmmdd
+\0
) 如何存储在内存中?
如果--defsym
创建一个包含地址的符号,为什么__BUILD_DATE
被定义为字符而不是指针或整数类型?
如果__BUILD_DATE
最终被转换为unsigned long
,为什么__BUILD_DATE
被定义为char
而不是unsigned long
?
【问题讨论】:
这对我来说像是 3 个问题。不是一个。也许您想发布 3 个单独的问题..? @JesperJuhl 我认为这是关于--defsym
用法的一个问题的三个小部分。拆分问题对我来说毫无意义。
“如果 __BUILD_DATE 最终被转换为 unsigned long,为什么它被定义为 char 而不是 unsigned long?”恕我直言,绝对是一个独立的问题。正如“如果 --defsym 创建一个包含地址的符号,为什么 __BUILD_DATE 被定义为 char 而不是指针或整数类型?”。但是,那可能只是我。
【参考方案1】:
链接器将全局变量视为地址(指向“实际”全局变量而不是实际全局变量的指针——即使该地址不存在实际全局变量)。 -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
设置地址 of __BUILD_DATE
而不是值。当__BUILD_DATE
链接器实体有地址但没有值时,您可以通过将实体声明为任何内容然后获取该地址来获取地址。
在:
#include <stdio.h>
//extern long __BUILD_DATE[128];
//extern int __BUILD_DATE;
extern char __BUILD_DATE;
int main(void)
printf("Build date: %lu\n", (unsigned long)&__BUILD_DATE);
这三个声明中的任何一个都应该有效。只是不要尝试使用该(伪)全局的值。这就像取消引用一个无效的指针。
应该回答 2 和 3。要回答 1,-Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
将$(date %Y%m%d)
返回的数字(标准输出)存储为__BUILD_DATE
的地址。它不存储字符串。
【讨论】:
所以使用--defsym
传递的任何内容只能与size_t
/ptrdiff_t
一样大?
@Sparkler 链接器的限制和 C 类型的限制之间不需要有太大的相关性,但实际上您很可能无法存储大于 SIZE_MAX 的地址。
有趣的是,上面的方法只对我有用。如果我使用 gcc 进行链接(使用任何 -fuse-ld
选项或不使用它),我将无法让它正常工作。如果我执行p (unsigned long)&__BUILD_DATE
,调试器总是显示存储的时间戳,但程序打印存储的值偏移0xffffaaaaaaaac000
,但前提是我的系统的地址布局随机化关闭。 (否则它是随机的)。我对此没有任何解释。以上是关于`--defsym` 链接器标志如何将值传递给源代码?的主要内容,如果未能解决你的问题,请参考以下文章
当我使用 if else 然后将值传递给设置 onClick 时,如何获取微调器值?
如何将值从 javascript 传递到 iOS UIWebView
如何将值从javascript传递到iOS UIWebView