Class: Elf::Section

Inherits:
Object
  • Object
show all
Defined in:
lib/elf/section.rb,
lib/elf/section.rb

Defined Under Namespace

Classes: Flags, Type, UnknownType

Constant Summary collapse

Undef =

Reserved sections’ indexes

nil
Reserved =

Would be ‘0’, but this fits enough

0xff00..0xffff
ProcSpecific =
0xff00..0xff1f
OsSpecific =
0xff20..0xff3f
SunW =

Sun-specific range, subset of OS-specific range

0xff3f..0xff3f
SunWIgnore =
0xff3f
Abs =

Absolute symbols

0xfff1
Common =

Common symbols

0xfff2
XIndex =
0xffff
FlagsToChars =
[
 [Flags::Write, "W"],
 [Flags::Alloc, "A"],
 [Flags::ExecInstr, "X"],
 [Flags::Merge, "M"],
 [Flags::Strings, "S"],
 [Flags::InfoLink, "I"],
 [Flags::LinkOrder, "L"],
 [Flags::Group, "G"],
 [Flags::TLS, "T" ],
 [Flags::Exclude, "E"],
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(elf, index, sectdata, type) ⇒ Section

Returns a new instance of Section.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/elf/section.rb', line 116

def initialize(elf, index, sectdata, type)
  @file =      elf
  @index =     index
  @type =      type
  @name =      sectdata[:name_idx]
  @flags_val = sectdata[:flags_val]
  @addr =      sectdata[:addr]
  @offset =    sectdata[:offset]
  @size =      sectdata[:size]
  @link =      sectdata[:link]
  @info =      sectdata[:info]
  @addralign = sectdata[:addralign]
  @entsize =   sectdata[:entsize]

  @numentries = @size/@entsize unless @entsize == 0
end

Instance Attribute Details

#addrObject (readonly)

Returns the value of attribute addr.



113
114
115
# File 'lib/elf/section.rb', line 113

def addr
  @addr
end

#addralignObject (readonly)

Returns the value of attribute addralign.



114
115
116
# File 'lib/elf/section.rb', line 114

def addralign
  @addralign
end

#entsizeObject (readonly)

Returns the value of attribute entsize.



114
115
116
# File 'lib/elf/section.rb', line 114

def entsize
  @entsize
end

#fileObject (readonly)

Returns the value of attribute file.



113
114
115
# File 'lib/elf/section.rb', line 113

def file
  @file
end

#indexObject (readonly) Also known as: to_i

Returns the value of attribute index.



113
114
115
# File 'lib/elf/section.rb', line 113

def index
  @index
end

#infoObject (readonly)

Returns the value of attribute info.



114
115
116
# File 'lib/elf/section.rb', line 114

def info
  @info
end

#offsetObject (readonly)

Returns the value of attribute offset.



113
114
115
# File 'lib/elf/section.rb', line 113

def offset
  @offset
end

#sizeObject (readonly)

Returns the value of attribute size.



113
114
115
# File 'lib/elf/section.rb', line 113

def size
  @size
end

#typeObject (readonly)

Returns the value of attribute type.



113
114
115
# File 'lib/elf/section.rb', line 113

def type
  @type
end

Class Method Details

.read(elf, index, sectdata) ⇒ Object

Create a new Section object reading the section’s header from the file. This function assumes that the elf file is aligned ad the start of a section header, and returns the file moved at the start of the next header.

Raises:



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/elf/section.rb', line 58

def Section.read(elf, index, sectdata)
  begin
    if Type::ProcSpecific.include?(sectdata[:type_id])
      begin
        case elf.machine
        when Elf::Machine::ARM
          type = Type::ProcARM[sectdata[:type_id]]
        else
          type = Type[sectdata[:type_id]]
        end
      rescue Value::OutOfBound
        type = Type[sectdata[:type_id]]
      end
    elsif Type::OsSpecific.include?(sectdata[:type_id])
      begin
        # Unfortunately, even though OS ABIs are well-defined for both
        # GNU/Linux and Solaris, they don't seem to get used at all.
        #
        # For this reason, instead of basing ourselves on (just) the
        # OS ABI, the name of the section is used to identify the type
        # of section to use

        # Don't set the name if there is no string table loaded
        name = elf.string_table ? elf.string_table[sectdata[:name_idx]] : ""
        if elf.abi == Elf::OsAbi::Solaris or
            name =~ /^\.SUNW_/
          type = Type::SunW[sectdata[:type_id]]
        elsif elf.abi == Elf::OsAbi::Linux or
            name =~ /^\.gnu\./
          type = Type::GNU[sectdata[:type_id]]
        else
          type = Type[sectdata[:type_id]]
        end
      rescue Value::OutOfBound
        type = Type[sectdata[:type_id]]
      end
    else
      type = Type[sectdata[:type_id]]
    end
    type = nil if Type.is_a? Value::Unknown
  rescue Value::OutOfBound
    type = nil
  end

  raise UnknownType.new(sectdata[:type_id],
                        elf.string_table ? elf.string_table[sectdata[:name_idx]] : sectdata[:name_idx]
                        ) if type.nil?

  if Type::Class[type]
    return Type::Class[type].new(elf, index, sectdata, type)
  else
    return Section.new(elf, index, sectdata, type)
  end
end

Instance Method Details

#==(other) ⇒ Object

Raises:

  • (TypeError)


133
134
135
136
137
138
139
140
141
142
# File 'lib/elf/section.rb', line 133

def ==(other)
  # For the sake of retrocompatibility and code readability,
  # accept these two types as a valid (albeit false) comparison.
  return false if other.nil? or other.is_a? Integer

  raise TypeError.new("wrong argument type #{other.class} (expected Elf::Section)") unless
    other.is_a? Section

  other.file == @file and other.addr == @addr
end

#flagsObject

Return a set of flag items, easier to check for single elements.



203
204
205
206
207
208
209
210
211
212
# File 'lib/elf/section.rb', line 203

def flags
  return @flags if @flags

  @flags = Set.new
  Flags.each do |flag|
    flags.add(flag) if (@flags_val & flag.val) == flag.val
  end

  @flags
end

#flags_iObject



240
241
242
# File 'lib/elf/section.rb', line 240

def flags_i
  @flags_val
end

#flags_sObject



227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/elf/section.rb', line 227

def flags_s
  return @flags_s if @flags_s

  @flags_s = FlagsToChars.collect { |flag, char|
    flags.include?(flag) ? char : ""
  }.join

  @flags_s << 'o' if (@flags_val & Flags::MaskOS) != 0
  @flags_s << 'p' if (@flags_val & Flags::MaskProc) != 0

  return @flags_s
end


158
159
160
161
162
163
164
165
# File 'lib/elf/section.rb', line 158

def link
  # We didn't get the linked section header yet
  if @link.is_a? Integer
    @link = @file[@link]
  end

  @link
end

#loadObject



167
168
169
170
171
172
173
174
# File 'lib/elf/section.rb', line 167

def load
  oldpos = @file.tell
  @file.seek(@offset, IO::SEEK_SET)

  load_internal

  @file.seek(oldpos, IO::SEEK_SET)
end

#nameObject Also known as: to_s



144
145
146
147
148
149
150
151
152
# File 'lib/elf/section.rb', line 144

def name
  # We didn't read the name in form of string yet;
  # Check if the file has loaded a string table yet
  if @name.is_a? Integer and @file.string_table
    @name = @file.string_table[@name]
  end

  @name
end

#summaryObject



176
177
178
# File 'lib/elf/section.rb', line 176

def summary
  $stdout.puts "#{name}\t\t#{@type}\t#{@flags_val}\t#{@addr}\t#{@offset}\t#{@size}\t#{@link}\t#{@info}\t#{@addralign}\t#{@entsize}"
end