patchelf 1.6.3 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72b60be48f5040899d73767baf55e3e4338578e3301c91116a9769a396f28788
4
- data.tar.gz: 454399ea53bcbd52931102451dfaac13da564ded12675829e92b80eff77668f2
3
+ metadata.gz: e4c5ab178f3aa52c0413a57a7fd36aa9c8d6029a7655b5c0eb54f2a2a862f56e
4
+ data.tar.gz: 7f788f0f3033ea73cf04835869f1c7824b8329b7f9ba6e9aef49b796a6c79871
5
5
  SHA512:
6
- metadata.gz: d8741f0b203ce8592936f3305305214fff490f64caa145dda380e3d65cbc95809868871c137ef68a674956438a3ea7eac8640b68707ad7146d98f5c90170fedb
7
- data.tar.gz: b903bcccd2d07f03470c3915616f26b0d98027c5ffe79c63578b2aa1feb25123a990ea9617f4cc6b4d8796d3caf7832fe2aa6b5e8d52d91e89d9a4700a24497d
6
+ metadata.gz: 3e59603f46178a5f78a3dc41b20c0b65e305d2f7d13ee3a47f088a0bbab75875df53921d94d38fb5470b5f3d1dca5b175b44e5e76eb8d4ade2d05a9df0168c75
7
+ data.tar.gz: ed6b7e5e63a383150c8052dabf64f865b572b2f3490c373267314720d60cf1d0b60380e9eaebb7fda1d2c515f31c910caa4244fb7cbcd336394b9a26b8044a30
data/.yardopts ADDED
@@ -0,0 +1,7 @@
1
+ --no-private
2
+ --markup markdown
3
+ -
4
+ README.md
5
+ CONTRIBUTING.md
6
+ THIRD_PARTY_NOTICES.md
7
+ LICENSE
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,73 @@
1
+ # Contributing to patchelf.rb
2
+
3
+ Thank you for helping improve `patchelf.rb`.
4
+
5
+ ## Set up the repository
6
+
7
+ Install Ruby 3.3 or newer and Bundler, then install the locked dependencies:
8
+
9
+ ```console
10
+ bundle install
11
+ ```
12
+
13
+ Run the same repository-owned checks used by CI:
14
+
15
+ ```console
16
+ bundle exec rake
17
+ ```
18
+
19
+ That command runs RuboCop, the complete RSpec suite, YARD documentation checks,
20
+ and a build-and-smoke test of the packaged gem. Complete suite runs enforce
21
+ minimum line and branch coverage percentages. Focused spec runs still generate
22
+ coverage reports, but do not apply repository-wide minimums.
23
+
24
+ Useful focused commands are:
25
+
26
+ ```console
27
+ bundle exec rspec
28
+ bundle exec rspec spec/patcher_spec.rb
29
+ bundle exec rubocop
30
+ bundle exec rake doc
31
+ bundle exec rake build
32
+ ```
33
+
34
+ The suite can inspect ELF files on macOS, but tests that execute patched ELF
35
+ binaries are Linux-only and are reported as pending elsewhere. CI runs both
36
+ platforms. A change affecting executable layout should be verified on Linux.
37
+
38
+ ## Submit a change
39
+
40
+ - Add a focused regression test for behavior changes and bug fixes.
41
+ - Keep public behavior and limitations documented in `README.md` and YARD
42
+ comments.
43
+ - Keep commits focused and include a `Signed-off-by` trailer. `git commit -s`
44
+ adds it automatically.
45
+ - Run `bundle exec rake` before opening a pull request.
46
+
47
+ The README is intentionally static. Update it directly when public behavior
48
+ changes.
49
+
50
+ ## Test fixtures
51
+
52
+ ELF fixtures live in `spec/files`. Prefer a small, source-generated reproducer
53
+ over copying a production executable.
54
+
55
+ Any new or replaced binary fixture must include:
56
+
57
+ - the smallest practical source or deterministic generation recipe;
58
+ - the upstream source and version, when applicable;
59
+ - a SHA-256 digest for externally built artifacts;
60
+ - the reason the fixture is necessary and the spec that exercises it; and
61
+ - its license and attribution requirements.
62
+
63
+ Update both `spec/files/README.md` and `THIRD_PARTY_NOTICES.md` when third-party
64
+ fixture provenance changes. Do not regenerate committed fixtures casually: ELF
65
+ layout varies with compiler and linker versions, so review the resulting binary
66
+ diff and run the full Linux suite.
67
+
68
+ ## Reporting problems
69
+
70
+ Use [GitHub Issues](https://github.com/Homebrew/patchelf.rb/issues) for ordinary
71
+ bugs. Report suspected vulnerabilities privately through
72
+ [GitHub's security advisory form](https://github.com/Homebrew/patchelf.rb/security/advisories/new)
73
+ and follow [Homebrew's security policy](https://github.com/Homebrew/.github/security/policy).
data/README.md CHANGED
@@ -1,150 +1,148 @@
1
- [![Downloads](https://img.shields.io/endpoint?url=https://gem-badge-h3lg.onrender.com/downloads/patchelf)](https://rubygems.org/gems/patchelf)
1
+ # patchelf.rb
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/patchelf.svg)](https://badge.fury.io/rb/patchelf)
4
4
  [![CI](https://github.com/Homebrew/patchelf.rb/actions/workflows/tests.yml/badge.svg)](https://github.com/Homebrew/patchelf.rb/actions/workflows/tests.yml)
5
- [![Coverage Status](https://codecov.io/gh/Homebrew/patchelf.rb/graph/badge.svg)](https://codecov.io/gh/Homebrew/patchelf.rb)
6
- [![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/patchelf)
7
- [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://choosealicense.com/licenses/mit/)
8
-
9
- # patchelf.rb
5
+ [![Coverage](https://codecov.io/gh/Homebrew/patchelf.rb/graph/badge.svg)](https://codecov.io/gh/Homebrew/patchelf.rb)
6
+ [![API documentation](https://img.shields.io/badge/API-RubyDoc-blue.svg)](https://www.rubydoc.info/gems/patchelf)
7
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
10
8
 
11
- Implements features of NixOS/patchelf in pure Ruby.
9
+ `patchelf.rb` is a pure-Ruby library and command-line tool for inspecting and
10
+ modifying selected fields in ELF executables and shared libraries. It implements
11
+ the operations Homebrew needs, but it is not a complete drop-in replacement for
12
+ [NixOS/patchelf](https://github.com/NixOS/patchelf).
12
13
 
13
- ## Installation
14
+ ## Requirements
14
15
 
15
- Available on RubyGems.org!
16
- ```
17
- $ gem install patchelf
18
- ```
16
+ - Ruby 3.3 or newer.
17
+ - An ELF input file. The host running Ruby does not itself need to be Linux.
19
18
 
20
- ## Usage
19
+ CI tests the gem on Linux and macOS with Ruby 3.3, 3.4, and 4.0. Tests that
20
+ execute patched ELF files run on Linux only. Windows is not currently tested.
21
21
 
22
- ```
23
- $ patchelf.rb
24
- # Usage: patchelf.rb <commands> FILENAME [OUTPUT_FILE]
25
- # --print-interpreter, --pi Show interpreter's name.
26
- # --print-needed, --pn Show needed libraries specified in DT_NEEDED.
27
- # --print-runpath, --pr Show the path specified in DT_RUNPATH.
28
- # --print-soname, --ps Show soname specified in DT_SONAME.
29
- # --set-interpreter, --interp INTERP
30
- # Set interpreter's name.
31
- # --set-needed, --needed LIB1,LIB2,LIB3
32
- # Set needed libraries, this will remove all existent needed libraries.
33
- # --add-needed LIB Append a new needed library.
34
- # --remove-needed LIB Remove a needed library.
35
- # --replace-needed LIB1,LIB2 Replace needed library LIB1 as LIB2.
36
- # --set-runpath, --runpath PATH
37
- # Set the path of runpath.
38
- # --force-rpath According to the ld.so docs, DT_RPATH is obsolete,
39
- # patchelf.rb will always try to get/set DT_RUNPATH first.
40
- # Use this option to force every operations related to runpath (e.g. --runpath)
41
- # to consider 'DT_RPATH' instead of 'DT_RUNPATH'.
42
- # --set-soname, --so SONAME Set name of a shared library.
43
- # --version Show current gem's version.
22
+ ## Installation
44
23
 
45
- ```
24
+ Install the released gem from RubyGems:
46
25
 
47
- ### Display information
26
+ ```console
27
+ gem install patchelf
48
28
  ```
49
- $ patchelf.rb --print-interpreter --print-needed /bin/ls
50
- # interpreter: /lib64/ld-linux-x86-64.so.2
51
- # needed: libselinux.so.1 libc.so.6
52
29
 
53
- ```
30
+ Or add it to a Bundler-managed project:
54
31
 
55
- ### Change the dynamic loader (interpreter)
32
+ ```ruby
33
+ gem 'patchelf'
56
34
  ```
57
- # $ patchelf.rb --interp NEW_INTERP input.elf output.elf
58
- $ patchelf.rb --interp /lib/AAAA.so /bin/ls ls.patch
59
35
 
60
- $ file ls.patch
61
- # ls.patch: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/AAAA.so, for GNU/Linux 3.2.0, BuildID[sha1]=9567f9a28e66f4d7ec4baf31cfbf68d0410f0ae6, stripped
36
+ ## Command-line usage
62
37
 
38
+ ```console
39
+ patchelf.rb [OPTIONS] INPUT_FILE [OUTPUT_FILE]
63
40
  ```
64
41
 
65
- ### Modify dependency libraries
42
+ If `OUTPUT_FILE` is omitted, the input file is modified in place. In-place
43
+ writes are not atomic, so use an explicit output path when the original cannot
44
+ be recreated safely.
66
45
 
67
- #### Add
68
- ```
69
- $ patchelf.rb --add-needed libnew.so /bin/ls ls.patch
70
- ```
46
+ Run `patchelf.rb --help` for the complete option list. Common operations are:
71
47
 
72
- #### Remove
73
- ```
74
- $ patchelf.rb --remove-needed libc.so.6 /bin/ls ls.patch
75
- ```
48
+ | Operation | Option |
49
+ | --- | --- |
50
+ | Print the interpreter | `--print-interpreter`, `--pi` |
51
+ | Print needed libraries | `--print-needed`, `--pn` |
52
+ | Print `DT_RUNPATH` | `--print-runpath`, `--pr` |
53
+ | Print the shared-library name | `--print-soname`, `--ps` |
54
+ | Set the interpreter | `--set-interpreter INTERP`, `--interp INTERP` |
55
+ | Set all needed libraries | `--set-needed LIB1,LIB2`, `--needed LIB1,LIB2` |
56
+ | Add, remove, or replace one needed library | `--add-needed`, `--remove-needed`, `--replace-needed` |
57
+ | Set `DT_RUNPATH` | `--set-runpath PATH`, `--runpath PATH` |
58
+ | Operate on `DT_RPATH` instead | `--force-rpath` |
59
+ | Set the shared-library name | `--set-soname SONAME`, `--so SONAME` |
76
60
 
77
- #### Replace
78
- ```
79
- $ patchelf.rb --replace-needed libc.so.6,libcnew.so.6 /bin/ls ls.patch
61
+ These examples use Linux paths and tools:
80
62
 
81
- $ readelf -d ls.patch | grep NEEDED
82
- # 0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
83
- # 0x0000000000000001 (NEEDED) Shared library: [libcnew.so.6]
63
+ ```console
64
+ # Inspect an executable.
65
+ patchelf.rb --print-interpreter --print-needed /bin/ls
84
66
 
85
- ```
67
+ # Write a changed copy instead of modifying the input.
68
+ patchelf.rb --runpath '$ORIGIN/../lib' input.elf output.elf
86
69
 
87
- #### Set directly
70
+ # Replace one DT_NEEDED entry.
71
+ patchelf.rb --replace-needed libc.so.6,libcnew.so.6 input.elf output.elf
88
72
  ```
89
- $ patchelf.rb --needed a.so,b.so,c.so /bin/ls ls.patch
90
73
 
91
- $ readelf -d ls.patch | grep NEEDED
92
- # 0x0000000000000001 (NEEDED) Shared library: [a.so]
93
- # 0x0000000000000001 (NEEDED) Shared library: [b.so]
94
- # 0x0000000000000001 (NEEDED) Shared library: [c.so]
74
+ The executable exits non-zero for invalid options, missing arguments, more than
75
+ two positional arguments, unreadable inputs, invalid ELF files, and expected
76
+ patching failures.
95
77
 
96
- ```
78
+ ## Library usage
97
79
 
98
- ### Set RUNPATH of an executable
99
- ```
100
- $ patchelf.rb --runpath . /bin/ls ls.patch
80
+ ```ruby
81
+ require 'patchelf'
101
82
 
102
- $ readelf -d ls.patch | grep RUNPATH
103
- # 0x000000000000001d (RUNPATH) Library runpath: [.]
83
+ patcher = PatchELF::Patcher.new('/path/to/input.elf', on_error: :exception)
84
+ puts patcher.interpreter
85
+ puts patcher.needed
104
86
 
87
+ patcher.interpreter = '/new/dynamic/loader'
88
+ patcher.runpath = '$ORIGIN/../lib'
89
+ patcher.save('/path/to/output.elf', patchelf_compatible: true)
105
90
  ```
106
91
 
107
- ### Change SONAME of a shared library
108
- ```
109
- $ patchelf.rb --so libc.so.217 /lib/x86_64-linux-gnu/libc.so.6 libc.patch
92
+ `on_error` controls how missing ELF segments and tags are handled:
110
93
 
111
- $ readelf -d libc.patch | grep SONAME
112
- # 0x000000000000000e (SONAME) Library soname: [libc.so.217]
94
+ - `:log` logs a warning and returns `nil`.
95
+ - `:silent` returns `nil` without logging.
96
+ - `:exception` raises a `PatchELF` exception.
113
97
 
114
- ```
98
+ `Patcher#save` provides two rewriting strategies:
115
99
 
116
- ### As Ruby library
117
- ```rb
118
- require 'patchelf'
100
+ | Strategy | Intended use | Current mutation support |
101
+ | --- | --- | --- |
102
+ | Default | General-purpose rewriting | Interpreter, needed libraries, RPATH/RUNPATH, and SONAME |
103
+ | `patchelf_compatible: true` | Layout behavior closer to NixOS/patchelf | Interpreter and RPATH/RUNPATH |
119
104
 
120
- patcher = PatchELF::Patcher.new('/bin/ls')
121
- patcher.interpreter
122
- #=> "/lib64/ld-linux-x86-64.so.2"
105
+ The compatible saver does not yet implement needed-library or SONAME changes.
106
+ Some ELF layouts also require growth operations that are not implemented and
107
+ raise `NotImplementedError`. The CLI currently uses the default saver; use the
108
+ Ruby API when compatible layout behavior is required.
123
109
 
124
- patcher.interpreter = '/lib/AAAA.so.2'
125
- patcher.interpreter
126
- #=> "/lib/AAAA.so.2"
110
+ A patcher keeps its input file open for the lifetime of the object. Avoid
111
+ retaining patcher instances in long-running processes after their work is
112
+ complete.
127
113
 
128
- patcher.save('ls.patch')
114
+ Fixture coverage is primarily x86-64, with a 32-bit x86 regression fixture and
115
+ unit coverage for architecture-specific page sizes. Validate rewritten binaries
116
+ on every target architecture before distributing them.
129
117
 
130
- # $ file ls.patch
131
- # ls.patch: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/AAAA.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=9567f9a28e66f4d7ec4baf31cfbf68d0410f0ae6, stripped
118
+ Full API documentation is available on
119
+ [RubyDoc](https://www.rubydoc.info/gems/patchelf).
132
120
 
133
- ```
121
+ ## Contributing
122
+
123
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, test commands, fixture policy,
124
+ and the release-quality checks run in CI.
134
125
 
135
- ## Environment
126
+ Bug reports and feature requests belong in
127
+ [GitHub Issues](https://github.com/Homebrew/patchelf.rb/issues).
136
128
 
137
- patchelf.rb is implemented in pure Ruby, so it should work in all environments include Linux, macOS, and Windows!
129
+ ## Security
138
130
 
139
- ## Project Authors
131
+ Please report suspected vulnerabilities through
132
+ [GitHub private vulnerability reporting](https://github.com/Homebrew/patchelf.rb/security/advisories/new),
133
+ following [Homebrew's security policy](https://github.com/Homebrew/.github/security/policy).
134
+ Do not disclose a suspected vulnerability in a public issue before maintainers
135
+ have had a reasonable opportunity to investigate it.
140
136
 
141
- The git history remains the definitive record of all contributions.
137
+ ## Authors and maintainers
142
138
 
143
- ### Original Author and Project Founder
139
+ The Git history is the definitive record of contributions.
144
140
 
145
- * david942j (@david942j)
141
+ - Original author and project founder: david942j (`@david942j`)
142
+ - Maintainers: Homebrew maintainers and david942j
146
143
 
147
- ### Maintainers
144
+ ## License
148
145
 
149
- * Homebrew maintainers
150
- * david942j (@david942j)
146
+ The gem is available under the [MIT License](LICENSE). Historical third-party
147
+ test fixtures retain their upstream terms, documented in
148
+ [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
@@ -0,0 +1,37 @@
1
+ # Third-party test fixture notices
2
+
3
+ The files described here are used only by the test suite under `spec/files` and
4
+ are excluded from the released Ruby gem. They retain their upstream license
5
+ terms; the repository's MIT license does not replace those terms.
6
+
7
+ ## NixOS/patchelf 0.15.0 test material
8
+
9
+ `spec/files/contiguous-note-sections.s` and
10
+ `spec/files/contiguous-note-sections.ld` match the corresponding source files in
11
+ the [NixOS/patchelf 0.15.0 test suite](https://github.com/NixOS/patchelf/tree/0.15.0/tests).
12
+ `spec/files/contiguous-note-sections.elf` is built from those files.
13
+
14
+ `spec/files/libbig-dynstr.debug` was built from the upstream 0.15.0 test
15
+ sources represented by
16
+ [`tests/big-dynstr.sh`](https://github.com/NixOS/patchelf/blob/0.15.0/tests/big-dynstr.sh).
17
+
18
+ NixOS/patchelf 0.15.0 provides the
19
+ [GNU General Public License version 3](https://github.com/NixOS/patchelf/blob/0.15.0/COPYING).
20
+
21
+ ## Syncthing 1.4.0
22
+
23
+ `spec/files/syncthing` was extracted from the historical Homebrew bottle for
24
+ Syncthing 1.4.0. It is retained as a regression fixture for ELF layouts that the
25
+ default saver can rewrite incorrectly.
26
+
27
+ - Committed executable SHA-256:
28
+ `996e0fb40fc7f7a5c7bf2c42ee0bb9078c1f7a467d5769a65fb3c56c0edecb29`
29
+ - Historical bottle archive SHA-256 recorded when the fixture was added:
30
+ `982b710fe714387b4ce4fb82f16a170ab20e8cda09f4609194f12496848a27ac`
31
+ - Upstream source release:
32
+ [syncthing/syncthing v1.4.0](https://github.com/syncthing/syncthing/releases/tag/v1.4.0)
33
+ - Upstream license:
34
+ [Mozilla Public License 2.0](https://github.com/syncthing/syncthing/blob/v1.4.0/LICENSE)
35
+
36
+ The original bottle download endpoint is no longer available. Replacing this
37
+ 20 MB executable with a small, source-generated reproducer remains preferred.
data/bin/patchelf.rb CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require 'patchelf/cli'
5
5
 
6
- PatchELF::CLI.work(ARGV)
6
+ exit PatchELF::CLI.work(ARGV)
@@ -318,7 +318,7 @@ module PatchELF
318
318
  zi = StringIO.new
319
319
  dyn_rpath.write zi
320
320
  zi.rewind
321
- new_dynamic_data[0...dyn_num_bytes] = zi.read
321
+ new_dynamic_data[0...dyn_num_bytes] = zi.read.b
322
322
  end
323
323
 
324
324
  # given a index into old_sections table
@@ -332,7 +332,7 @@ module PatchELF
332
332
  raise ArgumentError if old_shndx >= old_sections.count
333
333
 
334
334
  old_sec = old_sections[old_shndx]
335
- raise PatchError, "old_sections[#{shndx}] is nil" if old_sec.nil?
335
+ raise PatchError, "old_sections[#{old_shndx}] is nil" if old_sec.nil?
336
336
 
337
337
  # TODO: handle case of non existing section in (new) @sections.
338
338
  find_section_idx(old_sec.name)
data/lib/patchelf/cli.rb CHANGED
@@ -11,14 +11,14 @@ module PatchELF
11
11
  # Name of binary.
12
12
  SCRIPT_NAME = 'patchelf.rb'
13
13
  # CLI usage string.
14
- USAGE = format('Usage: %s <commands> FILENAME [OUTPUT_FILE]', SCRIPT_NAME).freeze
14
+ USAGE = format('Usage: %s [OPTIONS] INPUT_FILE [OUTPUT_FILE]', SCRIPT_NAME).freeze
15
15
 
16
16
  module_function
17
17
 
18
18
  # Main method of CLI.
19
19
  # @param [Array<String>] argv
20
20
  # Command line arguments.
21
- # @return [void]
21
+ # @return [Integer] Process exit status: zero on success, non-zero on usage or input errors.
22
22
  # @example
23
23
  # PatchELF::CLI.work(%w[--help])
24
24
  # # usage message to stdout
@@ -30,27 +30,41 @@ module PatchELF
30
30
  print: [],
31
31
  needed: []
32
32
  }
33
- return $stdout.puts "PatchELF Version #{PatchELF::VERSION}" if argv.include?('--version')
34
- return $stdout.puts option_parser unless parse?(argv)
33
+ unless parse?(argv)
34
+ $stdout.puts option_parser
35
+ return 1
36
+ end
35
37
 
36
- # Now the options are (hopefully) valid, let's process the ELF file.
37
- begin
38
- @patcher = PatchELF::Patcher.new(@options[:in_file])
39
- rescue ELFTools::ELFError, Errno::ENOENT => e
40
- return PatchELF::Logger.error(e.message)
38
+ case @options[:action]
39
+ when :version
40
+ $stdout.puts "PatchELF Version #{PatchELF::VERSION}"
41
+ return 0
42
+ when :help
43
+ $stdout.puts option_parser
44
+ return 0
41
45
  end
46
+
47
+ # Now the options are (hopefully) valid, let's process the ELF file.
48
+ @patcher = PatchELF::Patcher.new(@options[:in_file])
42
49
  patcher.use_rpath! if @options[:force_rpath]
43
50
  readonly
44
51
  patch_requests
45
52
  patcher.save(@options[:out_file])
53
+ 0
54
+ rescue OptionParser::ParseError, ELFTools::ELFError, SystemCallError, NotImplementedError => e
55
+ PatchELF::Logger.error(e.message)
56
+ 1
46
57
  end
47
58
 
48
59
  private
49
60
 
61
+ # @return [PatchELF::Patcher]
50
62
  def patcher
51
63
  @patcher
52
64
  end
53
65
 
66
+ # Print the requested ELF metadata.
67
+ # @return [void]
54
68
  def readonly
55
69
  @options[:print].uniq.each do |s|
56
70
  content = patcher.__send__(s)
@@ -61,6 +75,8 @@ module PatchELF
61
75
  end
62
76
  end
63
77
 
78
+ # Apply all requested ELF mutations to the patcher.
79
+ # @return [void]
64
80
  def patch_requests
65
81
  @options[:set].each do |sym, val|
66
82
  patcher.__send__(:"#{sym}=", val)
@@ -71,15 +87,21 @@ module PatchELF
71
87
  end
72
88
  end
73
89
 
90
+ # Parse options and capture the input and optional output paths.
91
+ # @param [Array<String>] argv
92
+ # @return [Boolean]
74
93
  def parse?(argv)
75
94
  remain = option_parser.permute(argv)
95
+ return true if @options[:action]
76
96
  return false if remain.first.nil?
97
+ raise OptionParser::InvalidArgument, 'too many positional arguments' if remain.length > 2
77
98
 
78
99
  @options[:in_file] = remain.first
79
100
  @options[:out_file] = remain[1] # can be nil
80
101
  true
81
102
  end
82
103
 
104
+ # @return [OptionParser]
83
105
  def option_parser
84
106
  @option_parser ||= OptionParser.new do |opts|
85
107
  opts.banner = USAGE
@@ -139,7 +161,13 @@ module PatchELF
139
161
  @options[:set][:soname] = soname
140
162
  end
141
163
 
142
- opts.on('--version', 'Show current gem\'s version.')
164
+ opts.on('-h', '--help', 'Show this help.') do
165
+ @options[:action] = :help
166
+ end
167
+
168
+ opts.on('--version', 'Show current gem\'s version.') do
169
+ @options[:action] = :version
170
+ end
143
171
  end
144
172
  end
145
173
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module PatchELF
4
4
  # Current gem version.
5
- VERSION = '1.6.3'
5
+ VERSION = '1.7.0'
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patchelf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - david942j
@@ -85,14 +85,20 @@ dependencies:
85
85
  requirements:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
- version: '0.22'
88
+ version: '1.1'
89
+ - - "<"
90
+ - !ruby/object:Gem::Version
91
+ version: '2'
89
92
  type: :development
90
93
  prerelease: false
91
94
  version_requirements: !ruby/object:Gem::Requirement
92
95
  requirements:
93
96
  - - ">="
94
97
  - !ruby/object:Gem::Version
95
- version: '0.22'
98
+ version: '1.1'
99
+ - - "<"
100
+ - !ruby/object:Gem::Version
101
+ version: '2'
96
102
  - !ruby/object:Gem::Dependency
97
103
  name: simplecov-cobertura
98
104
  requirement: !ruby/object:Gem::Requirement
@@ -135,9 +141,8 @@ dependencies:
135
141
  - - "~>"
136
142
  - !ruby/object:Gem::Version
137
143
  version: '0.9'
138
- description: |2
139
- A simple utility for modifying existing ELF executables and
140
- libraries.
144
+ description: A Ruby library and command-line tool for inspecting and modifying ELF
145
+ executables and libraries.
141
146
  email:
142
147
  - david942j@gmail.com
143
148
  executables:
@@ -145,8 +150,11 @@ executables:
145
150
  extensions: []
146
151
  extra_rdoc_files: []
147
152
  files:
153
+ - ".yardopts"
154
+ - CONTRIBUTING.md
148
155
  - LICENSE
149
156
  - README.md
157
+ - THIRD_PARTY_NOTICES.md
150
158
  - bin/patchelf.rb
151
159
  - lib/patchelf.rb
152
160
  - lib/patchelf/alt_saver.rb
@@ -165,6 +173,8 @@ metadata:
165
173
  rubygems_mfa_required: 'true'
166
174
  source_code_uri: https://github.com/Homebrew/patchelf.rb
167
175
  bug_tracker_uri: https://github.com/Homebrew/patchelf.rb/issues
176
+ documentation_uri: https://www.rubydoc.info/gems/patchelf
177
+ changelog_uri: https://github.com/Homebrew/patchelf.rb/releases
168
178
  funding_uri: https://github.com/sponsors/Homebrew
169
179
  rdoc_options: []
170
180
  require_paths:
@@ -182,5 +192,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
192
  requirements: []
183
193
  rubygems_version: 4.0.16
184
194
  specification_version: 4
185
- summary: patchelf
195
+ summary: Inspect and modify ELF binaries in pure Ruby
186
196
  test_files: []