• arm下dlsym返回的符号地址居然不是偶对齐的。


    我们都知道在写汇编函数过程都会偶对齐,而gcc编译器都会将函数编译为cpu字长对齐的地址。arm指令集是固定32位指令长度,thumb指令集是固定16位指令长度, 但是运行在arm下的程序,dlsym返回的符号地址居然不是对齐的。

    先来看现象,下面是从libui库中取两个函数符号。

     结果显示为两个奇数地址,这两个地址都在正确的函数地址的基础上加了1。

    如果按上面两个函数地址去反汇编的话,一定会得到不正确的反汇编代码。但如果自作聪明将地址手动令其对齐反而会出错。手动将地址对齐(addr & ~3)后再调用就会引起SIGILL或SIGSEGV,诚然我对arm涉足并不深,(也就是基于x86去看arm的代码,也就是翻译成我理解的x86汇编来看arm汇编),当然也就干了上面的事。

    dlsym返回的地址被加1,这是有原因的。看下面反汇编出来的代码

    从指令地址的偏移规律,可以看出是在使用thumb指令集,从push.w这一指令可以知道还是thumb2模式,'.w'强制thumb模式下某一指令应用32位长度。arm运行在不同模式以执行不同的指令集,而切换这种模式就是BLX或BX跳转指令(函数调用,Branch to register)提供的功能。由于函数地址要求是偶对齐的,所以函数地址的最低位被利用作为控制位,当这个位为1时,BX或BLX指令而进入thumb模式,否则进入arm模式,不同模式下对代码段进行指令译码就会有不同的结果。

    指令的官方文档在http://www.keil.com/support/man/docs/armasm/armasm_dom1361289866046.htm

    在lldb调试中可以通过help arch查看支持的指令体系,在反汇编时加-A arch选项指定应用的指令集。

    如何在调试获知cpu当前执行在哪种模式,可以参考https://stackoverflow.com/questions/22660025/how-can-i-tell-if-i-am-in-arm-mode-or-thumb-mode-in-gdb

    就是查看寄存器cpsr的第5位(第0位是末位)是否1, p $cpsr & (1<<5)

    lldb也不总会正确反汇编一帧来,

     

  • 相关阅读:
    BigDecimal 使用方法详解
    vbs xml 解析
    hybris
    淘宝SKU组合查询算法实现
    GitHub入门教程 Hello World for GitHub
    利用Java进行MySql数据库的导入和导出
    计算机网络自顶向下第三章传输层二TCP
    django网站搭建常用的一些代码
    django中日志使用学习记录
    python遍历当前目录并删除某文件
  • 原文地址:https://www.cnblogs.com/bbqzsl/p/7805590.html
Copyright © 2020-2023  润新知