Class: PatchELF::Patcher
- Inherits:
-
Object
- Object
- PatchELF::Patcher
- Defined in:
- lib/patchelf/patcher.rb
Overview
Class to handle all patching things.
Instance Attribute Summary collapse
- #elf ⇒ Object readonly
Instance Method Summary collapse
-
#add_needed(need) ⇒ void
Add the needed library.
-
#initialize(filename, on_error: :log, logging: true) ⇒ Patcher
constructor
Instantiate a Patcher object.
-
#interpreter ⇒ String?
Get interpreter’s name.
-
#interpreter=(interp) ⇒ Object
Set interpreter’s name.
-
#needed ⇒ Array<String>
Get needed libraries.
-
#needed=(needs) ⇒ Object
Set needed libraries.
-
#remove_needed(need) ⇒ void
Remove the needed library.
-
#replace_needed(src, tar) ⇒ void
Replace needed library
srcwithtar. -
#rpath ⇒ Object
Get rpath return [String?].
-
#rpath=(rpath) ⇒ Object
Set rpath.
-
#runpath ⇒ String?
Get runpath.
-
#runpath=(runpath) ⇒ Object
Set runpath.
-
#save(out_file = nil, patchelf_compatible: false) ⇒ void
Save the patched ELF as
out_file. -
#soname ⇒ String?
Get the soname of a shared library.
-
#soname=(name) ⇒ Object
Set soname.
-
#use_rpath! ⇒ self
Set all operations related to DT_RUNPATH to use DT_RPATH.
Constructor Details
#initialize(filename, on_error: :log, logging: true) ⇒ Patcher
Instantiate a PatchELF::Patcher object.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/patchelf/patcher.rb', line 30 def initialize(filename, on_error: :log, logging: true) @in_file = filename f = File.open(filename) @elf = ELFTools::ELFFile.new(f) @set = {} @rpath_sym = :runpath @on_error = logging ? on_error : :exception on_error_syms = i[exception log silent] raise ArgumentError, "on_error must be one of #{on_error_syms}" unless on_error_syms.include?(@on_error) # Ensure file is closed when the {Patcher} object is garbage collected. ObjectSpace.define_finalizer(self, Helper.close_file_proc(f)) end |
Instance Attribute Details
#elf ⇒ Object (readonly)
This setting will be saved after #save being invoked.
18 19 20 |
# File 'lib/patchelf/patcher.rb', line 18 def elf @elf end |
Instance Method Details
#add_needed(need) ⇒ void
This setting will be saved after #save being invoked.
This method returns an undefined value.
Add the needed library.
87 88 89 90 |
# File 'lib/patchelf/patcher.rb', line 87 def add_needed(need) @set[:needed] ||= needed_ @set[:needed] << need end |
#interpreter ⇒ String?
Returns Get interpreter’s name.
50 51 52 |
# File 'lib/patchelf/patcher.rb', line 50 def interpreter @set[:interpreter] || interpreter_ end |
#interpreter=(interp) ⇒ Object
This setting will be saved after #save being invoked.
Set interpreter’s name.
If the input ELF has no existent interpreter, this method will show a warning and has no effect.
60 61 62 63 64 |
# File 'lib/patchelf/patcher.rb', line 60 def interpreter=(interp) return if interpreter_.nil? # will also show warning if there's no interp segment. @set[:interpreter] = interp end |
#needed ⇒ Array<String>
Get needed libraries.
72 73 74 |
# File 'lib/patchelf/patcher.rb', line 72 def needed @set[:needed] || needed_ end |
#needed=(needs) ⇒ Object
This setting will be saved after #save being invoked.
Set needed libraries.
79 80 81 |
# File 'lib/patchelf/patcher.rb', line 79 def needed=(needs) @set[:needed] = needs end |
#remove_needed(need) ⇒ void
This setting will be saved after #save being invoked.
This method returns an undefined value.
Remove the needed library.
96 97 98 99 |
# File 'lib/patchelf/patcher.rb', line 96 def remove_needed(need) @set[:needed] ||= needed_ @set[:needed].delete(need) end |
#replace_needed(src, tar) ⇒ void
This setting will be saved after #save being invoked.
This method returns an undefined value.
Replace needed library src with tar.
109 110 111 112 |
# File 'lib/patchelf/patcher.rb', line 109 def replace_needed(src, tar) @set[:needed] ||= needed_ @set[:needed].map! { |v| v == src ? tar : v } end |
#rpath ⇒ Object
Get rpath return [String?]
148 149 150 |
# File 'lib/patchelf/patcher.rb', line 148 def rpath @set[:rpath] || runpath_(:rpath) end |
#rpath=(rpath) ⇒ Object
This setting will be saved after #save being invoked.
Set rpath
Modify / set DT_RPATH of the given ELF. similar to runpath= except DT_RPATH is modifed/created in DYNAMIC segment.
158 159 160 |
# File 'lib/patchelf/patcher.rb', line 158 def rpath=(rpath) @set[:rpath] = rpath end |
#runpath ⇒ String?
Get runpath.
142 143 144 |
# File 'lib/patchelf/patcher.rb', line 142 def runpath @set[@rpath_sym] || runpath_(@rpath_sym) end |
#runpath=(runpath) ⇒ Object
This setting will be saved after #save being invoked.
Set runpath.
If DT_RUNPATH is not presented in the input ELF, a new DT_RUNPATH attribute will be inserted into the DYNAMIC segment.
168 169 170 |
# File 'lib/patchelf/patcher.rb', line 168 def runpath=(runpath) @set[@rpath_sym] = runpath end |
#save(out_file = nil, patchelf_compatible: false) ⇒ void
This method returns an undefined value.
Save the patched ELF as out_file.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/patchelf/patcher.rb', line 185 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 = 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 |
#soname ⇒ String?
Get the soname of a shared library.
124 125 126 |
# File 'lib/patchelf/patcher.rb', line 124 def soname @set[:soname] || soname_ end |
#soname=(name) ⇒ Object
This setting will be saved after #save being invoked.
Set soname.
If the input ELF is not a shared library with a soname, this method will show a warning and has no effect.
134 135 136 137 138 |
# File 'lib/patchelf/patcher.rb', line 134 def soname=(name) return if soname_.nil? @set[:soname] = name end |
#use_rpath! ⇒ self
Set all operations related to DT_RUNPATH to use DT_RPATH.
174 175 176 177 |
# File 'lib/patchelf/patcher.rb', line 174 def use_rpath! @rpath_sym = :rpath self end |