ARM сборка - bl разветвляется по неверному адресу - PullRequest
0 голосов
/ 06 сентября 2018

решено: цикл питания исправил это.Возможно, возникла электрическая проблема с верхним блоком флэш-памяти, из-за которой исполнительный модуль HW считал неправильное значение из флэш-памяти

Я выполняю сборку и происходит что-то странное.

У меня есть два отдельных флэш-блока, и они оба содержат код.Поскольку они так далеко друг от друга, вызовы функций из одного блока в другой требуют промежуточного перехода, известного как veneer, который автоматически генерируется компоновщиком.

Это работало до сих пор, и я что-то сделал - понятия не имеючто - сломать его.

0x1001a9ca: 0x0cf0c5fe bl 0x10027758 <__atiupy_PutOutput2_veneer>

После того, как это выполнено, ПК 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.Этот вывод является результатом опции компиляции -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) update

Я создал минимальный пример, но проблема не возникает.Поэтому я думаю, что это что-то в моей среде.Я начну отменять локальные изменения и буду обновлять.Я бы не назвал приведенный ниже код complete , потому что вам нужен файл компоновщика, но так как он не воспроизводит проблему, я не вижу смысла в предоставлении всего.

main.cpp

#include "common.h"

int main()
{
    test1();
}

int main_test()
{
    int a = 5;
    a = 23424 * a;
    return a;
}

test.c

#include "common.h"

void test1()
{
    int a;
    a = main_test();
    a *= 2;
}

common.h

#ifdef __cplusplus
extern "C" {
#endif //#ifdef __cplusplus


int main_test();
void test1();


#ifdef __cplusplus
}
#endif //#ifdef __cplusplus

main.obj находится в «нижнем» блоке флэш-памяти, в то время как test.obj находится в верхнем блоке.При переходе от верхнего к нижнему ПК правильно переходит на правильный адрес для veneer.

1 Ответ

0 голосов
/ 07 сентября 2018

решено: цикл питания исправил это. Возможно, возникла электрическая проблема с верхним блоком вспышки, из-за которой исполнительный блок HW считал неправильное значение из вспышки.

...