Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use patchelf.rb to set interpreter instead of patchelf. First step towards shelless elftools #7213

Merged
merged 1 commit into from
Aug 28, 2020

Conversation

rmNULL
Copy link
Contributor

@rmNULL rmNULL commented Mar 24, 2020

Add a new gem requirement to patchelf.rb,

patchelf command was used to update the name of interpreter and replace DT_RPATH.
Same features of patchelf.rb, was used as a substitute.

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew style with your changes locally?
  • Have you successfully run brew tests with your changes locally?

Sorry, something went wrong.

@iMichka iMichka requested a review from sjackman March 24, 2020 06:34
@jonchang jonchang requested a review from woodruffw March 24, 2020 11:22
@jonchang
Copy link
Contributor

I believe you'll need to run brew vendor-gems on this branch and push up the changes, as this is required on install time (like ruby-macho).

@MikeMcQuaid
Copy link
Member

Nice work so far here @rmNULL!

@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 24, 2020

I believe you'll need to run brew vendor-gems on this branch and push up the changes, as this is required on install time (like ruby-macho).

thanks, i'll push. should "vendor/bundle" be added to git ? command committed it.

@rmNULL rmNULL force-pushed the linux-shelless-elftools branch 2 times, most recently from e403927 to 737a809 Compare March 24, 2020 16:35
@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 24, 2020

Nice work so far here @rmNULL!

Thanks, i appreciate it.

@woodruffw
Copy link
Member

Looks like a great start to me, thanks @rmNULL! Will do some initial review tonight (ET).

@MikeMcQuaid
Copy link
Member

Would be good to see if it's possible to partially vendor any of the gems. >8000 lines added isn't great for a Linux-only dependency (but we'll suck it up if need be).

@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 25, 2020

Would be good to see if it's possible to partially vendor any of the gems. >8000 lines added isn't great for a Linux-only dependency (but we'll suck it up if need be).

most of the lines come from bindata which is required by elftools which patchelf also depends on.
elftools can be used to replace readelf binary, as we are proceeding in that direction, we have all the gems that is required for full replacement of readelf, patchelf binary.

@MikeMcQuaid
Copy link
Member

most of the lines come from bindata which is required by elftools which patchelf also depends on.
elftools can be used to replace readelf binary, as we are proceeding in that direction, we have all the gems that is required for full replacement of readelf, patchelf binary.

Cool, that would be good. I ask because what I've done with some gems in the past is try to remove all files until it breaks so we can figure out what the bare minimum files (or at least directories) we need to include. This may be overkill in this case, though.

@sjackman
Copy link
Contributor

Nice work! I'm curious if it's faster or slower than before. It might be difficult to get good timing results, but could you try giving it a shot? Find a package with a lot of ELF files that need to be patched, and try timing it before and after. This isn't critical, but would be cool to see if it's actually faster.

@sjackman
Copy link
Contributor

Could you please report the output of brew install -s hello && readelf -d /home/linuxbrew/.linuxbrew/bin/hello with your patch applied, and compare it the output without your patch applied?

@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 25, 2020

Could you please report the output of brew install -s hello && readelf -d /home/linuxbrew/.linuxbrew/bin/hello with your patch applied, and compare it the output without your patch applied?

Note: When I did this my brew installation was at /home/rmnull/.linuxbrew,
but for following comments the installation location has been changed to /home/linuxbrew/.linuxbrew.

Images

patch

readelf-patch

master

readelf-master

Above shell interaction as text

rmnull @ eos: linux-shelless-elftools ~/.linuxbrew/Homebrew
∫
rmnull @ eos: linux-shelless-elftools ~/.linuxbrew/Homebrew
∫ brew rm hello
Uninstalling /home/rmnull/.linuxbrew/Cellar/hello/2.10... (52 files, 591.6KB)
rmnull @ eos: linux-shelless-elftools ~/.linuxbrew/Homebrew
∫
rmnull @ eos: linux-shelless-elftools ~/.linuxbrew/Homebrew
∫ brew install -s hello
Updating Homebrew...
==> Auto-updated Homebrew!
Updated Homebrew from 5e63d0cef to fa8fe0fc3.
Updated 1 tap (homebrew/core).
==> New Formulae
oil
==> Updated Formulae
algernon        bazel           cmake           docbook-xsl     firebase-cli    helm@2          memcached       openfortivpn    rke             vala
antibody        bnd             cython          duplicity       gatsby-cli      hiredis         mimic           pandoc          sn0int          vulkan-headers
assh            cargo-c         dashing         exploitdb       gitlab-runner   hugo            nano            parallel        solr            webpack
audacious       cfn-lint        devspace        fastlane        glooctl         jenkins         now-cli         pgloader        sql-translator  xonsh
awscli          circleci        dnscrypt-proxy  fd              gnupg           lazygit         nrpe            prettier        travis          youtube-dl

==> Downloading https://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz
Already downloaded: /home/rmnull/.cache/Homebrew/downloads/0d3dc7a1e45d7ac6eb8d853c8ecccad6a4ab6abbbf38038f552e4735ad15d3cc--hello-2.10.tar.gz
==> ./configure --prefix=/home/rmnull/.linuxbrew/Cellar/hello/2.10
==> make install
🍺  /home/rmnull/.linuxbrew/Cellar/hello/2.10: 53 files, 605.4KB, built in 19 seconds
rmnull @ eos: linux-shelless-elftools ~/.linuxbrew/Homebrew
∫ readelf -d ~/.linuxbrew/bin/hello

Dynamic section at offset 0x6e08 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [/home/rmnull/.linuxbrew/Cellar/hello/2.10/lib:/home/rmnull/.linuxbrew/lib]
 0x000000000000000c (INIT)               0x402000
 0x000000000000000d (FINI)               0x404850
 0x0000000000000019 (INIT_ARRAY)         0x407d10
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x407d18
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x400310
 0x0000000000000005 (STRTAB)             0x400898
 0x0000000000000006 (SYMTAB)             0x400358
 0x000000000000000a (STRSZ)              639 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x408000
 0x0000000000000002 (PLTRELSZ)           1080 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x400ca8
 0x0000000000000007 (RELA)               0x400be8
 0x0000000000000008 (RELASZ)             192 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x400b88
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x400b18
 0x0000000000000000 (NULL)               0x0
rmnull @ eos: linux-shelless-elftools ~/.linuxbrew/Homebrew
∫ g co master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
rmnull @ eos: master ~/.linuxbrew/Homebrew
∫ brew install -s hello
Warning: hello 2.10 is already installed and up-to-date
To reinstall 2.10, run `brew reinstall hello`
rmnull @ eos: master ~/.linuxbrew/Homebrew
∫ brew rm hello
Uninstalling /home/rmnull/.linuxbrew/Cellar/hello/2.10... (53 files, 605.4KB)
rmnull @ eos: master ~/.linuxbrew/Homebrew
∫ brew install -s hello
==> Downloading https://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz
Already downloaded: /home/rmnull/.cache/Homebrew/downloads/0d3dc7a1e45d7ac6eb8d853c8ecccad6a4ab6abbbf38038f552e4735ad15d3cc--hello-2.10.tar.gz
==> ./configure --prefix=/home/rmnull/.linuxbrew/Cellar/hello/2.10
==> make install
🍺  /home/rmnull/.linuxbrew/Cellar/hello/2.10: 53 files, 605.4KB, built in 19 seconds
rmnull @ eos: master ~/.linuxbrew/Homebrew
∫
rmnull @ eos: master ~/.linuxbrew/Homebrew
∫ readelf -d ~/.linuxbrew/bin/hello

Dynamic section at offset 0x6e08 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [/home/rmnull/.linuxbrew/Cellar/hello/2.10/lib:/home/rmnull/.linuxbrew/lib]
 0x000000000000000c (INIT)               0x402000
 0x000000000000000d (FINI)               0x404850
 0x0000000000000019 (INIT_ARRAY)         0x407d10
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x407d18
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x400310
 0x0000000000000005 (STRTAB)             0x400898
 0x0000000000000006 (SYMTAB)             0x400358
 0x000000000000000a (STRSZ)              639 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x408000
 0x0000000000000002 (PLTRELSZ)           1080 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x400ca8
 0x0000000000000007 (RELA)               0x400be8
 0x0000000000000008 (RELASZ)             192 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x400b88
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x400b18
 0x0000000000000000 (NULL)               0x0
rmnull @ eos: master ~/.linuxbrew/Homebrew
∫

@rmNULL rmNULL force-pushed the linux-shelless-elftools branch from 737a809 to 7148e9d Compare March 25, 2020 22:01
@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 26, 2020

Nice work! I'm curious if it's faster or slower than before. It might be difficult to get good timing results, but could you try giving it a shot? Find a package with a lot of ELF files that need to be patched, and try timing it before and after. This isn't critical, but would be cool to see if it's actually faster.

@sjackman I'm afraid it gets slower in some cases.

benchmark

hello and ocaml

hello and ocaml

GCC and Boost

bm-gcc-boost

benchmark snippet

require "benchmark"
class Keg
  def relocate_dynamic_linkage(relocation)
    # Patching the dynamic linker of glibc breaks it.
    return if name == "glibc"

    ::Benchmark.bm(8) do |b|
      b.report("PATCH") do
        elf_files.each do |file|
          file.ensure_writable do
            change_rpath(file, relocation.old_prefix, relocation.new_prefix)
          end
        end
      end

      b.report("MASTER") do
        elf_files.each do |file|
          file.ensure_writable do
            master_change_rpath(file, relocation.old_prefix, relocation.new_prefix)
          end
        end
      end
    end
  end
   
   def change_rpath(file, old_prefix, new_prefix)
           #  patch 
   end

   def master_change_rpath(file, old_prefix, new_prefix)
           #  original code
   end

   # ....
end

opencv install log

rmnull @ eos: linux-shelless-elftools /home/linuxbrew/.linuxbrew/Homebrew
∫ brew install opencv
==> Installing dependencies for opencv: cmake, eigen, gflags, glog, metis, openblas, suite-sparse, ceres-solver, numpy, ilmbase, openexr, isl, gcc@6, protobuf and tbb
==> Installing opencv dependency: cmake
==> Downloading https://linuxbrew.bintray.com/bottles/cmake-3.17.0.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/d7/d7910f7121f01ab7793cc354dda8be54cf4403a085c7aca10e4ea06ec6e91c9e?__gda__=exp=1585187483~hmac=8ffae3381da673f89ffc2b205d4516d33eaf90257beda59ceac7a1ec31ad760b&response-content-disposition=a
######################################################################## 100.0%
==> Pouring cmake-3.17.0.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.264945   0.112339   0.385813 (  0.387642)
MASTER     0.079227   0.067473   0.205443 (  0.205277)
==> Caveats
Emacs Lisp files have been installed to:
  /home/linuxbrew/.linuxbrew/share/emacs/site-lisp/cmake
==> Summary
🍺  /home/linuxbrew/.linuxbrew/Cellar/cmake/3.17.0: 6,159 files, 62.8MB
==> Installing opencv dependency: eigen
==> Downloading https://linuxbrew.bintray.com/bottles/eigen-3.3.7.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/aa/aadf704e7dcb42aa6ff5f6ab4d42cda3a3a2fc4325efa10c37636aa5ca6b1968?__gda__=exp=1585187491~hmac=9c88642289367aa716a791d6fc49155ecd625c271fb3d8dd8ea7e1cbcae12182&response-content-disposition=a
######################################################################## 100.0%
==> Pouring eigen-3.3.7.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.009067   0.004967   0.014034 (  0.014437)
MASTER     0.009215   0.005868   0.015083 (  0.015258)
🍺  /home/linuxbrew/.linuxbrew/Cellar/eigen/3.3.7: 487 files, 6.8MB
==> Installing opencv dependency: gflags
==> Downloading https://linuxbrew.bintray.com/bottles/gflags-2.2.2.x86_64_linux.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring gflags-2.2.2.x86_64_linux.bottle.1.tar.gz
               user     system      total        real
PATCH      0.005018   0.010724   0.027526 (  0.027198)
MASTER     0.000000   0.010854   0.028292 (  0.027550)
🍺  /home/linuxbrew/.linuxbrew/Cellar/gflags/2.2.2: 24 files, 456.9KB
==> Installing opencv dependency: glog
==> Downloading https://linuxbrew.bintray.com/bottles/glog-0.4.0_1.x86_64_linux.bottle.tar.gz
######################################################################## 100.0%
==> Pouring glog-0.4.0_1.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.004207   0.003976   0.014692 (  0.014582)
MASTER     0.000000   0.005183   0.015460 (  0.015143)
🍺  /home/linuxbrew/.linuxbrew/Cellar/glog/0.4.0_1: 19 files, 313.8KB
==> Installing opencv dependency: metis
==> Downloading https://linuxbrew.bintray.com/bottles/metis-5.1.0.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/5b/5bae428970f681f9bea501461d755d60127ab380bc0572b35156c4733021df22?__gda__=exp=1585187513~hmac=af98262edd78a24db771516397cdb5500b7946ec68f0a96adb8cbf566fb991bd&response-content-disposition=a
######################################################################## 100.0%
==> Pouring metis-5.1.0.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.041469   0.015017   0.072390 (  0.071972)
MASTER     0.006038   0.028319   0.091383 (  0.089025)
🍺  /home/linuxbrew/.linuxbrew/Cellar/metis/5.1.0: 18 files, 12.1MB
==> Installing opencv dependency: openblas
==> Downloading https://linuxbrew.bintray.com/bottles/openblas-0.3.9.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/c1/c1635e1d745cc42aa583eb3a53d1165296a04bebacd5620a34c959a3d6f8f57d?__gda__=exp=1585187523~hmac=08f99ea027faffacdf0b5546a6040c0655d12c36ce34c654ddc19bd998b5c2aa&response-content-disposition=a
######################################################################## 100.0%
==> Pouring openblas-0.3.9.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.004847   0.003143   0.014833 (  0.014679)
MASTER     0.001437   0.005039   0.098567 (  0.156641)
🍺  /home/linuxbrew/.linuxbrew/Cellar/openblas/0.3.9: 24 files, 76.9MB
==> Installing opencv dependency: suite-sparse
==> Downloading https://linuxbrew.bintray.com/bottles/suite-sparse-5.7.1.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/b5/b5c0745e50fcb6b8e2c4472eb4ae8348cb7347f34aa467425f2c584719ea568c?__gda__=exp=1585187529~hmac=6fe845a3e2b2540431ed5a15e9eb50a183a4926b840dd92b6c24c14c91078d55&response-content-disposition=a
######################################################################## 100.0%
==> Pouring suite-sparse-5.7.1.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.099916   0.049390   0.221851 (  0.219612)
MASTER     0.011264   0.071705   0.357970 (  0.474828)
🍺  /home/linuxbrew/.linuxbrew/Cellar/suite-sparse/5.7.1: 158 files, 64.3MB
==> Installing opencv dependency: ceres-solver
==> Downloading https://linuxbrew.bintray.com/bottles/ceres-solver-1.14.0_11.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/dd/dd13c401cf2078a85be33f1ad5a47d1f169feac957b39f8c070529260c513616?__gda__=exp=1585187567~hmac=1ac9669aeb6d42089d3726fae698db6b9948f6aa68cf12129b776688e7835003&response-content-disposition=a
######################################################################## 100.0%
==> Pouring ceres-solver-1.14.0_11.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.015954   0.005980   0.025251 (  0.025476)
MASTER     0.005091   0.011991   0.031891 (  0.031937)
🍺  /home/linuxbrew/.linuxbrew/Cellar/ceres-solver/1.14.0_11: 481 files, 18.6MB
==> Installing opencv dependency: numpy
==> Downloading https://linuxbrew.bintray.com/bottles/numpy-1.18.1_1.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/fb/fb5b52c9515599b24e57437a38584dc18bb8da707721eb43a0d6324360ee0acb?__gda__=exp=1585187579~hmac=6295e702005b2af3cdabb434886f8f5d2358907c4bc79f76e365a54c92632fe5&response-content-disposition=a
######################################################################## 100.0%
==> Pouring numpy-1.18.1_1.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.090185   0.058715   0.230182 (  0.227761)
MASTER     0.011987   0.099297   0.335043 (  0.368126)
🍺  /home/linuxbrew/.linuxbrew/Cellar/numpy/1.18.1_1: 484 files, 40MB
==> Installing opencv dependency: ilmbase
==> Downloading https://linuxbrew.bintray.com/bottles/ilmbase-2.4.1.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/66/664e35377689613ba36abea4811dba1a08011f311cee70fbb358b9d6d496eca6?__gda__=exp=1585187596~hmac=ab56a33b7f997e90e201d76dfa77b7467ec90e0cc342640ac28d3031450d75b2&response-content-disposition=a
######################################################################## 100.0%
==> Pouring ilmbase-2.4.1.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.083220   0.038772   0.156256 (  0.155529)
MASTER     0.022686   0.034229   0.130907 (  0.128038)
🍺  /home/linuxbrew/.linuxbrew/Cellar/ilmbase/2.4.1: 456 files, 7.5MB
==> Installing opencv dependency: openexr
==> Downloading https://linuxbrew.bintray.com/bottles/openexr-2.4.1.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/2c/2cbfb115aa4a7a863550012d7d41c9cb323a9d02df76dc1312b7a564aa7b6925?__gda__=exp=1585187601~hmac=37b40b1e703c8bcb5137ef7f11a9667c950f5a0c1b179f6c824549d20ef08ea6&response-content-disposition=a
######################################################################## 100.0%
==> Pouring openexr-2.4.1.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.240024   0.049678   0.315906 (  0.316442)
MASTER     0.007571   0.037883   0.113795 (  0.111086)
🍺  /home/linuxbrew/.linuxbrew/Cellar/openexr/2.4.1: 152 files, 7.4MB
==> Installing opencv dependency: isl
==> Downloading https://linuxbrew.bintray.com/bottles/isl-0.22.1.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/f2/f211005727b3ff0a59cbca6521f9a5aaaef54cfc801e3725a1b2708f9576fa0c?__gda__=exp=1585187606~hmac=04740a4aae8c1de43b12ab4c9cd00f8d5af4111e0e615f48500a171987b6612d&response-content-disposition=a
######################################################################## 100.0%
==> Pouring isl-0.22.1.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.007032   0.002018   0.016297 (  0.016243)
MASTER     0.001153   0.005691   0.025369 (  0.025061)
🍺  /home/linuxbrew/.linuxbrew/Cellar/isl/0.22.1: 74 files, 6.4MB
==> Installing opencv dependency: gcc@6
==> Downloading https://linuxbrew.bintray.com/bottles/gcc@6-6.5.0_4.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/d6/d67445571d72bd8696dfb4a019b3204be46e6705a7d8ed1113ed02887303c66a?__gda__=exp=1585187610~hmac=1dcbcfaaaa7aa016407e3aedf92b0c50d2191222b188d380675facd1f79222aa&response-content-disposition=a
######################################################################## 100.0%
==> Pouring gcc@6-6.5.0_4.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      5.799229   1.998370   7.949649 (  7.969755)
MASTER     0.025352   0.190669   0.658485 (  0.649643)
==> Creating the GCC specs file: /home/linuxbrew/.linuxbrew/Cellar/gcc@6/6.5.0_4/lib/gcc/6/gcc/x86_64-pc-linux-gnu/6.5.0/specs
🍺  /home/linuxbrew/.linuxbrew/Cellar/gcc@6/6.5.0_4: 1,394 files, 195.3MB
==> Installing opencv dependency: protobuf
==> Downloading https://linuxbrew.bintray.com/bottles/protobuf-3.11.4.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/e8/e883669c1432e638c98a3a27f12443fa3d60cf3b9b38e565243295e7a828701d?__gda__=exp=1585187633~hmac=9a6e90dd0b333589b2499b098f89a453c459050717f8a5aac50bb702dc6a0a54&response-content-disposition=a
######################################################################## 100.0%
==> Pouring protobuf-3.11.4.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.045272   0.019989   0.090700 (  0.090597)
MASTER     0.007960   0.029216   0.126586 (  0.125289)
Warning: protobuf dependency gmp was built with a different C++ standard
library (libstdc++ from gcc-5). This may cause problems at runtime.
🍺  /home/linuxbrew/.linuxbrew/Cellar/protobuf/3.11.4: 272 files, 30.2MB
==> Installing opencv dependency: tbb
==> Downloading https://linuxbrew.bintray.com/bottles/tbb-2020_U1_1.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/ee/ee4888ae79644d70c7f8cbef5de02c7b415fdbc06a2c906ea33de6c487a5f648?__gda__=exp=1585187639~hmac=2a007a740a2990db302ab27e2bf2a61c5df8525a3370b740f329896a6e33aadc&response-content-disposition=a
######################################################################## 100.0%
==> Pouring tbb-2020_U1_1.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.022557   0.014738   0.058407 (  0.057818)
MASTER     0.007297   0.026021   0.087423 (  0.085983)
🍺  /home/linuxbrew/.linuxbrew/Cellar/tbb/2020_U1_1: 150 files, 3.9MB
==> Installing opencv
==> Downloading https://linuxbrew.bintray.com/bottles/opencv-4.2.0_3.x86_64_linux.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/9c/9cedae0527072a3d59ca5fe2032ccfcb373e29236e750c5719a9200f31efdcda?__gda__=exp=1585187646~hmac=149cf3721e454c59d4c1f8033b23d5bfc9cd5caeec96215a28e50ca3ec2baa60&response-content-disposition=a
######################################################################## 100.0%
==> Pouring opencv-4.2.0_3.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.886032   0.468456   1.691102 (  1.689027)
MASTER     0.070747   0.448959   1.610320 (  1.649985)
Warning: opencv dependency protobuf was built with a different C++ standard
library (libstdc++ from gcc-6). This may cause problems at runtime.
🍺  /home/linuxbrew/.linuxbrew/Cellar/opencv/4.2.0_3: 763 files, 357.4MB
==> Caveats
==> cmake
Emacs Lisp files have been installed to:
  /home/linuxbrew/.linuxbrew/share/emacs/site-lisp/cmake

@david942j
Copy link

Hi I'm the maintainer of patchelf.rb
If the time is an issue, I'm glad to see if I can improve its efficiency

@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 26, 2020

Hi I'm the maintainer of patchelf.rb
If the time is an issue, I'm glad to see if I can improve its efficiency

@david942j 😎.
If possible, please do an independent check(I'll carry on my own profiling) as to why binaries like gcc or ocaml have a huge time difference. Few binaries are on par with (some faster, e.g: boost) system call to patchelf.

@MikeMcQuaid
Copy link
Member

benchmark results for hello and ocaml binaries.
benchmark results for gcc and boost

Screenshot 2020-03-26 at 10 11 44

@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 26, 2020

benchmark results for hello and ocaml binaries.
benchmark results for gcc and boost

Screenshot 2020-03-26 at 10 11 44

can u try with other browser, if that doesn't work, i'll reupload.

@MikeMcQuaid
Copy link
Member

can u try with other browser, if that doesn't work, i'll reupload.

@rmNULL Could you instead just drag and drop the images into the GitHub comments so they can be seen by everyone (regardless of browser)? Thanks!

@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 26, 2020

can u try with other browser, if that doesn't work, i'll reupload.

@rmNULL Could you instead just drag and drop the images into the GitHub comments so they can be seen by everyone (regardless of browser)? Thanks!

didn't know i could drag and drop, nice. The comment is updated

@david942j
Copy link

@rmNULL I believe the time issue is a bug of your benchmark code :p

    ::Benchmark.bm(8) do |b|
      b.report("PATCH") do
        elf_files.each do |file|
          file.ensure_writable do
            change_rpath(file, relocation.old_prefix, relocation.new_prefix)
          end
        end
      end

      b.report("MASTER") do
        elf_files.each do |file|
          file.ensure_writable do
            master_change_rpath(file, relocation.old_prefix, relocation.new_prefix)
          end
        end
      end
    end

Since it's an in-place patch, the input file will be modified at the first time of patching. I simply swapped the order of "PATCH" and "MASTER" and got a totally different result:

bin/brew install gcc
==> Downloading https://linuxbrew.bintray.com/bottles/gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/b91d14d1e15ddd20f9b3114d36aa006c86f2ecf8aa07e5c328ab950e9b4c40f8--gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
==> Pouring gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
               user     system      total        real
MASTER     0.043929   0.176066   1.350618 (  1.319474)
PATCH      0.273413   0.099844   0.582204 (  0.572442)
Warning: This keg was marked linked already, continuing anyway
==> Creating the GCC specs file: /home/david942j/brew-patch/Cellar/gcc/5.5.0_7/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.5.0/sp
🍺  /home/david942j/brew-patch/Cellar/gcc/5.5.0_7: 1,350 files, 174.8MB

@rmNULL
Copy link
Contributor Author

rmNULL commented Mar 26, 2020

@rmNULL I believe the time issue is a bug of your benchmark code :p

    ::Benchmark.bm(8) do |b|
      b.report("PATCH") do
        elf_files.each do |file|
          file.ensure_writable do
            change_rpath(file, relocation.old_prefix, relocation.new_prefix)
          end
        end
      end

      b.report("MASTER") do
        elf_files.each do |file|
          file.ensure_writable do
            master_change_rpath(file, relocation.old_prefix, relocation.new_prefix)
          end
        end
      end
    end

Since it's an in-place patch, the input file will be modified at the first time of patching. I simply swapped the order of "PATCH" and "MASTER" and got a totally different result:

bin/brew install gcc
==> Downloading https://linuxbrew.bintray.com/bottles/gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/b91d14d1e15ddd20f9b3114d36aa006c86f2ecf8aa07e5c328ab950e9b4c40f8--gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
==> Pouring gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
               user     system      total        real
MASTER     0.043929   0.176066   1.350618 (  1.319474)
PATCH      0.273413   0.099844   0.582204 (  0.572442)
Warning: This keg was marked linked already, continuing anyway
==> Creating the GCC specs file: /home/david942j/brew-patch/Cellar/gcc/5.5.0_7/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.5.0/sp
🍺  /home/david942j/brew-patch/Cellar/gcc/5.5.0_7: 1,350 files, 174.8MB

@david942j i had doubt about my bench marking code, thanks for pointing it out.
I did verify your claims, the order does matter,
and to adjust the inequality i let a dummy run before benchmarking,
the ruby library was faster,
a/w i'll perform a perform a standalone test for both of them.
(quick and dirty didn't work well ;)

Thanks

@david942j
Copy link

david942j commented Mar 26, 2020

NP.
I'm also doing the benchmark on them and the Ruby version is slower than patchelf bin
benchmark code:

rollback = proc do
  elf_files.each do |file|
    file.ensure_writable do
      master_change_rpath(file, relocation.new_prefix, relocation.old_prefix)
    end
  end
end

::Benchmark.bm(8) do |b|
  b.report("PATCH") do
    elf_files.each do |file|
      file.ensure_writable do
        change_rpath(file, relocation.old_prefix, relocation.new_prefix)
      end
    end
  end
  rollback.call
  b.report("MASTER") do
    elf_files.each do |file|
      file.ensure_writable do
        master_change_rpath(file, relocation.old_prefix, relocation.new_prefix)
      end
    end
  end
  rollback.call
end

result:

➔ bin/brew install gcc
==> Installing dependencies for gcc: patchelf, gmp, mpfr, libmpc, isl@0.18 and zlib
==> Installing gcc dependency: patchelf
==> Downloading https://linuxbrew.bintray.com/bottles/patchelf-0.10.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/405227c46362964d2bc2e9ff6428fe082dff4dbd3a4b0b29453743f71923304b--patchelf-0.10.x86_64_linux.bottle.tar.gz
==> Pouring patchelf-0.10.x86_64_linux.bottle.tar.gz
Warning: This keg was marked linked already, continuing anyway
🍺  /home/david942j/brew-patch/Cellar/patchelf/0.10: 8 files, 921.5KB
==> Installing gcc dependency: gmp
==> Downloading https://linuxbrew.bintray.com/bottles/gmp-6.2.0.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/0bdf02541fafcf4086bb1c8cdb102c7759064428ae49a79b808ebf83cce490d1--gmp-6.2.0.x86_64_linux.bottle.tar.gz
==> Pouring gmp-6.2.0.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.008985   0.008436   0.026330 (  0.025696)
MASTER     0.000000   0.010567   0.037777 (  0.036347)
Warning: This keg was marked linked already, continuing anyway
🍺  /home/david942j/brew-patch/Cellar/gmp/6.2.0: 23 files, 3.9MB
==> Installing gcc dependency: mpfr
==> Downloading https://linuxbrew.bintray.com/bottles/mpfr-4.0.2.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/e1cafd8261512613dd2c8f348649b4ab6654c6290ad7be540d19c6cccd56acfc--mpfr-4.0.2.x86_64_linux.bottle.tar.gz
==> Pouring mpfr-4.0.2.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.008858   0.008431   0.022577 (  0.022230)
MASTER     0.003511   0.001828   0.020431 (  0.019791)
Warning: This keg was marked linked already, continuing anyway
🍺  /home/david942j/brew-patch/Cellar/mpfr/4.0.2: 29 files, 5.2MB
==> Installing gcc dependency: libmpc
==> Downloading https://linuxbrew.bintray.com/bottles/libmpc-1.1.0.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/366984cb086372edd145a2d6ac5a96b80ce5c6b2d77626722231ebf4a55de9e8--libmpc-1.1.0.x86_64_linux.bottle.tar.gz
==> Pouring libmpc-1.1.0.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.007910   0.003951   0.020186 (  0.020006)
MASTER     0.004897   0.000477   0.028342 (  0.027762)
Warning: This keg was marked linked already, continuing anyway
🍺  /home/david942j/brew-patch/Cellar/libmpc/1.1.0: 13 files, 1.5MB
==> Installing gcc dependency: isl@0.18
==> Downloading https://linuxbrew.bintray.com/bottles/isl@0.18-0.18.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/ac5bbc01c5aa0b49aa7415c5930ccd8b81a1329b7da248911faf2e06c128ba9c--isl@0.18-0.18.x86_64_linux.bottle.tar.gz
==> Pouring isl@0.18-0.18.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.005446   0.004756   0.016201 (  0.015960)
MASTER     0.006463   0.001281   0.037563 (  0.036914)
==> Caveats
isl@0.18 is keg-only, which means it was not symlinked into /home/david942j/brew-patch,
because this is an alternate version of another formula.

For compilers to find isl@0.18 you may need to set:
  export LDFLAGS="-L/home/david942j/brew-patch/opt/isl@0.18/lib"
  export CPPFLAGS="-I/home/david942j/brew-patch/opt/isl@0.18/include"

For pkg-config to find isl@0.18 you may need to set:
  export PKG_CONFIG_PATH="/home/david942j/brew-patch/opt/isl@0.18/lib/pkgconfig"

==> Summary
🍺  /home/david942j/brew-patch/Cellar/isl@0.18/0.18: 81 files, 6.4MB
==> Installing gcc dependency: zlib
==> Downloading https://linuxbrew.bintray.com/bottles/zlib-1.2.11.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/e26d7f94e9190e27f35a0ca17586414d88d5bb82ae7927206a18556eab619109--zlib-1.2.11.x86_64_linux.bottle.tar.gz
==> Pouring zlib-1.2.11.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      0.008980   0.002323   0.014102 (  0.013857)
MASTER     0.003542   0.001964   0.018557 (  0.017859)
Warning: This keg was marked linked already, continuing anyway
🍺  /home/david942j/brew-patch/Cellar/zlib/1.2.11: 12 files, 424.0KB
==> Installing gcc
==> Downloading https://linuxbrew.bintray.com/bottles/gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
Already downloaded: /home/david942j/.cache/Homebrew/downloads/b91d14d1e15ddd20f9b3114d36aa006c86f2ecf8aa07e5c328ab950e9b4c40f8--gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
==> Pouring gcc-5.5.0_7.x86_64_linux.bottle.tar.gz
               user     system      total        real
PATCH      3.765572   1.456532   5.434032 (  5.426521)
MASTER     0.022669   0.248940   1.514552 (  1.481219)
Warning: This keg was marked linked already, continuing anyway
==> Creating the GCC specs file: /home/david942j/brew-patch/Cellar/gcc/5.5.0_7/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.5.0/sp
🍺  /home/david942j/brew-patch/Cellar/gcc/5.5.0_7: 1,350 files, 185.4MB

So the Ruby ver is around ~4 times slower than patchelf. I feel it's a reasonable and acceptable difference since string manipulations in Ruby is expected to be much slower than pure C in this scale.

@rmNULL rmNULL marked this pull request as draft August 14, 2020 00:29
@rmNULL rmNULL force-pushed the linux-shelless-elftools branch from c1ce2b7 to 7a8de09 Compare August 15, 2020 21:22
Copy link
Contributor

@sjackman sjackman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submodule patchelf.rb-3a4fe5e8d35c added at 3a4fe5

No Git submodules, please. We don't use submodules in Homebrew/brew.

$ git submodule init
fatal: No url found for submodule path 'Library/Homebrew/vendor/bundle/ruby/2.6.0/bundler/gems/patchelf.rb-3a4fe5e8d35c' in .gitmodules

.gitmodules is also missing.

@@ -21,7 +21,7 @@ gem "tapioca"
gem "activesupport"
gem "concurrent-ruby"
gem "mechanize"
gem "patchelf"
gem "patchelf", git: "https://github.com/rmnull/patchelf.rb", ref: "3a4fe5e8"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be bumped to the latest work on david942j/patchelf.rb#28, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, working on it, ditching few commits, plus i'm not sure whether we wait for upstream to merge.
and then vendor it.
i think we better for @sjackman

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, working on it, ditching few commits, plus i'm not sure whether we wait for upstream to merge.
and then vendor it.

Let's keep this PR up-to-date with your branch. Once upstream merges it, we can vendor here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

@rmNULL rmNULL force-pushed the linux-shelless-elftools branch 4 times, most recently from b05b7a9 to 05fd281 Compare August 26, 2020 17:28
@sjackman sjackman requested a review from MikeMcQuaid August 26, 2020 21:10
@sjackman
Copy link
Contributor

sjackman commented Aug 26, 2020

@MikeMcQuaid Could you please give this PR a re-review when you have a chance?

This PR will be changed to use vendored Gems once PR david942j/patchelf.rb#28 is merged.

@rmNULL
Copy link
Contributor Author

rmNULL commented Aug 27, 2020

Instructions to test the bottling of PR

docker run -it --rm homebrew/brew

Once you are in docker running this command should be do the trick.

curl "https://gist.githubusercontent.com/rmNULL/f0cbb96dcbd60601f7aacc15b80d6dce/raw/ea70d8eeda4b77421ada10754753bf6a8dbb59f3/env-setup-bi-bottle-test.sh" | bash -

Reference

Quirks

the script my stop on first run, if that happens, please run it again.

@MikeMcQuaid
Copy link
Member

@MikeMcQuaid Could you please give this PR a re-review when you have a chance?

@sjackman I will this time but, in general, I don't think there's a huge amount of point reviewing PRs with failing CI.

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits but looking good otherwise.

@@ -21,7 +21,7 @@ gem "tapioca"
gem "activesupport"
gem "concurrent-ruby"
gem "mechanize"
gem "patchelf"
gem "patchelf", git: "https://github.com/rmnull/patchelf.rb", branch: "for-brew"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: don't merge until this is merged upstream.

Verified

This commit was signed with the committer’s verified signature.
mkmik Marko Mikulicic
@rmNULL rmNULL force-pushed the linux-shelless-elftools branch from 1757a50 to 649e02b Compare August 27, 2020 17:27
@rmNULL rmNULL marked this pull request as ready for review August 27, 2020 18:08
@MikeMcQuaid MikeMcQuaid merged commit f908b35 into Homebrew:master Aug 28, 2020
@MikeMcQuaid
Copy link
Member

Thanks again @rmNULL!

@sjackman
Copy link
Contributor

Good show! Congratulations on completing this work, rmNull! 🏆

@BrewTestBot BrewTestBot added the outdated PR was locked due to age label Dec 14, 2020
@Homebrew Homebrew locked as resolved and limited conversation to collaborators Dec 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
gsoc-outreachy Google Summer of Code or Outreachy outdated PR was locked due to age
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants