我正在尝试创建输出相对虚拟地址的LLVM IR。但是,在编译和链接之后,我发现它会根据可执行文件的首选映像基址输出地址,而不是相对地址。如何在LLVM IR中获取程序的图像基地址
举例来说,如果我用这样的代码:
@.myconstant = private constant [12 x i8] c"My constant\00"
@.myglobal = global {i8*} {i8* bitcast([12 x i8]* @.myconstant to i8*)}
在匹配执行部分,我看到一个十六进制值,如:
44 30 40 00
或者干脆0x403044,这远远大于我的整个可执行文件大小,即使在部分对齐后。
如果我手动减为0x400000,就像这样:
@.myconstant = private constant [12 x i8] c"My constant\00"
@.myglobal = global {i8*} {i8* inttoptr (i32 sub(i32 ptrtoint([12 x i8]* @.myconstant to i32), i32 u0x400000) to i8*)}
我的可执行文件得到正确的地址。但是这个解决方案是不可维护的,因为图像基地址不能保证是0x400000。
与此同时,我不得不使用一个指向全局的指针,因为我不知道全局最终会到达相关部分的哪里(因为这取决于同一部分中的其他全局变量),还是什么将为该部分分配相对内存地址(因为这取决于与前面部分的对齐)。
所以我的问题是,我该如何获得基地址作为一个常数,或得到一个地址相对于加载地址的程序?
更新:显然,LLD的开发人员已经遇到了这个问题,并增加了一个推广到AT & T汇编语言来说明这一点:
.regular_global:
.long .L.myconstant # Outputs 0x403044
.rva_global:
.long [email protected] # Outputs 0x3044
所以我的问题是:我如何导致这个组件通过IR产生?