summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Cournoyer <maxim@guixotic.coop>2025-10-30 16:19:50 +0900
committerMaxim Cournoyer <maxim@guixotic.coop>2025-10-30 16:19:50 +0900
commit0f39db9c1942969bcbc603b306d8e47f8feb8566 (patch)
tree4c277554d2167559e9325afc191c53e262733918
parent9d60fdf6a2e482e7d52184521191c14449619aec (diff)
Revert "Use mmap for the elf parser, reducing memory usage."
This reverts commit 2c1fe0df11ae0f66392b8abb6f62430d79305538.
-rw-r--r--gnu/packages/gnuzilla.scm8
-rw-r--r--gnu/packages/librewolf.scm6
-rw-r--r--guix/build/debug-link.scm17
-rw-r--r--guix/build/gremlin.scm62
-rw-r--r--guix/scripts/pack.scm13
-rw-r--r--tests/debug-link.scm187
-rw-r--r--tests/gremlin.scm18
7 files changed, 164 insertions, 147 deletions
diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm
index d24797b85a0..259f9a6fc6e 100644
--- a/gnu/packages/gnuzilla.scm
+++ b/gnu/packages/gnuzilla.scm
@@ -996,10 +996,16 @@ preferences/advanced-scripts.dtd"
996 (search-input-file inputs "lib/libavcodec.so"))))) 996 (search-input-file inputs "lib/libavcodec.so")))))
997 (add-after 'fix-ffmpeg-runtime-linker 'build-sandbox-whitelist 997 (add-after 'fix-ffmpeg-runtime-linker 'build-sandbox-whitelist
998 (lambda* (#:key inputs #:allow-other-keys) 998 (lambda* (#:key inputs #:allow-other-keys)
999 (define (runpath-of lib)
1000 (call-with-input-file lib
1001 (compose elf-dynamic-info-runpath
1002 elf-dynamic-info
1003 parse-elf
1004 get-bytevector-all)))
999 (define (runpaths-of-input label) 1005 (define (runpaths-of-input label)
1000 (let* ((dir (string-append (assoc-ref inputs label) "/lib")) 1006 (let* ((dir (string-append (assoc-ref inputs label) "/lib"))
1001 (libs (find-files dir "\\.so$"))) 1007 (libs (find-files dir "\\.so$")))
1002 (append-map file-runpath libs))) 1008 (append-map runpath-of libs)))
1003 ;; Populate the sandbox read-path whitelist as needed by ffmpeg. 1009 ;; Populate the sandbox read-path whitelist as needed by ffmpeg.
1004 (let* ((whitelist 1010 (let* ((whitelist
1005 (map (cut string-append <> "/") 1011 (map (cut string-append <> "/")
diff --git a/gnu/packages/librewolf.scm b/gnu/packages/librewolf.scm
index 6c852d7f1c2..f8800b19252 100644
--- a/gnu/packages/librewolf.scm
+++ b/gnu/packages/librewolf.scm
@@ -530,11 +530,15 @@
530 ;; The following two functions are from Guix's icecat package in 530 ;; The following two functions are from Guix's icecat package in
531 ;; (gnu packages gnuzilla). See commit 531 ;; (gnu packages gnuzilla). See commit
532 ;; b7a0935420ee630a29b7e5ac73a32ba1eb24f00b. 532 ;; b7a0935420ee630a29b7e5ac73a32ba1eb24f00b.
533 (define (runpath-of lib)
534 (call-with-input-file lib
535 (compose elf-dynamic-info-runpath elf-dynamic-info
536 parse-elf get-bytevector-all)))
533 (define (runpaths-of-input label) 537 (define (runpaths-of-input label)
534 (let* ((dir (string-append (assoc-ref inputs label) 538 (let* ((dir (string-append (assoc-ref inputs label)
535 "/lib")) 539 "/lib"))
536 (libs (find-files dir "\\.so$"))) 540 (libs (find-files dir "\\.so$")))
537 (append-map file-runpath libs))) 541 (append-map runpath-of libs)))
538 (let* ((out (assoc-ref outputs "out")) 542 (let* ((out (assoc-ref outputs "out"))
539 (lib (string-append out "/lib")) 543 (lib (string-append out "/lib"))
540 (libs (map 544 (libs (map
diff --git a/guix/build/debug-link.scm b/guix/build/debug-link.scm
index 7a74e6001b7..80941df2fc7 100644
--- a/guix/build/debug-link.scm
+++ b/guix/build/debug-link.scm
@@ -1,6 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2018, 2023 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2018, 2023 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2025 Maxim Cournoyer <maxim@guixotic.coop>
4;;; 3;;;
5;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
6;;; 5;;;
@@ -19,7 +18,6 @@
19 18
20(define-module (guix build debug-link) 19(define-module (guix build debug-link)
21 #:use-module (guix elf) 20 #:use-module (guix elf)
22 #:use-module (guix build io)
23 #:use-module ((guix build utils) 21 #:use-module ((guix build utils)
24 #:select (find-files elf-file? make-file-writable)) 22 #:select (find-files elf-file? make-file-writable))
25 #:use-module (rnrs bytevectors) 23 #:use-module (rnrs bytevectors)
@@ -149,13 +147,16 @@ Return #f for both if ELF lacks a '.gnu_debuglink' section."
149(define (set-debuglink-crc file debug-file) 147(define (set-debuglink-crc file debug-file)
150 "Compute the CRC of DEBUG-FILE and set it as the '.gnu_debuglink' CRC in 148 "Compute the CRC of DEBUG-FILE and set it as the '.gnu_debuglink' CRC in
151FILE." 149FILE."
152 (let* ((bv (file->bytevector file #:protection (logior PROT_READ PROT_WRITE))) 150 (let* ((elf (parse-elf (call-with-input-file file get-bytevector-all)))
153 (elf (parse-elf bv))
154 (offset (elf-debuglink-crc-offset elf))) 151 (offset (elf-debuglink-crc-offset elf)))
155 (when offset 152 (and offset
156 (let ((crc (call-with-input-file debug-file debuglink-crc32))) 153 (let* ((crc (call-with-input-file debug-file debuglink-crc32))
157 (bytevector-u32-set! bv offset crc (elf-byte-order elf)) 154 (bv (make-bytevector 4)))
158 (munmap bv))))) 155 (bytevector-u32-set! bv 0 crc (elf-byte-order elf))
156 (let ((port (open file O_RDWR)))
157 (set-port-position! port offset)
158 (put-bytevector port bv)
159 (close-port port))))))
159 160
160 161
161;;; 162;;;
diff --git a/guix/build/gremlin.scm b/guix/build/gremlin.scm
index 2392a74a359..2a74d51dd91 100644
--- a/guix/build/gremlin.scm
+++ b/guix/build/gremlin.scm
@@ -1,6 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015, 2018, 2020 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2015, 2018, 2020 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2025 Maxim Cournoyer <maxim@guixotic.coop>
4;;; 3;;;
5;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
6;;; 5;;;
@@ -19,7 +18,6 @@
19 18
20(define-module (guix build gremlin) 19(define-module (guix build gremlin)
21 #:use-module (guix elf) 20 #:use-module (guix elf)
22 #:use-module (guix build io)
23 #:use-module ((guix build utils) #:select (store-file-name?)) 21 #:use-module ((guix build utils) #:select (store-file-name?))
24 #:use-module (ice-9 match) 22 #:use-module (ice-9 match)
25 #:use-module (srfi srfi-1) 23 #:use-module (srfi srfi-1)
@@ -250,7 +248,9 @@ string table if the type is a string."
250(define (file-dynamic-info file) 248(define (file-dynamic-info file)
251 "Return the <elf-dynamic-info> record of FILE, or #f if FILE lacks dynamic 249 "Return the <elf-dynamic-info> record of FILE, or #f if FILE lacks dynamic
252info." 250info."
253 (elf-dynamic-info (parse-elf (file->bytevector file)))) 251 (call-with-input-file file
252 (lambda (port)
253 (elf-dynamic-info (parse-elf (get-bytevector-all port))))))
254 254
255(define (file-runpath file) 255(define (file-runpath file)
256 "Return the DT_RUNPATH dynamic entry of FILE as a list of strings, or #f if 256 "Return the DT_RUNPATH dynamic entry of FILE as a list of strings, or #f if
@@ -362,7 +362,8 @@ exceeds total size~%"
362 (elf-segment-type segment)) 362 (elf-segment-type segment))
363 #f))) 363 #f)))
364 364
365 (let* ((elf (parse-elf (file->bytevector file))) 365 (let* ((elf (call-with-input-file file
366 (compose parse-elf get-bytevector-all)))
366 (expand (cute expand-origin <> (dirname file))) 367 (expand (cute expand-origin <> (dirname file)))
367 (dyninfo (elf-dynamic-info elf))) 368 (dyninfo (elf-dynamic-info elf)))
368 (when dyninfo 369 (when dyninfo
@@ -401,13 +402,12 @@ according to DT_NEEDED."
401 needed))) 402 needed)))
402 runpath)) 403 runpath))
403 404
404 (define bv (file->bytevector file #:protection 405 (define port
405 (logior PROT_READ PROT_WRITE))) 406 (open-file file "r+b"))
406 407
407 (dynamic-wind 408 (catch #t
408 (const #t)
409 (lambda () 409 (lambda ()
410 (let* ((elf (parse-elf bv)) 410 (let* ((elf (parse-elf (get-bytevector-all port)))
411 (entries (dynamic-entries elf (dynamic-link-segment elf))) 411 (entries (dynamic-entries elf (dynamic-link-segment elf)))
412 (needed (filter-map (lambda (entry) 412 (needed (filter-map (lambda (entry)
413 (and (= (dynamic-entry-type entry) 413 (and (= (dynamic-entry-type entry)
@@ -425,14 +425,15 @@ according to DT_NEEDED."
425 "~a: stripping RUNPATH to ~s (removed ~s)~%" 425 "~a: stripping RUNPATH to ~s (removed ~s)~%"
426 file new 426 file new
427 (lset-difference string=? old new)) 427 (lset-difference string=? old new))
428 ;; Write to bytevector directly. 428 (seek port (dynamic-entry-offset runpath) SEEK_SET)
429 (let ((src (string->utf8 (string-append (string-join new ":") 429 (put-bytevector port (string->utf8 (string-join new ":")))
430 "\0")))) 430 (put-u8 port 0))
431 (bytevector-copy! src 0 bv (dynamic-entry-offset runpath) 431 (close-port port)
432 (bytevector-length src))))
433 new)) 432 new))
434 (lambda () 433 (lambda (key . args)
435 (munmap bv)))) 434 (false-if-exception (close-port port))
435 (apply throw key args))))
436
436 437
437(define-condition-type &missing-runpath-error &elf-error 438(define-condition-type &missing-runpath-error &elf-error
438 missing-runpath-error? 439 missing-runpath-error?
@@ -446,18 +447,20 @@ according to DT_NEEDED."
446 "Set the value of the DT_RUNPATH dynamic entry of FILE, which must name an 447 "Set the value of the DT_RUNPATH dynamic entry of FILE, which must name an
447ELF file, to PATH, a list of strings. Raise a &missing-runpath-error or 448ELF file, to PATH, a list of strings. Raise a &missing-runpath-error or
448&runpath-too-long-error when appropriate." 449&runpath-too-long-error when appropriate."
449 (define bv (file->bytevector file #:protection 450 (define (call-with-input+output-file file proc)
450 (logior PROT_READ PROT_WRITE))) 451 (let ((port (open-file file "r+b")))
451 (dynamic-wind 452 (guard (c (#t (close-port port) (raise c)))
452 (const #t) 453 (proc port)
453 (lambda () 454 (close-port port))))
454 (let* ((elf (parse-elf bv)) 455
456 (call-with-input+output-file file
457 (lambda (port)
458 (let* ((elf (parse-elf (get-bytevector-all port)))
455 (entries (dynamic-entries elf (dynamic-link-segment elf))) 459 (entries (dynamic-entries elf (dynamic-link-segment elf)))
456 (runpath (find (lambda (entry) 460 (runpath (find (lambda (entry)
457 (= DT_RUNPATH (dynamic-entry-type entry))) 461 (= DT_RUNPATH (dynamic-entry-type entry)))
458 entries)) 462 entries))
459 (path (string->utf8 (string-append (string-join path ":") 463 (path (string->utf8 (string-join path ":"))))
460 "\0"))))
461 (unless runpath 464 (unless runpath
462 (raise (condition (&missing-runpath-error (elf elf) 465 (raise (condition (&missing-runpath-error (elf elf)
463 (file file))))) 466 (file file)))))
@@ -470,7 +473,10 @@ ELF file, to PATH, a list of strings. Raise a &missing-runpath-error or
470 (raise (condition (&runpath-too-long-error (elf #f #;elf) 473 (raise (condition (&runpath-too-long-error (elf #f #;elf)
471 (file file))))) 474 (file file)))))
472 475
473 (bytevector-copy! path 0 bv (dynamic-entry-offset runpath) 476 (seek port (dynamic-entry-offset runpath) SEEK_SET)
474 (bytevector-length path)))) 477 (put-bytevector port path)
475 (lambda () 478 (put-u8 port 0)))))
476 (munmap bv)))) 479
480;;; Local Variables:
481;;; eval: (put 'call-with-input+output-file 'scheme-indent-function 1)
482;;; End:
diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm
index 432e846bf4f..a6a7babf595 100644
--- a/guix/scripts/pack.scm
+++ b/guix/scripts/pack.scm
@@ -5,7 +5,7 @@
5;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com> 5;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
6;;; Copyright © 2018 Efraim Flashner <efraim@flashner.co.il> 6;;; Copyright © 2018 Efraim Flashner <efraim@flashner.co.il>
7;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr> 7;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
8;;; Copyright © 2020-2023, 2025 Maxim Cournoyer <maxim@guixotic.coop> 8;;; Copyright © 2020, 2021, 2022, 2023 Maxim Cournoyer <maxim@guixotic.coop>
9;;; Copyright © 2020 Eric Bavier <bavier@posteo.net> 9;;; Copyright © 2020 Eric Bavier <bavier@posteo.net>
10;;; Copyright © 2022 Alex Griffin <a@ajgrf.com> 10;;; Copyright © 2022 Alex Griffin <a@ajgrf.com>
11;;; Copyright © 2023 Graham James Addis <graham@addis.org.uk> 11;;; Copyright © 2023 Graham James Addis <graham@addis.org.uk>
@@ -1221,14 +1221,12 @@ libfakechroot.so and related ld.so machinery as a fallback."
1221 1221
1222 (define build 1222 (define build
1223 (with-imported-modules (source-module-closure 1223 (with-imported-modules (source-module-closure
1224 '((guix build io) 1224 '((guix build utils)
1225 (guix build utils)
1226 (guix build union) 1225 (guix build union)
1227 (guix build gremlin) 1226 (guix build gremlin)
1228 (guix elf))) 1227 (guix elf)))
1229 #~(begin 1228 #~(begin
1230 (use-modules (guix build io) 1229 (use-modules (guix build utils)
1231 (guix build utils)
1232 ((guix build union) #:select (symlink-relative)) 1230 ((guix build union) #:select (symlink-relative))
1233 (guix elf) 1231 (guix elf)
1234 (guix build gremlin) 1232 (guix build gremlin)
@@ -1262,7 +1260,7 @@ libfakechroot.so and related ld.so machinery as a fallback."
1262 (match (find (lambda (segment) 1260 (match (find (lambda (segment)
1263 (= (elf-segment-type segment) PT_INTERP)) 1261 (= (elf-segment-type segment) PT_INTERP))
1264 (elf-segments elf)) 1262 (elf-segments elf))
1265 (#f #f) ;maybe a .so 1263 (#f #f) ;maybe a .so
1266 (segment 1264 (segment
1267 (let ((bv (make-bytevector (- (elf-segment-memsz segment) 1)))) 1265 (let ((bv (make-bytevector (- (elf-segment-memsz segment) 1))))
1268 (bytevector-copy! (elf-bytes elf) 1266 (bytevector-copy! (elf-bytes elf)
@@ -1282,7 +1280,8 @@ libfakechroot.so and related ld.so machinery as a fallback."
1282 #$(if fakechroot? 1280 #$(if fakechroot?
1283 ;; TODO: Handle scripts by wrapping their interpreter. 1281 ;; TODO: Handle scripts by wrapping their interpreter.
1284 #~(if (elf-file? program) 1282 #~(if (elf-file? program)
1285 (let* ((bv (file->bytevector program)) 1283 (let* ((bv (call-with-input-file program
1284 get-bytevector-all))
1286 (elf (parse-elf bv)) 1285 (elf (parse-elf bv))
1287 (interp (elf-interpreter elf)) 1286 (interp (elf-interpreter elf))
1288 (gconv (and interp 1287 (gconv (and interp
diff --git a/tests/debug-link.scm b/tests/debug-link.scm
index 7ccc054a5d9..a1ae4f141c0 100644
--- a/tests/debug-link.scm
+++ b/tests/debug-link.scm
@@ -1,6 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2025 Maxim Cournoyer <maxim@guixotic.coop>
4;;; 3;;;
5;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
6;;; 5;;;
@@ -21,15 +20,12 @@
21 #:use-module (guix elf) 20 #:use-module (guix elf)
22 #:use-module (guix build utils) 21 #:use-module (guix build utils)
23 #:use-module (guix build debug-link) 22 #:use-module (guix build debug-link)
24 #:use-module (guix build io)
25 #:use-module (guix gexp) 23 #:use-module (guix gexp)
26 #:use-module (guix modules)
27 #:use-module (guix store) 24 #:use-module (guix store)
28 #:use-module (guix tests) 25 #:use-module (guix tests)
29 #:use-module (guix monads) 26 #:use-module (guix monads)
30 #:use-module (guix derivations) 27 #:use-module (guix derivations)
31 #:use-module (gnu packages bootstrap) 28 #:use-module (gnu packages bootstrap)
32 #:use-module ((gnu packages guile) #:select (guile-3.0))
33 #:use-module (srfi srfi-1) 29 #:use-module (srfi srfi-1)
34 #:use-module (srfi srfi-26) 30 #:use-module (srfi srfi-26)
35 #:use-module (srfi srfi-64) 31 #:use-module (srfi srfi-64)
@@ -44,12 +40,15 @@
44 (_ 40 (_
45 #f))) 41 #f)))
46 42
43(define read-elf
44 (compose parse-elf get-bytevector-all))
45
47 46
48(test-begin "debug-link") 47(test-begin "debug-link")
49 48
50(unless %guile-executable (test-skip 1)) 49(unless %guile-executable (test-skip 1))
51(test-assert "elf-debuglink, no .gnu_debuglink section" 50(test-assert "elf-debuglink"
52 (let ((elf (parse-elf (file->bytevector %guile-executable)))) 51 (let ((elf (call-with-input-file %guile-executable read-elf)))
53 (match (call-with-values (lambda () (elf-debuglink elf)) list) 52 (match (call-with-values (lambda () (elf-debuglink elf)) list)
54 ((#f #f) ;no '.gnu_debuglink' section 53 ((#f #f) ;no '.gnu_debuglink' section
55 (pk 'no-debuglink #t)) 54 (pk 'no-debuglink #t))
@@ -57,101 +56,95 @@
57 (string-suffix? ".debug" file))))) 56 (string-suffix? ".debug" file)))))
58 57
59;; Since we need %BOOTSTRAP-GCC and co., we have to skip the following tests 58;; Since we need %BOOTSTRAP-GCC and co., we have to skip the following tests
60;; when networking is unreachable because we'd fail to download it. Since 59;; when networking is unreachable because we'd fail to download it.
61;; using mmap to load ELF more efficiently, we also need the regular Guile 60(unless (network-reachable?) (test-skip 1))
62;; package, as guile-bootstrap cannot resolve dynamic symbols. 61(test-assertm "elf-debuglink"
63(with-external-store store 62 ;; Check whether we can compute the CRC just like objcopy, and whether we
64 (unless (and (network-reachable?) store) (test-skip 1)) 63 ;; can retrieve it.
65 (test-assertm "elf-debuglink" 64 (let* ((code (plain-file "test.c" "int main () { return 42; }"))
66 ;; Check whether we can compute the CRC just like objcopy, and whether we 65 (exp (with-imported-modules '((guix build utils)
67 ;; can retrieve it. 66 (guix build debug-link)
68 (let* ((code (plain-file "test.c" "int main () { return 42; }")) 67 (guix elf))
69 (exp (with-imported-modules (source-module-closure 68 #~(begin
70 '((guix build io) 69 (use-modules (guix build utils)
71 (guix build utils) 70 (guix build debug-link)
72 (guix build debug-link) 71 (guix elf)
73 (guix elf))) 72 (rnrs io ports))
74 #~(begin
75 (use-modules (guix build io)
76 (guix build utils)
77 (guix build debug-link)
78 (guix elf)
79 (rnrs io ports))
80 73
81 (define read-elf 74 (define read-elf
82 (compose parse-elf file->bytevector)) 75 (compose parse-elf get-bytevector-all))
83 76
84 (setenv "PATH" (string-join '(#$%bootstrap-gcc 77 (setenv "PATH" (string-join '(#$%bootstrap-gcc
85 #$%bootstrap-binutils) 78 #$%bootstrap-binutils)
86 "/bin:" 'suffix)) 79 "/bin:" 'suffix))
87 (invoke "gcc" "-O0" "-g" #$code "-o" "exe") 80 (invoke "gcc" "-O0" "-g" #$code "-o" "exe")
88 (copy-file "exe" "exe.debug") 81 (copy-file "exe" "exe.debug")
89 (invoke "strip" "--only-keep-debug" "exe.debug") 82 (invoke "strip" "--only-keep-debug" "exe.debug")
90 (invoke "strip" "--strip-debug" "exe") 83 (invoke "strip" "--strip-debug" "exe")
91 (invoke "objcopy" "--add-gnu-debuglink=exe.debug" 84 (invoke "objcopy" "--add-gnu-debuglink=exe.debug"
92 "exe") 85 "exe")
93 (call-with-values (lambda () 86 (call-with-values (lambda ()
94 (elf-debuglink (read-elf "exe"))) 87 (elf-debuglink
95 (lambda (file crc) 88 (call-with-input-file "exe"
96 (call-with-output-file #$output 89 read-elf)))
97 (lambda (port) 90 (lambda (file crc)
98 (let ((expected (call-with-input-file "exe.debug" 91 (call-with-output-file #$output
99 debuglink-crc32))) 92 (lambda (port)
100 (write (list file (= crc expected)) 93 (let ((expected (call-with-input-file "exe.debug"
101 port)))))))))) 94 debuglink-crc32)))
102 (mlet* %store-monad ((drv (gexp->derivation "debuglink" exp)) 95 (write (list file (= crc expected))
103 (x (built-derivations (list drv)))) 96 port))))))))))
104 (call-with-input-file (derivation->output-path drv) 97 (mlet* %store-monad ((drv (gexp->derivation "debuglink" exp))
105 (lambda (port) 98 (x (built-derivations (list drv))))
106 (return (match (read port) 99 (call-with-input-file (derivation->output-path drv)
107 (("exe.debug" #t) #t) 100 (lambda (port)
108 (x (pk 'fail x #f))))))))) 101 (return (match (read port)
102 (("exe.debug" #t) #t)
103 (x (pk 'fail x #f)))))))))
109 104
110 (unless (and (network-reachable?) store) (test-skip 1)) 105(unless (network-reachable?) (test-skip 1))
111 (test-assertm "set-debuglink-crc" 106(test-assertm "set-debuglink-crc"
112 ;; Check whether 'set-debuglink-crc' successfully updates the CRC. 107 ;; Check whether 'set-debuglink-crc' successfully updates the CRC.
113 (let* ((code (plain-file "test.c" "int main () { return 42; }")) 108 (let* ((code (plain-file "test.c" "int main () { return 42; }"))
114 (debug (plain-file "exe.debug" "a")) 109 (debug (plain-file "exe.debug" "a"))
115 (exp (with-imported-modules (source-module-closure 110 (exp (with-imported-modules '((guix build utils)
116 '((guix build io) 111 (guix build debug-link)
117 (guix build utils) 112 (guix elf))
118 (guix build debug-link) 113 #~(begin
119 (guix elf))) 114 (use-modules (guix build utils)
120 #~(begin 115 (guix build debug-link)
121 (use-modules (guix build io) 116 (guix elf)
122 (guix build utils) 117 (rnrs io ports))
123 (guix build debug-link)
124 (guix elf)
125 (rnrs io ports))
126 118
127 (define read-elf 119 (define read-elf
128 (compose parse-elf file->bytevector)) 120 (compose parse-elf get-bytevector-all))
129 121
130 (setenv "PATH" (string-join '(#$%bootstrap-gcc 122 (setenv "PATH" (string-join '(#$%bootstrap-gcc
131 #$%bootstrap-binutils) 123 #$%bootstrap-binutils)
132 "/bin:" 'suffix)) 124 "/bin:" 'suffix))
133 (invoke "gcc" "-O0" "-g" #$code "-o" "exe") 125 (invoke "gcc" "-O0" "-g" #$code "-o" "exe")
134 (copy-file "exe" "exe.debug") 126 (copy-file "exe" "exe.debug")
135 (invoke "strip" "--only-keep-debug" "exe.debug") 127 (invoke "strip" "--only-keep-debug" "exe.debug")
136 (invoke "strip" "--strip-debug" "exe") 128 (invoke "strip" "--strip-debug" "exe")
137 (invoke "objcopy" "--add-gnu-debuglink=exe.debug" 129 (invoke "objcopy" "--add-gnu-debuglink=exe.debug"
138 "exe") 130 "exe")
139 (set-debuglink-crc "exe" #$debug) 131 (set-debuglink-crc "exe" #$debug)
140 (call-with-values (lambda () 132 (call-with-values (lambda ()
141 (elf-debuglink 133 (elf-debuglink
142 (read-elf "exe"))) 134 (call-with-input-file "exe"
143 (lambda (file crc) 135 read-elf)))
144 (call-with-output-file #$output 136 (lambda (file crc)
145 (lambda (port) 137 (call-with-output-file #$output
146 (write (list file crc) port))))))))) 138 (lambda (port)
147 (mlet* %store-monad ((drv (gexp->derivation "debuglink" exp)) 139 (write (list file crc) port)))))))))
148 (x (built-derivations (list drv)))) 140 (mlet* %store-monad ((drv (gexp->derivation "debuglink" exp))
149 (call-with-input-file (derivation->output-path drv) 141 (x (built-derivations (list drv))))
150 (lambda (port) 142 (call-with-input-file (derivation->output-path drv)
151 (return (match (read port) 143 (lambda (port)
152 (("exe.debug" crc) 144 (return (match (read port)
153 (= crc (debuglink-crc32 (open-input-string "a")))) 145 (("exe.debug" crc)
154 (x 146 (= crc (debuglink-crc32 (open-input-string "a"))))
155 (pk 'fail x #f)))))))))) 147 (x
148 (pk 'fail x #f)))))))))
156 149
157(test-end "debug-link") 150(test-end "debug-link")
diff --git a/tests/gremlin.scm b/tests/gremlin.scm
index 44237e2ad37..280b1d88192 100644
--- a/tests/gremlin.scm
+++ b/tests/gremlin.scm
@@ -23,7 +23,6 @@
23 #:use-module (guix tests) 23 #:use-module (guix tests)
24 #:use-module ((guix utils) #:select (call-with-temporary-directory 24 #:use-module ((guix utils) #:select (call-with-temporary-directory
25 target-aarch64?)) 25 target-aarch64?))
26 #:use-module (guix build io)
27 #:use-module (guix build utils) 26 #:use-module (guix build utils)
28 #:use-module (guix build gremlin) 27 #:use-module (guix build gremlin)
29 #:use-module (gnu packages bootstrap) 28 #:use-module (gnu packages bootstrap)
@@ -45,6 +44,9 @@
45 (_ 44 (_
46 #f))) 45 #f)))
47 46
47(define read-elf
48 (compose parse-elf get-bytevector-all))
49
48(define c-compiler 50(define c-compiler
49 (or (which "gcc") (which "cc") (which "g++"))) 51 (or (which "gcc") (which "cc") (which "g++")))
50 52
@@ -53,7 +55,8 @@
53 55
54(unless %guile-executable (test-skip 1)) 56(unless %guile-executable (test-skip 1))
55(test-assert "elf-dynamic-info-needed, executable" 57(test-assert "elf-dynamic-info-needed, executable"
56 (let ((dyninfo (file-dynamic-info %guile-executable))) 58 (let* ((elf (call-with-input-file %guile-executable read-elf))
59 (dyninfo (elf-dynamic-info elf)))
57 (or (not dyninfo) ;static executable 60 (or (not dyninfo) ;static executable
58 (lset<= string=? 61 (lset<= string=?
59 (list (string-append "libguile-" (effective-version)) 62 (list (string-append "libguile-" (effective-version))
@@ -137,7 +140,9 @@
137 (display "int main () { puts(\"hello\"); }" port))) 140 (display "int main () { puts(\"hello\"); }" port)))
138 (invoke c-compiler "t.c" 141 (invoke c-compiler "t.c"
139 "-Wl,--enable-new-dtags" "-Wl,-rpath=/foo" "-Wl,-rpath=/bar") 142 "-Wl,--enable-new-dtags" "-Wl,-rpath=/foo" "-Wl,-rpath=/bar")
140 (let* ((dyninfo (file-dynamic-info "a.out")) 143 (let* ((dyninfo (elf-dynamic-info
144 (parse-elf (call-with-input-file "a.out"
145 get-bytevector-all))))
141 (old (elf-dynamic-info-runpath dyninfo)) 146 (old (elf-dynamic-info-runpath dyninfo))
142 (new (strip-runpath "a.out")) 147 (new (strip-runpath "a.out"))
143 (new* (strip-runpath "a.out"))) 148 (new* (strip-runpath "a.out")))
@@ -191,7 +196,10 @@
191 (display "// empty file" port))) 196 (display "// empty file" port)))
192 (invoke c-compiler "t.c" 197 (invoke c-compiler "t.c"
193 "-shared" "-Wl,-soname,libfoo.so.2") 198 "-shared" "-Wl,-soname,libfoo.so.2")
194 (let ((dyninfo (file-dynamic-info "a.out"))) 199 (let* ((dyninfo (elf-dynamic-info
195 (elf-dynamic-info-soname dyninfo)))))) 200 (parse-elf (call-with-input-file "a.out"
201 get-bytevector-all))))
202 (soname (elf-dynamic-info-soname dyninfo)))
203 soname)))))
196 204
197(test-end "gremlin") 205(test-end "gremlin")