diff --git a/.github/workflows/config.yml b/.github/workflows/config.yml index 40a2f361b..02915004c 100644 --- a/.github/workflows/config.yml +++ b/.github/workflows/config.yml @@ -93,6 +93,8 @@ jobs: include: - DOCKER_IMAGE: arm64v8/ubuntu:jammy - DOCKER_IMAGE: arm64v8/ubuntu:noble + - DOCKER_IMAGE: arm32v5/debian:sid + - DOCKER_IMAGE: arm32v7/debian:sid - DOCKER_IMAGE: arm64v8/debian:sid fail-fast: false diff --git a/.travis.sh b/.travis.sh index 74b11e0d8..add50c0bc 100755 --- a/.travis.sh +++ b/.travis.sh @@ -11,21 +11,26 @@ function travis_time_start { fi TRAVIS_TIME_ID=$(head /dev/urandom | base64 | head -c 8) TRAVIS_FOLD_NAME=$1 - echo -e "\e[0Ktravis_fold:start:$TRAVIS_FOLD_NAME" - echo -e "\e[0Ktravis_time:start:$TRAVIS_TIME_ID" + echo -e "::group::$TRAVIS_FOLD_NAME" + # echo -e "\e[0Ktravis_fold:start:$TRAVIS_FOLD_NAME" + # echo -e "\e[0Ktravis_time:start:$TRAVIS_TIME_ID" set -x # enable debug information } function travis_time_end { set +x # disable debug information _COLOR=${1:-32} + if [ "$_COLOR" -le 30 ]; then + _COLOR=31 # red + fi if [ "$TRAVIS_OS_NAME" == "osx" ]; then TRAVIS_END_TIME=$(( $(date +%s)*1000000000 )) else TRAVIS_END_TIME=$(date +%s%N) fi TIME_ELAPSED_SECONDS=$(( ($TRAVIS_END_TIME - $TRAVIS_START_TIME)/1000000000 )) - echo -e "travis_time:end:$TRAVIS_TIME_ID:start=$TRAVIS_START_TIME,finish=$TRAVIS_END_TIME,duration=$(($TRAVIS_END_TIME - $TRAVIS_START_TIME))\n\e[0K" - echo -e "travis_fold:end:$TRAVIS_FOLD_NAME" + echo -e "::endgroup::" + # echo -e "travis_time:end:$TRAVIS_TIME_ID:start=$TRAVIS_START_TIME,finish=$TRAVIS_END_TIME,duration=$(($TRAVIS_END_TIME - $TRAVIS_START_TIME))\n\e[0K" + # echo -e "travis_fold:end:$TRAVIS_FOLD_NAME" echo -e "\e[0K\e[${_COLOR}mFunction $TRAVIS_FOLD_NAME takes $(( $TIME_ELAPSED_SECONDS / 60 )) min $(( $TIME_ELAPSED_SECONDS % 60 )) sec\e[0m" } diff --git a/lisp/Makefile.LinuxARM b/lisp/Makefile.LinuxARM index 780754d32..30f43633a 100644 --- a/lisp/Makefile.LinuxARM +++ b/lisp/Makefile.LinuxARM @@ -106,7 +106,7 @@ THREADDEP=mthread_posix.c #THREADDEP=pthreads.c # If you don't like optimization, comment out the next line. -OFLAGS=-O2 +OFLAGS=-O2 -fno-omit-frame-pointer # link-editor's default flags ?-rdynamic SOFLAGS:= $(LDFLAGS) -shared -Xlinker -build-id diff --git a/lisp/c/eus.c b/lisp/c/eus.c index 06f40da2b..78bb5fb68 100644 --- a/lisp/c/eus.c +++ b/lisp/c/eus.c @@ -776,11 +776,15 @@ static void initclasses() /* 16 ---new for Solaris */ LDMODULE=basicclass("LOAD-MODULE",C_CODE, &ldmodulecp, #if ARM // ARM uses entry2 in struct ldmodule in eus.h - 4,"ENTRY2", + 5,"ENTRY2", #else 3, #endif - "SYMBOL-TABLE","OBJECT-FILE", "HANDLE"); + "SYMBOL-TABLE","OBJECT-FILE", "HANDLE" +#if ARM + ,"HANDLE2" +#endif + ); C_LDMOD=speval(LDMODULE); /*17*/ LABREF=basicclass("LABEL-REFERENCE",C_OBJECT,&labrefcp,4, @@ -971,7 +975,15 @@ static void initfeatures() /*system function module*/ sysmod=makemodule(ctx,0); sysmod->c.ldmod.codevec=makeint(0); - sysmod->c.ldmod.handle=makeint((eusinteger_t)dlopen(0, RTLD_LAZY)>>2); + void *handle = dlopen(0, RTLD_LAZY); + sysmod->c.ldmod.handle=makeint((eusinteger_t)handle>>2); +#if ARM +#if (WORD_SIZE == 64) + sysmod->c.ldmod.handle2=makeint((eusinteger_t)handle&0x00000000ffffffff); +#else + sysmod->c.ldmod.handle2=makeint((eusinteger_t)handle&0x0000ffff); +#endif +#endif sysobj=cons(ctx,sysmod, sysobj); } diff --git a/lisp/c/eus.h b/lisp/c/eus.h index 1019f458c..60fc70abe 100644 --- a/lisp/c/eus.h +++ b/lisp/c/eus.h @@ -256,7 +256,11 @@ struct ldmodule { /*foreign language object module*/ #endif pointer symtab; pointer objname; - pointer handle;}; /* dl's handle */ + pointer handle; +#if ARM + pointer handle2; /* some archtecture did not set code on 4 byte alignment */ +#endif + }; struct closure { pointer codevec; diff --git a/lisp/c/eval.c b/lisp/c/eval.c index 94cb3d662..987b16fac 100644 --- a/lisp/c/eval.c +++ b/lisp/c/eval.c @@ -1003,7 +1003,7 @@ extern int exec_function_f(void (*)(), int *, int *, int, int *); "ldr r3, [r7, #60]\n\t" /* i */ \ /* https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/function-parameters-on-32-bit-arm */ \ "lsl r4, r3, #2\n\t" /* r4 = i * 2 */ \ - "ldr r1, [r7, #80]\n\t" /* vargv[0] */ \ + "ldr r1, [r7, #16]\n\t" /* vargv[0] */ \ "add r1, r1, r4\n\t" /* vargv[i] */ \ "add r2, sp, r4\n\t" /* stack[i] */ \ "ldr r0, [r1]\n\t" \ @@ -1050,19 +1050,21 @@ __asm__ (".align 4\n" ".global exec_function_i\n\t" ".type exec_function_i, %function\n" "exec_function_i:\n\t" - "push {r7, lr}\n\t" + "push {r3, r4, r5, r6, r7, lr}\n\t" "sub sp, sp, #136\n\t" "add r7, sp, #64\n\t" "str r0, [r7, #12]\n\t" // fc "str r1, [r7, #8]\n\t" // iargv "str r2, [r7, #4]\n\t" // fargv "str r3, [r7]\n\t" // vcntr + "ldr r0, [r7, #96]\n\t" // get 5th argument (vargv) + "str r0, [r7, #16]\n\t" // store vargv to #16 exec_function_asm("FUNCI") // retval "adds r7, r7, #72\n\t" "mov sp, r7\n\t" "@ sp needed @\n\t" - "pop {r7, pc}\n\t" + "pop {r3, r4, r5, r6, r7, pc}\n\t" ".size exec_function_i, .-exec_function_i\n\t" ); @@ -1070,13 +1072,15 @@ __asm__ (".align 4\n" ".global exec_function_f\n\t" ".type exec_function_f, %function\n" "exec_function_f:\n\t" - "push {r7, lr}\n\t" + "push {r3, r4, r5, r6, r7, lr}\n\t" "sub sp, sp, #136\n\t" "add r7, sp, #64\n\t" "str r0, [r7, #12]\n\t" // fc "str r1, [r7, #8]\n\t" // iargv "str r2, [r7, #4]\n\t" // fargv "str r3, [r7]\n\t" // vcntr + "ldr r0, [r7, #96]\n\t" // get 5th argument (vargv) + "str r0, [r7, #16]\n\t" // store vargv to #16 exec_function_asm("FUNCF") // retval "vmov r0, s0 @ \n\t" @@ -1084,7 +1088,7 @@ __asm__ (".align 4\n" "adds r7, r7, #72\n\t" "mov sp, r7\n\t" "@ sp needed @\n\t" - "pop {r7, pc}\n\t" + "pop {r3, r4, r5, r6, r7, pc}\n\t" ".size exec_function_f, .-exec_function_f\n\t" ); @@ -1119,8 +1123,13 @@ pointer args[]; double f; if (code->c.fcode.entry2 != NIL) { +#if (WORD_SIZE == 64) ifunc = (eusinteger_t (*)())((((eusinteger_t)ifunc)&0xffffffff00000000) | (intval(code->c.fcode.entry2)&0x00000000ffffffff)); +#else + ifunc = (eusinteger_t (*)())((((eusinteger_t)ifunc)&0xffff0000) + | (intval(code->c.fcode.entry2)&0x0000ffff)); +#endif /* R.Hanai 090726 */ } while (iscons(paramtypes)) { @@ -1306,13 +1315,13 @@ pointer args[]; if (resulttype==K_FLOAT || resulttype==K_FLOAT32) { union { eusfloat_t f; -#if __ARM_ARCH==4 +#if __ARM_ARCH==4 || __ARM_ARCH==5 eusinteger_t i; // ARM 32bit armel #else eusfloat_t i; // Intel 32bit x86 #endif } n; -#if __ARM_ARCH==4 +#if __ARM_ARCH==4 || __ARM_ARCH==5 typedef eusinteger_t ifunc_ret_type; #else typedef double ifunc_ret_type; diff --git a/lisp/c/makes.c b/lisp/c/makes.c index a4638a2d2..8c243f872 100644 --- a/lisp/c/makes.c +++ b/lisp/c/makes.c @@ -501,6 +501,9 @@ int size; mod->c.ldmod.symtab=NIL; mod->c.ldmod.objname=NIL; mod->c.ldmod.handle=NIL; +#if ARM + mod->c.ldmod.handle2=NIL; +#endif return(mod);} pointer makeclosure(code,quote,f,e0,e1,e2) diff --git a/lisp/c/unixcall.c b/lisp/c/unixcall.c index 177660670..d9f3cf9c7 100644 --- a/lisp/c/unixcall.c +++ b/lisp/c/unixcall.c @@ -132,7 +132,7 @@ pointer LOCALTIME(ctx,n,argv) register context *ctx; int n; pointer argv[]; -{ long clock; +{ time_t clock; /* sizoef time(0) is machine dependent and may differ from long */ struct tm *tms; pointer timevec; pointer *tv; @@ -203,6 +203,9 @@ register pointer argv[]; #else atp=asctime_r(tms,at,ASCTIME_STRLEN); /* asctime --> asctime_r */ #endif + if (atp == NULL) { + error(E_USER,(pointer)strerror(errno)); + } return(makestring(atp,strlen(atp)));} #if !Solaris2 @@ -211,16 +214,28 @@ pointer GETRUSAGE(ctx,n,argv) register context *ctx; int n; pointer argv[]; { register int who,i; - long rusage[18]; + struct rusage usage; eusfloat_t utime,stime; register pointer r=NIL; numunion nu; - ckarg(1); who=ckintval(argv[0]); - getrusage(who,(struct rusage *)rusage); - utime=rusage[0]+rusage[1]*1.0e-6; - stime=rusage[2]+rusage[3]*1.0e-6; - for (i=17; i>=4; i--) r=cons(ctx,makeint(rusage[i]),r); + getrusage(who,&usage); + utime=usage.ru_utime.tv_sec+usage.ru_utime.tv_usec*1.0e-6; + stime=usage.ru_stime.tv_sec+usage.ru_stime.tv_usec*1.0e-6; + r = cons(ctx, makeint(usage.ru_nivcsw), r); // 4 + r = cons(ctx, makeint(usage.ru_nvcsw), r); // 5 + r = cons(ctx, makeint(usage.ru_nsignals), r); // 6 + r = cons(ctx, makeint(usage.ru_msgrcv), r); // 7 + r = cons(ctx, makeint(usage.ru_msgsnd), r); // 8 + r = cons(ctx, makeint(usage.ru_oublock), r); // 9 + r = cons(ctx, makeint(usage.ru_inblock), r); // 10 + r = cons(ctx, makeint(usage.ru_nswap), r); // 11 + r = cons(ctx, makeint(usage.ru_majflt), r); // 12 + r = cons(ctx, makeint(usage.ru_minflt), r); // 13 + r = cons(ctx, makeint(usage.ru_isrss), r); // 14 + r = cons(ctx, makeint(usage.ru_idrss), r); // 15 + r = cons(ctx, makeint(usage.ru_ixrss), r); // 16 + r = cons(ctx, makeint(usage.ru_maxrss), r); // 17 r=cons(ctx,makeflt(stime),r); r=cons(ctx,makeflt(utime),r); /*(utime stime maxrss ixrss idrss isrss page-reclaims page-faults swap inblock outblock msgsnd msgrcv nsignals diff --git a/lisp/xwindow/xforeign.c.c b/lisp/xwindow/xforeign.c.c index aa9a2e581..9ceff2b18 100644 --- a/lisp/xwindow/xforeign.c.c +++ b/lisp/xwindow/xforeign.c.c @@ -433,7 +433,17 @@ char *xentry; dlhandle=(eusinteger_t)dlopen("libX11.dylib", RTLD_LAZY); entry=(eusinteger_t)dlsym((void *)dlhandle, xentry); #else - entry=(eusinteger_t)dlsym((void *)((eusinteger_t)(sysmod->c.ldmod.handle) & ~3), xentry); + eusinteger_t dlhandle = (eusinteger_t)(sysmod->c.ldmod.handle) & ~3; +#if ARM + if ( sysmod->c.ldmod.handle2 != NIL ) { +#if (WORD_SIZE == 64) + dlhandle = (dlhandle & 0xffffffff00000000) | (intval(sysmod->c.ldmod.handle2) & 0x00000000ffffffff); +#else + dlhandle = (dlhandle & 0xffff0000) | (intval(sysmod->c.ldmod.handle2) & 0x0000ffff); +#endif + } +#endif + entry=(eusinteger_t)dlsym((void *)(dlhandle), xentry); #endif if (entry){ xsym=intern(ctx,lname, len-1, xpkg); diff --git a/test/time.l b/test/time.l index 4d9353b27..cde956c0b 100644 --- a/test/time.l +++ b/test/time.l @@ -62,6 +62,14 @@ ) +(deftest test-asctime + ;; asctime segfaults on arm32:sid + (unix::asctime (unix::localtime)) ;; check if asctime works + (assert (string= + (unix::asctime #(41 26 15 27 8 125 6 269 nil ("JST" "JST"))) + (format nil "Sat Sep 27 15:26:41 2025~%"))) +) + (eval-when (load eval) (run-all-tests) (exit))