def oncore_cb(tid, cpu, dummy) : """This callback happens before IRET mutates state. Put the CPU structure into the map so that we know to ask it directly, below.""" if u.copyout_int(cpu, cpu.esp+4) & 0x3 != 0x0 : u.log('410-tidinfo', 'ONCORE %r %d' % (cpu, tid)); go_oncore(tid,cpu) SIM_hap_delete_callback_obj('Core_Exception_Return', cpu, oncore_cb, tid)
def reg_process(dummy, cpu, param): fname = "" try : fname = copyout_str(cpu, cpu.edx) except : cs410_utils.log('410-warning', '410mods-userdebug.py: Unable to read string at %x; not registering process' % cpu.edx) return if fname == "" or '/' in fname: return cr3 = cpu.ecx sname = "prog-"+fname user_process_registry[cr3] = sname # see if symbol table for fname exists. # if not make it and load the symbols. try: SIM_get_object(sname) ### FIXME We would like to empty the symbol table if ### it exists, but we'll do the best we can by reloading ### symbols below. except SimExc_General: cs410_utils.alone(make_new_symtable, sname, fname, cr3) cs410_utils.alone(switch_current_symtable, cpu)
def reg_process(dummy, cpu, param): global user_process_registry fname = "" try : fname = copyout_str(cpu, cpu.edx) except : cs410_utils.log('410-warning', '410mods-userdebug.py: Unable to read string at %x; not registering process' % cpu.edx) return if fname == "" or '/' in fname: return cr3 = cpu.ecx sname = fname+"_prog" user_process_registry[cr3] = sname # see if symbol table for fname exists. # if not make it and load the symbols. try: SIM_get_object(sname) ### FIXME We would like to empty the symbol table if ### it exists, but we'll do the best we can by reloading ### symbols below. except SimExc_General: cs410_utils.alone(make_new_symtable, sname, fname, cr3) cs410_utils.alone(switch_current_symtable, cpu)
def oncore_cb(tid, cpu, dummy): """This callback happens before IRET mutates state. Put the CPU structure into the map so that we know to ask it directly, below.""" if u.copyout_int(cpu, cpu.esp + 4) & 0x3 != 0x0: u.log('410-tidinfo', 'ONCORE %r %d' % (cpu, tid)) go_oncore(tid, cpu) SIM_hap_delete_callback_obj('Core_Exception_Return', cpu, oncore_cb, tid)
def offcore_cb(tid, cpu, dummy): """This callback fires before we take the fault. Read out the CPU state and store it in our map""" u.log('410-tidinfo', 'OFFCORE %r %d' % (cpu, tid)) tidcontext[tid] = u.trap_frame_from_cpu(cpu) SIM_hap_delete_callback_obj('Core_Exception', cpu, offcore_cb, tid) SIM_hap_add_callback_obj('Core_Exception_Return', cpu, 0, oncore_cb, tid)
def offcore_cb(tid, cpu, dummy) : """This callback fires before we take the fault. Read out the CPU state and store it in our map""" u.log('410-tidinfo', 'OFFCORE %r %d' % (cpu, tid)); tidcontext[tid] = u.trap_frame_from_cpu(cpu) SIM_hap_delete_callback_obj('Core_Exception', cpu, offcore_cb, tid) SIM_hap_add_callback_obj('Core_Exception_Return', cpu, 0, oncore_cb, tid)
def make_new_symtable(sname, fname, cr3): fpath = user_prog_path+fname if not os.path.isfile(fpath) or '/' in fname: cs410_utils.log('410-warning', 'Unable to load user symbols for "%s"' % fname) del user_process_registry[cr3] return try: cli.quiet_run_command('new-symtable %s' % sname) cli.quiet_run_command('%s.load-symbols "%s"' % (sname, kern_path)) cli.quiet_run_command('%s.load-symbols "%s"' % (sname, fpath)) cli.quiet_run_command('%s.source-path "%s/;%s/;%s/"' % (sname, working_dir, user_src_path, test_src_path)) except: cs410_utils.log('410-warning', 'Unable to load user symbols for "%s"' % fname) del user_process_registry[cr3]
def tidinfo_del(dummy, cpu, param) : tid = cpu.ecx u.log('410-tidinfo', 'DEL %r %d' % (cpu, tid)); if tid in tidcontext : if tidcontext[tid] == cpu.__class__ : u.log('410-tidinfo', \ 'WARN: DEL called from CPU %r for TID %d which is ONCORE on %r' \ % (cpu,tid,tidcontext[cpu])); del cputid[tidcontext[tid]] SIM_hap_delete_callback('Core_Exception', offcore_cb, tid) SIM_hap_delete_callback('Core_Exception', offcore_cb, tid) SIM_hap_delete_callback('Core_Exception_Return', oncore_cb, tid) SIM_hap_delete_callback('Core_Exception_Return', oncore_cb, tid) if tid in tidcontext: del tidcontext[tid] if tid in tidtaskname: del tidtaskname[tid]
def tidinfo_del(dummy, cpu, param): tid = cpu.ecx u.log('410-tidinfo', 'DEL %r %d' % (cpu, tid)) if tid in tidcontext: if tidcontext[tid] == cpu.__class__: u.log('410-tidinfo', \ 'WARN: DEL called from CPU %r for TID %d which is ONCORE on %r' \ % (cpu,tid,tidcontext[cpu])) del cputid[tidcontext[tid]] SIM_hap_delete_callback('Core_Exception', offcore_cb, tid) SIM_hap_delete_callback('Core_Exception', offcore_cb, tid) SIM_hap_delete_callback('Core_Exception_Return', oncore_cb, tid) SIM_hap_delete_callback('Core_Exception_Return', oncore_cb, tid) if tid in tidcontext: del tidcontext[tid] if tid in tidtaskname: del tidtaskname[tid]
def tidinfo_set(dummy, cpu, param) : """Bind a tid to the current CPU as soon as it mode switches down""" tid = cpu.ecx u.log('410-tidinfo', 'SET %r %d' % (cpu, tid)); if tid in tidcontext and tidcontext[tid] == cpu.__class__ : if tidcontext[tid] == cpu : u.log('410-tidinfo', 'WARN: Oncore called twice in a row on %r for tid %d' % (cpu,tid)); # Purge any existing callbacks to reset our state machine; we'll add # the right one below SIM_hap_delete_callback_obj('Core_Exception', tidcontext[tid], offcore_cb, tid) SIM_hap_delete_callback_obj('Core_Exception_Return', tidcontext[tid], oncore_cb, tid) # Remove whichever other tid in whatever state had previously been on this CPU if cpu in cputid and cputid[cpu] is not None : SIM_hap_delete_callback_obj('Core_Exception', cpu, offcore_cb, cputid[cpu]) SIM_hap_delete_callback_obj('Core_Exception_Return', cpu, oncore_cb, cputid[cpu]) cputid[cpu] = tid if cpu.cs[2] != 0 : u.log('410-tidinfo', 'WARN: Oncore called from ring %d' % cpu.cs[2]); go_oncore(tid, cpu) # Go oncore immediately. else : # We go oncore once we engage a mode switch, since the kernel cannot # actually tell us when we go back on core SIM_hap_add_callback_obj('Core_Exception_Return', cpu, 0, oncore_cb, tid)
def __callback_magic(dummy, cpu, param): global kernel_up, hap_handlers op = cpu.ebx # Check what triggered the magic instruction # if cpu.cr0 & 0x1 == 1 or cpu.cs[1] == 1: # # Protected mode is engaged # # Or the D bit in CS is turned on, so we're in 32 bit mode # ### We used to differentiate between modes so we would do # ### different reads. We now always read out 32 bit values. # pass # else : # # Protected mode not engaged # ### We used to read out a 16 bit value here via cpu.bx; # ### instead we'll now just check for the BIOS region and # ### bail in that case. # if cpu.cs[7] == 0x0F0000l : # ## Suppress BIOS warning in early boot. # ## The cycle count here is by observation and might be subject # ## to change. We may wish to have some boot flag indicate that # ## we have loaded? # if cpu.cycles > 0x01400000l : # print ("Looks like magic from a BIOS region," \ # + " bailing out (%x:%x, %x, %x)") \ # % ( cpu.cs[7], cpu.eip, str_flag, cpu.cycles) # return if kernel_up == 0 and op != cs410_namespace.magic_opcodes["booted"]: # print ("Looks like magic preboot," \ # + " bailing out (%x:%x, %x, %x)") \ # % ( cpu.cs[7], cpu.eip, str_flag, cpu.cycles) return if hap_handlers.has_key(op): hap_handlers[op](dummy, cpu, param) else: cs410_utils.log( "410-warning", "Invalid magic %08x %s %08x %08x %08x %04x" % (op, cpu.name, cpu.cycles, cpu.eip, cpu.cr0, cpu.cs[0]), )
def __callback_magic(dummy, cpu, param): global kernel_up, hap_handlers op = cpu.ebx # Check what triggered the magic instruction #if cpu.cr0 & 0x1 == 1 or cpu.cs[1] == 1: # # Protected mode is engaged # # Or the D bit in CS is turned on, so we're in 32 bit mode # ### We used to differentiate between modes so we would do # ### different reads. We now always read out 32 bit values. # pass #else : # # Protected mode not engaged # ### We used to read out a 16 bit value here via cpu.bx; # ### instead we'll now just check for the BIOS region and # ### bail in that case. # if cpu.cs[7] == 0x0F0000l : # ## Suppress BIOS warning in early boot. # ## The cycle count here is by observation and might be subject # ## to change. We may wish to have some boot flag indicate that # ## we have loaded? # if cpu.cycles > 0x01400000l : # print ("Looks like magic from a BIOS region," \ # + " bailing out (%x:%x, %x, %x)") \ # % ( cpu.cs[7], cpu.eip, str_flag, cpu.cycles) # return if kernel_up == 0 and op != cs410_namespace.magic_opcodes["booted"]: #print ("Looks like magic preboot," \ # + " bailing out (%x:%x, %x, %x)") \ # % ( cpu.cs[7], cpu.eip, str_flag, cpu.cycles) return if hap_handlers.has_key(op): hap_handlers[op](dummy, cpu, param) else: cs410_utils.log( '410-warning', 'Invalid magic %08x %s %08x %08x %08x %04x' % (op, cpu.name, cpu.cycles, cpu.eip, cpu.cr0, cpu.cs[0]))
def cmd_tidinfo(tid): if not tidcontext: print "This kernel does not appear to support the modern infrastructure for this command." print "*** If this is a reference kernel, perhaps you need to 'make update'? If that doesn't help, contact course staff." return if tid not in tidcontext : print "Kernel did not register a tid %d; are you sure that's right?" % tid return if tid in tidtaskname : u.log('410', 'TID %d symbols are in %s' % (tid, tidtaskname[tid])) else : u.log('410', 'TID %d has unknown symbol table' % (tid)) tf = tidcontext[tid] if isinstance(tf, dict) : # Off core, stored decoded frame at registration time u.log('410', 'TID %d is off-core right now' % tid) u.print_trap_frame(tf) else : # On core, read from cpu right now u.log('410', 'TID %d is on-core right now: %s' % (tid, tf.name)) u.print_trap_frame(u.trap_frame_from_cpu(tf))
def cmd_tidinfo(tid): if not tidcontext: print "This kernel does not appear to support the modern infrastructure for this command." print "*** If this is a reference kernel, perhaps you need to 'make update'? If that doesn't help, contact course staff." return if tid not in tidcontext: print "Kernel did not register a tid %d; are you sure that's right?" % tid return if tid in tidtaskname: u.log('410', 'TID %d symbols are in %s' % (tid, tidtaskname[tid])) else: u.log('410', 'TID %d has unknown symbol table' % (tid)) tf = tidcontext[tid] if isinstance(tf, dict): # Off core, stored decoded frame at registration time u.log('410', 'TID %d is off-core right now' % tid) u.print_trap_frame(tf) else: # On core, read from cpu right now u.log('410', 'TID %d is on-core right now: %s' % (tid, tf.name)) u.print_trap_frame(u.trap_frame_from_cpu(tf))
def tidinfo_set(dummy, cpu, param): """Bind a tid to the current CPU as soon as it mode switches down""" tid = cpu.ecx u.log('410-tidinfo', 'SET %r %d' % (cpu, tid)) if tid in tidcontext and tidcontext[tid] == cpu.__class__: if tidcontext[tid] == cpu: u.log( '410-tidinfo', 'WARN: Oncore called twice in a row on %r for tid %d' % (cpu, tid)) # Purge any existing callbacks to reset our state machine; we'll add # the right one below SIM_hap_delete_callback_obj('Core_Exception', tidcontext[tid], offcore_cb, tid) SIM_hap_delete_callback_obj('Core_Exception_Return', tidcontext[tid], oncore_cb, tid) # Remove whichever other tid in whatever state had previously been on this CPU if cpu in cputid and cputid[cpu] is not None: SIM_hap_delete_callback_obj('Core_Exception', cpu, offcore_cb, cputid[cpu]) SIM_hap_delete_callback_obj('Core_Exception_Return', cpu, oncore_cb, cputid[cpu]) cputid[cpu] = tid if cpu.cs[2] != 0: u.log('410-tidinfo', 'WARN: Oncore called from ring %d' % cpu.cs[2]) go_oncore(tid, cpu) # Go oncore immediately. else: # We go oncore once we engage a mode switch, since the kernel cannot # actually tell us when we go back on core SIM_hap_add_callback_obj('Core_Exception_Return', cpu, 0, oncore_cb, tid)
def halt(dummy, cpu, param): cs410_utils.log('410-core', 'Halted.') cs410_dispatch.run_halt_callbacks() SIM_quit(0)
def lputs(dummy, cpu, param): if cpu.cs[0] & 3: mc = 'udbg' else: mc = 'kdbg' cs410_utils.log(mc, cs410_utils.copyout_str(cpu, cpu.ecx))
if isinstance(tf, dict): # Off core, stored decoded frame at registration time u.log('410', 'TID %d is off-core right now' % tid) u.print_trap_frame(tf) else: # On core, read from cpu right now u.log('410', 'TID %d is on-core right now: %s' % (tid, tf.name)) u.print_trap_frame(u.trap_frame_from_cpu(tf)) def cmd_tids(): u.log('410', 'TIDs registered right now: %r' % tidcontext.keys()) cs410_dispatch.add_simcall(tidinfo_set) cs410_dispatch.add_simcall(tidinfo_del) new_command( "tidinfo", cmd_tidinfo, args=[arg(int_t, "tid")], short="Ask kernel for thread information by TID", doc="This reports thread information as derived from simulation state") new_command("tids", cmd_tids, short="Report the list of tids registered for tidinfo debugging.", doc="This reports the list of tids being tracked.") # u.logging['410-tidinfo'] = True # u.printing['410-tidinfo'] = True u.log('410-tidinfo', 'tidinfo loaded')
def cmd_tids(): u.log('410', 'TIDs registered right now: %r' % tidcontext.keys())
def cmd_tids() : u.log('410', 'TIDs registered right now: %r' % tidcontext.keys());
if tid in tidtaskname : u.log('410', 'TID %d symbols are in %s' % (tid, tidtaskname[tid])) else : u.log('410', 'TID %d has unknown symbol table' % (tid)) tf = tidcontext[tid] if isinstance(tf, dict) : # Off core, stored decoded frame at registration time u.log('410', 'TID %d is off-core right now' % tid) u.print_trap_frame(tf) else : # On core, read from cpu right now u.log('410', 'TID %d is on-core right now: %s' % (tid, tf.name)) u.print_trap_frame(u.trap_frame_from_cpu(tf)) def cmd_tids() : u.log('410', 'TIDs registered right now: %r' % tidcontext.keys()); cs410_dispatch.add_simcall(tidinfo_set) cs410_dispatch.add_simcall(tidinfo_del) new_command("tidinfo", cmd_tidinfo, args=[arg(int_t, "tid")], short="Ask kernel for thread information by TID", doc="This reports thread information as derived from simulation state") new_command("tids", cmd_tids, short="Report the list of tids registered for tidinfo debugging.", doc="This reports the list of tids being tracked.") # u.logging['410-tidinfo'] = True # u.printing['410-tidinfo'] = True u.log('410-tidinfo', 'tidinfo loaded')