Class: Elf::Symbol
- Inherits:
-
Object
- Object
- Elf::Symbol
- Defined in:
- lib/elf/symbol.rb
Defined Under Namespace
Classes: Binding, InvalidName, Type, UnknownNMCode, Visibility
Instance Attribute Summary collapse
-
#bind ⇒ Object
readonly
Returns the value of attribute bind.
-
#file ⇒ Object
readonly
Returns the value of attribute file.
-
#idx ⇒ Object
readonly
Returns the value of attribute idx.
-
#other ⇒ Object
readonly
Returns the value of attribute other.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
-
#value ⇒ Object
readonly
Returns the value of attribute value.
-
#visibility ⇒ Object
readonly
Returns the value of attribute visibility.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Check whether two symbols are the same.
-
#=~(other) ⇒ Object
Check whether one symbol is compatible with the other.
-
#address_string ⇒ Object
Reports the symbol’s address as a string, if any is provided.
- #defined? ⇒ Boolean
-
#demangle ⇒ Object
begin Demanglers = [ ] def demangle return @demangled if @demangled.
- #eql?(other) ⇒ Boolean
-
#initialize(elf, symsect, idx) ⇒ Symbol
constructor
Create a new Symbol object reading the symbol structure from the file.
- #name ⇒ Object (also: #to_s)
-
#nm_code ⇒ Object
Show the letter code as compatible with GNU nm.
-
#nm_code_internal ⇒ Object
Convenience function for the first tile the nm code is requested.
- #section ⇒ Object
- #version ⇒ Object
-
#version_default? ⇒ Boolean
the default symbol version is the one that the link editor will use when linking against the library; any symbol is the default symbol unless bit 15 of its version index is set.
Constructor Details
#initialize(elf, symsect, idx) ⇒ Symbol
Create a new Symbol object reading the symbol structure from the file. This function assumes that the elf file is aligned ad the start of a symbol structure, and returns the file moved at the start of the symbol.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/elf/symbol.rb', line 93 def initialize(elf, symsect, idx) @symsect = symsect @idx = idx case elf.elf_class when Class::Elf32 @name = elf.read_word @value = elf.read_addr @size = elf.read_word info = elf.read_u8 @other = elf.read_u8 @section = elf.read_section when Class::Elf64 @name = elf.read_word info = elf.read_u8 @other = elf.read_u8 @section = elf.read_section @value = elf.read_addr @size = elf.read_xword end begin type_value = info & 0xF @type = case when Type::OsSpecific.include?(type_value) # Assume always GNU for now, but it's wrong Type::GNU[type_value] else Type[type_value] end binding_value = info >> 4 @bind = case when Binding::OsSpecific.include?(binding_value) # Assume always GNU for now, but it's wrong Binding::GNU[binding_value] else Binding[binding_value] end rescue Elf::Value::OutOfBound => e e.(sprintf("While processing symbol %d. Symbol 'info' value: 0x%x", @idx, info)) raise e end begin @visibility = Visibility[@other & 0x03] rescue Elf::Value::OutOfBound => e e.(sprintf("While procesing symbol %d. Symbol 'other' value: 0x%x", @idx, other)) raise e end @file = elf end |
Instance Attribute Details
#bind ⇒ Object (readonly)
Returns the value of attribute bind.
87 88 89 |
# File 'lib/elf/symbol.rb', line 87 def bind @bind end |
#file ⇒ Object (readonly)
Returns the value of attribute file.
87 88 89 |
# File 'lib/elf/symbol.rb', line 87 def file @file end |
#idx ⇒ Object (readonly)
Returns the value of attribute idx.
87 88 89 |
# File 'lib/elf/symbol.rb', line 87 def idx @idx end |
#other ⇒ Object (readonly)
Returns the value of attribute other.
87 88 89 |
# File 'lib/elf/symbol.rb', line 87 def other @other end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
87 88 89 |
# File 'lib/elf/symbol.rb', line 87 def size @size end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
87 88 89 |
# File 'lib/elf/symbol.rb', line 87 def type @type end |
#value ⇒ Object (readonly)
Returns the value of attribute value.
87 88 89 |
# File 'lib/elf/symbol.rb', line 87 def value @value end |
#visibility ⇒ Object (readonly)
Returns the value of attribute visibility.
87 88 89 |
# File 'lib/elf/symbol.rb', line 87 def visibility @visibility end |
Instance Method Details
#==(other) ⇒ Object
Check whether two symbols are the same
This function compares the name, version and section of two symbols to tell if they are the same symbol.
342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/elf/symbol.rb', line 342 def ==(other) return false unless other.is_a? Symbol return false unless name == other.name return false unless version == other.version return false if section == nil and other.section != nil return false if section != nil and other.section == nil return true end |
#=~(other) ⇒ Object
Check whether one symbol is compatible with the other
This function compares the name and version of two symbols, and ensures that only one of them is undefined; this allows to establish whether one symbol might be satisfied by another.
363 364 365 366 367 368 369 370 371 372 373 |
# File 'lib/elf/symbol.rb', line 363 def =~(other) return false unless other.is_a? Symbol return false unless name == other.name return false unless version == other.version return false if section == nil and other.section == nil return false if section != nil and other.section != nil return true end |
#address_string ⇒ Object
Reports the symbol’s address as a string, if any is provided
Reports a string full of whitespace if the symbols is not defined (as there is no address)
334 335 336 |
# File 'lib/elf/symbol.rb', line 334 def address_string section ? sprintf("%0#{@file.address_print_size}x", value) : '' end |
#defined? ⇒ Boolean
219 220 221 222 223 224 |
# File 'lib/elf/symbol.rb', line 219 def defined? return false if section.nil? return false if section.is_a?(Integer) return false if bind == Binding::Weak and value == 0 return true end |
#demangle ⇒ Object
begin
Demanglers = [ ]
def demangle
return @demangled if @demangled
Demanglers.each do |demangler|
break if (@demangled ||= demangler.demangle(name))
end
# We're going to remove top-namespace specifications as we don't
# need them, but it's easier for the demangler to still emit
# them.
@demangled.gsub!(/(^| |\()::/, '\1') if @demangled
return @demangled ||= name
end
rescue LoadError
392 393 394 |
# File 'lib/elf/symbol.rb', line 392 def demangle return name end |
#eql?(other) ⇒ Boolean
354 355 356 |
# File 'lib/elf/symbol.rb', line 354 def eql?(other) return self == other end |
#name ⇒ Object Also known as: to_s
158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/elf/symbol.rb', line 158 def name # We didn't read the name in form of string yet; if @name.is_a? Integer and @symsect.link begin name = @symsect.link[@name] rescue Utilities::OffsetTable::InvalidIndex raise InvalidName.new(@name, self, @symsect) end @name = name if name end @name end |
#nm_code ⇒ Object
Show the letter code as compatible with GNU nm
This function has been moved inside the library since multiple tools based on ruby-elf would be using these code to report symbols, and since the code is complex it’s easier to have it here.
The resturned value is a one-letter string. The function may raise an UnknownNMCode exception.
250 251 252 |
# File 'lib/elf/symbol.rb', line 250 def nm_code @nmflag ||= nm_code_internal end |
#nm_code_internal ⇒ Object
Convenience function for the first tile the nm code is requested.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/elf/symbol.rb', line 255 def nm_code_internal nmflag = nil case when idx == 0 return " " # When the section is nil, it means it goes into the Undef # section, and the symbol is not defined. when section.nil? nmflag = "U" when bind == Binding::Weak nmflag = case type when Type::Object then 'V' # we cannot use 'v' when value is zero, as for a # variable, a zero address is correct, it's just # functions that cannot be at zero address. when value == 0 then 'w' else 'W' end when bind == Binding::GNU::Unique nmflag = 'u' when section == Elf::Section::Abs nmflag = "A" when type == Type::Common, section == Elf::Section::Common # section check _should_ be limited to objects with # Type::Data, but turns out that ICC does not emit # uninitialised variables correctly, creating a Type::None # object defined in Section::Common. Handle that properly. nmflag = 'C' when type == Type::Object, type == Type::TLS # data object, distinguish between writable or read-only data, # as well as data in Section::Type::NoBits sections. nmflag = case when section.is_a?(Integer) then nil when !section.flags.include?(Elf::Section::Flags::Write) then "R" when section.type == Elf::Section::Type::NoBits then "B" else "D" end when type == Type::None # try being smarter than simply reporthing this as a none-type # symbol, as some compilers (namely pathCC) emit STT_NONE # symbols that are instead functions. nmflag = case when section.is_a?(Integer) then "N" when section.flags.include?(Elf::Section::Flags::ExecInstr) then "T" when section.type == Elf::Section::Type::NoBits then "B" else "N" end when type == Type::Func nmflag = 'T' when type == Type::Section nmflag = 'S' when type == Type::File nmflag = 'F' when type == Type::GNU::IFunc nmflag = 'i' end # If we haven't found the flag with the above code, we don't # know what to use, so raise exception. raise UnknownNMCode.new(self) if nmflag.nil? nmflag = nmflag.dup nmflag.downcase! if bind == Binding::Local return nmflag end |
#section ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/elf/symbol.rb', line 175 def section # We didn't read the section yet. @section = nil if @section.is_a? Integer and @section == 0 if @section.is_a? Integer and not Section::Reserved.include?(@section) and @file.has_section?(@section) @section = @file[@section] end @section end |
#version ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/elf/symbol.rb', line 189 def version # bit 15 is meant to say that this symbol is _not_ the default # version to link to; we don't care about that here so we simply # ignore its presence. version_idx = version_index & ~(1 << 15) return nil unless version_idx && version_idx >= 1 return '' if version_idx == 1 begin if section.nil? return @file['.gnu.version_r'][version_idx][:name] else return @file['.gnu.version_d'][version_idx][:names][0] end rescue Elf::File::MissingSection return @file['.gnu.version_r'][version_idx][:name] end end |
#version_default? ⇒ Boolean
the default symbol version is the one that the link editor will use when linking against the library; any symbol is the default symbol unless bit 15 of its version index is set.
An undefined symbol cannot be the default symbol
215 216 217 |
# File 'lib/elf/symbol.rb', line 215 def version_default? !section.nil? and (version_index & (1 << 15) == 0) end |