From 6a0a1992f50764b53ae8bae35ed044788ddd4219 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 27 Aug 2020 12:45:31 +0000 Subject: [PATCH 1/2] Bump patchelf from 1.2.0 to 1.3.0 in /Library/Homebrew Bumps [patchelf](https://github.com/david942j/patchelf.rb) from 1.2.0 to 1.3.0. - [Release notes](https://github.com/david942j/patchelf.rb/releases) - [Commits](https://github.com/david942j/patchelf.rb/commits) Signed-off-by: dependabot-preview[bot] --- Library/Homebrew/Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock index 8f59318000..bac57c96fe 100644 --- a/Library/Homebrew/Gemfile.lock +++ b/Library/Homebrew/Gemfile.lock @@ -23,7 +23,7 @@ GEM docile (1.3.2) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - elftools (1.1.2) + elftools (1.1.3) bindata (~> 2) highline (2.0.3) hpricot (0.8.6) @@ -64,8 +64,8 @@ GEM sorbet-runtime (>= 0.5) parser (2.7.1.4) ast (~> 2.4.1) - patchelf (1.2.0) - elftools (~> 1.1) + patchelf (1.3.0) + elftools (>= 1.1.3) plist (3.5.0) pry (0.13.1) coderay (~> 1.1) From 180d523979e760bbee08adfd192947a0848805d8 Mon Sep 17 00:00:00 2001 From: Jonathan Chang Date: Thu, 27 Aug 2020 23:21:10 +1000 Subject: [PATCH 2/2] brew vendor-gems: commit updates. --- .../Homebrew/vendor/bundle/bundler/setup.rb | 4 +- .../lib/elftools.rb | 0 .../lib/elftools/constants.rb | 17 + .../lib/elftools/dynamic.rb | 0 .../lib/elftools/elf_file.rb | 2 +- .../lib/elftools/exceptions.rb | 0 .../lib/elftools/lazy_array.rb | 0 .../lib/elftools/note.rb | 0 .../lib/elftools/sections/dynamic_section.rb | 0 .../lib/elftools/sections/note_section.rb | 0 .../lib/elftools/sections/null_section.rb | 0 .../elftools/sections/relocation_section.rb | 0 .../lib/elftools/sections/section.rb | 0 .../lib/elftools/sections/sections.rb | 0 .../lib/elftools/sections/str_tab_section.rb | 0 .../lib/elftools/sections/sym_tab_section.rb | 0 .../lib/elftools/segments/dynamic_segment.rb | 0 .../lib/elftools/segments/interp_segment.rb | 0 .../lib/elftools/segments/load_segment.rb | 0 .../lib/elftools/segments/note_segment.rb | 0 .../lib/elftools/segments/segment.rb | 0 .../lib/elftools/segments/segments.rb | 0 .../lib/elftools/structs.rb | 0 .../lib/elftools/util.rb | 0 .../lib/elftools/version.rb | 2 +- .../lib/patchelf.rb | 0 .../patchelf-1.3.0/lib/patchelf/alt_saver.rb | 831 ++++++++++++++++++ .../lib/patchelf/cli.rb | 0 .../lib/patchelf/exceptions.rb | 0 .../lib/patchelf/helper.rb | 0 .../lib/patchelf/logger.rb | 2 +- .../lib/patchelf/mm.rb | 0 .../lib/patchelf/patcher.rb | 11 +- .../lib/patchelf/saver.rb | 31 +- .../lib/patchelf/version.rb | 2 +- 35 files changed, 877 insertions(+), 25 deletions(-) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/constants.rb (96%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/dynamic.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/elf_file.rb (99%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/exceptions.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/lazy_array.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/note.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/sections/dynamic_section.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/sections/note_section.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/sections/null_section.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/sections/relocation_section.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/sections/section.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/sections/sections.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/sections/str_tab_section.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/sections/sym_tab_section.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/segments/dynamic_segment.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/segments/interp_segment.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/segments/load_segment.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/segments/note_segment.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/segments/segment.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/segments/segments.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/structs.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/util.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{elftools-1.1.2 => elftools-1.1.3}/lib/elftools/version.rb (78%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf.rb (100%) create mode 100644 Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/alt_saver.rb rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf/cli.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf/exceptions.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf/helper.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf/logger.rb (90%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf/mm.rb (100%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf/patcher.rb (93%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf/saver.rb (93%) rename Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/{patchelf-1.2.0 => patchelf-1.3.0}/lib/patchelf/version.rb (73%) diff --git a/Library/Homebrew/vendor/bundle/bundler/setup.rb b/Library/Homebrew/vendor/bundle/bundler/setup.rb index 1ced058a45..2476b5edec 100644 --- a/Library/Homebrew/vendor/bundle/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle/bundler/setup.rb @@ -31,7 +31,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwi $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unf_ext-0.0.7.7/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unf-0.1.4/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/domain_name-0.5.20190701/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/elftools-1.1.2/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/elftools-1.1.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/hpricot-0.8.6" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/hpricot-0.8.6/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/http-cookie-1.0.3/lib" @@ -53,7 +53,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parser-2.7.1.4/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rainbow-3.0.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-0.5.5880/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parlour-4.0.1/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/patchelf-1.2.0/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/patchelf-1.3.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/plist-3.5.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/pry-0.13.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/rdiscount-2.2.0.2" diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/constants.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/constants.rb similarity index 96% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/constants.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/constants.rb index 197ec969d0..35ee1939ca 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/constants.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/constants.rb @@ -95,6 +95,7 @@ module ELFTools DT_VERDEF = 0x6ffffffc # address of version definition table DT_VERDEFNUM = 0x6ffffffd # number of entries in {DT_VERDEF} DT_VERNEED = 0x6ffffffe # address of version dependency table + DT_VERSYM = 0x6ffffff0 # section address of .gnu.version DT_VERNEEDNUM = 0x6fffffff # number of entries in {DT_VERNEED} # Values between {DT_LOPROC} and {DT_HIPROC} are reserved for processor-specific semantics. DT_LOPROC = 0x70000000 @@ -212,6 +213,14 @@ module ELFTools end include ET + # Program header permission flags, records bitwise OR value in +p_flags+. + module PF + PF_X = 1 + PF_W = 2 + PF_R = 4 + end + include PF + # Program header types, records in +p_type+. module PT PT_NULL = 0 # null segment @@ -233,6 +242,14 @@ module ELFTools end include PT + # Special indices to section. These are used when there is no valid index to section header. + # The meaning of these values is left upto the embedding header. + module SHN + SHN_UNDEF = 0 # undefined section + SHN_LORESERVE = 0xff00 # start of reserved indices + end + include SHN + # Section header types, records in +sh_type+. module SHT SHT_NULL = 0 # null section diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/dynamic.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/dynamic.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/dynamic.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/dynamic.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/elf_file.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/elf_file.rb similarity index 99% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/elf_file.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/elf_file.rb index 3b58d27330..5f6fa229e0 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/elf_file.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/elf_file.rb @@ -56,7 +56,7 @@ module ELFTools note = section.notes.first return nil if note.nil? - note.desc.unpack('H*').first + note.desc.unpack1('H*') end # Get machine architecture. diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/exceptions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/exceptions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/exceptions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/exceptions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/lazy_array.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/lazy_array.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/lazy_array.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/lazy_array.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/note.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/note.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/note.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/note.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/dynamic_section.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/dynamic_section.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/dynamic_section.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/dynamic_section.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/note_section.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/note_section.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/note_section.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/note_section.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/null_section.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/null_section.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/null_section.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/null_section.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/relocation_section.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/relocation_section.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/relocation_section.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/relocation_section.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/section.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/section.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/section.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/section.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/sections.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/sections.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/sections.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/sections.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/str_tab_section.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/str_tab_section.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/str_tab_section.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/str_tab_section.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/sym_tab_section.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/sym_tab_section.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/sections/sym_tab_section.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/sections/sym_tab_section.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/dynamic_segment.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/dynamic_segment.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/dynamic_segment.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/dynamic_segment.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/interp_segment.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/interp_segment.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/interp_segment.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/interp_segment.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/load_segment.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/load_segment.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/load_segment.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/load_segment.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/note_segment.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/note_segment.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/note_segment.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/note_segment.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/segment.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/segment.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/segment.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/segment.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/segments.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/segments.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/segments/segments.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/segments/segments.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/structs.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/structs.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/structs.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/structs.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/util.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/util.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/util.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/util.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/version.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/version.rb similarity index 78% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/version.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/version.rb index 1108d841fc..243f277a3f 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.2/lib/elftools/version.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib/elftools/version.rb @@ -2,5 +2,5 @@ module ELFTools # Current gem version - VERSION = '1.1.2' + VERSION = '1.1.3' end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/alt_saver.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/alt_saver.rb new file mode 100644 index 0000000000..6f256995d9 --- /dev/null +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/alt_saver.rb @@ -0,0 +1,831 @@ +# frozen_string_literal: true + +require 'elftools/constants' +require 'elftools/elf_file' +require 'elftools/structs' +require 'elftools/util' +require 'fileutils' + +require 'patchelf/helper' + +#:nodoc: +module PatchELF + # TODO: refactor buf_* methods here + # TODO: move all refinements into a seperate file / helper file. + # refinements for cleaner syntax / speed / memory optimizations + module Refinements + refine StringIO do + # behaves like C memset. Equivalent to calling stream.write(char * nbytes) + # the benefit of preferring this over `stream.write(char * nbytes)` is only when data to be written is large. + # @param [String] char + # @param [Integer] nbytes + # @return[void] + def fill(char, nbytes) + at_once = Helper::PAGE_SIZE + pending = nbytes + + if pending > at_once + to_write = char * at_once + while pending >= at_once + write(to_write) + pending -= at_once + end + end + write(char * pending) if pending.positive? + end + end + end + using Refinements + + # Internal use only. + # alternative to +Saver+, that aims to be byte to byte equivalent with NixOS/patchelf. + # + # *DISCLAIMER*: This differs from +Saver+ in number of ways. No lazy reading, + # inconsistent use of existing internal API(e.g: manual reading of data instead of calling +section.data+) + # @private + class AltSaver + attr_reader :in_file # @return [String] Input filename. + attr_reader :out_file # @return [String] Output filename. + + # Instantiate a {AltSaver} object. + # the params passed are the same as the ones passed to +Saver+ + # @param [String] in_file + # @param [String] out_file + # @param [{Symbol => String, Array}] set + def initialize(in_file, out_file, set) + @in_file = in_file + @out_file = out_file + @set = set + + f = File.open(in_file, 'rb') + # the +@buffer+ and +@elf+ both could work on same +StringIO+ stream, + # the updating of @buffer in place blocks us from looking up old values. + # TODO: cache the values needed later, use same stream for +@buffer+ and +@elf+. + # also be sure to update the stream offset passed to Segments::Segment. + @elf = ELFTools::ELFFile.new(f) + @buffer = StringIO.new(f.tap(&:rewind).read) # StringIO makes easier to work with Bindata + + @ehdr = @elf.header + @endian = @elf.endian + @elf_class = @elf.elf_class + + @segments = @elf.segments # usage similar to phdrs + @sections = @elf.sections # usage similar to shdrs + update_section_idx! + + # {String => String} + # section name to its data mapping + @replaced_sections = {} + @section_alignment = ehdr.e_phoff.num_bytes + + # using the same environment flag as patchelf, makes it easier for debugging + Logger.level = ::Logger.const_get(ENV['PATCHELF_DEBUG'] ? :DEBUG : :WARN) + end + + # @return [void] + def save! + @set.each { |mtd, val| send(:"modify_#{mtd}") if val } + rewrite_sections + + FileUtils.cp(in_file, out_file) if out_file != in_file + patch_out + # Let output file have the same permission as input. + FileUtils.chmod(File.stat(in_file).mode, out_file) + end + + private + + attr_reader :ehdr, :endian, :elf_class + + def old_sections + @old_sections ||= @elf.sections + end + + def buf_cstr(off) + cstr = [] + with_buf_at(off) do |buf| + loop do + c = buf.read 1 + break if c.nil? || c == "\x00" + + cstr.push c + end + end + cstr.join + end + + def buf_move!(dst_idx, src_idx, n_bytes) + with_buf_at(src_idx) do |buf| + to_write = buf.read(n_bytes) + buf.seek dst_idx + buf.write to_write + end + end + + def dynstr + find_section '.dynstr' + end + + # yields dynamic tag, and offset in buffer + def each_dynamic_tags + return unless block_given? + + sec = find_section '.dynamic' + return unless sec + + shdr = sec.header + with_buf_at(shdr.sh_offset) do |buf| + dyn = ELFTools::Structs::ELF_Dyn.new(elf_class: elf_class, endian: endian) + loop do + buf_dyn_offset = buf.tell + dyn.clear + dyn.read(buf) + break if dyn.d_tag == ELFTools::Constants::DT_NULL + + yield dyn, buf_dyn_offset + # there's a possibility for caller to modify @buffer.pos, seek to avoid such issues + buf.seek buf_dyn_offset + dyn.num_bytes + end + end + end + + # the idea of uniquely identifying section by its name has its problems + # but this is how patchelf operates and is prone to bugs. + # e.g: https://github.com/NixOS/patchelf/issues/197 + def find_section(sec_name) + idx = find_section_idx sec_name + return unless idx + + @sections[idx] + end + + def find_section_idx(sec_name) + @section_idx_by_name[sec_name] + end + + def buf_grow!(newsz) + bufsz = @buffer.size + return if newsz <= bufsz + + @buffer.truncate newsz + end + + def modify_interpreter + @replaced_sections['.interp'] = @set[:interpreter] + "\x00" + end + + def modify_needed + # due to gsoc time constraints only implmenting features used by brew. + raise NotImplementedError + end + + # not checking for nil as modify_rpath is only called if @set[:rpath] + def modify_rpath + modify_rpath_helper @set[:rpath], force_rpath: true + end + + # not checking for nil as modify_runpath is only called if @set[:runpath] + def modify_runpath + modify_rpath_helper @set[:runpath] + end + + def collect_runpath_tags + tags = {} + each_dynamic_tags do |dyn, off| + case dyn.d_tag + when ELFTools::Constants::DT_RPATH + tag_type = :rpath + when ELFTools::Constants::DT_RUNPATH + tag_type = :runpath + else + next + end + + # clone does shallow copy, and for some reason d_tag and d_val can't be pass as argument + dyn_rpath = ELFTools::Structs::ELF_Dyn.new(endian: endian, elf_class: elf_class) + dyn_rpath.assign({ d_tag: dyn.d_tag.to_i, d_val: dyn.d_val.to_i }) + tags[tag_type] = { offset: off, header: dyn_rpath } + end + tags + end + + def resolve_rpath_tag_conflict(dyn_tags, force_rpath: false) + dyn_runpath, dyn_rpath = dyn_tags.values_at(:runpath, :rpath) + + update_sym = + if !force_rpath && dyn_rpath && dyn_runpath.nil? + :runpath + elsif force_rpath && dyn_runpath + :rpath + end + return unless update_sym + + delete_sym, = %i[rpath runpath] - [update_sym] + dyn_tag = dyn_tags[update_sym] = dyn_tags[delete_sym] + dyn = dyn_tag[:header] + dyn.d_tag = ELFTools::Constants.const_get("DT_#{update_sym.upcase}") + with_buf_at(dyn_tag[:offset]) { |buf| dyn.write(buf) } + dyn_tags.delete(delete_sym) + end + + def modify_rpath_helper(new_rpath, force_rpath: false) + shdr_dynstr = dynstr.header + + dyn_tags = collect_runpath_tags + resolve_rpath_tag_conflict(dyn_tags, force_rpath: force_rpath) + # (:runpath, :rpath) order_matters. + resolved_rpath_dyns = dyn_tags.values_at(:runpath, :rpath).compact + + old_rpath = '' + rpath_off = nil + resolved_rpath_dyns.each do |dyn| + rpath_off = shdr_dynstr.sh_offset + dyn[:header].d_val + old_rpath = buf_cstr(rpath_off) + break + end + return if old_rpath == new_rpath + + with_buf_at(rpath_off) { |b| b.write('X' * old_rpath.size) } if rpath_off + if new_rpath.size <= old_rpath.size + with_buf_at(rpath_off) { |b| b.write "#{new_rpath}\x00" } + return + end + + Logger.debug 'rpath is too long, resizing...' + new_dynstr = replace_section '.dynstr', shdr_dynstr.sh_size + new_rpath.size + 1 + new_rpath_strtab_idx = shdr_dynstr.sh_size.to_i + new_dynstr[new_rpath_strtab_idx..(new_rpath_strtab_idx + new_rpath.size)] = "#{new_rpath}\x00" + + dyn_tags.each do |_, dyn| + dyn[:header].d_val = new_rpath_strtab_idx + with_buf_at(dyn[:offset]) { |b| dyn[:header].write(b) } + end + + return unless dyn_tags.empty? + + add_dt_rpath!( + d_tag: force_rpath ? ELFTools::Constants::DT_RPATH : ELFTools::Constants::DT_RUNPATH, + d_val: new_rpath_strtab_idx + ) + end + + def modify_soname + return unless ehdr.e_type == ELFTools::Constants::ET_DYN + + # due to gsoc time constraints only implmenting features used by brew. + raise NotImplementedError + end + + def add_segment!(**phdr_vals) + new_phdr = ELFTools::Structs::ELF_Phdr[elf_class].new(endian: endian, **phdr_vals) + # nil = no reference to stream; we only want @segments[i].header + new_segment = ELFTools::Segments::Segment.new(new_phdr, nil) + @segments.push new_segment + ehdr.e_phnum += 1 + nil + end + + def add_dt_rpath!(d_tag: nil, d_val: nil) + dyn_num_bytes = nil + dt_null_idx = 0 + each_dynamic_tags do |dyn| + dyn_num_bytes ||= dyn.num_bytes + dt_null_idx += 1 + end + + # allot for new dt_runpath + shdr_dynamic = find_section('.dynamic').header + new_dynamic_data = replace_section '.dynamic', shdr_dynamic.sh_size + dyn_num_bytes + + # consider DT_NULL when copying + replacement_size = (dt_null_idx + 1) * dyn_num_bytes + + # make space for dt_runpath tag at the top, shift data by one tag positon + new_dynamic_data[dyn_num_bytes..(replacement_size + dyn_num_bytes)] = new_dynamic_data[0..replacement_size] + + dyn_rpath = ELFTools::Structs::ELF_Dyn.new endian: endian, elf_class: elf_class + dyn_rpath.d_tag = d_tag + dyn_rpath.d_val = d_val + + zi = StringIO.new + dyn_rpath.write zi + zi.rewind + new_dynamic_data[0...dyn_num_bytes] = zi.read + end + + # given a index into old_sections table + # returns the corresponding section index in @sections + # + # raises ArgumentError if old_shndx can't be found in old_sections + # TODO: handle case of non existing section in (new) @sections. + def new_section_idx(old_shndx) + return if old_shndx == ELFTools::Constants::SHN_UNDEF || old_shndx >= ELFTools::Constants::SHN_LORESERVE + + raise ArgumentError if old_shndx >= old_sections.count + + old_sec = old_sections[old_shndx] + raise PatchError, "old_sections[#{shndx}] is nil" if old_sec.nil? + + # TODO: handle case of non existing section in (new) @sections. + find_section_idx(old_sec.name) + end + + def page_size + Helper::PAGE_SIZE + end + + def patch_out + with_buf_at(0) { |b| ehdr.write(b) } + + File.open(out_file, 'wb') do |f| + @buffer.rewind + f.write @buffer.read + end + end + + # size includes NUL byte + def replace_section(section_name, size) + data = @replaced_sections[section_name] + unless data + shdr = find_section(section_name).header + # avoid calling +section.data+ as the @buffer contents may vary from + # the stream provided to section at initialization. + # ideally, calling section.data should work, however avoiding it to prevent + # future traps. + with_buf_at(shdr.sh_offset) { |b| data = b.read shdr.sh_size } + end + rep_data = if data.size == size + data + elsif data.size < size + data.ljust(size, "\x00") + else + data[0...size] + "\x00" + end + @replaced_sections[section_name] = rep_data + end + + def write_phdrs_to_buf! + sort_phdrs! + with_buf_at(ehdr.e_phoff) do |buf| + @segments.each { |seg| seg.header.write(buf) } + end + end + + def write_shdrs_to_buf! + raise PatchError, 'ehdr.e_shnum != @sections.count' if ehdr.e_shnum != @sections.count + + sort_shdrs! + with_buf_at(ehdr.e_shoff) do |buf| + @sections.each { |section| section.header.write(buf) } + end + sync_dyn_tags! + end + + # data for manual packing and unpacking of symbols in symtab sections. + def meta_sym_pack + return @meta_sym_pack if @meta_sym_pack + + # resort to manual packing and unpacking of data, + # as using bindata is painfully slow :( + if elf_class == 32 + sym_num_bytes = 16 # u32 u32 u32 u8 u8 u16 + pack_code = endian == :little ? 'VVVCCv' : 'NNNCCn' + pack_st_info = 3 + pack_st_shndx = 5 + pack_st_value = 1 + else # 64 + sym_num_bytes = 24 # u32 u8 u8 u16 u64 u64 + pack_code = endian == :little ? 'VCCvQQ>' + pack_st_info = 1 + pack_st_shndx = 3 + pack_st_value = 4 + end + + @meta_sym_pack = { + num_bytes: sym_num_bytes, code: pack_code, + st_info: pack_st_info, st_shndx: pack_st_shndx, st_value: pack_st_value + } + end + + # yields +symbol+, +entry+ + def each_symbol(shdr) + return unless [ELFTools::Constants::SHT_SYMTAB, ELFTools::Constants::SHT_DYNSYM].include?(shdr.sh_type) + + pack_code, sym_num_bytes = meta_sym_pack.values_at(:code, :num_bytes) + + with_buf_at(shdr.sh_offset) do |buf| + num_symbols = shdr.sh_size / sym_num_bytes + num_symbols.times do |entry| + sym = buf.read(sym_num_bytes).unpack(pack_code) + sym_modified = yield sym, entry + + if sym_modified + buf.seek buf.tell - sym_num_bytes + buf.write sym.pack(pack_code) + end + end + end + end + + def rewrite_headers(phdr_address) + # there can only be a single program header table according to ELF spec + @segments.find { |seg| seg.header.p_type == ELFTools::Constants::PT_PHDR }&.tap do |seg| + phdr = seg.header + phdr.p_offset = ehdr.e_phoff.to_i + phdr.p_vaddr = phdr.p_paddr = phdr_address.to_i + phdr.p_filesz = phdr.p_memsz = phdr.num_bytes * @segments.count # e_phentsize * e_phnum + end + write_phdrs_to_buf! + write_shdrs_to_buf! + + pack = meta_sym_pack + @sections.each do |sec| + each_symbol(sec.header) do |sym, entry| + old_shndx = sym[pack[:st_shndx]] + + begin + new_index = new_section_idx(old_shndx) + next unless new_index + rescue ArgumentError + Logger.warn "entry #{entry} in symbol table refers to a non existing section, skipping" + end + + sym[pack[:st_shndx]] = new_index + + # right 4 bits in the st_info field is st_type + if (sym[pack[:st_info]] & 0xF) == ELFTools::Constants::STT_SECTION + sym[pack[:st_value]] = @sections[new_index].header.sh_addr.to_i + end + true + end + end + end + + def rewrite_sections + return if @replaced_sections.empty? + + case ehdr.e_type + when ELFTools::Constants::ET_DYN + rewrite_sections_library + when ELFTools::Constants::ET_EXEC + rewrite_sections_executable + else + raise PatchError, 'unknown ELF type' + end + end + + def replaced_section_indices + return enum_for(:replaced_section_indices) unless block_given? + + last_replaced = 0 + @sections.each_with_index do |sec, idx| + if @replaced_sections[sec.name] + last_replaced = idx + yield last_replaced + end + end + raise PatchError, 'last_replaced = 0' if last_replaced.zero? + raise PatchError, 'last_replaced + 1 >= @sections.size' if last_replaced + 1 >= @sections.size + end + + def start_replacement_shdr + last_replaced = replaced_section_indices.max + start_replacement_hdr = @sections[last_replaced + 1].header + + prev_sec_name = '' + (1..last_replaced).each do |idx| + sec = @sections[idx] + shdr = sec.header + if (sec.type == ELFTools::Constants::SHT_PROGBITS && sec.name != '.interp') || prev_sec_name == '.dynstr' + start_replacement_hdr = shdr + break + elsif @replaced_sections[sec.name].nil? + Logger.debug " replacing section #{sec.name} which is in the way" + replace_section(sec.name, shdr.sh_size) + end + prev_sec_name = sec.name + end + + start_replacement_hdr + end + + def copy_shdrs_to_eof + shoff_new = @buffer.size + # honestly idk why `ehdr.e_shoff` is considered when we are only moving shdrs. + sh_size = ehdr.e_shoff + ehdr.e_shnum * ehdr.e_shentsize + buf_grow! @buffer.size + sh_size + ehdr.e_shoff = shoff_new + raise PatchError, 'ehdr.e_shnum != @sections.size' if ehdr.e_shnum != @sections.size + + with_buf_at(ehdr.e_shoff + @sections.first.header.num_bytes) do |buf| # skip writing to NULL section + @sections.each_with_index do |sec, idx| + next if idx.zero? + + sec.header.write buf + end + end + end + + def rewrite_sections_executable + sort_shdrs! + shdr = start_replacement_shdr + start_offset = shdr.sh_offset + start_addr = shdr.sh_addr + first_page = start_addr - start_offset + + Logger.debug "first reserved offset/addr is 0x#{start_offset.to_i.to_s 16}/0x#{start_addr.to_i.to_s 16}" + + unless start_addr % page_size == start_offset % page_size + raise PatchError, 'start_addr != start_offset (mod PAGE_SIZE)' + end + + Logger.debug "first page is 0x#{first_page.to_i.to_s 16}" + + copy_shdrs_to_eof if ehdr.e_shoff < start_offset + + seg_num_bytes = @segments.first.header.num_bytes + needed_space = ( + ehdr.num_bytes + + (@segments.count * seg_num_bytes) + + @replaced_sections.sum { |_, str| Helper.alignup(str.size, @section_alignment) } + ) + + if needed_space > start_offset + needed_space += seg_num_bytes # new load segment is required + + needed_pages = Helper.alignup(needed_space - start_offset, page_size) / page_size + Logger.debug "needed pages is #{needed_pages}" + raise PatchError, 'virtual address space underrun' if needed_pages * page_size > first_page + + first_page -= needed_pages * page_size + start_offset += needed_pages * page_size + + shift_file(needed_pages, first_page) + end + Logger.debug "needed space is #{needed_space}" + + cur_off = ehdr.num_bytes + (@segments.count * seg_num_bytes) + Logger.debug "clearing first #{start_offset - cur_off} bytes" + with_buf_at(cur_off) { |buf| buf.fill("\x00", (start_offset - cur_off)) } + + cur_off = write_replaced_sections cur_off, first_page, 0 + raise PatchError, "cur_off(#{cur_off}) != needed_space" if cur_off != needed_space + + rewrite_headers first_page + ehdr.e_phoff + end + + def replace_sections_in_the_way_of_phdr! + pht_size = ehdr.num_bytes + (@segments.count + 1) * @segments.first.header.num_bytes + + # replace sections that may overlap with expanded program header table + @sections.each_with_index do |sec, idx| + shdr = sec.header + next if idx.zero? || @replaced_sections[sec.name] + break if shdr.sh_addr > pht_size + + replace_section sec.name, shdr.sh_size + end + end + + def seg_end_addr(seg) + phdr = seg.header + Helper.alignup(phdr.p_vaddr + phdr.p_memsz, page_size) + end + + def rewrite_sections_library + start_page = seg_end_addr(@segments.max_by(&method(:seg_end_addr))) + + Logger.debug "Last page is 0x#{start_page.to_s 16}" + replace_sections_in_the_way_of_phdr! + needed_space = @replaced_sections.sum { |_, str| Helper.alignup(str.size, @section_alignment) } + Logger.debug "needed space = #{needed_space}" + + start_offset = Helper.alignup(@buffer.size, page_size) + buf_grow! start_offset + needed_space + + # executable shared object + if start_offset > start_page && @segments.any? { |seg| seg.header.p_type == ELFTools::Constants::PT_INTERP } + Logger.debug( + "shifting new PT_LOAD segment by #{start_offset - start_page} bytes to work around a Linux kernel bug" + ) + start_page = start_offset + end + + ehdr.e_phoff = ehdr.num_bytes + add_segment!( + p_type: ELFTools::Constants::PT_LOAD, + p_offset: start_offset, + p_vaddr: start_page, + p_paddr: start_page, + p_filesz: needed_space, + p_memsz: needed_space, + p_flags: ELFTools::Constants::PF_R | ELFTools::Constants::PF_W, + p_align: page_size + ) + + cur_off = write_replaced_sections start_offset, start_page, start_offset + raise PatchError, 'cur_off != start_offset + needed_space' if cur_off != start_offset + needed_space + + rewrite_headers ehdr.e_phoff + end + + def shift_file(extra_pages, start_page) + oldsz = @buffer.size + shift = extra_pages * page_size + buf_grow!(oldsz + shift) + buf_move! shift, 0, oldsz + with_buf_at(ehdr.num_bytes) { |buf| buf.write "\x00" * (shift - ehdr.num_bytes) } + + ehdr.e_phoff = ehdr.num_bytes + ehdr.e_shoff = ehdr.e_shoff + shift + + @sections.each_with_index do |sec, i| + next if i.zero? # dont touch NULL section + + shdr = sec.header + shdr.sh_offset += shift + end + + @segments.each do |seg| + phdr = seg.header + phdr.p_offset += shift + phdr.p_align = page_size if phdr.p_align != 0 && (phdr.p_vaddr - phdr.p_offset) % phdr.p_align != 0 + end + + add_segment!( + p_type: ELFTools::Constants::PT_LOAD, + p_offset: 0, + p_vaddr: start_page, + p_paddr: start_page, + p_filesz: shift, + p_memsz: shift, + p_flags: ELFTools::Constants::PF_R | ELFTools::Constants::PF_W, + p_align: page_size + ) + end + + def sort_phdrs! + pt_phdr = ELFTools::Constants::PT_PHDR + @segments.sort! do |me, you| + next 1 if you.header.p_type == pt_phdr + next -1 if me.header.p_type == pt_phdr + + me.header.p_paddr.to_i <=> you.header.p_paddr.to_i + end + end + + # section headers may contain sh_info and sh_link values that are + # references to another section + def collect_section_to_section_refs + rel_syms = [ELFTools::Constants::SHT_REL, ELFTools::Constants::SHT_RELA] + # Translate sh_link, sh_info mappings to section names. + @sections.each_with_object({ linkage: {}, info: {} }) do |s, collected| + hdr = s.header + collected[:linkage][s.name] = @sections[hdr.sh_link].name if hdr.sh_link.nonzero? + collected[:info][s.name] = @sections[hdr.sh_info].name if hdr.sh_info.nonzero? && rel_syms.include?(hdr.sh_type) + end + end + + # @param collected + # this must be the value returned by +collect_section_to_section_refs+ + def restore_section_to_section_refs!(collected) + rel_syms = [ELFTools::Constants::SHT_REL, ELFTools::Constants::SHT_RELA] + linkage, info = collected.values_at(:linkage, :info) + @sections.each do |sec| + hdr = sec.header + hdr.sh_link = find_section_idx(linkage[sec.name]) if hdr.sh_link.nonzero? + hdr.sh_info = find_section_idx(info[sec.name]) if hdr.sh_info.nonzero? && rel_syms.include?(hdr.sh_type) + end + end + + def sort_shdrs! + section_dep_values = collect_section_to_section_refs + shstrtab_name = @sections[ehdr.e_shstrndx].name + @sections.sort! { |me, you| me.header.sh_offset.to_i <=> you.header.sh_offset.to_i } + update_section_idx! + restore_section_to_section_refs!(section_dep_values) + ehdr.e_shstrndx = find_section_idx shstrtab_name + end + + # given a +dyn.d_tag+, returns the section name it must be synced to. + # it may return nil, when given tag maps to no section, + # or when its okay to skip if section is not found. + def dyn_tag_to_section_name(d_tag) + case d_tag + when ELFTools::Constants::DT_STRTAB, ELFTools::Constants::DT_STRSZ + '.dynstr' + when ELFTools::Constants::DT_SYMTAB + '.dynsym' + when ELFTools::Constants::DT_HASH + '.hash' + when ELFTools::Constants::DT_GNU_HASH + '.gnu.hash' + when ELFTools::Constants::DT_JMPREL + sec_name = %w[.rel.plt .rela.plt .rela.IA_64.pltoff].find { |s| find_section(s) } + raise PatchError, 'cannot find section corresponding to DT_JMPREL' unless sec_name + + sec_name + when ELFTools::Constants::DT_REL + # regarding .rel.got, NixOS/patchelf says + # "no idea if this makes sense, but it was needed for some program" + # + # return nil if not found, patchelf claims no problem in skipping + %w[.rel.dyn .rel.got].find { |s| find_section(s) } + when ELFTools::Constants::DT_RELA + # return nil if not found, patchelf claims no problem in skipping + find_section('.rela.dyn')&.name + when ELFTools::Constants::DT_VERNEED + '.gnu.version_r' + when ELFTools::Constants::DT_VERSYM + '.gnu.version' + end + end + + # updates dyn tags by syncing it with @section values + def sync_dyn_tags! + each_dynamic_tags do |dyn, buf_off| + sec_name = dyn_tag_to_section_name(dyn.d_tag) + next unless sec_name + + shdr = find_section(sec_name).header + dyn.d_val = dyn.d_tag == ELFTools::Constants::DT_STRSZ ? shdr.sh_size.to_i : shdr.sh_addr.to_i + + with_buf_at(buf_off) { |wbuf| dyn.write(wbuf) } + end + end + + def update_section_idx! + @section_idx_by_name = @sections.map.with_index { |sec, idx| [sec.name, idx] }.to_h + end + + def with_buf_at(pos) + return unless block_given? + + opos = @buffer.tell + @buffer.seek pos + yield @buffer + @buffer.seek opos + nil + end + + def sync_sec_to_seg(shdr, phdr) + phdr.p_offset = shdr.sh_offset.to_i + phdr.p_vaddr = phdr.p_paddr = shdr.sh_addr.to_i + phdr.p_filesz = phdr.p_memsz = shdr.sh_size.to_i + end + + def phdrs_by_type(seg_type) + return unless seg_type + + @segments.each_with_index do |seg, idx| + next unless (phdr = seg.header).p_type == seg_type + + yield phdr, idx + end + end + + def write_replaced_sections(cur_off, start_addr, start_offset) + sht_no_bits = ELFTools::Constants::SHT_NOBITS + + # the original source says this has to be done seperately to + # prevent clobbering the previously written section contents. + @replaced_sections.each do |rsec_name, _| + shdr = find_section(rsec_name).header + with_buf_at(shdr.sh_offset) { |b| b.fill('X', shdr.sh_size) } if shdr.sh_type != sht_no_bits + end + + # the sort is necessary, the strategy in ruby and Cpp to iterate map/hash + # is different, patchelf v0.10 iterates the replaced_sections sorted by + # keys. + @replaced_sections.sort.each do |rsec_name, rsec_data| + section = find_section(rsec_name) + shdr = section.header + + Logger.debug <<~DEBUG + rewriting section '#{rsec_name}' + from offset 0x#{shdr.sh_offset.to_i.to_s 16}(size #{shdr.sh_size}) + to offset 0x#{cur_off.to_i.to_s 16}(size #{rsec_data.size}) + DEBUG + + with_buf_at(cur_off) { |b| b.write rsec_data } + + shdr.sh_offset = cur_off + shdr.sh_addr = start_addr + (cur_off - start_offset) + shdr.sh_size = rsec_data.size + shdr.sh_addralign = @section_alignment + + seg_type = { + '.interp' => ELFTools::Constants::PT_INTERP, + '.dynamic' => ELFTools::Constants::PT_DYNAMIC + }[section.name] + + phdrs_by_type(seg_type) { |phdr| sync_sec_to_seg(shdr, phdr) } + + cur_off += Helper.alignup(rsec_data.size, @section_alignment) + end + @replaced_sections.clear + + cur_off + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/cli.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/cli.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/cli.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/cli.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/exceptions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/exceptions.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/exceptions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/exceptions.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/helper.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/helper.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/helper.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/helper.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/logger.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/logger.rb similarity index 90% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/logger.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/logger.rb index ee376f962f..f5a4a1c9ff 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/logger.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/logger.rb @@ -15,7 +15,7 @@ module PatchELF end end - %i[info warn error].each do |sym| + %i[debug info warn error level=].each do |sym| define_method(sym) do |msg| @logger.__send__(sym, msg) nil diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/mm.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/mm.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/mm.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/mm.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/patcher.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/patcher.rb similarity index 93% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/patcher.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/patcher.rb index 4027f65464..9fbb991e9d 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/patcher.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/patcher.rb @@ -173,13 +173,20 @@ module PatchELF # Save the patched ELF as +out_file+. # @param [String?] out_file # If +out_file+ is +nil+, the original input file will be modified. + # @param [Boolean] patchelf_compatible + # When +patchelf_compatible+ is true, tries to produce same ELF as the one produced by NixOS/patchelf. # @return [void] - def save(out_file = nil) + def save(out_file = nil, patchelf_compatible: false) # If nothing is modified, return directly. return if out_file.nil? && !dirty? out_file ||= @in_file - saver = PatchELF::Saver.new(@in_file, out_file, @set) + saver = if patchelf_compatible + require 'patchelf/alt_saver' + PatchELF::AltSaver.new(@in_file, out_file, @set) + else + PatchELF::Saver.new(@in_file, out_file, @set) + end saver.save! end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/saver.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/saver.rb similarity index 93% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/saver.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/saver.rb index 313a5aa5b1..4ecd806795 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/saver.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/saver.rb @@ -121,30 +121,27 @@ module PatchELF def patch_needed original_needs = dynamic.tags_by_type(:needed) @set[:needed].uniq! + + original = original_needs.map(&:name) + replace = @set[:needed] + # 3 sets: # 1. in original and in needs - remain unchanged # 2. in original but not in needs - remove # 3. not in original and in needs - append - original_needs.each do |n| - next if @set[:needed].include?(n.name) + append = replace - original + remove = original - replace - n.header.d_tag = IGNORE # temporarily mark + ignored_dyns = remove.each_with_object([]) do |name, ignored| + dyn = original_needs.find { |n| n.name == name }.header + dyn.d_tag = IGNORE + ignored << dyn end - extra = @set[:needed] - original_needs.map(&:name) - original_needs.each do |n| - break if extra.empty? - next if n.header.d_tag != IGNORE - - n.header.d_tag = ELFTools::Constants::DT_NEEDED - reg_str_table(extra.shift) { |idx| n.header.d_val = idx } - end - return if extra.empty? - - # no spaces, need append - extra.each do |name| - tag = lazy_dyn(:needed) - reg_str_table(name) { |idx| tag.d_val = idx } + append.zip(ignored_dyns) do |name, ignored_dyn| + dyn = ignored_dyn || lazy_dyn(:needed) + dyn.d_tag = ELFTools::Constants::DT_NEEDED + reg_str_table(name) { |idx| dyn.d_val = idx } end end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/version.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/version.rb similarity index 73% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/version.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/version.rb index fb96c432d3..b862ba2bab 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.2.0/lib/patchelf/version.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/patchelf-1.3.0/lib/patchelf/version.rb @@ -2,5 +2,5 @@ module PatchELF # Current gem version. - VERSION = '1.2.0'.freeze + VERSION = '1.3.0'.freeze end