c - long long int values are incorrectly printed -
when cross compile application target armv7 core, variables 'long long int' incorrectly printed.
typedef long long int vmm_int64; typedef unsigned long long int vmm_uint64; int main(int argc, char *argv[]) { vmm_int64 a, b, result; = 5; b = 24; result = 0; printf("initial values are:\n"); printf("\t : %lld \n", a); printf("\t b : %lld \n", b); printf("\t result : %lld \n", result); fflush(stdout); result = + b; printf("final values are:\n"); printf("\t : %lld \n", a); printf("\t b : %lld \n", b); printf("\t result : %lld \n", result); fflush(stdout); return 0; } the output follows:
initial values are: : 23639177792 b : 105243556416 result : 2164341312 final values are: : 23639177792 b : 105243556416 result : 126718392896 could please explain going on here? should make right?
after more analysis, observed that
a = 0x5 (0x00000005 81013a44 hex 23639177792) b = 0x18 (0x00000018 81013a40 hex 105243556416) i. result = 0 (0x00000000 81013a40 hex 2164341312) ii. result = 0x1d (0x0000001d 81013a40 hex 126718392896) the upper 32 bits contain correct values. don't understand why
- the result upper/lower word swapped.
- even if words swapped, why there junk in lower word.
compiler info:
arm-none-eabi-gcc -v using built-in specs. collect_gcc=c:\program files\codesourcery\sourcery g++ lite\bin\arm-none-eabi-gcc.exe collect_lto_wrapper=c:/program files/codesourcery/sourcery g++ lite/bin/../libexec/gcc/arm-none-eabi/4.5.2/lto-wrapper.exe target: arm-none-eabi configured with: /scratch/janisjo/arm-eabi-lite/src/gcc-4.5-2011.03/configure --build=i686-pc-linux-gnu --host=i686-mingw32 --target=arm-none-eabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --enable-extra-sgxxlite-multilibs --with-gnu-as --with-gnu-ld --with-specs='%{save-temps: -fverbose-asm} -d__cs_sourcerygxx_maj__=2011 -d__cs_sourcerygxx_min__=3 -d__cs_sourcerygxx_rev__=42 %{o2:%{!fno-remove-local-statics: -fremove-local-statics}} %{o*:%{o|o0|o1|o2|os:;:%{!fno-remove-local-statics: -fremove-local-statics}}}' --enable-languages=c,c++ --disable-shared --enable-lto --with-newlib --with-pkgversion='sourcery g++ lite 2011.03-42' --with-bugurl=https://support.codesourcery.com/gnutoolchain/ --disable-nls --prefix=/opt/codesourcery --with-headers=yes --with-sysroot=/opt/codesourcery/arm-none-eabi --with-build-sysroot=/scratch/janisjo/arm-eabi-lite/install/host-i686-mingw32/arm-none-eabi --with-libiconv-prefix=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-gmp=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-mpfr=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-mpc=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-ppl=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-host-libstdcxx='-static-libgcc -wl,-bstatic,-lstdc++,-bdynamic -lm' --with-cloog=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --with-libelf=/scratch/janisjo/arm-eabi-lite/obj/host-libs-2011.03-42-arm-none-eabi-i686-mingw32/usr --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/scratch/janisjo/arm-eabi-lite/obj/tools-i686-pc-linux-gnu-2011.03-42-arm-none-eabi-i686-mingw32/arm-none-eabi/bin --with-build-time-tools=/scratch/janisjo/arm-eabi-lite/obj/tools-i686-pc-linux-gnu-2011.03-42-arm-none-eabi-i686-mingw32/arm-none-eabi/bin thread model: single gcc version 4.5.2 (sourcery g++ lite 2011.03-42)
looks you're mixing abis. cross compiler using apcs (aka old abi) while android runtime expects eabi.
one important difference between 2 how 64-bit values passed in registers. old abi uses next available pair of registers, e.g.
; printf("\t : %lld \n", a); load format string r0 load 'a' r1 , r2 call printf while eabi uses next even-aligned register pair:
; printf("\t : %lld \n", a); load format string r0 load 'a' r2 , r3 call printf let's how a passed both abis:
1. actual: 5 = 0 (high32) , 5 (low32)
oabi: r1 = 0, r2 = 5
eabi: r2 = 0, r3 = 5
printed: 23639177792 = 0x581013a40 = 0x5 (high32) , 0x81013a40 (low32)
oabi: r1 = 5, r2 = 0x81013a40
eabi: r2 = 5, r3 = 0x81013a40
so code loaded 0 r1 , 5 r2, printf interpreted r2 high part , garbage r3 low part. can check inspecting generated assembly.
the fix should easy - use compiler option generate eabi code, or use toolchain targets android, e.g. android ndk.
edit: had high , low parts swapped. here's correct version:
actual: 5 = 0 (high32) , 5 (low32)
oabi: r1 = 5, r2 = 0
eabi: r2 = 5, r3 = 0printed: 23639177792 = 0x581013a40 = 0x5 (high32) , 0x81013a40 (low32)
oabi: r1 = 0x81013a40, r2 = 5
eabi: r2 = 0x81013a40, r3 = 5
so, evidence suggests opposite: code using eabi while printf expecting oabi.
Comments
Post a Comment