gcc command for keeping addresses as they were?
有没有办法在每次编译程序时保持所有函数和变量的偏移量不变?
- 你确定它会随着编译器的每次运行或程序的每次运行而改变吗?在后一种情况下,它可能是内核安全措施,每次运行程序都会改变地址空间。对于软件开发人员来说确实非常不方便。
-
会是这样的好处吗?即使给定的函数或对象恰好在程序的一次编译到下一次编译中具有相同的地址,我也想不出任何合理的方法来利用它。
-
@KeithThompson 一些嵌入式设备和游戏机需要特定地址的东西。
-
@m0skit0:然后您需要使用一些(可能是特定于编译器的)机制将这些东西映射到那些特定的地址,从一个编译到下一个编译都是稳定的。这似乎不是 OP 所要求的。
-
@KeithThompson AFAIK 没有专门针对此的编译器,例如Sony 使用 gcc 为 PlayStation 机型编译。我们复制它的方法是使用链接器脚本并小心...
没有。这不是编译器本身的限制,而是"逻辑"限制。想象一下,你有一个装满东西的盒子。现在你想在盒子 A 上添加东西,但你不想要一个新盒子。好吧,你不能,这是一个物理限制。
或者说更多"计算机化":
函数a()占用地址0到0xA00(大小为0xA00)
函数b()占用地址0xA01到0xB00(大小0x100)
现在你修改 a() 使它更大,假设它的大小现在是 0xB00。您如何将 a() 和 b() 保存在同一个地址中?除非你做一些讨厌的技巧,比如将函数 a() 分成两部分,否则你不能这样做,但我认为这不是你想要的。
这并没有考虑现代操作系统具有 ASLR 和其他安全方法。
- 也就是说,您可以编写一个链接描述文件来指定每个函数的内存地址。 (如果将来对函数的更改使其与另一个函数重叠,这可能会出现问题)
-
是的,当然,您可以指定链接器在哪里放置东西(例如,我之前在控制台开发中确实这样做过),但您必须了解上述情况:)
是的,不是的。不,因为 m0skit0 所说的。是的,因为您可以告诉链接器在指定地址设置某些符号 - 至少我知道 GCC 的端口可以用于各种嵌入式目标。使用这种技术的代码比较常见,例如从稍后加载的模块加载固件或类似的东西。
这个问题的答案告诉你一些方法来做到这一点。虽然这是非常不便携的,但我相信你明白这样做的所有陷阱:)