Решение сабжевой проблемы от Azq2: [Link] и iliyap: [Link]!
Железка ARMv4, ARM7TDMI-S. Код собирается старым ARM ADS компилятором и работает. Я решил собирать код православным GCC вместо проприетарного барахла: arm-none-eabi-gcc (10.3.1)
. В железке есть прошивка и она скомпилирована ADS. Функции прошивки я дёргаю из своего кода, который компилю GCC. Проверил – всё работает, кроме variadic functions. Параметры компиляции у ADS и у GCC следующие:
# ADS
/opt/arm/bin/tcc -c UtilLogStringData.c -o UtilLogStringData.o -bigend -apcs /interwork -O2
# GCC
arm-none-eabi-gcc -mabi=aapcs -ffreestanding -mbig-endian -march=armv4t -mtune=arm7tdmi-s -mthumb -mthumb-interwork -O2 -nostdlib -fshort-wchar -fshort-enums -fpack-struct=4 -fno-builtin -c UtilLogStringData.c -o UtilLogStringData.o
Сама функция:
void UtilLogStringData(const char *format, ...) {
char buffer[255];
va_list vars;
va_start(vars, format);
vsprintf(buffer, format, vars);
va_end(vars);
suLogData(0, 0x5151, 1, strlen(buffer) + 1, buffer);
}
ADS на этом даёт вот такую картину:
10901958 <UtilLogStringData>:
10901958: b40f push {r0, r1, r2, r3}
1090195a: b580 push {r7, lr}
1090195c: b0c2 sub sp, #264 ; 0x108
1090195e: a845 add r0, sp, #276 ; 0x114
10901960: 0880 lsrs r0, r0, #2
10901962: 0080 lsls r0, r0, #2
10901964: 9001 str r0, [sp, #4]
10901966: a802 add r0, sp, #8
10901968: aa01 add r2, sp, #4
1090196a: 9944 ldr r1, [sp, #272] ; 0x110
1090196c: f765 fdcc bl 10867508 <vsprintf>
10901970: 2000 movs r0, #0
10901972: 9001 str r0, [sp, #4]
10901974: a802 add r0, sp, #8
10901976: f765 fd47 bl 10867408 <strlen>
1090197a: aa02 add r2, sp, #8
1090197c: 9200 str r2, [sp, #0]
1090197e: 2201 movs r2, #1
10901980: 1c43 adds r3, r0, #1
10901982: 2000 movs r0, #0
10901984: 49b7 ldr r1, [pc, #732] ; (10901c64 <loadELF+0x2ae>)
10901986: f491 fd5d bl 10593444 <suLogData>
1090198a: b042 add sp, #264 ; 0x108
1090198c: bc80 pop {r7}
1090198e: bc08 pop {r3}
10901990: b004 add sp, #16
10901992: 4718 bx r3
GCC выдаёт следующее, падение происходит на vsprintf:
109018f4 <UtilLogStringData>:
109018f4: b40f push {r0, r1, r2, r3}
109018f6: b510 push {r4, lr}
109018f8: b0c4 sub sp, #272 ; 0x110
109018fa: aa46 add r2, sp, #280 ; 0x118
109018fc: ca02 ldmia r2!, {r1}
109018fe: ac04 add r4, sp, #16
10901900: 0020 movs r0, r4
10901902: 9203 str r2, [sp, #12]
10901904: f765 fe00 bl 10867508 <vsprintf>
10901908: 0020 movs r0, r4
1090190a: f765 fd7d bl 10867408 <strlen>
1090190e: 2201 movs r2, #1
10901910: 1c43 adds r3, r0, #1
10901912: 9400 str r4, [sp, #0]
10901914: 2000 movs r0, #0
10901916: 4904 ldr r1, [pc, #16] ; (10901928 <UtilLogStringData+0x34>)
10901918: f491 fd94 bl 10593444 <suLogData>
1090191c: b044 add sp, #272 ; 0x110
1090191e: bc10 pop {r4}
10901920: bc08 pop {r3}
10901922: b004 add sp, #16
10901924: 4718 bx r3
10901926: 46c0 nop ; (mov r8, r8)
10901928: 00005151 andeq r5, r0, r1, asr r1
Так собственно вопрос, можно ли как-то заставить GCC генерить код так как это делает ADS, чтобы всё работало? В чём вообще причины того что всё отлетело? Я-то конечно забил ASM-костылём скопированным с ADS, но хочется чтобы GCC начисто генерировал корректный код.