Class: Elf::Dynamic
Defined Under Namespace
Modules: Features1, Flags, Flags1, PosFlags1 Classes: Entry, SectionLink, StringEntry, TimestampEntry, Type
Constant Summary collapse
- ClassMap =
{ Type::Needed => StringEntry, Type::Hash => SectionLink, Type::StrTab => SectionLink, Type::SymTab => SectionLink, Type::Init => SectionLink, Type::Fini => SectionLink, Type::SoName => StringEntry, Type::RPath => StringEntry, Type::RunPath => StringEntry, Type::GNUPrelinked => TimestampEntry, Type::GNUHash => SectionLink, Type::Auxiliary => StringEntry }
Constants inherited from Section
Section::Abs, Section::Common, Section::FlagsToChars, Section::OsSpecific, Section::ProcSpecific, Section::Reserved, Section::SunW, Section::SunWIgnore, Section::Undef, Section::XIndex
Instance Attribute Summary
Attributes inherited from Section
#addr, #addralign, #entsize, #file, #index, #info, #offset, #size, #type
Instance Method Summary collapse
-
#auxiliary_library_path(type) ⇒ Object
Returns the auxiliary path specified by the given type.
-
#complete_library_path ⇒ Object
Returns the complete library path for the current ELF file.
-
#count ⇒ Object
Return the amount of entries in the .dynamic section.
-
#each_entry(&block) ⇒ Object
Iterate over all the entries in the .dynamic section.
-
#find_library(soname) ⇒ Object
Return the ELF library corresponding to the given soname.
- #load_internal ⇒ Object
-
#needed_libraries ⇒ Object
Returns an hash representing the dependencies of the ELF file.
-
#needed_sonames ⇒ Object
Returns an array of needed sonames from .dynamic section.
-
#rpath ⇒ Object
Returns the value of DT_RPATH entries in the file.
-
#runpath ⇒ Object
Returns the value of DT_RUNPATH entries in the file.
- #soname ⇒ Object
Methods inherited from Section
#==, #flags, #flags_i, #flags_s, #initialize, #link, #load, #name, read, #summary
Constructor Details
This class inherits a constructor from Elf::Section
Instance Method Details
#auxiliary_library_path(type) ⇒ Object
Returns the auxiliary path specified by the given type
Please never use this function because it does not caches its values, use Dynamic#rpath or Dynamic#runpath instead.
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/elf/dynamic.rb', line 279 def auxiliary_library_path(type) retval = Array.new each_entry do |entry| next unless entry.type == type retval.concat entry.parsed.split(":") end return retval.uniq.collect do |path| if path == "$ORIGIN" or path == "${ORIGIN}" Pathname.new(@file.path).dirname else begin Pathname.new(path).realpath rescue Errno::ENOENT path end end.to_s end end |
#complete_library_path ⇒ Object
Returns the complete library path for the current ELF file.
Since the ELF loaders have somewhat complex rules to identify the path to load dependencies from, we evalute it on a per-file basis.
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/elf/dynamic.rb', line 305 def complete_library_path if @complete_library_path.nil? @complete_library_path = Array.new # If there is no DT_RUNPATH. RPATH wins over the LD_LIBRARY_PATH @complete_library_path.concat rpath unless runpath.empty? @complete_library_path.concat Elf::Utilities.environment_library_path # If there is a DT_RUNPATH it wins over the system library path @complete_library_path.concat runpath @complete_library_path.concat Elf::Utilities.system_library_path @complete_library_path.uniq! end return @complete_library_path end |
#count ⇒ Object
Return the amount of entries in the .dynamic section.
251 252 253 254 255 |
# File 'lib/elf/dynamic.rb', line 251 def count load unless @entries @entries.size end |
#each_entry(&block) ⇒ Object
Iterate over all the entries in the .dynamic section.
244 245 246 247 248 |
# File 'lib/elf/dynamic.rb', line 244 def each_entry(&block) load unless @entries @entries.each(&block) end |
#find_library(soname) ⇒ Object
Return the ELF library corresponding to the given soname.
This function gets the system library paths and eventually adds the rpaths as expressed by the file itself, then look them up to find the proper library, just like the loader would.
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/elf/dynamic.rb', line 330 def find_library(soname) complete_library_path.each do |path| # For the ELF linker an empty entry in the library path is the # same as "." and means the current working directory, so # replace it. path = "." if path == "" if FileTest.exist? "#{path}/#{soname}" begin possible_library = Elf::Utilities::FilePool["#{path}/#{soname}"] return possible_library if @file.is_compatible(possible_library) rescue Errno::ENOENT, Errno::EACCES, Errno::EISDIR, Elf::File::NotAnELF # we don't care if the file does not exist and similar. end end end return nil end |
#load_internal ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/elf/dynamic.rb', line 225 def load_internal elf32 = @file.elf_class == Class::Elf32 @entries = [] for i in 1..@numentries type = Type[elf32 ? @file.read_sword : @file.read_sxword] @entries << if ClassMap.has_key? type ClassMap[type].new(type, @file) else Entry.new(type, @file) end break if type == Type::Null end end |
#needed_libraries ⇒ Object
Returns an hash representing the dependencies of the ELF file.
This function reads the .dynamic section of the file for DT_NEEDED entries, then looks for them and add them to an hash.
Note that nil values in the hash means that the library couldn’t be found on either the runpath of the file or the system library path.
377 378 379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'lib/elf/dynamic.rb', line 377 def needed_libraries # Make sure to cache the thing, we don't want to have to parse # this multiple times since we might access it over and over to # check the dependencies. if @needed_libraries.nil? @needed_libraries = Hash.new needed_sonames.each do |soname| @needed_libraries[soname] = find_library(soname) end end return @needed_libraries end |
#needed_sonames ⇒ Object
Returns an array of needed sonames from .dynamic section
This function reads the .dynamic section of the file for DT_NEEDED entries, and fills an array with them.
355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/elf/dynamic.rb', line 355 def needed_sonames if @needed_sonames.nil? @needed_sonames = Array.new each_entry do |entry| next unless entry.type == Elf::Dynamic::Type::Needed @needed_sonames << entry.parsed end end return @needed_sonames end |
#rpath ⇒ Object
Returns the value of DT_RPATH entries in the file
266 267 268 |
# File 'lib/elf/dynamic.rb', line 266 def rpath @rpath ||= auxiliary_library_path(Type::RPath) end |
#runpath ⇒ Object
Returns the value of DT_RUNPATH entries in the file
271 272 273 |
# File 'lib/elf/dynamic.rb', line 271 def runpath @runpath ||= auxiliary_library_path(Type::RunPath) end |
#soname ⇒ Object
257 258 259 260 261 262 263 |
# File 'lib/elf/dynamic.rb', line 257 def soname each_entry do |entry| return entry.parsed if entry.type == Type::SoName end return nil end |