Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / examples / python / file_extract.py
blob1a9b313b285895694b9e5e6e054d3ccbe1a603c4
1 #!/usr/bin/env python
3 import string
4 import struct
5 import sys
8 class FileExtract:
9 """Decode binary data from a file"""
11 def __init__(self, f, b="="):
12 """Initialize with an open binary file and optional byte order"""
14 self.file = f
15 self.byte_order = b
16 self.offsets = list()
18 def set_byte_order(self, b):
19 '''Set the byte order, valid values are "big", "little", "swap", "native", "<", ">", "@", "="'''
20 if b == "big":
21 self.byte_order = ">"
22 elif b == "little":
23 self.byte_order = "<"
24 elif b == "swap":
25 # swap what ever the current byte order is
26 self.byte_order = swap_unpack_char()
27 elif b == "native":
28 self.byte_order = "="
29 elif b == "<" or b == ">" or b == "@" or b == "=":
30 self.byte_order = b
31 else:
32 print("error: invalid byte order specified: '%s'" % b)
34 def is_in_memory(self):
35 return False
37 def seek(self, offset, whence=0):
38 if self.file:
39 return self.file.seek(offset, whence)
40 raise ValueError
42 def tell(self):
43 if self.file:
44 return self.file.tell()
45 raise ValueError
47 def read_size(self, byte_size):
48 s = self.file.read(byte_size)
49 if len(s) != byte_size:
50 return None
51 return s
53 def push_offset_and_seek(self, offset):
54 '''Push the current file offset and seek to "offset"'''
55 self.offsets.append(self.file.tell())
56 self.file.seek(offset, 0)
58 def pop_offset_and_seek(self):
59 """Pop a previously pushed file offset, or do nothing if there were no previously pushed offsets"""
60 if len(self.offsets) > 0:
61 self.file.seek(self.offsets.pop())
63 def get_sint8(self, fail_value=0):
64 """Extract a single int8_t from the binary file at the current file position, returns a single integer"""
65 s = self.read_size(1)
66 if s:
67 (v,) = struct.unpack(self.byte_order + "b", s)
68 return v
69 else:
70 return fail_value
72 def get_uint8(self, fail_value=0):
73 """Extract a single uint8_t from the binary file at the current file position, returns a single integer"""
74 s = self.read_size(1)
75 if s:
76 (v,) = struct.unpack(self.byte_order + "B", s)
77 return v
78 else:
79 return fail_value
81 def get_sint16(self, fail_value=0):
82 """Extract a single int16_t from the binary file at the current file position, returns a single integer"""
83 s = self.read_size(2)
84 if s:
85 (v,) = struct.unpack(self.byte_order + "h", s)
86 return v
87 else:
88 return fail_value
90 def get_uint16(self, fail_value=0):
91 """Extract a single uint16_t from the binary file at the current file position, returns a single integer"""
92 s = self.read_size(2)
93 if s:
94 (v,) = struct.unpack(self.byte_order + "H", s)
95 return v
96 else:
97 return fail_value
99 def get_sint32(self, fail_value=0):
100 """Extract a single int32_t from the binary file at the current file position, returns a single integer"""
101 s = self.read_size(4)
102 if s:
103 (v,) = struct.unpack(self.byte_order + "i", s)
104 return v
105 else:
106 return fail_value
108 def get_uint32(self, fail_value=0):
109 """Extract a single uint32_t from the binary file at the current file position, returns a single integer"""
110 s = self.read_size(4)
111 if s:
112 (v,) = struct.unpack(self.byte_order + "I", s)
113 return v
114 else:
115 return fail_value
117 def get_sint64(self, fail_value=0):
118 """Extract a single int64_t from the binary file at the current file position, returns a single integer"""
119 s = self.read_size(8)
120 if s:
121 (v,) = struct.unpack(self.byte_order + "q", s)
122 return v
123 else:
124 return fail_value
126 def get_uint64(self, fail_value=0):
127 """Extract a single uint64_t from the binary file at the current file position, returns a single integer"""
128 s = self.read_size(8)
129 if s:
130 (v,) = struct.unpack(self.byte_order + "Q", s)
131 return v
132 else:
133 return fail_value
135 def get_fixed_length_c_string(
136 self, n, fail_value="", isprint_only_with_space_padding=False
138 """Extract a single fixed length C string from the binary file at the current file position, returns a single C string"""
139 s = self.read_size(n)
140 if s:
141 (cstr,) = struct.unpack(self.byte_order + ("%i" % n) + "s", s)
142 # Strip trialing NULLs
143 cstr = string.strip(cstr, "\0")
144 if isprint_only_with_space_padding:
145 for c in cstr:
146 if c in string.printable or ord(c) == 0:
147 continue
148 return fail_value
149 return cstr
150 else:
151 return fail_value
153 def get_c_string(self):
154 """Extract a single NULL terminated C string from the binary file at the current file position, returns a single C string"""
155 cstr = ""
156 byte = self.get_uint8()
157 while byte != 0:
158 cstr += "%c" % byte
159 byte = self.get_uint8()
160 return cstr
162 def get_n_sint8(self, n, fail_value=0):
163 """Extract "n" int8_t integers from the binary file at the current file position, returns a list of integers"""
164 s = self.read_size(n)
165 if s:
166 return struct.unpack(self.byte_order + ("%u" % n) + "b", s)
167 else:
168 return (fail_value,) * n
170 def get_n_uint8(self, n, fail_value=0):
171 """Extract "n" uint8_t integers from the binary file at the current file position, returns a list of integers"""
172 s = self.read_size(n)
173 if s:
174 return struct.unpack(self.byte_order + ("%u" % n) + "B", s)
175 else:
176 return (fail_value,) * n
178 def get_n_sint16(self, n, fail_value=0):
179 """Extract "n" int16_t integers from the binary file at the current file position, returns a list of integers"""
180 s = self.read_size(2 * n)
181 if s:
182 return struct.unpack(self.byte_order + ("%u" % n) + "h", s)
183 else:
184 return (fail_value,) * n
186 def get_n_uint16(self, n, fail_value=0):
187 """Extract "n" uint16_t integers from the binary file at the current file position, returns a list of integers"""
188 s = self.read_size(2 * n)
189 if s:
190 return struct.unpack(self.byte_order + ("%u" % n) + "H", s)
191 else:
192 return (fail_value,) * n
194 def get_n_sint32(self, n, fail_value=0):
195 """Extract "n" int32_t integers from the binary file at the current file position, returns a list of integers"""
196 s = self.read_size(4 * n)
197 if s:
198 return struct.unpack(self.byte_order + ("%u" % n) + "i", s)
199 else:
200 return (fail_value,) * n
202 def get_n_uint32(self, n, fail_value=0):
203 """Extract "n" uint32_t integers from the binary file at the current file position, returns a list of integers"""
204 s = self.read_size(4 * n)
205 if s:
206 return struct.unpack(self.byte_order + ("%u" % n) + "I", s)
207 else:
208 return (fail_value,) * n
210 def get_n_sint64(self, n, fail_value=0):
211 """Extract "n" int64_t integers from the binary file at the current file position, returns a list of integers"""
212 s = self.read_size(8 * n)
213 if s:
214 return struct.unpack(self.byte_order + ("%u" % n) + "q", s)
215 else:
216 return (fail_value,) * n
218 def get_n_uint64(self, n, fail_value=0):
219 """Extract "n" uint64_t integers from the binary file at the current file position, returns a list of integers"""
220 s = self.read_size(8 * n)
221 if s:
222 return struct.unpack(self.byte_order + ("%u" % n) + "Q", s)
223 else:
224 return (fail_value,) * n