Hi! In case anybody is reading along here. I digged deeper and found something rather interessting :P
>From my understanding by reading through the records.scm from guix (and please note that im a total scheme newbee), the abi check works by calculation a string-hash over the record field names and storing the hash as hidden field in the record. During runtime this string-hash is computed again and compared to the compiled hash. If they don't match, the abi is broken because a field was added or removed. The hash is calculated in the `compute-abi-cookie` procedure in the records.scm. I extended the procedure with the following debug outputs --8<---------------cut here---------------start------------->8--- (define (compute-abi-cookie field-specs) ;; Compute an "ABI cookie" for the given FIELD-SPECS. We use ;; 'string-hash' because that's a better hash function that 'hash' on a ;; list of symbols. (let ((hash (syntax-case field-specs () (((field get properties ...) ...) (string-hash (object->string (syntax->datum #'((field properties ...) ...))) ;; (bla) (cond-expand (guile-3 (target-most-positive-fixnum)) (else most-positive-fixnum)) )))) (fd (syntax-case field-specs () (((field get properties ...) ...) (object->string (syntax->datum #'((field properties ...) ...))))))) (format #t "Compute-abi-cookie: ~a~%" hash) (format #t "field-specs: ~a~%" field-specs) (format #t "fd: ~a~%" fd) (format #t "hashsize ~a~%: " (cond-expand (guile-3 (target-most-positive-fixnum)) (else most-positive-fixnum))) hash)) --8<---------------cut here---------------end--------------->8--- Now, if i compile a simple test record --8<---------------cut here---------------start------------->8--- (define-record-type* <test-system> test-system make-test-system test-system? (device test-system-device) (mount-point test-system-mount-point)) (define test-abi (test-system (device "my-root") (mount-point "/"))) --8<---------------cut here---------------end--------------->8--- on x64 using guile cross-compiling (in a `guix shell --container guix guile` environment) using the call --8<---------------cut here---------------start------------->8--- (with-target "arm-linux-gnueabihf" (lambda () (compile-file "test-abi.scm"))) --8<---------------cut here---------------end--------------->8--- the following outputs are generated: --8<---------------cut here---------------start------------->8--- Compute-abi-cookie: 212719825 field-specs: ((#<syntax device> #<syntax test-system-device>) (#<syntax mount-point> #<syntax test-system-mount-point>)) fd: ((device) (mount-point)) hashsize 536870911 --8<---------------cut here---------------end--------------->8--- The abi cookie is computed by calculating the string hash over "((device) (mount-point))" while limiting the size of the hash by 536870911. One can manually check this by calling --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> (string-hash "((device) (mount-point))" 536870911) $1 = 212719825 --8<---------------cut here---------------end--------------->8--- in the repl. Now, if i do the same in a qemu arm32 environment (using `guix shell --container guix guile --system=armhf-linux`), a different hash is printed, even though the hash is calculated over the same string, see: --8<---------------cut here---------------start------------->8--- Compute-abi-cookie: 2434018 field-specs: ((#<syntax device> #<syntax test-system-device>) (#<syntax mount-point> #<syntax test-system-mount-point>)) fd: ((device) (mount-point)) hashsize 536870911 --8<---------------cut here---------------end--------------->8--- You can verify this in the repl as well: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> (string-hash "((device) (mount-point))" 536870911) $1 = 2434018 --8<---------------cut here---------------end--------------->8--- My first intuition after seeing the source of `compute-abi-cookie` was, that maybe the `target-most-positive-fixnum` results in an wrong value when called in a cross-compile context. But as you can see, this is not the case. Instead, the `string-hash` calculates a different hash even thought the input values are the same. Now, i am not even sure if one can expect that hash functions running on different architectures result in the same hash if the input is the same. If not, then the implementation in guix record.scm would be buggy. If one expects that the hash of `string-hash` for the same input must be the same regardless of the architecture, then this would hint to a bug in the `string-hash` function in guile for arm32. Any inputs and thoughts regarding this issue would be appreciated. Greetings Christoph -- Best regards Christoph