unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* 'patchelf' doesn't change shared libraries
@ 2013-07-14 13:33 Nikita Karetnikov
  2013-07-14 13:44 ` Ludovic Courtès
  0 siblings, 1 reply; 15+ messages in thread
From: Nikita Karetnikov @ 2013-07-14 13:33 UTC (permalink / raw)
  To: guix-devel


[-- Attachment #1.1: Type: text/plain, Size: 410 bytes --]

I've attached a patch that fails with this error

/nix/store/4g873aa2h6c8c2qfsiw0j1cbvhginx4d-ghc-bin-7.0.1/lib/ghc-7.0.1/ghc-pkg: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory
make[1]: *** [install_packages] Error 127
make: *** [install] Error 2

Why does 'patchelf' fail to adjust shared libraries?  (Note that
'--set-interpreter' works fine.)


[-- Attachment #1.2: ghc.scm --]
[-- Type: text/plain, Size: 4560 bytes --]

;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu packages ghc)
  #:use-module ((guix licenses) #:select (bsd-style))
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix build-system gnu)
  #:use-module (gnu packages base)
  #:use-module (gnu packages bootstrap)
  #:use-module (gnu packages multiprecision)
  #:use-module (gnu packages ncurses)
  #:use-module (gnu packages patchelf)
  #:use-module (gnu packages perl))

(define-public ghc-7.0.1-bin
  (package
    (name "ghc-bin")
    ;; 7.0.2--7.6.3
    (version "7.0.1")
    (source
     (origin
      (method url-fetch)
      ;; XXX: Support other platforms.
      (uri (string-append "http://www.haskell.org/ghc/dist/"
                          version "/ghc-" version
                          "-i386-unknown-linux.tar.bz2"))
      (sha256
       (base32
        "1cc9ih3h804gj53vf1xabg4155m6bz5r468mjsv54kckmabgsmav"))))
    (build-system gnu-build-system)
    (arguments
     `(#:modules ((guix build gnu-build-system)
                  (guix build utils)
                  (srfi srfi-1))
       #:phases (alist-cons-before
                 'configure 'pre-configure
                 (lambda _
                   (let ((gmp (format #f "~a/lib"
                                      (assoc-ref %build-inputs "gmp")))
                         (linker (format #f "~a~a"
                                         (assoc-ref %build-inputs "libc")
                                         ,(glibc-dynamic-linker)))
                         (ncurses (format #f "~a/lib"
                                          (assoc-ref %build-inputs "ncurses"))))
                     (begin (substitute* '("configure"
                                           "mk/config.mk.in"
                                           "utils/ghc-pkg/ghc.mk"
                                           "inplace/bin/mkdirhier"
                                           "utils/ghc-pkg/ghc.mk")
                              (("/bin/sh") (which "sh"))
                              (("/usr/local/bin/bash") (which "sh")))

                            (substitute* "configure"
                              (("utils/ghc-pwd/ghc-pwd") (which "pwd")))

                            ;; XXX: The following doesn't change shared libs.
                            (every (lambda (file)
                                     (zero?
                                      (system (format #f
                                                      "~a ~a ~a ~a ~a:~a ~a"
                                                      (which "patchelf")
                                                      "--set-interpreter"
                                                      linker
                                                      "--set-rpath"
                                                      gmp
                                                      ncurses
                                                      file))))
                                   (filter executable-file?
                                           (find-files "utils" ""))))))

                 (alist-delete 'build %standard-phases))
       #:tests? #f))
    (inputs
     `(("gmp" ,gmp)
       ("libc" ,glibc)
       ("ncurses" ,ncurses)
       ("patchelf" ,patchelf)
       ("perl" ,perl)))
    (home-page "http://www.haskell.org/ghc/")
    (synopsis "Haskell compiler and interactive environment")
    (description
     "This is a binary distribution of GHC, a compiler and interactive
environment for the Haskell functional programming language.")
    (license (bsd-style "file://LICENSE"
                        "See LICENSE in the distribution."))))

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'patchelf' doesn't change shared libraries
  2013-07-14 13:33 'patchelf' doesn't change shared libraries Nikita Karetnikov
@ 2013-07-14 13:44 ` Ludovic Courtès
  2013-07-14 15:10   ` Nikita Karetnikov
  0 siblings, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2013-07-14 13:44 UTC (permalink / raw)
  To: Nikita Karetnikov; +Cc: guix-devel

Nikita Karetnikov <nikita@karetnikov.org> skribis:

> I've attached a patch that fails with this error
>
> /nix/store/4g873aa2h6c8c2qfsiw0j1cbvhginx4d-ghc-bin-7.0.1/lib/ghc-7.0.1/ghc-pkg: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory
> make[1]: *** [install_packages] Error 127
> make: *** [install] Error 2

[...]

>                                       (system (format #f
>                                                       "~a ~a ~a ~a ~a:~a ~a"
>                                                       (which "patchelf")
>                                                       "--set-interpreter"
>                                                       linker
>                                                       "--set-rpath"
>                                                       gmp
>                                                       ncurses
>                                                       file))))

Look like it should work.

Could you run ‘objdump -x .../ghc-pkg | grep PATH’, to check what its
actual RPATH/RUNPATH is?

Perhaps you could try to run it by hand to see what happens (copy the
original binary by hand, and try it.)

(Stylistic note: prefer ‘system*’, which allows arguments to be
distinguished, whereas ‘system’ uses shell expansion.  Prefer
‘string-append’ over ‘format’ for concatenation.

Better yet: use ‘augment-rpath’ from (guix build rpath).)

HTH,
Ludo’.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'patchelf' doesn't change shared libraries
  2013-07-14 13:44 ` Ludovic Courtès
@ 2013-07-14 15:10   ` Nikita Karetnikov
  2013-07-15 22:01     ` Ludovic Courtès
  0 siblings, 1 reply; 15+ messages in thread
From: Nikita Karetnikov @ 2013-07-14 15:10 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 866 bytes --]

> Could you run ‘objdump -x .../ghc-pkg | grep PATH’, to check what its
> actual RPATH/RUNPATH is?

  RUNPATH              /nix/store/jndql2lmx3mzqmwhqh44bhm95wj8r9cy-gmp-5.1.2/lib:/nix/store/bz3az8a2699c77bgy8nm5cy77rypgw96-ncurses-5.9/lib

$ objdump -x /nix/store/4g873aa2h6c8c2qfsiw0j1cbvhginx4d-ghc-bin-7.0.1/lib/ghc-7.0.1/ghc-pkg | egrep 'libgmp|libncurses'
  NEEDED               libncurses.so.5
  NEEDED               libgmp.so.3

Is there a way to solve this without a symlink [1]?

> Perhaps you could try to run it by hand to see what happens (copy the
> original binary by hand, and try it.)

Do you mean 'ghc-7.0.1/utils/ghc-pkg/dist-install/build/tmp/ghc-pkg'?

$ ./ghc-pkg
./ghc-pkg: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory

[1] http://askubuntu.com/a/288202

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'patchelf' doesn't change shared libraries
  2013-07-14 15:10   ` Nikita Karetnikov
@ 2013-07-15 22:01     ` Ludovic Courtès
  2013-07-16 17:55       ` 'substitute*' fails with "string contains #\nul character" (was: 'patchelf' doesn't change shared libraries) Nikita Karetnikov
  0 siblings, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2013-07-15 22:01 UTC (permalink / raw)
  To: Nikita Karetnikov; +Cc: guix-devel

Nikita Karetnikov <nikita@karetnikov.org> skribis:

>> Could you run ‘objdump -x .../ghc-pkg | grep PATH’, to check what its
>> actual RPATH/RUNPATH is?
>
>   RUNPATH              /nix/store/jndql2lmx3mzqmwhqh44bhm95wj8r9cy-gmp-5.1.2/lib:/nix/store/bz3az8a2699c77bgy8nm5cy77rypgw96-ncurses-5.9/lib
>
> $ objdump -x /nix/store/4g873aa2h6c8c2qfsiw0j1cbvhginx4d-ghc-bin-7.0.1/lib/ghc-7.0.1/ghc-pkg | egrep 'libgmp|libncurses'
>   NEEDED               libncurses.so.5
>   NEEDED               libgmp.so.3
>
> Is there a way to solve this without a symlink [1]?
>
>> Perhaps you could try to run it by hand to see what happens (copy the
>> original binary by hand, and try it.)
>
> Do you mean 'ghc-7.0.1/utils/ghc-pkg/dist-install/build/tmp/ghc-pkg'?

Yes.

> $ ./ghc-pkg
> ./ghc-pkg: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory

OK, so the RUNPATH is correct, but ghc-pkg expects a libgmp with an
older SONAME.

The correct fix would be to add the old GMP version that produces
libgmp.so.3 to multiprecision.scm, and to use that as an input to GHC.

According to <https://bbs.archlinux.org/viewtopic.php?id=94146>,
libgmp.so.3 may correspond to GMP 4.3.2.

So:

  (define gmp-4.3
    (package (inherit gmp)
      (version "4.3.2")
      (source (origin ...))))

And the use that in GHC.

HTH!

Ludo’.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* 'substitute*' fails with "string contains #\nul character" (was: 'patchelf' doesn't change shared libraries)
  2013-07-15 22:01     ` Ludovic Courtès
@ 2013-07-16 17:55       ` Nikita Karetnikov
  2013-07-16 19:07         ` 'substitute*' fails with "string contains #\nul character" Ludovic Courtès
  2013-08-05 21:20         ` Nikita Karetnikov
  0 siblings, 2 replies; 15+ messages in thread
From: Nikita Karetnikov @ 2013-07-16 17:55 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel


[-- Attachment #1.1: Type: text/plain, Size: 2361 bytes --]

'substitute*' fails to patch a binary and returns the following error

[...]

starting phase `pre-configure'
Backtrace:
In ice-9/boot-9.scm:
2320: 19 [save-module-excursion #<procedure 8e81de0 at ice-9/boot-9.scm:3961:3 ()>]
3966: 18 [#<procedure 8e81de0 at ice-9/boot-9.scm:3961:3 ()>]
1645: 17 [%start-stack load-stack ...]
1650: 16 [#<procedure 8e84df8 ()>]
In unknown file:
   ?: 15 [primitive-load "/nix/store/rcjkvdqp28dnp7igksnf3lzgwzxqvadb-ghc-bin-7.0.1-guile-builder"]
In ice-9/eval.scm:
 387: 14 [eval # ()]
In srfi/srfi-1.scm:
 830: 13 [every1 #<procedure 9090f10 at /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/gnu-build-system.scm:364:9 (expr)> ...]
In /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/gnu-build-system.scm:
 368: 12 [#<procedure 9090f10 at /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/gnu-build-system.scm:364:9 (expr)> #]
In ice-9/eval.scm:
 432: 11 [eval # #]
In srfi/srfi-1.scm:
 616: 10 [for-each #<procedure 9097a98 at ice-9/eval.scm:416:20 (a)> #]
In ice-9/boot-9.scm:
 171: 9 [with-throw-handler #t ...]
 793: 8 [call-with-input-file "inplace/bin/ghc-cabal" ...]
In /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/utils.scm:
 336: 7 [#<procedure 908b4e0 at /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/utils.scm:335:10 (in)> #<input: inplace/bin/ghc-cabal 11>]
 361: 6 [#<procedure 9320fc0 at /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/utils.scm:357:6 (in out)> #<input: inplace/bin/ghc-cabal 11> ...]
In srfi/srfi-1.scm:
 465: 5 [fold #<procedure 9026f40 at /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/utils.scm:361:32 (r+p line)> ...]
In /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/utils.scm:
 364: 4 [#<procedure 9026f40 at /nix/store/04z6assixr4ms2fmvm2m42aw1a8k07x5-module-import/guix/build/utils.scm:361:32 (r+p line)> # ...]
In ice-9/regex.scm:
 189: 3 [list-matches # ...]
 176: 2 [fold-matches # ...]
In unknown file:
   ?: 1 [regexp-exec # ...]
In ice-9/boot-9.scm:
 106: 0 [#<procedure 908b500 at ice-9/boot-9.scm:97:6 (thrown-k . args)> misc-error ...]

ice-9/boot-9.scm:106:20: In procedure #<procedure 908b500 at ice-9/boot-9.scm:97:6 (thrown-k . args)>:
ice-9/boot-9.scm:106:20: string contains #\nul character:

[...]


[-- Attachment #1.2: ghc-7.0.1-bin.diff --]
[-- Type: text/x-diff, Size: 7516 bytes --]

diff --git a/gnu/packages/ghc.scm b/gnu/packages/ghc.scm
new file mode 100644
index 0000000..1a3d308
--- /dev/null
+++ b/gnu/packages/ghc.scm
@@ -0,0 +1,114 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages ghc)
+  #:use-module ((guix licenses) #:select (bsd-style))
+  #:use-module (guix packages)
+  #:use-module (guix download)
+  #:use-module (guix build-system gnu)
+  #:use-module (gnu packages base)
+  #:use-module (gnu packages bootstrap)
+  #:use-module (gnu packages libffi)
+  #:use-module (gnu packages multiprecision)
+  #:use-module (gnu packages ncurses)
+  #:use-module (gnu packages patchelf)
+  #:use-module (gnu packages perl))
+
+(define-public ghc-7.0.1-bin
+  (package
+    (name "ghc-bin")
+    ;; 7.0.2--7.6.3
+    (version "7.0.1")
+    (source
+     (origin
+      (method url-fetch)
+      ;; XXX: Support other platforms.
+      (uri (string-append "http://www.haskell.org/ghc/dist/"
+                          version "/ghc-" version
+                          "-i386-unknown-linux.tar.bz2"))
+      (sha256
+       (base32
+        "1cc9ih3h804gj53vf1xabg4155m6bz5r468mjsv54kckmabgsmav"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:modules ((guix build gnu-build-system)
+                  (guix build utils)
+                  (srfi srfi-1))
+       #:phases (alist-cons-before
+                 'configure 'pre-configure
+                 (lambda _
+                   (let ((gmp (string-append (assoc-ref %build-inputs "gmp")
+                                             "/lib"))
+                         (linker (string-append
+                                  (assoc-ref %build-inputs "libc")
+                                  ,(glibc-dynamic-linker)))
+                         (libffi (string-append
+                                  (assoc-ref %build-inputs "libffi")
+                                  "/lib"))
+                         (ncurses (string-append
+                                   (assoc-ref %build-inputs "ncurses")
+                                   "/lib"))
+                         (patchelf (which "patchelf"))
+                         (pwd (which "pwd"))
+                         (sh (which "sh")))
+                     (begin (substitute* '("configure"
+                                           "mk/config.mk.in"
+                                           "utils/ghc-pkg/ghc.mk"
+
+                                           ;; Fails with a "string contains
+                                           ;; #\nul character" error.
+                                           "inplace/bin/ghc-cabal"
+
+                                           "inplace/bin/mkdirhier"
+                                           "utils/ghc-pkg/ghc.mk")
+                              (("/bin/sh") sh)
+                              (("/usr/local/bin/bash") sh)
+                              (("utils/ghc-pwd/ghc-pwd") pwd))
+
+                            (every (lambda (file)
+                                     (zero?
+                                      (system* patchelf
+                                               "--set-interpreter" linker
+                                               "--set-rpath"
+                                               (string-append gmp ":" ncurses)
+                                               file)))
+                                   (filter executable-file?
+                                           (find-files "utils" "")))
+
+                            (zero? (system* patchelf
+                                            "--set-interpreter" linker
+                                            "--set-rpath"
+                                            (string-append gmp ":" libffi)
+                                            "inplace/bin/ghc-cabal")))))
+
+                 (alist-delete 'build %standard-phases))
+       #:tests? #f))
+    (inputs
+     `(("gmp" ,gmp-4.3)
+       ("libc" ,glibc)
+       ("libffi" ,libffi-3.0)
+       ("ncurses" ,ncurses)
+       ("patchelf" ,patchelf)
+       ("perl" ,perl)))
+    (home-page "http://www.haskell.org/ghc/")
+    (synopsis "Haskell compiler and interactive environment")
+    (description
+     "This is a binary distribution of GHC, a compiler and interactive
+environment for the Haskell functional programming language.")
+    (license (bsd-style "file://LICENSE"
+                        "See LICENSE in the distribution."))))
diff --git a/gnu/packages/libffi.scm b/gnu/packages/libffi.scm
index e4a2761..dbc41c3 100644
--- a/gnu/packages/libffi.scm
+++ b/gnu/packages/libffi.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -71,3 +72,16 @@ conversions for values passed between the two languages.")
     ;; See <http://github.com/atgreen/libffi/blob/master/LICENSE>.
     (license expat))))
 
+(define-public libffi-3.0
+  (package (inherit libffi)
+    (name "libffi")
+    (version "3.0.10")
+    (source
+     (origin
+      (method url-fetch)
+      (uri
+       (string-append "ftp://sourceware.org/pub/libffi/"
+                      name "-" version ".tar.gz"))
+      (sha256
+       (base32 "0bs97dgvqrbzc9zv9y2ff5flfvbmfyc68dpnxvm6mdcygq1bj7ph"))))
+    (arguments `(#:phases (alist-delete 'post-install %standard-phases)))))
diff --git a/gnu/packages/multiprecision.scm b/gnu/packages/multiprecision.scm
index 16383d1..f8553c8 100644
--- a/gnu/packages/multiprecision.scm
+++ b/gnu/packages/multiprecision.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -65,9 +66,20 @@ emphasis on speed.
 GMP is faster than any other bignum library.  The advantage for GMP increases
 with the operand sizes for many operations, since GMP uses asymptotically
 faster algorithms.")
-   (license lgpl3+)
+   (license (list gpl3+ lgpl3+))
    (home-page "http://gmplib.org/")))
 
+(define-public gmp-4.3
+  (package (inherit gmp)
+   (version "4.3.2")
+   (source
+    (origin
+     (method url-fetch)
+     (uri
+      (string-append "mirror://gnu/gmp/gmp-" version ".tar.bz2"))
+     (sha256
+      (base32 "0x8prpqi9amfcmi7r4zrza609ai9529pjaq0h4aw51i867064qck"))))))
+
 (define-public mpfr
   (package
    (name "mpfr")

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-07-16 17:55       ` 'substitute*' fails with "string contains #\nul character" (was: 'patchelf' doesn't change shared libraries) Nikita Karetnikov
@ 2013-07-16 19:07         ` Ludovic Courtès
  2013-08-05 21:20         ` Nikita Karetnikov
  1 sibling, 0 replies; 15+ messages in thread
From: Ludovic Courtès @ 2013-07-16 19:07 UTC (permalink / raw)
  To: Nikita Karetnikov; +Cc: guix-devel

Nikita Karetnikov <nikita@karetnikov.org> skribis:

> 'substitute*' fails to patch a binary and returns the following error

[...]

> ice-9/boot-9.scm:106:20: string contains #\nul character:

Yes, that is expected.  ‘substitute*’ is for textual files.

‘fold-port-matches’ from (guix build utils) can be used for binary files
(see ‘remove-store-references’ for an example use.)

HTH,
Ludo’.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-07-16 17:55       ` 'substitute*' fails with "string contains #\nul character" (was: 'patchelf' doesn't change shared libraries) Nikita Karetnikov
  2013-07-16 19:07         ` 'substitute*' fails with "string contains #\nul character" Ludovic Courtès
@ 2013-08-05 21:20         ` Nikita Karetnikov
  2013-08-15 10:37           ` Ludovic Courtès
  1 sibling, 1 reply; 15+ messages in thread
From: Nikita Karetnikov @ 2013-08-05 21:20 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 1428 bytes --]

>> ice-9/boot-9.scm:106:20: string contains #\nul character:

> Yes, that is expected.  ‘substitute*’ is for textual files.

> ‘fold-port-matches’ from (guix build utils) can be used for binary files
> (see ‘remove-store-references’ for an example use.)

Here’s what I’m trying to use:

(use-modules (srfi srfi-14)
             (guix build utils)
             (rnrs bytevectors)
             (rnrs io ports))

(define (binary-substitute file old new)
  "Replace an OLD string with a NEW one in FILE."
  (with-atomic-file-replacement file
    (lambda (in out)
      (format #t "replacing '~a' with '~a' in '~a'...~%"
              old new file)

      (fold-port-matches (lambda (match result)
                           (put-bytevector out (string->utf8 new))
                           #t)
                         #f
                         old
                         in
                         (lambda (char result)
                           (put-u8 out (char->integer char))
                           result)))))

If you compile this program:

#include <stdio.h>

int main()
{
  printf("Hello, world!\n");

  return 0;
}

and try to replace “Hello” with “Hallo,” it will work.  If strings are
not equally sized, ‘a.out’ will crash with a segfault.

I’m not sure how to proceed and fail to find any howtos.  Is there a
tool that I could use?

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-08-05 21:20         ` Nikita Karetnikov
@ 2013-08-15 10:37           ` Ludovic Courtès
  2013-08-18  5:57             ` Nikita Karetnikov
  0 siblings, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2013-08-15 10:37 UTC (permalink / raw)
  To: Nikita Karetnikov; +Cc: guix-devel

Hi!

Nikita Karetnikov <nikita@karetnikov.org> skribis:

> If you compile this program:
>
> #include <stdio.h>
>
> int main()
> {
>   printf("Hello, world!\n");
>
>   return 0;
> }
>
> and try to replace “Hello” with “Hallo,” it will work.  If strings are
> not equally sized, ‘a.out’ will crash with a segfault.

This is expected.

> I’m not sure how to proceed and fail to find any howtos.  Is there a
> tool that I could use?

ELF tools like Andy Wingo’s tools being added to Guile 2.1, or maybe BFD
(part of Binutils), might allow you to modify the ELF string table that
contains string constants.

For the purposes of bootstrapping GHC, I would rather steal whatever
trick Nixpkgs uses, though.  :-)

HTH,
Ludo’.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-08-15 10:37           ` Ludovic Courtès
@ 2013-08-18  5:57             ` Nikita Karetnikov
  2013-08-18 22:13               ` Ludovic Courtès
  0 siblings, 1 reply; 15+ messages in thread
From: Nikita Karetnikov @ 2013-08-18  5:57 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 1958 bytes --]

> For the purposes of bootstrapping GHC, I would rather steal whatever
> trick Nixpkgs uses, though.  :-)

I can’t find anything relevant there.  I suppose that Nix people don’t
have to touch those binaries since they have ‘/bin/sh’ in a chroot.

> ELF tools like Andy Wingo’s tools being added to Guile 2.1, or maybe BFD
> (part of Binutils), might allow you to modify the ELF string table that
> contains string constants.

Are you talking about the (system vm elf) module?  I’ve been trying to
cook a patch but haven’t succeeded yet.  Even though I’ve looked through
the ELF spec and this handy tutorial [1], some things are still not
clear.

First, here’s my understanding of the format.  Each ELF file has an
executable header, which is used to describe the rest of the file.  A
file can also include the following:

1. A program header, which describes the segments (in-memory
   representation).

2. Sections, which are used for linking (in-file representation).

3. A section table header, which stores information about the
   sections.

For starters, I’d like to change the string in the “Hello, world!”
binary.  I assume that I don’t have to deal with segements in that case;
and the binary only includes an executable header, sections, and a
section table header.  Right?

For instance, in order to change the “Hello” part, I have to adjust the
corresponding section (i.e., “.rodata”).  Assuming that sections are
stored in order, I have to modify the offsets of the subsequent sections
and the offset of the section header table itself if I change the size
of “.rodata.”  Finally, I can combine the changed executable header
(contains the offset of the section table header), the sections, and the
section table header.

Is it correct?

[1] http://sourceforge.net/projects/elftoolchain/files/Documentation/libelf-by-example/20120308/libelf-by-example.pdf/download

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-08-18  5:57             ` Nikita Karetnikov
@ 2013-08-18 22:13               ` Ludovic Courtès
  2013-08-18 23:53                 ` Nikita Karetnikov
  0 siblings, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2013-08-18 22:13 UTC (permalink / raw)
  To: Nikita Karetnikov; +Cc: guix-devel

Nikita Karetnikov <nikita@karetnikov.org> skribis:

>> For the purposes of bootstrapping GHC, I would rather steal whatever
>> trick Nixpkgs uses, though.  :-)
>
> I can’t find anything relevant there.  I suppose that Nix people don’t
> have to touch those binaries since they have ‘/bin/sh’ in a chroot.

What string exactly are you trying to patch?  Just /bin/sh?  In which
binary?

>> ELF tools like Andy Wingo’s tools being added to Guile 2.1, or maybe BFD
>> (part of Binutils), might allow you to modify the ELF string table that
>> contains string constants.
>
> Are you talking about the (system vm elf) module?

I think so.

> I’ve been trying to cook a patch but haven’t succeeded yet.  Even
> though I’ve looked through the ELF spec and this handy tutorial [1],
> some things are still not clear.

[...]

> For instance, in order to change the “Hello” part, I have to adjust the
> corresponding section (i.e., “.rodata”).  Assuming that sections are
> stored in order, I have to modify the offsets of the subsequent sections
> and the offset of the section header table itself if I change the size
> of “.rodata.”  Finally, I can combine the changed executable header
> (contains the offset of the section table header), the sections, and the
> section table header.
>
> Is it correct?

I’m not sure about the details.  I would have expected tools like BFD or
libelf to provide the necessary support to make this kind of operation
easier, but I’ve never tried myself.

Ludo’.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-08-18 22:13               ` Ludovic Courtès
@ 2013-08-18 23:53                 ` Nikita Karetnikov
  2013-08-19 11:22                   ` Ludovic Courtès
  0 siblings, 1 reply; 15+ messages in thread
From: Nikita Karetnikov @ 2013-08-18 23:53 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 539 bytes --]

>> I can’t find anything relevant there.  I suppose that Nix people don’t
>> have to touch those binaries since they have ‘/bin/sh’ in a chroot.

> What string exactly are you trying to patch?  Just /bin/sh?  In which
> binary?

For now, at least ‘/bin/sh’ in ‘inplace/bin/ghc-cabal’.

> I’m not sure about the details.  I would have expected tools like BFD or
> libelf to provide the necessary support to make this kind of operation
> easier, but I’ve never tried myself.

OK, I’ll try and report back.

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-08-18 23:53                 ` Nikita Karetnikov
@ 2013-08-19 11:22                   ` Ludovic Courtès
  2013-08-20  5:42                     ` Nikita Karetnikov
  0 siblings, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2013-08-19 11:22 UTC (permalink / raw)
  To: Nikita Karetnikov; +Cc: guix-devel

Nikita Karetnikov <nikita@karetnikov.org> skribis:

>>> I can’t find anything relevant there.  I suppose that Nix people don’t
>>> have to touch those binaries since they have ‘/bin/sh’ in a chroot.
>
>> What string exactly are you trying to patch?  Just /bin/sh?  In which
>> binary?
>
> For now, at least ‘/bin/sh’ in ‘inplace/bin/ghc-cabal’.

What is it used for?  Some kind of ‘system’ function?

If that is the case, perhaps you could replace the relevant calls to
that function in the source with something equivalent (like
execve(/nix/store/.../bin/sh)).

Ludo’.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-08-19 11:22                   ` Ludovic Courtès
@ 2013-08-20  5:42                     ` Nikita Karetnikov
  2013-08-20  7:23                       ` Ludovic Courtès
  0 siblings, 1 reply; 15+ messages in thread
From: Nikita Karetnikov @ 2013-08-20  5:42 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 750 bytes --]

>> For now, at least ‘/bin/sh’ in ‘inplace/bin/ghc-cabal’.

> What is it used for?  Some kind of ‘system’ function?

What do you mean by “’system’ function”?

It’s used to build the libraries [1].  Here’s the source [2].

> If that is the case, perhaps you could replace the relevant calls to
> that function in the source with something equivalent (like
> execve(/nix/store/.../bin/sh)).

I think it’s not the case.

Another possible solution is to ship our own bootstrap binary (like we
do with Guile and Bash).  But first, I’ll try to patch it.  Are you OK
with that?

[1] http://ghc.haskell.org/trac/ghc/wiki/Commentary/SourceTree
[2] https://github.com/ghc/ghc/blob/master/utils/ghc-cabal/Main.hs

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-08-20  5:42                     ` Nikita Karetnikov
@ 2013-08-20  7:23                       ` Ludovic Courtès
  2013-08-21  5:15                         ` Nikita Karetnikov
  0 siblings, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2013-08-20  7:23 UTC (permalink / raw)
  To: Nikita Karetnikov; +Cc: guix-devel

Nikita Karetnikov <nikita@karetnikov.org> skribis:

>>> For now, at least ‘/bin/sh’ in ‘inplace/bin/ghc-cabal’.
>
>> What is it used for?  Some kind of ‘system’ function?
>
> What do you mean by “’system’ function”?

I mean like the function called ‘system’ in libc and in Guile.

> Another possible solution is to ship our own bootstrap binary (like we
> do with Guile and Bash).  But first, I’ll try to patch it.  Are you OK
> with that?

With shipping a binary of GHC?  Well, if that’s the only reasonable way
to do it, then yes.

GNU/MIT Scheme does that for instance, but that’s “their
responsibility”, not ours.  Does the GHC project distribute binaries for
bootstrapping purposes?

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: 'substitute*' fails with "string contains #\nul character"
  2013-08-20  7:23                       ` Ludovic Courtès
@ 2013-08-21  5:15                         ` Nikita Karetnikov
  0 siblings, 0 replies; 15+ messages in thread
From: Nikita Karetnikov @ 2013-08-21  5:15 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 699 bytes --]

>> Another possible solution is to ship our own bootstrap binary (like we
>> do with Guile and Bash).  But first, I’ll try to patch it.  Are you OK
>> with that?

> With shipping a binary of GHC?  Well, if that’s the only reasonable way
> to do it, then yes.

> GNU/MIT Scheme does that for instance, but that’s “their
> responsibility”, not ours.  Does the GHC project distribute binaries for
> bootstrapping purposes?

Yes.  Actually, I’m trying to package a binary version of GHC [1], but I
was talking about shipping ‘ghc-cabal’.

Again, I think that patching is a better solution.

[1] http://www.haskell.org/ghc/dist/7.0.1/ghc-7.0.1-i386-unknown-linux.tar.bz2

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2013-08-21  5:12 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-14 13:33 'patchelf' doesn't change shared libraries Nikita Karetnikov
2013-07-14 13:44 ` Ludovic Courtès
2013-07-14 15:10   ` Nikita Karetnikov
2013-07-15 22:01     ` Ludovic Courtès
2013-07-16 17:55       ` 'substitute*' fails with "string contains #\nul character" (was: 'patchelf' doesn't change shared libraries) Nikita Karetnikov
2013-07-16 19:07         ` 'substitute*' fails with "string contains #\nul character" Ludovic Courtès
2013-08-05 21:20         ` Nikita Karetnikov
2013-08-15 10:37           ` Ludovic Courtès
2013-08-18  5:57             ` Nikita Karetnikov
2013-08-18 22:13               ` Ludovic Courtès
2013-08-18 23:53                 ` Nikita Karetnikov
2013-08-19 11:22                   ` Ludovic Courtès
2013-08-20  5:42                     ` Nikita Karetnikov
2013-08-20  7:23                       ` Ludovic Courtès
2013-08-21  5:15                         ` Nikita Karetnikov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).