我正在尝试编写自己的加载程序。在这个程序中,我将程序复制到RAM中的特定地址,并通过读取精灵的入口点跳转到入口点地址。但是,我无法理解装载程序地址是什么?这是否意味着只需要在编译时指定的加载器地址复制二进制文件。我不能在其他位置加载程序而不是在编译时指定的加载地址?我的基本问题如下:“我不能在其他位置加载程序而不是在编译时指定的加载地址吗?”
答案 0 :(得分:1)
正。
完全链接的ELF程序不包含重定位信息,这些信息允许您在将程序加载到其他地址后修复引用。
使用链接器的-Ur
选项(或适当的链接描述文件),可以生成带有重定位的ELF文件 - 为这些编写加载器更加困难。
答案 1 :(得分:1)
你是否正在瞄准ARM?
您的问题的解决方案是PIC / PIE(位置无关代码/可执行文件)。这样,程序编译如下:
这样,程序在代码中的任何地方都不包含绝对地址。它在代码中也没有重定位。唯一需要的重新安置就是放置GOT本身。
GOT是一个包含所有全局对象,函数和数据的地址的表。在非PIC代码中,数据的绝对地址直接嵌入代码中。该函数需要知道GOT表地址和GOT表中与特定对象相对应的条目号。对象编号是PIC代码中嵌入的唯一内容。 GOT地址通过我遇到的两种方式之一呈现给函数:附加在函数体末端或预定义CPU寄存器中的重定位。我发现后一种选择更好。
如果您的程序最初加载了内存映射ROM,并且您希望将其复制到RAM中以加快速度并允许修改数据,那么PIC非常有用。
请注意,您可以在没有PIC的情况下完成上述所有操作,这只是更麻烦。您将在代码内部进行大量重定位(如果PIC移动函数代码只是一个简单的memcpy),您必须立即复制所有数据块(正确编写的PIC可执行文件允许在不同的位置移动单个对象)记忆区域。)
如果您很好奇,那么我可以向您发送一些用于ARM体系结构的链接描述文件。
答案 2 :(得分:0)