我可能还差得远,但这就是我所做的,我也试图让它从linux到mac的交叉编译工作
我在C中用write,malloc和realloc做了一个hello world之类的事情。我注意到在汇编中它使用了adrp,但我不知道如何使用那个指令。我一直得到一个标签必须是GOT相对错误。我希望我可以使用部分作为标签,但最后写了一个标签,没有帮助。
基本上,write
c存根函数使用adrp,然后使用ldr [x16,#24].由于我无法理解adrp,我使用了mov和movk。它似乎做了同样的事情,但当我执行它时,我得到了一个段错误。单步执行lldb时,代码似乎做了我认为的事情,但GOT部分并没有像我想象的那样在运行时被替换。Objdump让我相信我命名的部分是正确的。我不知道是否弄清楚adrp是我需要得到这个工作的全部,或者是否我做的一切都完全错误
.global _main
.align 2
_main:
mov X0, #1
adr X1, hello
mov X2, #13
mov X16, #4
svc 0
mov x16, 16384
movk x16, 0x1, lsl 32
ldr x16, [x16, #24]
#adrp x16, HowGOTLabel
#ldr x16, [x16, #24]
br x16
mov X0, #0
mov X16, #1
svc 0
hello: .ascii "Hello\n"
.section __DATA_CONST,__got
.align 3
HowGOTLabel:
.word 0
.word 0x80100000
.word 1
.word 0x80100000
.word 2
.word 0x80100000
.word 3
.word 0x80000000
1条答案
按热度按时间ndh0cuux1#
arm 64上的达尔文强制所有用户区二进制文件使用ASLR,因此您不能将
movz
/movk
用于PC相对地址。adrp
不能工作的原因是它只能引用0x 1000字节对齐的位置。对于更细粒度的目标,您可以使用adr
,但您会遇到指令被限制在± 1 MB的问题。对于Linux目标,编译器在这里似乎更宽松,但对于达尔文目标,adr
实际上只能用于同一节中的位置,而您试图从__TEXT.__text
引用__DATA_CONST.__got
。那么,如何解决这个问题呢?您可以使用
@PAGE
和@PAGEOFF
:如果目标在范围内,您甚至可以在链接时使用一些asm指令将其修复到
adr+nop
:如果第二条指令是
ldr
而不是add.
,也可以使用AdrpLdr
执行此操作但是,一旦解决了这个问题,代码中就会出现另外两个问题:
1.你使用
br x16
,这意味着你不会返回到调用点,函数调用使用blr
。1.你实际上没有任何导入吗?不清楚你认为这将如何结束调用库函数,但实际上你可以这样做:
编译器和链接器将处理导入。