代码之家  ›  专栏  ›  技术社区  ›  Bob

臂组件-bl分支到错误的地址

  •  2
  • Bob  · 技术社区  · 6 年前

    解决方法:一个电源循环修复它。一定是上部闪存块的电气问题导致硬件执行单元从闪存读取错误的值

    我正在组装,奇怪的事情正在发生。

    我有两个独立的flash块,它们都包含代码。 veneer 由链接器自动生成。

    到现在为止我一直在努力,我做了些什么-不知道是什么-打破了它。

    0x1001a9ca: 0x0cf0c5fe bl 0x10027758 <__atiupy_PutOutput2_veneer>

    在执行之后,PC被激活 0x100275ce .

    如果我在反汇编窗口中滚动到 0x10027758 ,我看到标签了 __atiupy_PutOutput2_veneer .

    为什么跳错地址了?

    它在跳 C代码 C++代码。是的,我有 extern "C" .h 对于C++代码中的函数调用,由C代码调用。

    C编译选项包括: -x c -Wall -Werror -std=c99 -nostdlib -mthumb -mtune=cortex-m4 -mlittle-endian -Wdouble-promotion -DNDEBUG -fdata-sections -ffunction-sections -c -save-temps=obj -g3 -gdwarf-2

    C++编译选项是: -mthumb -mlittle-endian -x c++ -gdwarf-2 -g3 -fomit-frame-pointer -fnothrow-opt -ffreestanding -fverbose-asm -std=c++11 -c -fno-rtti -ffunction-sections -fdata-sections -fno-exceptions

    根据要求,使用 objdump -d .

    它要跳到哪里去 0x10027758

    1001a9bc <mp_hal_stdout_tx_strn_cooked>:
    1001a9bc:   b580        push    {r7, lr}
    1001a9be:   b082        sub sp, #8
    1001a9c0:   af00        add r7, sp, #0
    1001a9c2:   6078        str r0, [r7, #4]
    1001a9c4:   6039        str r1, [r7, #0]
    1001a9c6:   6878        ldr r0, [r7, #4]
    1001a9c8:   6839        ldr r1, [r7, #0]
    1001a9ca:   f00c fec5   bl  10027758 <__atiupy_PutOutput2_veneer>
    1001a9ce:   f107 0708   add.w   r7, r7, #8
    1001a9d2:   46bd        mov sp, r7
    1001a9d4:   bd80        pop {r7, pc}
    1001a9d6:   bf00        nop
    

    它应该跳到哪里

    10027758 <__atiupy_PutOutput2_veneer>:
    10027758:   b401        push    {r0}
    1002775a:   4802        ldr r0, [pc, #8]    ; (10027764 <__atiupy_PutOutput2_veneer+0xc>)
    1002775c:   4684        mov ip, r0
    1002775e:   bc01        pop {r0}
    10027760:   4760        bx  ip
    10027762:   bf00        nop
    10027764:   00035abd    .word   0x00035abd
    

    它实际上跳到了 0x100275ce 但我要粘贴这里的整个函数

    100275c8 <___ZN21CKinetisI2CController7DisableEv_veneer>:
    100275c8:   b401        push    {r0}
    100275ca:   4802        ldr r0, [pc, #8]    ; (100275d4 <___ZN21CKinetisI2CController7DisableEv_veneer+0xc>)
    100275cc:   4684        mov ip, r0
    100275ce:   bc01        pop {r0}
    100275d0:   4760        bx  ip
    100275d2:   bf00        nop
    100275d4:   00029b2d    .word   0x00029b2d
    

    我设置了一个断点 mp_hal_stdout_tx_strn_cooked 然后使用 stepi

    p/x $pc
    $2 = 0x1001a9c6
    disass
    Dump of assembler code for function mp_hal_stdout_tx_strn_cooked:
       0x1001a9bc <+0>: push    {r7, lr}
       0x1001a9be <+2>: sub sp, #8
       0x1001a9c0 <+4>: add r7, sp, #0
       0x1001a9c2 <+6>: str r0, [r7, #4]
       0x1001a9c4 <+8>: str r1, [r7, #0]
    => 0x1001a9c6 <+10>:    ldr r0, [r7, #4]
       0x1001a9c8 <+12>:    ldr r1, [r7, #0]
       0x1001a9ca <+14>:    bl  0x10027758 <__atiupy_PutOutput2_veneer>
       0x1001a9ce <+18>:    add.w   r7, r7, #8
       0x1001a9d2 <+22>:    mov sp, r7
       0x1001a9d4 <+24>:    pop {r7, pc}
    End of assembler dump.
    stepi
    stepi
    0x1001a9c8  23      atiupy_PutOutput2(str, len);
    disass
    Dump of assembler code for function mp_hal_stdout_tx_strn_cooked:
       0x1001a9bc <+0>: push    {r7, lr}
       0x1001a9be <+2>: sub sp, #8
       0x1001a9c0 <+4>: add r7, sp, #0
       0x1001a9c2 <+6>: str r0, [r7, #4]
       0x1001a9c4 <+8>: str r1, [r7, #0]
       0x1001a9c6 <+10>:    ldr r0, [r7, #4]
    => 0x1001a9c8 <+12>:    ldr r1, [r7, #0]
       0x1001a9ca <+14>:    bl  0x10027758 <__atiupy_PutOutput2_veneer>
       0x1001a9ce <+18>:    add.w   r7, r7, #8
       0x1001a9d2 <+22>:    mov sp, r7
       0x1001a9d4 <+24>:    pop {r7, pc}
    End of assembler dump.
    stepi
    stepi
    0x1001a9ca  23      atiupy_PutOutput2(str, len);
    diasass
    Undefined command: "diasass".  Try "help".
    disass
    Dump of assembler code for function mp_hal_stdout_tx_strn_cooked:
       0x1001a9bc <+0>: push    {r7, lr}
       0x1001a9be <+2>: sub sp, #8
       0x1001a9c0 <+4>: add r7, sp, #0
       0x1001a9c2 <+6>: str r0, [r7, #4]
       0x1001a9c4 <+8>: str r1, [r7, #0]
       0x1001a9c6 <+10>:    ldr r0, [r7, #4]
       0x1001a9c8 <+12>:    ldr r1, [r7, #0]
    => 0x1001a9ca <+14>:    bl  0x10027758 <__atiupy_PutOutput2_veneer>
       0x1001a9ce <+18>:    add.w   r7, r7, #8
       0x1001a9d2 <+22>:    mov sp, r7
       0x1001a9d4 <+24>:    pop {r7, pc}
    End of assembler dump.
    stepi
    stepi
    0x100275ce in ___ZN21CKinetisI2CController7DisableEv_veneer ()
    disass
    Dump of assembler code for function ___ZN21CKinetisI2CController7DisableEv_veneer:
       0x100275c8 <+0>: push    {r0}
       0x100275ca <+2>: ldr r0, [pc, #8]    ; (0x100275d4 <___ZN21CKinetisI2CController7DisableEv_veneer+12>)
       0x100275cc <+4>: mov r12, r0
    => 0x100275ce <+6>: pop {r0}
       0x100275d0 <+8>: bx  r12
       0x100275d2 <+10>:    nop
       0x100275d4 <+12>:    ldr r3, [sp, #180]  ; 0xb4
       0x100275d6 <+14>:    movs    r2, r0
    End of assembler dump.
    stepi
    stepi
    0x100275d0 in ___ZN21CKinetisI2CController7DisableEv_veneer ()
    disass
    Dump of assembler code for function ___ZN21CKinetisI2CController7DisableEv_veneer:
       0x100275c8 <+0>: push    {r0}
       0x100275ca <+2>: ldr r0, [pc, #8]    ; (0x100275d4 <___ZN21CKinetisI2CController7DisableEv_veneer+12>)
       0x100275cc <+4>: mov r12, r0
       0x100275ce <+6>: pop {r0}
    => 0x100275d0 <+8>: bx  r12
       0x100275d2 <+10>:    nop
       0x100275d4 <+12>:    ldr r3, [sp, #180]  ; 0xb4
       0x100275d6 <+14>:    movs    r2, r0
    End of assembler dump.
    

    编译前的程序集文件

    有人想要编译器输出的汇编文件,而不是 objdump 的解释。此输出是compile选项的结果 -save-temps=obj

    .LFE14:
        .size   mp_hal_stdout_tx_strn, .-mp_hal_stdout_tx_strn
        .section    .text.mp_hal_stdout_tx_strn_cooked,"ax",%progbits
        .align  2
        .global mp_hal_stdout_tx_strn_cooked
        .thumb
        .thumb_func
        .type   mp_hal_stdout_tx_strn_cooked, %function
    mp_hal_stdout_tx_strn_cooked:
    .LFB15:
        .loc 1 22 0
        .cfi_startproc
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        push    {r7, lr}
    .LCFI11:
        .cfi_def_cfa_offset 8
        .cfi_offset 7, -8
        .cfi_offset 14, -4
        sub sp, sp, #8
    .LCFI12:
        .cfi_def_cfa_offset 16
        add r7, sp, #0
    .LCFI13:
        .cfi_def_cfa_register 7
        str r0, [r7, #4]
        str r1, [r7, #0]
        .loc 1 23 0
        ldr r0, [r7, #4]
        ldr r1, [r7, #0]
        bl  atiupy_PutOutput2
        .loc 1 25 0
        add r7, r7, #8
        mov sp, r7
        pop {r7, pc}
        .cfi_endproc
    

    (Sad)更新

    我创建了一个最小的示例,但问题没有出现。因此,我认为这是我所处的环境。我将开始还原本地更改并更新。我不会调用下面的代码 完成 因为您需要链接器文件,但由于它不会再现问题,所以我认为提供所有内容没有意义。

    主.cpp

    #include "common.h"
    
    int main()
    {
        test1();
    }
    
    int main_test()
    {
        int a = 5;
        a = 23424 * a;
        return a;
    }
    

    试验c

    #include "common.h"
    
    void test1()
    {
        int a;
        a = main_test();
        a *= 2;
    }
    

    普通.h

    #ifdef __cplusplus
    extern "C" {
    #endif //#ifdef __cplusplus
    
    
    int main_test();
    void test1();
    
    
    #ifdef __cplusplus
    }
    #endif //#ifdef __cplusplus
    

    主对象 测试对象 在上面的街区。从上到下跳跃时,电脑 跳转到正确的地址 .

    1 回复  |  直到 6 年前
        1
  •  1
  •   Bob    6 年前

    解决方法:一个电源循环修复它。一定是上部闪存块的电气问题导致硬件执行单元从闪存读取错误的值。