1#!/usr/bin/env python 2 3import lldb 4import struct 5 6 7class OperatingSystemPlugIn(object): 8 """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class""" 9 10 def __init__(self, process): 11 """Initialization needs a valid.SBProcess object. 12 13 This plug-in will get created after a live process is valid and has stopped for the 14 first time.""" 15 self.process = None 16 self.registers = None 17 self.threads = None 18 if isinstance(process, lldb.SBProcess) and process.IsValid(): 19 self.process = process 20 self.threads = None # Will be an dictionary containing info for each thread 21 22 def get_target(self): 23 # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target" 24 # tracks the current target in the LLDB command interpreter which isn't the 25 # correct thing to use for this plug-in. 26 return self.process.target 27 28 def create_thread(self, tid, context): 29 if tid == 0x444444444: 30 thread_info = { 31 "tid": tid, 32 "name": "four", 33 "queue": "queue4", 34 "state": "stopped", 35 "stop_reason": "none", 36 } 37 self.threads.append(thread_info) 38 return thread_info 39 return None 40 41 def get_thread_info(self): 42 if not self.threads: 43 # The sample dictionary below shows the values that can be returned for a thread 44 # tid => thread ID (mandatory) 45 # name => thread name (optional key/value pair) 46 # queue => thread dispatch queue name (optional key/value pair) 47 # state => thred state (mandatory, set to 'stopped' for now) 48 # stop_reason => thread stop reason. (mandatory, usually set to 'none') 49 # Possible values include: 50 # 'breakpoint' if the thread is stopped at a breakpoint 51 # 'none' thread is just stopped because the process is stopped 52 # 'trace' the thread just single stepped 53 # The usual value for this while threads are in memory is 'none' 54 # register_data_addr => the address of the register data in memory (optional key/value pair) 55 # Specifying this key/value pair for a thread will avoid a call to get_register_data() 56 # and can be used when your registers are in a thread context structure that is contiguous 57 # in memory. Don't specify this if your register layout in memory doesn't match the layout 58 # described by the dictionary returned from a call to the 59 # get_register_info() method. 60 self.threads = [{"tid": 0x111111111, "core": 0}] 61 return self.threads 62 63 def get_register_info(self): 64 if self.registers is None: 65 self.registers = dict() 66 self.registers["sets"] = ["GPR"] 67 self.registers["registers"] = [ 68 { 69 "name": "rax", 70 "bitsize": 64, 71 "offset": 0, 72 "encoding": "uint", 73 "format": "hex", 74 "set": 0, 75 "gcc": 0, 76 "dwarf": 0, 77 }, 78 { 79 "name": "rbx", 80 "bitsize": 64, 81 "offset": 8, 82 "encoding": "uint", 83 "format": "hex", 84 "set": 0, 85 "gcc": 3, 86 "dwarf": 3, 87 }, 88 { 89 "name": "rcx", 90 "bitsize": 64, 91 "offset": 16, 92 "encoding": "uint", 93 "format": "hex", 94 "set": 0, 95 "gcc": 2, 96 "dwarf": 2, 97 "generic": "arg4", 98 "alt-name": "arg4", 99 }, 100 { 101 "name": "rdx", 102 "bitsize": 64, 103 "offset": 24, 104 "encoding": "uint", 105 "format": "hex", 106 "set": 0, 107 "gcc": 1, 108 "dwarf": 1, 109 "generic": "arg3", 110 "alt-name": "arg3", 111 }, 112 { 113 "name": "rdi", 114 "bitsize": 64, 115 "offset": 32, 116 "encoding": "uint", 117 "format": "hex", 118 "set": 0, 119 "gcc": 5, 120 "dwarf": 5, 121 "generic": "arg1", 122 "alt-name": "arg1", 123 }, 124 { 125 "name": "rsi", 126 "bitsize": 64, 127 "offset": 40, 128 "encoding": "uint", 129 "format": "hex", 130 "set": 0, 131 "gcc": 4, 132 "dwarf": 4, 133 "generic": "arg2", 134 "alt-name": "arg2", 135 }, 136 { 137 "name": "rbp", 138 "bitsize": 64, 139 "offset": 48, 140 "encoding": "uint", 141 "format": "hex", 142 "set": 0, 143 "gcc": 6, 144 "dwarf": 6, 145 "generic": "fp", 146 "alt-name": "fp", 147 }, 148 { 149 "name": "rsp", 150 "bitsize": 64, 151 "offset": 56, 152 "encoding": "uint", 153 "format": "hex", 154 "set": 0, 155 "gcc": 7, 156 "dwarf": 7, 157 "generic": "sp", 158 "alt-name": "sp", 159 }, 160 { 161 "name": "r8", 162 "bitsize": 64, 163 "offset": 64, 164 "encoding": "uint", 165 "format": "hex", 166 "set": 0, 167 "gcc": 8, 168 "dwarf": 8, 169 "generic": "arg5", 170 "alt-name": "arg5", 171 }, 172 { 173 "name": "r9", 174 "bitsize": 64, 175 "offset": 72, 176 "encoding": "uint", 177 "format": "hex", 178 "set": 0, 179 "gcc": 9, 180 "dwarf": 9, 181 "generic": "arg6", 182 "alt-name": "arg6", 183 }, 184 { 185 "name": "r10", 186 "bitsize": 64, 187 "offset": 80, 188 "encoding": "uint", 189 "format": "hex", 190 "set": 0, 191 "gcc": 10, 192 "dwarf": 10, 193 }, 194 { 195 "name": "r11", 196 "bitsize": 64, 197 "offset": 88, 198 "encoding": "uint", 199 "format": "hex", 200 "set": 0, 201 "gcc": 11, 202 "dwarf": 11, 203 }, 204 { 205 "name": "r12", 206 "bitsize": 64, 207 "offset": 96, 208 "encoding": "uint", 209 "format": "hex", 210 "set": 0, 211 "gcc": 12, 212 "dwarf": 12, 213 }, 214 { 215 "name": "r13", 216 "bitsize": 64, 217 "offset": 104, 218 "encoding": "uint", 219 "format": "hex", 220 "set": 0, 221 "gcc": 13, 222 "dwarf": 13, 223 }, 224 { 225 "name": "r14", 226 "bitsize": 64, 227 "offset": 112, 228 "encoding": "uint", 229 "format": "hex", 230 "set": 0, 231 "gcc": 14, 232 "dwarf": 14, 233 }, 234 { 235 "name": "r15", 236 "bitsize": 64, 237 "offset": 120, 238 "encoding": "uint", 239 "format": "hex", 240 "set": 0, 241 "gcc": 15, 242 "dwarf": 15, 243 }, 244 { 245 "name": "rip", 246 "bitsize": 64, 247 "offset": 128, 248 "encoding": "uint", 249 "format": "hex", 250 "set": 0, 251 "gcc": 16, 252 "dwarf": 16, 253 "generic": "pc", 254 "alt-name": "pc", 255 }, 256 { 257 "name": "rflags", 258 "bitsize": 64, 259 "offset": 136, 260 "encoding": "uint", 261 "format": "hex", 262 "set": 0, 263 "generic": "flags", 264 "alt-name": "flags", 265 }, 266 { 267 "name": "cs", 268 "bitsize": 64, 269 "offset": 144, 270 "encoding": "uint", 271 "format": "hex", 272 "set": 0, 273 }, 274 { 275 "name": "fs", 276 "bitsize": 64, 277 "offset": 152, 278 "encoding": "uint", 279 "format": "hex", 280 "set": 0, 281 }, 282 { 283 "name": "gs", 284 "bitsize": 64, 285 "offset": 160, 286 "encoding": "uint", 287 "format": "hex", 288 "set": 0, 289 }, 290 ] 291 return self.registers 292 293 def get_register_data(self, tid): 294 return struct.pack( 295 "21Q", 296 tid + 1, 297 tid + 2, 298 tid + 3, 299 tid + 4, 300 tid + 5, 301 tid + 6, 302 tid + 7, 303 tid + 8, 304 tid + 9, 305 tid + 10, 306 tid + 11, 307 tid + 12, 308 tid + 13, 309 tid + 14, 310 tid + 15, 311 tid + 16, 312 tid + 17, 313 tid + 18, 314 tid + 19, 315 tid + 20, 316 tid + 21, 317 ) 318