On Tue, Oct 29, 2024 at 06:11:27PM +0100, Christoph Buck wrote: > Hi! > > In case anybody is reading along here. I digged deeper and found > something rather interessting :P Thank you! From where I'm sitting it's much easier (for me) to suggest things than to try and setup your environment. > 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 > 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: ((# #) (# #)) > 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: ((# #) (# #)) > 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. > Can you run it again, but with i686 -> armhf, and x86_64 -> i686? My curiosity includes i686 -> x86_64, but I suspect it won't tell us anything we won't learn from the previous tests. -- Efraim Flashner רנשלפ םירפא GPG key = A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351 Confidentiality cannot be guaranteed on emails sent or received unencrypted