热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

objdump产生错误的分支操作码解释

如何解决《objdump产生错误的分支操作码解释》经验,为你挑选了1个好方法。

请参阅以下objdump特定功能的特定目标文件的行(func):

3c:   e03a            b.n     78 

现在,e03a目标系统(ARMv6-M)中的操作码显示跳转到的位置PC + 0x78。正确的解释是:

3c:   e03a            b.n     B4 

每个其他函数和文件都包含正确的b.n解释,并在其objdump转储中包含正确的值计算。由于某些原因,仅此功能会导致objdump“混淆”。

注意:func从开始0x0

我无法想到这种情况的任何原因。而且由于我具有解析和使用objdump转储的工具,因此这对我造成了很大的问题。有什么合理的理由吗?

工具链: gcc-arm-none-eabi-4_9-2015q3

运行此工具链的平台: Ubuntu 16.04.2 LTS


编辑:我附加部分转储:

Disassembly of section i.func:

00000000 :
   0:   b531        push    {r0, r4, r5, lr}
   2:   b088        sub sp, #32
   4:   2100        movs    r1, #0
   6:   9106        str r1, [sp, #24]
   8:   482c        ldr r0, [pc, #176]  ; (bc )
   a:   6800        ldr r0, [r0, #0]
   c:   6840        ldr r0, [r0, #4]
   e:   9103        str r1, [sp, #12]
  10:   1c40        adds    r0, r0, #1
  12:   9002        str r0, [sp, #8]
  14:   492a        ldr r1, [pc, #168]  ; (c0 )
  16:   2000        movs    r0, #0
  18:   9104        str r1, [sp, #16]
  1a:   9005        str r0, [sp, #20]
  1c:   a802        add r0, sp, #8
  1e:   f7ff fffe   bl  0 
  22:   f7ff fffe   bl  0 
  26:   4604        mov r4, r0
  28:   4d26        ldr r5, [pc, #152]  ; (c4 )
  2a:   42ac        cmp r4, r5
  2c:   d007        beq.n   3e 
  2e:   a326        add r3, pc, #152    ; (adr r3, c8 )
  30:   22ee        movs    r2, #238    ; 0xee
  32:   492c        ldr r1, [pc, #176]  ; (e4 )
  34:   2000        movs    r0, #0
  36:   9400        str r4, [sp, #0]
  38:   f7ff fffe   bl  0 
  3c:   e03a        b.n 78    <---- PROBLEM IS HERE
  3e:   f7ff fffe   bl  0 
  42:   9006        str r0, [sp, #24]
  44:   f3bf 8f5f   dmb sy
  48:   a808        add r0, sp, #32
  4a:   7800        ldrb    r0, [r0, #0]
  4c:   2800        cmp r0, #0
  4e:   d00f        beq.n   70 
  50:   9806        ldr r0, [sp, #24]
  52:   2803        cmp r0, #3
  54:   d016        beq.n   84 
  56:   f7ff fffe   bl  0 
  5a:   4604        mov r4, r0
  5c:   42ac        cmp r4, r5
  5e:   d01a        beq.n   96 
  60:   a321        add r3, pc, #132    ; (adr r3, e8 )
  62:   22fa        movs    r2, #250    ; 0xfa
  64:   491f        ldr r1, [pc, #124]  ; (e4 )
  66:   2000        movs    r0, #0
  68:   9400        str r4, [sp, #0]
  6a:   f7ff fffe   bl  0 
  6e:   e021        b.n 46   <--- ALSO HERE SAME PROBLEM
  70:   f7ff fffe   bl  0 
  74:   2800        cmp r0, #0
  76:   d003        beq.n   80 
  78:   a808        add r0, sp, #32
  7a:   7800        ldrb    r0, [r0, #0]
  7c:   2800        cmp r0, #0
  7e:   d018        beq.n   b2 
  80:   f7ff fffe   bl  0 
  84:   f7ff fffe   bl  0 
  88:   2800        cmp r0, #0
  8a:   d002        beq.n   92 
  8c:   9806        ldr r0, [sp, #24]
  8e:   2803        cmp r0, #3
  90:   d00f        beq.n   b2 
  92:   f7ff fffe   bl  0 
  96:   f7ff fffe   bl  0 
  9a:   4604        mov r4, r0
  9c:   42ac        cmp r4, r5
  9e:   d008        beq.n   b2 
  a0:   22ff        movs    r2, #255    ; 0xff
  a2:   a318        add r3, pc, #96 ; (adr r3, 104 )
  a4:   3201        adds    r2, #1
  a6:   490f        ldr r1, [pc, #60]   ; (e4 )
  a8:   2000        movs    r0, #0
  aa:   9400        str r4, [sp, #0]
  ac:   f7ff fffe   bl  0 
  b0:   e000        b.n b4 
  b2:   462c        mov r4, r5
  b4:   4620        mov r0, r4

Ctx.. 6

看起来像个虫子;每次在两次跳转之间跳转时,都需要像这里一样进行重新定位

38:   f7ff fffe   bl  0 
3c:   e03a        b.n 78    <---- PROBLEM IS HERE
3e:   f7ff fffe   bl  0 

或在这里

6a:   f7ff fffe   bl  0 
6e:   e021        b.n 46 
70:   f7ff fffe   bl  0 

计算错误。

没有正当的理由;向错误跟踪系统http://www.sourceware.org/bugzilla/的报告可能是适当的(在验证后,最新版本也受到此错误的影响)

编辑:我有一些时间深入研究此错误。

的问题是,如果该指令之前b.n任何32位指令和该指令之后b.n受搬迁,objdump的错误地假定该b.n指令具有与它和套的相对pc用于偏移计算相关联的为0的重定位。

该代码部分来自binutils/objdump.c罪魁祸首:

              bfd_signed_vma distance_to_rel;

              distance_to_rel = (**relppp)->address
                - (rel_offset + addr_offset);

              /* Check to see if the current reloc is associated with
                 the instruction that we are about to disassemble.  */
              if (distance_to_rel == 0
                  /* FIXME: This is wrong.  We are trying to catch
                     relocs that are addressed part way through the
                     current instruction, as might happen with a packed
                     VLIW instruction.  Unfortunately we do not know the
                     length of the current instruction since we have not
                     disassembled it yet.  Instead we take a guess based
                     upon the length of the previous instruction.  The
                     proper solution is to have a new target-specific
                     disassembler function which just returns the length
                     of an instruction at a given address without trying
                     to display its disassembly. */
                  || (distance_to_rel > 0
                      && distance_to_rel <(bfd_signed_vma) (previous_octets/ opb)))
                {
                  inf->flags |= INSN_HAS_RELOC;
                  aux->reloc = **relppp;
                }

注释说明了一切:该解析器从上一条32位指令中猜测,下一条指令也是 32位(不是!)。重定位是针对的3e,反汇编器假定下一条指令是从3c3f,因此将b.n标记为INSN_HAS_RELOC,从而导致错误的偏移量计算。看起来,这样很难解决。

但是,您可以尝试像这样修补objdump:

if (distance_to_rel == 0) {
              inf->flags |= INSN_HAS_RELOC;
              aux->reloc = **relppp;
}

反之,这可能会产生误差,但是这种情况很少见,也许您会更好。



1> Ctx..:

看起来像个虫子;每次在两次跳转之间跳转时,都需要像这里一样进行重新定位

38:   f7ff fffe   bl  0 
3c:   e03a        b.n 78    <---- PROBLEM IS HERE
3e:   f7ff fffe   bl  0 

或在这里

6a:   f7ff fffe   bl  0 
6e:   e021        b.n 46 
70:   f7ff fffe   bl  0 

计算错误。

没有正当的理由;向错误跟踪系统http://www.sourceware.org/bugzilla/的报告可能是适当的(在验证后,最新版本也受到此错误的影响)

编辑:我有一些时间深入研究此错误。

的问题是,如果该指令之前b.n任何32位指令和该指令之后b.n受搬迁,objdump的错误地假定该b.n指令具有与它和套的相对pc用于偏移计算相关联的为0的重定位。

该代码部分来自binutils/objdump.c罪魁祸首:

              bfd_signed_vma distance_to_rel;

              distance_to_rel = (**relppp)->address
                - (rel_offset + addr_offset);

              /* Check to see if the current reloc is associated with
                 the instruction that we are about to disassemble.  */
              if (distance_to_rel == 0
                  /* FIXME: This is wrong.  We are trying to catch
                     relocs that are addressed part way through the
                     current instruction, as might happen with a packed
                     VLIW instruction.  Unfortunately we do not know the
                     length of the current instruction since we have not
                     disassembled it yet.  Instead we take a guess based
                     upon the length of the previous instruction.  The
                     proper solution is to have a new target-specific
                     disassembler function which just returns the length
                     of an instruction at a given address without trying
                     to display its disassembly. */
                  || (distance_to_rel > 0
                      && distance_to_rel <(bfd_signed_vma) (previous_octets/ opb)))
                {
                  inf->flags |= INSN_HAS_RELOC;
                  aux->reloc = **relppp;
                }

注释说明了一切:该解析器从上一条32位指令中猜测,下一条指令也是 32位(不是!)。重定位是针对的3e,反汇编器假定下一条指令是从3c3f,因此将b.n标记为INSN_HAS_RELOC,从而导致错误的偏移量计算。看起来,这样很难解决。

但是,您可以尝试像这样修补objdump:

if (distance_to_rel == 0) {
              inf->flags |= INSN_HAS_RELOC;
              aux->reloc = **relppp;
}

反之,这可能会产生误差,但是这种情况很少见,也许您会更好。


推荐阅读
author-avatar
晴儿19082
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有