Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
target: pass whole register object
x86_64: fix active task %rip retrieval, clear up scheduled task's
registers retrieval.
  • Loading branch information
alesax committed Jun 30, 2016
commit 8d0b66fe581b18b0a7b042aa0e4ae5fe1b7881d2
50 changes: 29 additions & 21 deletions crash/arch/x86_64.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
class x86_64Architecture(CrashArchitecture):
ident = "i386:x86-64"
aliases = [ "x86_64" ]
# register position on stack (in the future, this should be generated
# dynamically)
stackregs = {"rbx": 1,
"r12": 2,
"r13": 3,
"r14": 4,
"r15": 5}

def __init__(self):
# PC for blocked threads
Expand All @@ -23,7 +30,7 @@ def setup_thread_info(self, thread):
def fetch_register_active(self, thread, register):
task = thread.info
for reg in task.regs:
if reg == "rip" and (register != 16 and register != -1):
if reg == "rip" and (register.name != "rip"):
continue
if reg in ["gs_base", "orig_ax", "rflags", "fs_base"]:
continue
Expand All @@ -32,40 +39,41 @@ def fetch_register_active(self, thread, register):
def fetch_register_scheduled(self, thread, register):
ulong_type = self.ulong_type
task = thread.info.task_struct
r = register.name

# Only write rip when requested; It resets the frame cache
if register == 16 or register == -1:
if r == 'rip':
thread.registers['rip'].value = self.rip
if register == 16:
return True
return True

rsp = task['thread']['sp'].cast(ulong_type.pointer())
rbp = rsp.dereference().cast(ulong_type.pointer())
rbx = (rbp - 1).dereference()
r12 = (rbp - 2).dereference()
r13 = (rbp - 3).dereference()
r14 = (rbp - 4).dereference()
r15 = (rbp - 5).dereference()

# The two pushes that don't have CFI info
if r in self.stackregs:
thread.registers[r].value = (rbp - self.stackregs[r]).dereference()
elif r == 'rsp':
thread.registers[r].value = rsp
thread.info.stack_pointer = rsp
thread.info.valid_stack = True
elif r == 'rbp':
thread.registers[r].value = rbp

# The two pushes that don't have CFI info
# rsp += 2

# ex = in_exception_stack(rsp)
# if ex:
# print "EXCEPTION STACK: pid %d" % task['pid']

thread.registers['rsp'].value = rsp
thread.registers['rbp'].value = rbp
thread.registers['rbx'].value = rbx
thread.registers['r12'].value = r12
thread.registers['r13'].value = r13
thread.registers['r14'].value = r14
thread.registers['r15'].value = r15
thread.registers['cs'].value = 2*8
thread.registers['ss'].value = 3*8
elif r == 'cs':
thread.registers['cs'].value = 2*8
elif r == 'ss':
thread.registers['ss'].value = 3*8
else:
gdb.write("wanted register %s\n" % r)
return False

thread.info.stack_pointer = rsp
thread.info.valid_stack = True
return True

def get_stack_pointer(self, thread):
return long(thread.registers['rsp'].value)
Expand Down
2 changes: 1 addition & 1 deletion crash/kdump/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def to_pid_to_str(self, ptid):

def to_fetch_registers(self, register):
thread = gdb.selected_thread()
self.arch.fetch_register(thread, register.regnum)
self.arch.fetch_register(thread, register)
return True

def to_prepare_to_store(self, thread):
Expand Down