Added a "sources.py" which adds a command that can print out the source files contained in one or more modules.

Added "mach_o.py" which is a mach-o parser that can dump mach-o file contents and also extract sections. It uses the "file_extract" module and the "dict_utils" module.

llvm-svn: 189959
diff --git a/lldb/examples/python/file_extract.py b/lldb/examples/python/file_extract.py
new file mode 100755
index 0000000..3afc0c3
--- /dev/null
+++ b/lldb/examples/python/file_extract.py
@@ -0,0 +1,221 @@
+#! /usr/bin/env python
+
+import string
+import struct
+import sys
+
+class FileExtract:
+    '''Decode binary data from a file'''
+    
+    def __init__(self, f, b = '='):
+        '''Initialize with an open binary file and optional byte order'''
+        
+        self.file = f
+        self.byte_order = b
+        self.offsets = list()
+    
+    def set_byte_order(self, b):
+        '''Set the byte order, valid values are "big", "little", "swap", "native", "<", ">", "@", "="'''
+        if b == 'big':
+            self.byte_order = '>'
+        elif b == 'little':
+            self.byte_order = '<'
+        elif b == 'swap':
+            # swap what ever the current byte order is
+            self.byte_order = swap_unpack_char()
+        elif b == 'native':
+            self.byte_order = '='
+        elif b == '<' or b == '>' or b == '@' or b == '=':
+            self.byte_order = b
+        else:
+            print "error: invalid byte order specified: '%s'" % b
+
+    def is_in_memory(self):
+        return False
+    
+    def seek(self, offset, whence = 0):
+        if self.file:
+            return self.file.seek(offset, whence)
+        raise ValueError    
+
+    def tell(self):
+        if self.file:
+            return self.file.tell()
+        raise ValueError    
+    
+    def read_size (self, byte_size):
+        s = self.file.read(byte_size)
+        if len(s) != byte_size:
+            return None
+        return s
+
+    def push_offset_and_seek(self, offset):
+        '''Push the current file offset and seek to "offset"'''
+        self.offsets.append(self.file.tell())
+        self.file.seek(offset, 0)
+    
+    def pop_offset_and_seek(self):
+        '''Pop a previously pushed file offset, or do nothing if there were no previously pushed offsets'''
+        if len(self.offsets) > 0:
+            self.file.seek(self.offsets.pop())
+        
+    def get_sint8(self, fail_value=0):
+        '''Extract a single int8_t from the binary file at the current file position, returns a single integer'''
+        s = self.read_size(1)
+        if s:
+            v, = struct.unpack(self.byte_order + 'b', s)
+            return v
+        else:
+            return fail_value
+
+    def get_uint8(self, fail_value=0):
+        '''Extract a single uint8_t from the binary file at the current file position, returns a single integer'''
+        s = self.read_size(1)
+        if s:
+            v, = struct.unpack(self.byte_order + 'B', s)
+            return v
+        else:
+            return fail_value
+
+    def get_sint16(self, fail_value=0):
+        '''Extract a single int16_t from the binary file at the current file position, returns a single integer'''
+        s = self.read_size(2)
+        if s:
+            v, = struct.unpack(self.byte_order + 'h', s)
+            return v
+        else:
+            return fail_value
+
+    def get_uint16(self, fail_value=0):
+        '''Extract a single uint16_t from the binary file at the current file position, returns a single integer'''
+        s = self.read_size(2)
+        if s:
+            v, = struct.unpack(self.byte_order + 'H', s)
+            return v
+        else:
+            return fail_value
+
+    def get_sint32(self, fail_value=0):
+        '''Extract a single int32_t from the binary file at the current file position, returns a single integer'''
+        s = self.read_size(4)
+        if s:
+            v, = struct.unpack(self.byte_order + 'i', s)
+            return v
+        else:
+            return fail_value
+
+    def get_uint32(self, fail_value=0):
+        '''Extract a single uint32_t from the binary file at the current file position, returns a single integer'''
+        s = self.read_size(4)
+        if s:
+            v, = struct.unpack(self.byte_order + 'I', s)
+            return v
+        else:
+            return fail_value
+        
+    def get_sint64(self, fail_value=0):
+        '''Extract a single int64_t from the binary file at the current file position, returns a single integer'''
+        s = self.read_size(8)
+        if s:
+            v, = struct.unpack(self.byte_order + 'q', s)
+            return v
+        else:
+            return fail_value
+
+    def get_uint64(self, fail_value=0):
+        '''Extract a single uint64_t from the binary file at the current file position, returns a single integer'''
+        s = self.read_size(8)
+        if s:
+            v, = struct.unpack(self.byte_order + 'Q', s)
+            return v
+        else:
+            return fail_value
+
+    def get_fixed_length_c_string(self, n, fail_value='', isprint_only_with_space_padding=False):
+        '''Extract a single fixed length C string from the binary file at the current file position, returns a single C string'''
+        s = self.read_size(n)
+        if s:
+            cstr, = struct.unpack(self.byte_order + ("%i" % n) + 's', s)
+            # Strip trialing NULLs
+            cstr = string.strip(cstr, "\0")
+            if isprint_only_with_space_padding:
+                for c in cstr:
+                    if c in string.printable or ord(c) == 0:
+                        continue
+                    return fail_value
+            return cstr
+        else:
+            return fail_value
+
+    def get_c_string(self):
+        '''Extract a single NULL terminated C string from the binary file at the current file position, returns a single C string'''
+        cstr = ''
+        byte = self.get_uint8()
+        while byte != 0:
+            cstr += "%c" % byte
+            byte = self.get_uint8()
+        return cstr
+
+    def get_n_sint8(self, n, fail_value=0):
+        '''Extract "n" int8_t integers from the binary file at the current file position, returns a list of integers'''
+        s = self.read_size(n)
+        if s:
+            return struct.unpack(self.byte_order + ("%u" % n) + 'b', s)
+        else:
+            return (fail_value,) * n
+
+    def get_n_uint8(self, n, fail_value=0):
+        '''Extract "n" uint8_t integers from the binary file at the current file position, returns a list of integers'''
+        s = self.read_size(n)
+        if s:
+            return struct.unpack(self.byte_order + ("%u" % n) + 'B', s)
+        else:
+            return (fail_value,) * n
+
+    def get_n_sint16(self, n, fail_value=0):
+        '''Extract "n" int16_t integers from the binary file at the current file position, returns a list of integers'''
+        s = self.read_size(2*n)
+        if s:
+            return struct.unpack(self.byte_order + ("%u" % n) + 'h', s)
+        else:
+            return (fail_value,) * n
+
+    def get_n_uint16(self, n, fail_value=0):
+        '''Extract "n" uint16_t integers from the binary file at the current file position, returns a list of integers'''
+        s = self.read_size(2*n)
+        if s:
+            return struct.unpack(self.byte_order + ("%u" % n) + 'H', s)
+        else:
+            return (fail_value,) * n
+
+    def get_n_sint32(self, n, fail_value=0):
+        '''Extract "n" int32_t integers from the binary file at the current file position, returns a list of integers'''
+        s = self.read_size(4*n)
+        if s:
+            return struct.unpack(self.byte_order + ("%u" % n) + 'i', s)
+        else:
+            return (fail_value,) * n
+
+    def get_n_uint32(self, n, fail_value=0):
+        '''Extract "n" uint32_t integers from the binary file at the current file position, returns a list of integers'''
+        s = self.read_size(4*n)
+        if s:
+            return struct.unpack(self.byte_order + ("%u" % n) + 'I', s)
+        else:
+            return (fail_value,) * n
+
+    def get_n_sint64(self, n, fail_value=0):
+        '''Extract "n" int64_t integers from the binary file at the current file position, returns a list of integers'''
+        s = self.read_size(8*n)
+        if s:
+            return struct.unpack(self.byte_order + ("%u" % n) + 'q', s)
+        else:
+            return (fail_value,) * n
+
+    def get_n_uint64(self, n, fail_value=0):
+        '''Extract "n" uint64_t integers from the binary file at the current file position, returns a list of integers'''
+        s = self.read_size(8*n)
+        if s:
+            return struct.unpack(self.byte_order + ("%u" % n) + 'Q', s)
+        else:
+            return (fail_value,) * n