Я пытаюсь создать 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.
В то же время я должен использовать указатель на глобальный, потому что я не знаю, где этот глобальный окажется внутри соответствующего раздела (так как это зависит от других глобалов в том же разделе) или что адрес относительной памяти будет назначен для этого раздела (так как это зависит от выравнивания с предыдущими разделами).
Итак, мой вопрос: как я могу получить базовый адрес как константу или получить адрес относительно загрузочного адреса программы?
Update: Видимо, разработчики LLD уже сталкивались с этой проблемой, и добавил расширение, к AT & T ассемблере для учета этого:
.regular_global:
.long .L.myconstant # Outputs 0x403044
.rva_global:
.long [email protected] # Outputs 0x3044
Поэтому мой вопрос становится: как я заставить эту сборку производить через ИК?