* [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) @ 2018-04-18 16:38 Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 1/3] gremlin: Preserve offset info for dynamic entries Ludovic Courtès 2018-05-04 20:52 ` [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) Ludovic Courtès 0 siblings, 2 replies; 8+ messages in thread From: Ludovic Courtès @ 2018-04-18 16:38 UTC (permalink / raw) To: 31208 Hello! As discussed before, this patch set is a first stab at getting rid of PatchELF (which has portability issues) in particular in the Meson build system. (The patches are for the next ‘core-updates’.) The second patch adds ‘strip-runpath’. It doesn’t add ‘augment-rpath’ though, because that’s a bit more involved (it needs to grow the string table and the section it’s in), and so I wanted to make sure we really need it first. :-) In the discussion of ‘meson-build-system’ in <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=28444>, we didn’t discuss this specific part. Peter & Marius: can you explain whether/why this is needed? Thanks, Ludo’. Ludovic Courtès (3): gremlin: Preserve offset info for dynamic entries. gremlin: Add 'strip-runpath'. build-system/meson: Use 'strip-runpath' instead of PatchELF. guix/build/gremlin.scm | 130 +++++++++++++++++++++--------- guix/build/meson-build-system.scm | 2 +- tests/gremlin.scm | 35 +++++++- 3 files changed, 129 insertions(+), 38 deletions(-) -- 2.17.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [bug#31208] [PATCH 1/3] gremlin: Preserve offset info for dynamic entries. 2018-04-18 16:38 [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) Ludovic Courtès @ 2018-04-18 16:40 ` Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 2/3] gremlin: Add 'strip-runpath' Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 3/3] build-system/meson: Use 'strip-runpath' instead of PatchELF Ludovic Courtès 2018-05-04 20:52 ` [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) Ludovic Courtès 1 sibling, 2 replies; 8+ messages in thread From: Ludovic Courtès @ 2018-04-18 16:40 UTC (permalink / raw) To: 31208 * guix/build/gremlin.scm (<dynamic-entry>): New record type. (raw-dynamic-entries): Return a list of <dynamic-entry>. (dynamic-entries): Adjust accordingly and return a list of <dynamic-entry>. (elf-dynamic-info)[matching-entry]: New procedure. Use it. --- guix/build/gremlin.scm | 84 ++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/guix/build/gremlin.scm b/guix/build/gremlin.scm index bb019967e..78d133311 100644 --- a/guix/build/gremlin.scm +++ b/guix/build/gremlin.scm @@ -99,10 +99,16 @@ dynamic linking information." ;; } d_un; ;; } Elf64_Dyn; +(define-record-type <dynamic-entry> + (dynamic-entry type value offset) + dynamic-entry? + (type dynamic-entry-type) ;DT_* + (value dynamic-entry-value) ;string | number | ... + (offset dynamic-entry-offset)) ;integer + (define (raw-dynamic-entries elf segment) - "Return as a list of type/value pairs all the dynamic entries found in -SEGMENT, the 'PT_DYNAMIC' segment of ELF. In the result, each car is a DT_ -value, and the interpretation of the cdr depends on the type." + "Return as a list of <dynamic-entry> for the dynamic entries found in +SEGMENT, the 'PT_DYNAMIC' segment of ELF." (define start (elf-segment-offset segment)) (define bytes @@ -123,7 +129,9 @@ value, and the interpretation of the cdr depends on the type." (if (= type DT_NULL) ;finished? (reverse result) (loop (+ offset (* 2 word-size)) - (alist-cons type value result))))))) + (cons (dynamic-entry type value + (+ start offset word-size)) + result))))))) (define (vma->offset elf vma) "Convert VMA, a virtual memory address, to an offset within ELF. @@ -148,35 +156,33 @@ offset." (define (dynamic-entries elf segment) "Return all the dynamic entries found in SEGMENT, the 'PT_DYNAMIC' segment -of ELF, as a list of type/value pairs. The type is a DT_ value, and the value -may be a string or an integer depending on the entry type (for instance, the -value of DT_NEEDED entries is a string.)" +of ELF, as a list of <dynamic-entry>. The value of each entry may be a string +or an integer depending on the entry type (for instance, the value of +DT_NEEDED entries is a string.) Likewise the offset is the offset within the +string table if the type is a string." (define entries (raw-dynamic-entries elf segment)) (define string-table-offset - (any (match-lambda - ((type . value) - (and (= type DT_STRTAB) value)) - (_ #f)) + (any (lambda (entry) + (and (= (dynamic-entry-type entry) DT_STRTAB) + (dynamic-entry-value entry))) entries)) - (define (interpret-dynamic-entry type value) - (cond ((memv type (list DT_NEEDED DT_SONAME DT_RPATH DT_RUNPATH)) - (if string-table-offset - (pointer->string - (bytevector->pointer (elf-bytes elf) - (vma->offset - elf - (+ string-table-offset value)))) - value)) - (else - value))) + (define (interpret-dynamic-entry entry) + (let ((type (dynamic-entry-type entry)) + (value (dynamic-entry-value entry))) + (cond ((memv type (list DT_NEEDED DT_SONAME DT_RPATH DT_RUNPATH)) + (if string-table-offset + (let* ((offset (vma->offset elf (+ string-table-offset value))) + (value (pointer->string + (bytevector->pointer (elf-bytes elf) offset)))) + (dynamic-entry type value offset)) + (dynamic-entry type value (dynamic-entry-offset entry)))) + (else + (dynamic-entry type value (dynamic-entry-offset entry)))))) - (map (match-lambda - ((type . value) - (cons type (interpret-dynamic-entry type value)))) - entries)) + (map interpret-dynamic-entry entries)) \f ;;; @@ -200,21 +206,29 @@ value of DT_NEEDED entries is a string.)" (define (elf-dynamic-info elf) "Return dynamic-link information for ELF as an <elf-dynamic-info> object, or #f if ELF lacks dynamic-link information." + (define (matching-entry type) + (lambda (entry) + (= type (dynamic-entry-type entry)))) + (match (dynamic-link-segment elf) (#f #f) ((? elf-segment? dynamic) (let ((entries (dynamic-entries elf dynamic))) - (%elf-dynamic-info (assv-ref entries DT_SONAME) - (filter-map (match-lambda - ((type . value) - (and (= type DT_NEEDED) value)) - (_ #f)) + (%elf-dynamic-info (find (matching-entry DT_SONAME) entries) + (filter-map (lambda (entry) + (and (= (dynamic-entry-type entry) + DT_NEEDED) + (dynamic-entry-value entry))) entries) - (or (and=> (assv-ref entries DT_RPATH) - search-path->list) + (or (and=> (find (matching-entry DT_RPATH) + entries) + (compose search-path->list + dynamic-entry-value)) '()) - (or (and=> (assv-ref entries DT_RUNPATH) - search-path->list) + (or (and=> (find (matching-entry DT_RUNPATH) + entries) + (compose search-path->list + dynamic-entry-value)) '())))))) (define %libc-libraries -- 2.17.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [bug#31208] [PATCH 2/3] gremlin: Add 'strip-runpath'. 2018-04-18 16:40 ` [bug#31208] [PATCH 1/3] gremlin: Preserve offset info for dynamic entries Ludovic Courtès @ 2018-04-18 16:40 ` Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 3/3] build-system/meson: Use 'strip-runpath' instead of PatchELF Ludovic Courtès 1 sibling, 0 replies; 8+ messages in thread From: Ludovic Courtès @ 2018-04-18 16:40 UTC (permalink / raw) To: 31208 * guix/build/gremlin.scm (strip-runpath): New procedure. * tests/gremlin.scm (c-compiler): New variable. ("strip-runpath"): New test. --- guix/build/gremlin.scm | 46 +++++++++++++++++++++++++++++++++++++++++- tests/gremlin.scm | 35 +++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/guix/build/gremlin.scm b/guix/build/gremlin.scm index 78d133311..e8ea66dfb 100644 --- a/guix/build/gremlin.scm +++ b/guix/build/gremlin.scm @@ -41,7 +41,8 @@ elf-dynamic-info-runpath expand-origin - validate-needed-in-runpath)) + validate-needed-in-runpath + strip-runpath)) ;;; Commentary: ;;; @@ -320,4 +321,47 @@ be found in RUNPATH ~s~%" ;; (format (current-error-port) "~a is OK~%" file)) (null? not-found)))))) +(define (strip-runpath file) + "Remove from the DT_RUNPATH of FILE any entries that are not necessary +according to DT_NEEDED." + (define (minimal-runpath needed runpath) + (filter (lambda (directory) + (and (string-prefix? "/" directory) + (any (lambda (lib) + (file-exists? (string-append directory "/" lib))) + needed))) + runpath)) + + (define port + (open-file file "r+b")) + + (catch #t + (lambda () + (let* ((elf (parse-elf (get-bytevector-all port))) + (entries (dynamic-entries elf (dynamic-link-segment elf))) + (needed (filter-map (lambda (entry) + (and (= (dynamic-entry-type entry) + DT_NEEDED) + (dynamic-entry-value entry))) + entries)) + (runpath (find (lambda (entry) + (= DT_RUNPATH (dynamic-entry-type entry))) + entries)) + (old (search-path->list + (dynamic-entry-value runpath))) + (new (minimal-runpath needed old))) + (unless (equal? old new) + (format (current-error-port) + "~a: stripping RUNPATH to ~s (removed ~s)~%" + file new + (lset-difference string=? old new)) + (seek port (dynamic-entry-offset runpath) SEEK_SET) + (put-bytevector port (string->utf8 (string-join new ":"))) + (put-u8 port 0)) + (close-port port) + new)) + (lambda (key . args) + (false-if-exception (close-port port)) + (apply throw key args)))) + ;;; gremlin.scm ends here diff --git a/tests/gremlin.scm b/tests/gremlin.scm index 288555496..1b47d5c38 100644 --- a/tests/gremlin.scm +++ b/tests/gremlin.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2015, 2018 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -18,12 +18,14 @@ (define-module (test-gremlin) #:use-module (guix elf) + #:use-module ((guix utils) #:select (call-with-temporary-directory)) #:use-module (guix build utils) #:use-module (guix build gremlin) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:use-module (srfi srfi-64) #:use-module (rnrs io ports) + #:use-module (ice-9 popen) #:use-module (ice-9 match)) (define %guile-executable @@ -37,6 +39,9 @@ (define read-elf (compose parse-elf get-bytevector-all)) +(define c-compiler + (or (which "gcc") (which "cc") (which "g++"))) + \f (test-begin "gremlin") @@ -63,4 +68,32 @@ "../${ORIGIN}/bar/$ORIGIN/baz" "ORIGIN/foo"))) +(unless c-compiler + (test-skip 1)) +(test-equal "strip-runpath" + "hello\n" + (call-with-temporary-directory + (lambda (directory) + (with-directory-excursion directory + (call-with-output-file "t.c" + (lambda (port) + (display "int main () { puts(\"hello\"); }" port))) + (invoke c-compiler "t.c" + "-Wl,-rpath=/foo" "-Wl,-rpath=/bar") + (let* ((dyninfo (elf-dynamic-info + (parse-elf (call-with-input-file "a.out" + get-bytevector-all)))) + (old (elf-dynamic-info-runpath dyninfo)) + (new (strip-runpath "a.out")) + (new* (strip-runpath "a.out"))) + (validate-needed-in-runpath "a.out") + (and (member "/foo" old) (member "/bar" old) + (not (member "/foo" new)) + (not (member "/bar" new)) + (equal? new* new) + (let* ((pipe (open-input-pipe "./a.out")) + (str (get-string-all pipe))) + (close-pipe pipe) + str))))))) + (test-end "gremlin") -- 2.17.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [bug#31208] [PATCH 3/3] build-system/meson: Use 'strip-runpath' instead of PatchELF. 2018-04-18 16:40 ` [bug#31208] [PATCH 1/3] gremlin: Preserve offset info for dynamic entries Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 2/3] gremlin: Add 'strip-runpath' Ludovic Courtès @ 2018-04-18 16:40 ` Ludovic Courtès 1 sibling, 0 replies; 8+ messages in thread From: Ludovic Courtès @ 2018-04-18 16:40 UTC (permalink / raw) To: 31208 * guix/build/meson-build-system.scm (fix-runpath): Call 'strip-runpath' instead of invoking 'patchelf'. --- guix/build/meson-build-system.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guix/build/meson-build-system.scm b/guix/build/meson-build-system.scm index e8cb5440e..793cc32e7 100644 --- a/guix/build/meson-build-system.scm +++ b/guix/build/meson-build-system.scm @@ -134,7 +134,7 @@ for example libraries only needed for the tests." (find-files dir elf-pred)) existing-elf-dirs)))) (for-each (lambda (elf-file) - (system* "patchelf" "--shrink-rpath" elf-file) + (strip-runpath elf-file) (handle-file elf-file elf-list)) elf-list))))) (for-each handle-output outputs) -- 2.17.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) 2018-04-18 16:38 [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 1/3] gremlin: Preserve offset info for dynamic entries Ludovic Courtès @ 2018-05-04 20:52 ` Ludovic Courtès [not found] ` <CADh9keX7zyDOoNFstawVKdinxNOMKfff3jQuZUOvxFDawZP9Hw@mail.gmail.com> 1 sibling, 1 reply; 8+ messages in thread From: Ludovic Courtès @ 2018-05-04 20:52 UTC (permalink / raw) To: 31208 Ping! :-) Ludovic Courtès <ludo@gnu.org> skribis: > Hello! > > As discussed before, this patch set is a first stab at getting rid of > PatchELF (which has portability issues) in particular in the Meson build > system. (The patches are for the next ‘core-updates’.) > > The second patch adds ‘strip-runpath’. It doesn’t add ‘augment-rpath’ > though, because that’s a bit more involved (it needs to grow the string > table and the section it’s in), and so I wanted to make sure we really > need it first. :-) > > In the discussion of ‘meson-build-system’ in > <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=28444>, we didn’t discuss > this specific part. Peter & Marius: can you explain whether/why this is > needed? > > Thanks, > Ludo’. > > Ludovic Courtès (3): > gremlin: Preserve offset info for dynamic entries. > gremlin: Add 'strip-runpath'. > build-system/meson: Use 'strip-runpath' instead of PatchELF. > > guix/build/gremlin.scm | 130 +++++++++++++++++++++--------- > guix/build/meson-build-system.scm | 2 +- > tests/gremlin.scm | 35 +++++++- > 3 files changed, 129 insertions(+), 38 deletions(-) ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <CADh9keX7zyDOoNFstawVKdinxNOMKfff3jQuZUOvxFDawZP9Hw@mail.gmail.com>]
* [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) [not found] ` <CADh9keX7zyDOoNFstawVKdinxNOMKfff3jQuZUOvxFDawZP9Hw@mail.gmail.com> @ 2018-05-05 20:02 ` Ludovic Courtès 2018-05-07 9:24 ` bug#31208: " Ludovic Courtès 2018-05-07 9:32 ` [bug#31208] " Ludovic Courtès 0 siblings, 2 replies; 8+ messages in thread From: Ludovic Courtès @ 2018-05-05 20:02 UTC (permalink / raw) To: Peter Mikkelsen; +Cc: 31208 Hello Peter, (I’m re-adding Cc, hope you don’t mind.) Peter Mikkelsen <petermikkelsen10@gmail.com> skribis: > Since I am not really that much into meson, I am not sure my answer > will be enough, but I will give it a go: > The augment-rpath is needed because in some software projects such as > nautilus, there is both a library and an executable. > When building the software, the library is built first, and then the > executable which depends on it, but then the runpath of the executable > is 'fixed' so > that libnautilus is no longer in the runpath of the nautilus binary. > This is a problem since libnautilus is needed at runtime, so it is > added using augment-rpath. Oh, I see. Back to this patch series, it means we still need ‘augment-rpath’. :-/ I suppose we can still apply these patches to ‘core-updates-next’ though, it’s a step in the right direction. > I think I remember something about the meson developers saying that it > is no problem, since libnautilus will be installed in a standard > location or something, > but I really don't remember, sorry.. What Libtool does is that it “relinks” executables upon “make install” so that they have the correct RUNPATH. > Sorry for the not so good reply, but I hope it makes a little bit sense :) It makes a lot of sense yes, thank you! Ludo’. ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#31208: [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) 2018-05-05 20:02 ` Ludovic Courtès @ 2018-05-07 9:24 ` Ludovic Courtès 2018-05-07 9:32 ` [bug#31208] " Ludovic Courtès 1 sibling, 0 replies; 8+ messages in thread From: Ludovic Courtès @ 2018-05-07 9:24 UTC (permalink / raw) To: Peter Mikkelsen; +Cc: 31208-done ludo@gnu.org (Ludovic Courtès) skribis: > Back to this patch series, it means we still need ‘augment-rpath’. :-/ > I suppose we can still apply these patches to ‘core-updates-next’ > though, it’s a step in the right direction. Done! Ludo’. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) 2018-05-05 20:02 ` Ludovic Courtès 2018-05-07 9:24 ` bug#31208: " Ludovic Courtès @ 2018-05-07 9:32 ` Ludovic Courtès 1 sibling, 0 replies; 8+ messages in thread From: Ludovic Courtès @ 2018-05-07 9:32 UTC (permalink / raw) To: Peter Mikkelsen; +Cc: 31208 ludo@gnu.org (Ludovic Courtès) skribis: > Peter Mikkelsen <petermikkelsen10@gmail.com> skribis: [...] >> I think I remember something about the meson developers saying that it >> is no problem, since libnautilus will be installed in a standard >> location or something, >> but I really don't remember, sorry.. > > What Libtool does is that it “relinks” executables upon “make install” > so that they have the correct RUNPATH. I found this issue, which mentions the problem: https://github.com/mesonbuild/meson/issues/2121#issuecomment-377971590 It’s a pity this isn’t properly solved. :-/ Ludo’. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-05-07 9:33 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-04-18 16:38 [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 1/3] gremlin: Preserve offset info for dynamic entries Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 2/3] gremlin: Add 'strip-runpath' Ludovic Courtès 2018-04-18 16:40 ` [bug#31208] [PATCH 3/3] build-system/meson: Use 'strip-runpath' instead of PatchELF Ludovic Courtès 2018-05-04 20:52 ` [bug#31208] [PATCH 0/3] Add 'strip-runpath' in (guix build gremlin) Ludovic Courtès [not found] ` <CADh9keX7zyDOoNFstawVKdinxNOMKfff3jQuZUOvxFDawZP9Hw@mail.gmail.com> 2018-05-05 20:02 ` Ludovic Courtès 2018-05-07 9:24 ` bug#31208: " Ludovic Courtès 2018-05-07 9:32 ` [bug#31208] " Ludovic Courtès
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).