Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
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