Module: ELFShim Private

Extended by:
T::Helpers
Defined in:
os/linux/elf.rb,
extend/pathname.rb

Overview

This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.

Pathname extension for dealing with ELF files.

Instance Method Summary collapse

Instance Method Details

#arch ⇒ Symbol

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'os/linux/elf.rb', line 83

def arch
  return :dunno unless elf?

  @arch ||= case read_uint16(ARCHITECTURE_OFFSET)
  when ARCHITECTURE_I386 then :i386
  when ARCHITECTURE_X86_64 then :x86_64
  when ARCHITECTURE_POWERPC then :ppc32
  when ARCHITECTURE_POWERPC64 then :ppc64
  when ARCHITECTURE_ARM then :arm
  when ARCHITECTURE_AARCH64 then :arm64
  else :dunno
  end
end

#arch_compatible?(wanted_arch) ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:

  • (Boolean)


98
99
100
101
102
103
104
105
# File 'os/linux/elf.rb', line 98

def arch_compatible?(wanted_arch)
  return true unless elf?

  # Treat ppc64le and ppc64 the same
  wanted_arch = :ppc64 if wanted_arch == :ppc64le

  wanted_arch == arch
end

#binary_executable? ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


124
125
126
# File 'os/linux/elf.rb', line 124

def binary_executable?
  elf_type == :executable
end

#dylib? ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


119
120
121
# File 'os/linux/elf.rb', line 119

def dylib?
  elf_type == :dylib
end

#dylib_id ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



482
483
484
# File 'os/linux/elf.rb', line 482

def dylib_id
  .dylib_id
end

#dynamic_elf? ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


160
161
162
# File 'os/linux/elf.rb', line 160

def dynamic_elf?
  .dynamic_elf?
end

#dynamically_linked_libraries(except: :none, resolve_variable_references: true) ⇒ Array<String>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • except (Symbol) (defaults to: :none)
  • resolve_variable_references (Boolean) (defaults to: true)

Returns:



487
488
489
# File 'os/linux/elf.rb', line 487

def dynamically_linked_libraries(except: :none, resolve_variable_references: true)
  .dylibs
end

#elf? ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


72
73
74
75
76
77
78
79
80
# File 'os/linux/elf.rb', line 72

def elf?
  return @elf unless @elf.nil?

  return @elf = false if read(MAGIC_NUMBER_ASCII.size, MAGIC_NUMBER_OFFSET) != MAGIC_NUMBER_ASCII

  # Check that this ELF file is for Linux or System V.
  # OS_ABI is often set to 0 (System V), regardless of the target platform.
  @elf = [OS_ABI_LINUX, OS_ABI_SYSTEM_V].include? read_uint8(OS_ABI_OFFSET)
end

#elf_type ⇒ Symbol

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



108
109
110
111
112
113
114
115
116
# File 'os/linux/elf.rb', line 108

def elf_type
  return :dunno unless elf?

  @elf_type ||= case read_uint16(TYPE_OFFSET)
  when TYPE_EXECUTABLE then :executable
  when TYPE_SHARED then :dylib
  else :dunno
  end
end

#initialize(path) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • path (T.anything)


48
49
50
51
52
53
54
55
56
57
58
59
# File 'os/linux/elf.rb', line 48

def initialize(path)
  @elf = T.let(nil, T.nilable(T::Boolean))
  @arch = T.let(nil, T.nilable(Symbol))
  @elf_type = T.let(nil, T.nilable(Symbol))
  @rpath = T.let(nil, T.nilable(String))
  @interpreter = T.let(nil, T.nilable(String))
  @dynamic_elf = T.let(nil, T.nilable(T::Boolean))
  @metadata = T.let(nil, T.nilable(Metadata))
  @section_names = T.let(nil, T.nilable(T::Array[String]))

  super
end

#interpreter ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



143
144
145
# File 'os/linux/elf.rb', line 143

def interpreter
  .interpreter
end

#patch!(interpreter: nil, rpath: nil) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Parameters:

  • interpreter (String, nil) (defaults to: nil)
  • rpath (String, nil) (defaults to: nil)


153
154
155
156
157
# File 'os/linux/elf.rb', line 153

def patch!(interpreter: nil, rpath: nil)
  return if interpreter.blank? && rpath.blank?

  save_using_patchelf_rb interpreter, rpath
end

#patchelf_patcher ⇒ ::PatchELF::Patcher

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Don't cache the patcher; it keeps the ELF file open so long as it is alive. Instead, for read-only access to the ELF file's metadata, fetch it and cache it with Metadata. PatchELF is loaded lazily inside this method, so avoid evaluating its return type at runtime before the constant is defined.

Returns:

  • (::PatchELF::Patcher)


470
471
472
473
# File 'os/linux/elf.rb', line 470

def patchelf_patcher
  require "patchelf"
  ::PatchELF::Patcher.new to_s, on_error: :silent
end

#pie? ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


148
149
150
# File 'os/linux/elf.rb', line 148

def pie?
  .pie?
end

#read_uint16(offset) ⇒ Integer

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



67
68
69
# File 'os/linux/elf.rb', line 67

def read_uint16(offset)
  read(2, offset).unpack1("v")
end

#read_uint8(offset) ⇒ Integer

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



62
63
64
# File 'os/linux/elf.rb', line 62

def read_uint8(offset)
  read(1, offset).unpack1("C")
end

#rpath ⇒ String?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

The runtime search path, such as: "/lib:/usr/lib:/usr/local/lib"

Returns:



131
132
133
# File 'os/linux/elf.rb', line 131

def rpath
  .rpath
end

#rpaths ⇒ Array<String>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

An array of runtime search path entries, such as: ["/lib", "/usr/lib", "/usr/local/lib"]

Returns:



138
139
140
# File 'os/linux/elf.rb', line 138

def rpaths
  Array(rpath&.split(":"))
end

#save_using_patchelf_rb(new_interpreter, new_rpath) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Parameters:



457
458
459
460
461
462
# File 'os/linux/elf.rb', line 457

def save_using_patchelf_rb(new_interpreter, new_rpath)
  patcher = patchelf_patcher
  patcher.interpreter = new_interpreter if new_interpreter.present?
  patcher.rpath = new_rpath if new_rpath.present?
  patcher.save(patchelf_compatible: true)
end

#section_names ⇒ Array<String>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Only bottling needs these and reading every section header costs far more than the rest of Metadata, so read them separately on demand.

Returns:



167
168
169
170
171
172
# File 'os/linux/elf.rb', line 167

def section_names
  @section_names ||= begin
    require "elftools"
    open("rb") { |file| ELFTools::ELFFile.new(file).sections.map(&:name).compact_blank }
  end
end