From 0062e9b95bb17ec104217587a3950b18173fbc3c Mon Sep 17 00:00:00 2001 From: Kei Date: Thu, 25 Sep 2025 21:06:47 +0900 Subject: [PATCH 01/10] add armhf/armel test, to check https://buildd.debian.org/status/fetch.php?pkg=euslisp&arch=armhf&ver=9.32%2Bdfsg-1&stamp=1758791999&raw=0 --- .github/workflows/config.yml | 2 ++ 1 file changed, 2 insertions(+) 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 From c7149e9ee8a47ab37a6fcd65086ce744b5e587e2 Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Fri, 26 Sep 2025 05:01:17 +0000 Subject: [PATCH 02/10] exec_function_i: keep r3,r4,r5,r6,r7 for #elif defined(ARM) && defined(__ARM_ARCH_7A__) /* not (defined(x86_64) || defined(aarch64)) */ --- lisp/c/eval.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lisp/c/eval.c b/lisp/c/eval.c index 94cb3d662..0a10537b6 100644 --- a/lisp/c/eval.c +++ b/lisp/c/eval.c @@ -1050,7 +1050,7 @@ __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 @@ -1062,7 +1062,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_i, .-exec_function_i\n\t" ); @@ -1070,7 +1070,7 @@ __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 @@ -1084,7 +1084,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 +1119,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)) { From 2ab431074bdb88bd80bd668c40e319a1a4c4d675 Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Fri, 26 Sep 2025 05:01:36 +0000 Subject: [PATCH 03/10] use -fno-omit-frame-pointer for #elif defined(ARM) && defined(__ARM_ARCH_7A__) /* not (defined(x86_64) || defined(aarch64)) */ --- lisp/Makefile.LinuxARM | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From fdebbb3bb7bce76b31c51e30ed2432bf16bc8d65 Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Fri, 26 Sep 2025 05:02:11 +0000 Subject: [PATCH 04/10] keep dlopen(0, RTLD_LAZY)(sysem library) handle to handle and handle2 for #elif defined(ARM) && defined(__ARM_ARCH_7A__) /* not (defined(x86_64) || defined(aarch64)) */ --- lisp/c/eus.c | 18 +++++++++++++++--- lisp/c/eus.h | 6 +++++- lisp/c/makes.c | 3 +++ lisp/xwindow/xforeign.c.c | 12 +++++++++++- 4 files changed, 34 insertions(+), 5 deletions(-) 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/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/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); From e7323bd8da96c279e9ddc918e0167aeefcf66dc6 Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Fri, 26 Sep 2025 07:40:30 +0000 Subject: [PATCH 05/10] unixcall.c: GETRUSAGE do not use rusage[18] because sizeof(struct rusage) may change, specially on arm32 --- lisp/c/unixcall.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/lisp/c/unixcall.c b/lisp/c/unixcall.c index 177660670..7dc95245c 100644 --- a/lisp/c/unixcall.c +++ b/lisp/c/unixcall.c @@ -211,16 +211,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 From a476655a72443b11d6ff68350542f3fbb52fa06b Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Fri, 26 Sep 2025 10:41:23 +0000 Subject: [PATCH 06/10] eval.c: get vargv to #16 and use it --- lisp/c/eval.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lisp/c/eval.c b/lisp/c/eval.c index 0a10537b6..eb585594e 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" \ @@ -1057,6 +1057,8 @@ __asm__ (".align 4\n" "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" @@ -1077,6 +1079,8 @@ __asm__ (".align 4\n" "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" From a591e0ff3d0d6232f96c01bfbf7fb002990646b8 Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Sat, 27 Sep 2025 06:24:46 +0000 Subject: [PATCH 07/10] .travis.sh: fix travis_time_start,end for Github Action --- .travis.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) 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" } From 5c0d4344124b75309aee9e76f59395cf33db5494 Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Sat, 27 Sep 2025 06:31:55 +0000 Subject: [PATCH 08/10] test/test.l add test to check asctime, this happens on 32bit arm debian sid --- test/time.l | 8 ++++++++ 1 file changed, 8 insertions(+) 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)) From c21799ccd9b3705c6c73ae387e48e26762bca9d5 Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Sat, 27 Sep 2025 16:11:27 +0900 Subject: [PATCH 09/10] unixcall.c: localtime sizoef time(0) is machine dependent and may differ from long, asctime, check return value --- lisp/c/unixcall.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lisp/c/unixcall.c b/lisp/c/unixcall.c index 7dc95245c..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 From 5f0630ae2cd329881df68b1ba773d7d5cb8c71de Mon Sep 17 00:00:00 2001 From: Kei Okada Date: Sat, 27 Sep 2025 17:09:02 +0900 Subject: [PATCH 10/10] eval.c: ARM 32bit armel could be __ARM_ARCH==4 or __ARM_ARCH==4 --- lisp/c/eval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/c/eval.c b/lisp/c/eval.c index eb585594e..987b16fac 100644 --- a/lisp/c/eval.c +++ b/lisp/c/eval.c @@ -1315,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;