Package vtrace :: Package platforms :: Module freebsd
[hide private]
[frames] | no frames]

Source Code for Module vtrace.platforms.freebsd

  1  """ 
  2  FreeBSD support... 
  3  """ 
  4   
  5  import os 
  6  import ctypes 
  7  import ctypes.util as cutil 
  8   
  9  import envi.memory as e_mem 
 10  import envi.cli as e_cli 
 11   
 12  import vtrace 
 13  import vtrace.archs.i386 as v_i386 
 14  import vtrace.archs.amd64 as v_amd64 
 15  import vtrace.platforms.base as v_base 
 16  import vtrace.platforms.posix as v_posix 
 17  import vtrace.util as v_util 
 18   
 19  libkvm = ctypes.CDLL(cutil.find_library("kvm")) 
 20   
 21  # kvm_getprocs cmds 
 22  KERN_PROC_ALL           = 0       # everything 
 23  KERN_PROC_PID           = 1       # by process id 
 24  KERN_PROC_PGRP          = 2       # by process group id 
 25  KERN_PROC_SESSION       = 3       # by session of pid 
 26  KERN_PROC_TTY           = 4       # by controlling tty 
 27  KERN_PROC_UID           = 5       # by effective uid 
 28  KERN_PROC_RUID          = 6       # by real uid 
 29  KERN_PROC_ARGS          = 7       # get/set arguments/proctitle 
 30  KERN_PROC_PROC          = 8       # only return procs 
 31  KERN_PROC_SV_NAME       = 9       # get syscall vector name 
 32  KERN_PROC_RGID          = 10      # by real group id 
 33  KERN_PROC_GID           = 11      # by effective group id 
 34  KERN_PROC_PATHNAME      = 12      # path to executable 
 35  KERN_PROC_INC_THREAD    = 0x10    # Include threads in filtered results 
 36   
 37  pid_t = ctypes.c_int32 
 38  lwpid_t = ctypes.c_int32 
 39  void_p = ctypes.c_void_p 
 40  dev_t = ctypes.c_uint32 
 41  sigset_t = ctypes.c_uint32*4 
 42  uid_t = ctypes.c_uint32 
 43  gid_t = ctypes.c_uint32 
 44  fixpt_t = ctypes.c_uint32 
 45  caddr_t = ctypes.c_void_p 
 46  vm_size_t = ctypes.c_ulong 
 47  segsz_t = ctypes.c_ulong 
 48   
 49  # Could go crazy and grep headers for this stuff ;) 
 50  KI_NGROUPS = 16 
 51  OCOMMLEN = 16 
 52  WMESGLEN = 8 
 53  LOGNAMELEN = 17 
 54  LOCKNAMELEN = 8 
 55  COMMLEN = 19 
 56  KI_EMULNAMELEN = 16 
 57  KI_NSPARE_INT = 10 
 58  KI_NSPARE_PTR = 7 
 59  KI_NSPARE_LONG = 12 
60 61 62 -def c_buf(size):
63 return ctypes.c_char * size
64
65 -class PRIORITY(ctypes.Structure):
66 _fields_ = ( 67 ("pri_class", ctypes.c_ubyte), 68 ("pri_level", ctypes.c_ubyte), 69 ("pri_native", ctypes.c_ubyte), 70 ("pri_user", ctypes.c_ubyte) 71 )
72
73 -class TIMEVAL(ctypes.Structure):
74 _fields_ = ( 75 ("tv_sec", ctypes.c_long), 76 ("tv_usec", ctypes.c_long) 77 )
78
79 -class RUSAGE(ctypes.Structure):
80 _fields_ = ( 81 ("ru_utime", TIMEVAL), # user time used 82 ("ru_stime", TIMEVAL), # system time used 83 ("ru_maxrss", ctypes.c_long), # 84 ("ru_ixrss", ctypes.c_long), # (j) integral shared memory size 85 ("ru_idrss", ctypes.c_long), # (j) integral unshared data 86 ("ru_isrss", ctypes.c_long), # (j) integral unshared stack 87 ("ru_minflt", ctypes.c_long), # (c) page reclaims 88 ("ru_majflt", ctypes.c_long), # (c) page faults 89 ("ru_nswap", ctypes.c_long), # (c + j) swaps 90 ("ru_inblock", ctypes.c_long), # (n) block input operations 91 ("ru_oublock", ctypes.c_long), # (n) block output operations 92 ("ru_msgsnd", ctypes.c_long), # (n) messages sent 93 ("ru_msgrcv", ctypes.c_long), # (n) messages received 94 ("ru_nsignals", ctypes.c_long), # (c) signals received 95 ("ru_nvcsw", ctypes.c_long), # (j) voluntary context switches 96 ("ru_nivcsw", ctypes.c_long), # (j) involuntary 97 )
98
99 100 -class KINFO_PROC(ctypes.Structure):
101 _fields_ = ( 102 ("ki_structsize", ctypes.c_int),# size of this structure 103 ("ki_layout", ctypes.c_int), # reserved: layout identifier 104 ("ki_args", void_p), # address of command arguments (struct pargs*) 105 ("ki_paddr", void_p), # address of proc (struct proc*) 106 ("ki_addr", void_p), # kernel virtual addr of u-area (struct user*) 107 ("ki_tracep", void_p), # pointer to trace file (struct vnode *) 108 ("ki_textvp", void_p), # pointer to executable file (struct vnode *) 109 ("ki_fd", void_p), # pointer to open file info (struct filedesc *) 110 ("ki_vmspace", void_p), # pointer to kernel vmspace struct (struct vmspace *) 111 ("ki_wchan", void_p), # sleep address (void*) 112 ("ki_pid", pid_t), # Process identifier 113 ("ki_ppid", pid_t), # parent process id 114 ("ki_pgid", pid_t), # process group id 115 ("ki_tpgid", pid_t), # tty process group id 116 ("ki_sid", pid_t), # Process session ID 117 ("ki_tsid", pid_t), # Terminal session ID 118 ("ki_jobc", ctypes.c_short), # job control counter 119 ("ki_spare_short1", ctypes.c_short), # 120 ("ki_tdev", dev_t), # controlling tty dev 121 ("ki_siglist", sigset_t), # Signals arrived but not delivered 122 ("ki_sigmask", sigset_t), # Current signal mask 123 ("ki_sigignore", sigset_t), # Signals being ignored 124 ("ki_sigcatch", sigset_t), # Signals being caught by user 125 ("ki_uid", uid_t), # effective user id 126 ("ki_ruid", uid_t), # Real user id 127 ("ki_svuid", uid_t), # Saved effective user id 128 ("ki_rgid", gid_t), # Real group id 129 ("ki_svgid", gid_t), # Saved effective group id 130 ("ki_ngroups", ctypes.c_short), # number of groups 131 ("ki_spare_short2", ctypes.c_short), 132 ("ki_groups", gid_t * KI_NGROUPS), # groups 133 ("ki_size", vm_size_t), # virtual size 134 ("ki_rssize", segsz_t), # current resident set size in pages 135 ("ki_swrss", segsz_t), # resident set size before last swap 136 ("ki_tsize", segsz_t), # text size (pages) XXX 137 ("ki_dsize", segsz_t), # data size (pages) XXX 138 ("ki_ssize", segsz_t), # stack size (pages) 139 ("ki_xstat", ctypes.c_ushort), # Exit status for wait and stop signal 140 ("ki_acflag", ctypes.c_ushort), # Accounting flags 141 ("ki_pctcpu", fixpt_t), # %cpu for process during ki_swtime 142 ("ki_estcpu", ctypes.c_uint), # Time averaged value of ki_cpticks 143 ("ki_slptime", ctypes.c_uint), # Time since last blocked 144 ("ki_swtime", ctypes.c_uint), # Time swapped in or out 145 ("ki_spareint1", ctypes.c_int), # unused (just here for alignment) 146 ("ki_runtime", ctypes.c_uint64),# Real time in microsec 147 ("ki_start", TIMEVAL), # starting time 148 ("ki_childtime", TIMEVAL), # time used by process children 149 ("ki_flag", ctypes.c_long), # P_* flags 150 ("ki_kiflag", ctypes.c_long), # KI_* flags 151 ("ki_traceflag", ctypes.c_int), # kernel trace points 152 ("ki_stat", ctypes.c_char), # S* process status 153 ("ki_nice", ctypes.c_ubyte), # Process "nice" value 154 ("ki_lock", ctypes.c_char), # Process lock (prevent swap) count 155 ("ki_rqindex", ctypes.c_char), # Run queue index 156 ("ki_oncpu", ctypes.c_char), # Which cpu we are on 157 ("ki_lastcpu", ctypes.c_char), # Last cpu we were on 158 ("ki_ocomm", c_buf(OCOMMLEN+1)), # command name 159 ("ki_wmesg", c_buf(WMESGLEN+1)), # wchan message 160 ("ki_login", c_buf(LOGNAMELEN+1)), # setlogin name 161 ("ki_lockname", c_buf(LOCKNAMELEN+1)),# lock name 162 ("ki_comm", c_buf(COMMLEN+1)), # command name 163 ("ki_emul", c_buf(KI_EMULNAMELEN+1)), # emulation name 164 ("ki_sparestrings",c_buf(68)), # spare string space 165 ("ki_spareints", ctypes.c_int*KI_NSPARE_INT), 166 ("ki_jid", ctypes.c_int), # Process jail ID 167 ("ki_numthreads", ctypes.c_int),# KSE number of total threads 168 ("ki_tid", lwpid_t), # thread id 169 ("ki_pri", PRIORITY), # process priority 170 ("ki_rusage", RUSAGE), # process rusage statistics 171 # XXX - most fields in ki_rusage_ch are not (yet) filled in 172 ("ki_rusage_ch", RUSAGE), # rusage of children processes 173 ("ki_pcb", void_p), # kernel virtual addr of pcb 174 ("ki_kstack", void_p), # kernel virtual addr of stack 175 ("ki_udata", void_p), # User convenience pointer 176 ("ki_spareptrs", void_p*KI_NSPARE_PTR), 177 ("ki_sparelongs", ctypes.c_long*KI_NSPARE_LONG), 178 ("ki_sflag", ctypes.c_long), # PS_* flags 179 ("ki_tdflags", ctypes.c_long), # KSE kthread flag 180 )
181 182 libkvm.kvm_getprocs.argtypes = [caddr_t, ctypes.c_int, ctypes.c_int, caddr_t] 183 libkvm.kvm_getprocs.restype = ctypes.POINTER(KINFO_PROC) 184 185 libkvm.kvm_open.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p] 186 libkvm.kvm_open.restype = caddr_t 187 188 # All the FreeBSD ptrace defines 189 PT_TRACE_ME = 0 #/* child declares it's being traced */ 190 PT_READ_I = 1 #/* read word in child's I space */ 191 PT_READ_D = 2 #/* read word in child's D space */ 192 PT_WRITE_I = 4 #/* write word in child's I space */ 193 PT_WRITE_D = 5 #/* write word in child's D space */ 194 PT_CONTINUE = 7 #/* continue the child */ 195 PT_KILL = 8 #/* kill the child process */ 196 PT_STEP = 9 #/* single step the child */ 197 PT_ATTACH = 10 #/* trace some running process */ 198 PT_DETACH = 11 #/* stop tracing a process */ 199 PT_IO = 12 #/* do I/O to/from stopped process. */ 200 PT_LWPINFO = 13 #/* Info about the LWP that stopped. */ 201 PT_GETNUMLWPS = 14 #/* get total number of threads */ 202 PT_GETLWPLIST = 15 #/* get thread list */ 203 PT_CLEARSTEP = 16 #/* turn off single step */ 204 PT_SETSTEP = 17 #/* turn on single step */ 205 PT_SUSPEND = 18 #/* suspend a thread */ 206 PT_RESUME = 19 #/* resume a thread */ 207 PT_TO_SCE = 20 # Stop on syscall entry 208 PT_TO_SCX = 21 # Stop on syscall exit 209 PT_SYSCALL = 22 # Stop on syscall entry and exit 210 PT_GETREGS = 33 #/* get general-purpose registers */ 211 PT_SETREGS = 34 #/* set general-purpose registers */ 212 PT_GETFPREGS = 35 #/* get floating-point registers */ 213 PT_SETFPREGS = 36 #/* set floating-point registers */ 214 PT_GETDBREGS = 37 #/* get debugging registers */ 215 PT_SETDBREGS = 38 #/* set debugging registers */
216 #PT_FIRSTMACH = 64 #/* for machine-specific requests */ 217 218 # On PT_IO addr is a pointer to a struct 219 220 -class PTRACE_IO_DESC(ctypes.Structure):
221 _fields_ = [ 222 ("piod_op", ctypes.c_int), # I/O operation 223 ("piod_offs", ctypes.c_void_p), # Child offset 224 ("piod_addr", ctypes.c_void_p), # Parent Offset 225 ("piod_len", ctypes.c_uint) # Size 226 ]
227 228 # Operations in piod_op. 229 PIOD_READ_D = 1 # Read from D space 230 PIOD_WRITE_D = 2 # Write to D space 231 PIOD_READ_I = 3 # Read from I space 232 PIOD_WRITE_I = 4 # Write to I space
233 234 -class PTRACE_LWPINFO(ctypes.Structure):
235 _fields_ = ( 236 ("pl_lwpid", lwpid_t), 237 ("pl_event", ctypes.c_int), 238 ("pl_flags", ctypes.c_int), 239 ("pl_sigmask", sigset_t), 240 ("pl_siglist", sigset_t), 241 )
242 243 PL_EVENT_NONE = 0 244 PL_EVENT_SIGNAL = 1 245 246 PL_FLAGS_SA = 0 247 PL_FLAGS_BOUND = 1
248 249 -class FreeBSDMixin:
250
251 - def __init__(self):
252 self.initMode("Syscall", False, "Break on Syscalls") 253 self.kvmh = libkvm.kvm_open(None, None, None, 0, "vtrace") 254 if not os.path.exists('/proc/curproc/file'): 255 raise Exception("VDB needs /proc! (use: mount -t procfs procfs /proc)")
256
257 - def finiMixin(self):
258 print "FIXME I DON'T THINK THIS IS BEING CALLED" 259 if self.kvmh != None: 260 libkvm.kvm_close(self.kvmh)
261
262 - def platformReadMemory(self, address, size):
263 #FIXME optimize for speed! 264 iod = PTRACE_IO_DESC() 265 buf = ctypes.create_string_buffer(size) 266 267 iod.piod_op = PIOD_READ_D 268 iod.piod_addr = ctypes.addressof(buf) 269 iod.piod_offs = address 270 iod.piod_len = size 271 272 if v_posix.ptrace(PT_IO, self.pid, ctypes.addressof(iod), 0) != 0: 273 raise Exception("ptrace PT_IO failed to read 0x%.8x" % address) 274 275 return buf.raw
276
277 - def platformWriteMemory(self, address, buf):
278 #FIXME optimize for speed! 279 iod = PTRACE_IO_DESC() 280 281 cbuf = ctypes.create_string_buffer(buf) 282 283 iod.piod_op = PIOD_WRITE_D 284 iod.piod_addr = ctypes.addressof(cbuf) 285 iod.piod_offs = address 286 iod.piod_len = len(buf) 287 288 if v_posix.ptrace(PT_IO, self.pid, ctypes.addressof(iod), 0) != 0: 289 raise Exception("ptrace PT_IO failed to read 0x%.8x" % address)
290 291 @v_base.threadwrap
292 - def platformAttach(self, pid):
293 if v_posix.ptrace(PT_ATTACH, pid, 0, 0) != 0: 294 raise Exception("Ptrace Attach Failed")
295
296 - def _getExeName(self, pid):
297 return os.readlink('/proc/%d/file' % pid)
298 299 #@v_base.threadwrap
300 - def platformExec(self, cmdline):
301 # Basically just like the one in the Ptrace mixin... 302 self.execing = True 303 cmdlist = e_cli.splitargs(cmdline) 304 os.stat(cmdlist[0]) 305 pid = os.fork() 306 if pid == 0: 307 v_posix.ptrace(PT_TRACE_ME, 0, 0, 0) 308 os.execv(cmdlist[0], cmdlist) 309 sys.exit(-1) 310 return pid
311
312 - def handleAttach(self):
313 self.setMeta('ExeName', self._getExeName(self.pid)) 314 return v_posix.PosixMixin.handleAttach(self)
315 316 @v_base.threadwrap
317 - def platformWait(self):
318 status = v_posix.PosixMixin.platformWait(self) 319 # Get the thread id from the ptrace interface 320 321 info = PTRACE_LWPINFO() 322 size = ctypes.sizeof(info) 323 if v_posix.ptrace(PT_LWPINFO, self.pid, ctypes.addressof(info), size) == 0: 324 self.setMeta("ThreadId", info.pl_lwpid) 325 else: 326 #FIXME this is because posix wait is linux specific and broke 327 self.setMeta("ThreadId", self.pid) 328 329 return status
330 331 @v_base.threadwrap
332 - def platformStepi(self):
333 self.stepping = True 334 if v_posix.ptrace(PT_STEP, self.pid, 1, 0) != 0: 335 raise Exception("ptrace PT_STEP failed!")
336 337 @v_base.threadwrap
338 - def platformContinue(self):
339 cmd = PT_CONTINUE 340 if self.getMode("Syscall"): 341 cmd = PT_SYSCALL 342 343 sig = self.getCurrentSignal() 344 if sig == None: 345 sig = 0 346 # In freebsd address is the place to continue from 347 # but 1 means use existing EIP 348 if v_posix.ptrace(cmd, self.pid, 1, sig) != 0: 349 raise Exception("ptrace PT_CONTINUE/PT_SYSCALL failed")
350 351 @v_base.threadwrap
352 - def platformDetach(self):
353 if v_posix.ptrace(PT_DETACH, self.pid, 1, 0) != 0: 354 raise Exception("Ptrace Detach Failed")
355 356 @v_base.threadwrap
357 - def platformGetThreads(self):
358 ret = {} 359 cnt = self._getThreadCount() 360 buf = (ctypes.c_int * cnt)() 361 if v_posix.ptrace(PT_GETLWPLIST, self.pid, ctypes.addressof(buf), cnt) != cnt: 362 raise Exception("ptrace PW_GETLWPLIST failed") 363 for x in buf: 364 ret[x] = x 365 return ret
366 367 @v_base.threadwrap
368 - def platformSuspendThread(self, tid):
369 if v_posix.ptrace(PT_SUSPEND, tid, 0, 0) != 0: 370 raise Exception("ptrace PT_SUSPEND failed!")
371 372 @v_base.threadwrap
373 - def platformResumeThread(self, tid):
374 if v_posix.ptrace(PT_RESUME, tid, 0, 0) != 0: 375 raise Exception("ptrace PT_RESUME failed!")
376
377 - def _getThreadCount(self):
378 return v_posix.ptrace(PT_GETNUMLWPS, self.pid, 0, 0)
379
380 - def platformGetFds(self):
381 return []
382
383 - def platformGetMaps(self):
384 # FIXME make this not need proc 385 ret = [] 386 mpath = "/proc/%d/map" % self.pid 387 388 mapfile = file(mpath, "rb") 389 for line in mapfile: 390 perms = 0 391 fname = "" 392 maptup = line.split(None) 393 base = int(maptup[0], 16) 394 max = int(maptup[1], 16) 395 permstr = maptup[5] 396 397 if maptup[11] == "vnode": 398 fname = maptup[12].strip() 399 400 if permstr[0] == 'r': 401 perms |= e_mem.MM_READ 402 403 if permstr[1] == 'w': 404 perms |= e_mem.MM_WRITE 405 406 if permstr[2] == 'x': 407 perms |= e_mem.MM_EXEC 408 409 ret.append((base, max-base, perms, fname)) 410 411 return ret
412
413 - def platformPs(self):
414 ret = [] 415 cnt = ctypes.c_uint(0) 416 417 p = libkvm.kvm_getprocs(self.kvmh, KERN_PROC_PROC, 0, ctypes.addressof(cnt)) 418 for i in xrange(cnt.value): 419 kinfo = p[i] 420 if kinfo.ki_structsize != ctypes.sizeof(KINFO_PROC): 421 print "WARNING: KINFO_PROC CHANGED SIZE, Trying to account for it... good luck" 422 ret.append((kinfo.ki_pid, kinfo.ki_comm)) 423 424 ret.reverse() 425 return ret
426
427 -class bsd_regs_i386(ctypes.Structure):
428 _fields_ = ( 429 ("fs", ctypes.c_ulong), 430 ("es", ctypes.c_ulong), 431 ("ds", ctypes.c_ulong), 432 ("edi", ctypes.c_ulong), 433 ("esi", ctypes.c_ulong), 434 ("ebp", ctypes.c_ulong), 435 ("isp", ctypes.c_ulong), 436 ("ebx", ctypes.c_ulong), 437 ("edx", ctypes.c_ulong), 438 ("ecx", ctypes.c_ulong), 439 ("eax", ctypes.c_ulong), 440 ("trapno", ctypes.c_ulong), 441 ("err", ctypes.c_ulong), 442 ("eip", ctypes.c_ulong), 443 ("cs", ctypes.c_ulong), 444 ("eflags", ctypes.c_ulong), 445 ("esp", ctypes.c_ulong), 446 ("ss", ctypes.c_ulong), 447 ("gs", ctypes.c_ulong), 448 ("debug0", ctypes.c_ulong), 449 ("debug1", ctypes.c_ulong), 450 ("debug2", ctypes.c_ulong), 451 ("debug3", ctypes.c_ulong), 452 ("debug4", ctypes.c_ulong), 453 ("debug5", ctypes.c_ulong), 454 ("debug6", ctypes.c_ulong), 455 ("debug7", ctypes.c_ulong), 456 )
457 458 i386_DBG_OFF = (19*4)
459 460 -class bsd_regs_amd64(ctypes.Structure):
461 _fields_ = ( 462 ("r15", ctypes.c_ulonglong), 463 ("r14", ctypes.c_ulonglong), 464 ("r13", ctypes.c_ulonglong), 465 ("r12", ctypes.c_ulonglong), 466 ("r11", ctypes.c_ulonglong), 467 ("r10", ctypes.c_ulonglong), 468 ("r9", ctypes.c_ulonglong), 469 ("r8", ctypes.c_ulonglong), 470 ("rdi", ctypes.c_ulonglong), 471 ("rsi", ctypes.c_ulonglong), 472 ("rbp", ctypes.c_ulonglong), 473 ("rbx", ctypes.c_ulonglong), 474 ("rdx", ctypes.c_ulonglong), 475 ("rcx", ctypes.c_ulonglong), 476 ("rax", ctypes.c_ulonglong), 477 ("trapno", ctypes.c_ulonglong), 478 ("err", ctypes.c_ulonglong), 479 ("rip", ctypes.c_ulonglong), 480 ("cs", ctypes.c_ulonglong), 481 ("rflags", ctypes.c_ulonglong), 482 ("rsp", ctypes.c_ulonglong), 483 ("ss", ctypes.c_ulonglong), 484 ("debug0", ctypes.c_ulonglong), 485 ("debug1", ctypes.c_ulonglong), 486 ("debug2", ctypes.c_ulonglong), 487 ("debug3", ctypes.c_ulonglong), 488 ("debug4", ctypes.c_ulonglong), 489 ("debug5", ctypes.c_ulonglong), 490 ("debug6", ctypes.c_ulonglong), 491 ("debug7", ctypes.c_ulonglong), 492 ("debug8", ctypes.c_ulonglong), 493 ("debug9", ctypes.c_ulonglong), 494 ("debug10", ctypes.c_ulonglong), 495 ("debug11", ctypes.c_ulonglong), 496 ("debug12", ctypes.c_ulonglong), 497 ("debug13", ctypes.c_ulonglong), 498 ("debug14", ctypes.c_ulonglong), 499 ("debug15", ctypes.c_ulonglong), 500 )
501 502 amd64_DBG_OFF = (22*ctypes.sizeof(ctypes.c_uint64))
503 504 -class FreeBSDi386Trace( 505 vtrace.Trace, 506 FreeBSDMixin, 507 v_i386.i386Mixin, 508 v_posix.ElfMixin, 509 v_posix.PosixMixin, 510 v_base.TracerBase):
511
512 - def __init__(self):
513 vtrace.Trace.__init__(self) 514 v_base.TracerBase.__init__(self) 515 v_posix.ElfMixin.__init__(self) 516 v_posix.PosixMixin.__init__(self) 517 v_i386.i386Mixin.__init__(self) 518 FreeBSDMixin.__init__(self)
519 520 @v_base.threadwrap
521 - def platformGetRegCtx(self, tid):
522 ctx = self.archGetRegCtx() 523 u = bsd_regs_i386() 524 525 addr = ctypes.addressof(u) 526 if v_posix.ptrace(PT_GETREGS, tid, addr, 0) != 0: 527 raise Exception("ptrace PT_GETREGS failed!") 528 if v_posix.ptrace(PT_GETDBREGS, tid, addr+i386_DBG_OFF, 0) != 0: 529 raise Exception("ptrace PT_GETDBREGS failed!") 530 531 ctx._rctx_Import(u) 532 533 return ctx
534 535 @v_base.threadwrap
536 - def platformSetRegCtx(self, tid, ctx):
537 u = bsd_regs_i386() 538 ctx._rctx_Export(u) 539 addr = ctypes.addressof(u) 540 if v_posix.ptrace(PT_SETREGS, self.pid, addr, 0) != 0: 541 raise Exception("ptrace PT_SETREGS failed!") 542 if v_posix.ptrace(PT_SETDBREGS, self.pid, addr+i386_DBG_OFF, 0) != 0: 543 raise Exception("ptrace PT_SETDBREGS failed!")
544
545 546 -class FreeBSDAmd64Trace( 547 vtrace.Trace, 548 FreeBSDMixin, 549 v_amd64.Amd64Mixin, 550 v_posix.ElfMixin, 551 v_posix.PosixMixin, 552 v_base.TracerBase):
553
554 - def __init__(self):
555 vtrace.Trace.__init__(self) 556 v_base.TracerBase.__init__(self) 557 v_posix.ElfMixin.__init__(self) 558 v_posix.PosixMixin.__init__(self) 559 v_amd64.Amd64Mixin.__init__(self) 560 FreeBSDMixin.__init__(self)
561
562 - def _getAmdRegsStruct(self, tid):
563 ''' 564 Get (and populate) a register structure 565 (even set regs needs to get it first...) 566 ''' 567 u = bsd_regs_amd64() 568 addr = ctypes.addressof(u) 569 if v_posix.ptrace(PT_GETREGS, tid, addr, 0) != 0: 570 raise Exception("ptrace PT_GETREGS failed!") 571 if v_posix.ptrace(PT_GETDBREGS, tid, addr+amd64_DBG_OFF, 0) != 0: 572 raise Exception("ptrace PT_GETDBREGS failed!") 573 return u
574 575 @v_base.threadwrap
576 - def platformGetRegCtx(self, tid):
577 ctx = self.archGetRegCtx() 578 u = self._getAmdRegsStruct(tid) 579 ctx._rctx_Import(u) 580 return ctx
581 582 @v_base.threadwrap
583 - def platformSetRegCtx(self, tid, ctx):
584 u = self._getAmdRegsStruct(tid) 585 ctx._rctx_Export(u) 586 addr = ctypes.addressof(u) 587 if v_posix.ptrace(PT_SETREGS, tid, addr, 0) != 0: 588 raise Exception("ptrace PT_SETREGS failed!") 589 if v_posix.ptrace(PT_SETDBREGS, tid, addr+amd64_DBG_OFF, 0) != 0: 590 raise Exception("ptrace PT_SETDBREGS failed!")
591