lib/indis-macho/command.rb in indis-macho-0.2.0 vs lib/indis-macho/command.rb in indis-macho-0.3.0
- old
+ new
@@ -15,10 +15,11 @@
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
##############################################################################
require 'indis-macho/symbol'
+require 'indis-macho/dyld_info_parser'
module Indis
module MachO
class UnknownCommandError < RuntimeError; end
@@ -138,15 +139,57 @@
end
class SectionSubCommand < Command # LC_SEGMENT.sub
f_string :sectname, 16
f_string :segname, 16
- f_uint32 :addr, :size, :offset, :align, :reloff, :nreloc, :flags, :reserved1, :reseved2
+ f_uint32 :addr, :size, :offset, :align, :reloff, :nreloc, :flags, :reserved1, :reserved2
attr_accessor :index
+ attr_reader :type, :attributes
+ SECTION_TYPE_MASK = 0x000000ff
+ SECTION_ATTRIBUTES_MASK = 0xffffff00
+
+ SECTION_TYPE = {
+ 0x00 => :S_REGULAR, # regular section
+ 0x01 => :S_ZEROFILL, # zero-fill on demand section
+ 0x02 => :S_CSTRING_LITERALS, # section with only literal C strings
+ 0x03 => :S_4BYTE_LITERALS, # section with only 4 byte literals
+ 0x04 => :S_8BYTE_LITERALS, # section with only 8 byte literals
+ 0x05 => :S_LITERAL_POINTERS, # section with only pointers to literals
+ 0x06 => :S_NON_LAZY_SYMBOL_POINTERS, # section with only non-lazy symbol pointers
+ 0x07 => :S_LAZY_SYMBOL_POINTERS, # section with only lazy symbol pointers
+ 0x08 => :S_SYMBOL_STUBS, # section with only symbol stubs (s.a. byte size of stub in the reserved2)
+ 0x09 => :S_MOD_INIT_FUNC_POINTERS, # section with only function pointers for initialization
+ 0x0a => :S_MOD_TERM_FUNC_POINTERS, # section with only function pointers for termination
+ 0x0b => :S_COALESCED, # section contains symbols that are to be coalesced
+ 0x0c => :S_GB_ZEROFILL, # zero fill on demand section (>4Gb)
+ 0x0d => :S_INTERPOSING, # section with only pairs of function pointers for interposing
+ 0x0e => :S_16BYTE_LITERALS, # section with only 16 byte literals
+ 0x0f => :S_DTRACE_DOF, # section contains DTrace Object Format
+ 0x10 => :S_LAZY_DYLIB_SYMBOL_POINTERS, # section with only lazy symbol pointers to lazy loaded dylibs
+ 0x11 => :S_THREAD_LOCAL_REGULAR, # template of initial values for TLVs
+ 0x12 => :S_THREAD_LOCAL_ZEROFILL, # template of initial values for TLVs (zero-filled on demand?)
+ 0x13 => :S_THREAD_LOCAL_VARIABLES, # TLV descriptors
+ 0x14 => :S_THREAD_LOCAL_VARIABLE_POINTERS, # pointers to TLV descriptors
+ 0x15 => :S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, # functions to call to initialize TLV values
+ }
+
+ SECTION_ATTRIBUTES = {
+ 0x80000000 => :S_ATTR_PURE_INSTRUCTIONS, # section contains only true machine instructions
+ 0x40000000 => :S_ATTR_NO_TOC, # section contains coalesced symbols that are not to be in a ranlib table of contents
+ 0x20000000 => :S_ATTR_STRIP_STATIC_SYMS, # ok to strip static symbols in this section in files with the MH_DYLDLINK flag
+ 0x10000000 => :S_ATTR_NO_DEAD_STRIP, # no dead stripping
+ 0x08000000 => :S_ATTR_LIVE_SUPPORT, # blocks are live if they reference live blocks
+ 0x04000000 => :S_ATTR_SELF_MODIFYING_CODE, # Used with i386 code stubs written on by dyld
+ # s.a. S_ATTR_DEBUG & friends in loader.h
+ }
+
def initialize(payload)
process(payload)
+ @type = SECTION_TYPE[@flags & SECTION_TYPE_MASK]
+ atr = @falgs & SECTION_ATTRIBUTES_MASK
+ @attributes = SECTION_ATTRIBUTES.map { |k,v| (atr & k == k) ? v : nil }.compact
end
end
class SegmentCommand < Command # LC_SEGMENT
f_string :segname, 16
@@ -189,10 +232,20 @@
class DySymTabCommand < Command # LC_DYSYMTAB
f_uint32 :ilocalsym, :nlocalsym, :iextdefsym, :nextdefsym, :iundefsym, :nundefsym, :tocoff,
:ntoc, :modtaboff, :nmodtab, :extrefsymoff, :nextrefsyms, :indirectsymoff, :nindirectsyms,
:extreloff, :nextrel, :locreloff, :nlocrel
+ attr_reader :indirect_symbols
+
+ def process(payload)
+ super(payload)
+
+ ofs = payload.pos
+ payload.pos = @indirectsymoff
+ @indirect_symbols = payload.read(@nindirectsyms * 4).unpack('V*')
+ payload.pos = ofs
+ end
end
class LoadDyLinkerCommand < Command # LC_LOAD_DYLINKER
attr_reader :name
@@ -263,9 +316,33 @@
end
class DyldInfoOnlyCommand < Command # LC_DYLD_INFO_ONLY
f_uint32 :rebase_off, :rebase_size, :bind_off, :bind_size, :weak_bind_off, :weak_bind_size,
:lazy_bind_off, :lazy_bind_size, :export_off, :export_size
+ attr_reader :bind_symbols, :weak_bind_symbols, :lazy_bind_symbols
+
+ def process(payload)
+ super(payload)
+
+ # TODO: rebase
+
+ off = payload.pos
+ payload.pos = @bind_off
+ bind = payload.read(@bind_size)
+ @bind_symbols = DyldInfoParser.new(bind).parse if @bind_size > 0
+
+ payload.pos = @weak_bind_off
+ weak_bind = payload.read(@weak_bind_size)
+ @weak_bind_symbols = DyldInfoParser.new(weak_bind).parse if @weak_bind_size > 0
+
+ payload.pos = @lazy_bind_off
+ lazy_bind = payload.read(@lazy_bind_size)
+ @lazy_bind_symbols = DyldInfoParser.new(lazy_bind).parse if @lazy_bind_size > 0
+
+ # TODO: export
+
+ payload.pos = off
+ end
end
end
end
\ No newline at end of file