Revert hack for musl libc

Decreasing the alien stack ptr by a word is expressly the wrong thing
because we want to catch, not hide, any mis-use of the stack.

So put in a diffent hack to detect structure size mismatch before
cold-init, and also have grovel-headers output a hardcoded definition
(for lack of a better idea) if the auto-defined struct would be wrong.
This commit is contained in:
Douglas Katzman 2024-07-19 17:03:13 -04:00
parent ecf7927a79
commit 3fd92b8aba
4 changed files with 33 additions and 11 deletions

View file

@ -860,3 +860,14 @@ way that the argument is passed.
(defun alien-void-type-p (type)
(and (alien-values-type-p type) (not (alien-values-type-values type))))
;;; Assert that two important types aren't messed up
(eval-when (:compile-toplevel)
(flet ((check-size (tag)
(let ((alien-type (parse-alien-type `(struct ,tag) nil)))
(unless (= (alien-type-bits alien-type)
(* (symbol-value (package-symbolicate "SB-UNIX" "SIZEOF-" tag))
sb-vm:n-byte-bits))
(error "(STRUCT ~S) has unexpected size" tag)))))
(check-size 'sb-unix::timespec)
(check-size 'sb-unix::timeval)))

View file

@ -1041,7 +1041,13 @@ alloc_thread_struct(void* spaces) {
th->state_word.user_thread_p = 1;
lispobj* alien_stack_end = (lispobj*)((char*)th->alien_stack_start + ALIEN_STACK_SIZE);
#if defined LISP_FEATURE_X86 || defined LISP_FEATURE_X86_64
// Alien-stack-pointer is predecremented upon use
th->alien_stack_pointer = alien_stack_end;
#else
// I do not know the convention for alien-stack-pointer
th->alien_stack_pointer = alien_stack_end - 1;
#endif
#ifdef HAVE_THREAD_PSEUDO_ATOMIC_BITS_SLOT
memset(&th->pseudo_atomic_bits, 0, sizeof th->pseudo_atomic_bits);

View file

@ -1,16 +1,5 @@
#+(or (not x86) (not linux)) (invoke-restart 'run-tests::skip-file)
;;; I'm not entirely satisfied with the solution to fixing the crash on Alpine linux
;;; and while investigating that, I found also that we supplied too high a limit
;;; to set_thread_area().
;;; [As to the problem on Alpine: if it were the case that we don't pre-decrement the
;;; alien-stack-pointer then we'd surely clobber th->no_tls_value_marker.
;;; But it works everywhere else. Alpine uses musl libc, so perhaps that's the distinguishing
;;; feature - something in libc takes an alien we allocated and writes past it by a word
;;; because we still after all these years don't fully get the structure padding requirements
;;; in the 32-bit ABI correct.]
(in-package sb-vm)
(defconstant os-page-size 4096)

View file

@ -380,9 +380,25 @@ main(int argc, char __attribute__((unused)) *argv[])
DEFSTRUCT(timeval, struct timeval,
DEFSLOT(tv-sec, tv_sec);
DEFSLOT(tv-usec, tv_usec));
// There is no way to detect musl libc (https://wiki.musl-libc.org/faq)
// I'm really just guessing, but maybe 32-bit ARM has padding too
#if defined LISP_FEATURE_LINUX && defined LISP_FEATURE_LITTLE_ENDIAN \
&& (defined LISP_FEATURE_X86 || defined LISP_FEATURE_ARM)
struct timespec dummy_ts;
if (sizeof dummy_ts > sizeof dummy_ts.tv_sec + sizeof dummy_ts.tv_nsec) {
fprintf(stderr, "WARNING: Assuming physical layout of timespec\n");
printf("(define-alien-type nil\n\
(struct timespec\n\
(tv-sec (signed 64))\n\
(tv-nsec (signed 32))\n\
(padding (signed 32))))\n");
} else
#endif
DEFSTRUCT(timespec, struct timespec,
DEFSLOT(tv-sec, tv_sec);
DEFSLOT(tv-nsec, tv_nsec));
defconstant("sizeof-timespec", sizeof (struct timespec));
defconstant("sizeof-timeval", sizeof (struct timeval));
printf("\n");
#ifdef LISP_FEATURE_ANDROID