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
src
withtar
. -
#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.
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/patchelf/patcher.rb', line 28 def initialize(filename, on_error: :log, logging: true) @in_file = filename @elf = ELFTools::ELFFile.new(File.open(filename)) @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) end |
Instance Attribute Details
#elf ⇒ Object (readonly)
This setting will be saved after #save being invoked.
16 17 18 |
# File 'lib/patchelf/patcher.rb', line 16 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.
81 82 83 84 |
# File 'lib/patchelf/patcher.rb', line 81 def add_needed(need) @set[:needed] ||= needed_ @set[:needed] << need end |
#interpreter ⇒ String?
Returns Get interpreter’s name.
44 45 46 |
# File 'lib/patchelf/patcher.rb', line 44 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.
54 55 56 57 58 |
# File 'lib/patchelf/patcher.rb', line 54 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.
66 67 68 |
# File 'lib/patchelf/patcher.rb', line 66 def needed @set[:needed] || needed_ end |
#needed=(needs) ⇒ Object
This setting will be saved after #save being invoked.
Set needed libraries.
73 74 75 |
# File 'lib/patchelf/patcher.rb', line 73 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.
90 91 92 93 |
# File 'lib/patchelf/patcher.rb', line 90 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
.
103 104 105 106 |
# File 'lib/patchelf/patcher.rb', line 103 def replace_needed(src, tar) @set[:needed] ||= needed_ @set[:needed].map! { |v| v == src ? tar : v } end |
#rpath ⇒ Object
Get rpath return [String?]
142 143 144 |
# File 'lib/patchelf/patcher.rb', line 142 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.
152 153 154 |
# File 'lib/patchelf/patcher.rb', line 152 def rpath=(rpath) @set[:rpath] = rpath end |
#runpath ⇒ String?
Get runpath.
136 137 138 |
# File 'lib/patchelf/patcher.rb', line 136 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.
162 163 164 |
# File 'lib/patchelf/patcher.rb', line 162 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
.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/patchelf/patcher.rb', line 179 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.
118 119 120 |
# File 'lib/patchelf/patcher.rb', line 118 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.
128 129 130 131 132 |
# File 'lib/patchelf/patcher.rb', line 128 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.
168 169 170 171 |
# File 'lib/patchelf/patcher.rb', line 168 def use_rpath! @rpath_sym = :rpath self end |