Re: invalid regs display in bt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dave Anderson wrote:
Richard J Moore wrote:



crash-utility-bounces@xxxxxxxxxx wrote on 27/09/2007 17:13:45:

 > Richard J Moore wrote:
 > >
 > > crash-utility-bounces@xxxxxxxxxx wrote on 27/09/2007 15:45:21:
 > >
 > >  > Richard J Moore wrote:
 > >  >
 > >  > > On looking at the code in entry.S at page_fault and the other
 > > exception
> > > > entry points I see no attempt to save regs to create a pt_regs struct.
 > >  > > The fact that do_page_fault takes pt_regs as the first arg is a
 > > hack to
 > >  > > get at CS:EIP and SS:ESP at the time of exception.
 > >  >
 > >  > KPROBE_ENTRY(page_fault)
 > >  >    RING0_EC_FRAME
 > >  >    pushl $do_page_fault
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    ALIGN
 > >  > error_code:
 > >  >    /* the function address is in %fs's slot on the stack */
 > >  >    pushl %es
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    /*CFI_REL_OFFSET es, 0*/
 > >  >    pushl %ds
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    /*CFI_REL_OFFSET ds, 0*/
 > >  >    pushl %eax
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    CFI_REL_OFFSET eax, 0
 > >  >    pushl %ebp
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    CFI_REL_OFFSET ebp, 0
 > >  >    pushl %edi
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    CFI_REL_OFFSET edi, 0
 > >  >    pushl %esi
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    CFI_REL_OFFSET esi, 0
 > >  >    pushl %edx
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    CFI_REL_OFFSET edx, 0
 > >  >    pushl %ecx
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    CFI_REL_OFFSET ecx, 0
 > >  >    pushl %ebx
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    CFI_REL_OFFSET ebx, 0
 > >  >    cld
 > >  >    pushl %fs
 > >  >    CFI_ADJUST_CFA_OFFSET 4
 > >  >    /*CFI_REL_OFFSET fs, 0*/
 > >  >    movl $(__KERNEL_PERCPU), %ecx
 > >  >    movl %ecx, %fs
 > >  >    UNWIND_ESPFIX_STACK
 > >  >    popl %ecx
 > >  >    CFI_ADJUST_CFA_OFFSET -4
 > >  >    /*CFI_REGISTER es, ecx*/
 > >  >    movl PT_FS(%esp), %edi      # get the function address
 > >  >    movl PT_ORIG_EAX(%esp), %edx   # get the error code
 > >  >    movl $-1, PT_ORIG_EAX(%esp)   # no syscall to restart
 > >  >    mov  %ecx, PT_FS(%esp)
 > >  >    /*CFI_REL_OFFSET fs, ES*/
 > >  >    movl $(__USER_DS), %ecx
 > >  >    movl %ecx, %ds
 > >  >    movl %ecx, %es
 > >  >    movl %esp,%eax         # pt_regs pointer
 > >  >    call *%edi
 > >  >    jmp ret_from_exception
 > >  >    CFI_ENDPROC
 > >  > KPROBE_END(page_fault)
 > >  >
 > >
> > Dave, it looks like error_code: has been change relatively recently. My
 > > source starts:
 > > error_code:
 > >         pushl %ds
 > >         pushl %eax
 > >         xorl  %eax,%eax
 > >         pushl %ebp
 > >         > > and so on. Clearly not a valid pt_regs struct.
> > The source I'm working with is from FC5. On your version of the kernel
 > > only the ERR, SS and ESP would be invalid.
 > > What tree is yours taken from?
 > >
 >
 > My example was from upstream 2.6.22-5.  RHEL5 (2.6.18-based)
 > is slightly different, as the "error_code:" chunk is located
 > in the "divide_error" entry point, but like 2.6.22-5, all of
 > the other exceptions jmp to it.
 >
 > But even your code is creating the remainder of the pt_regs
 > after the essential registers laid down by the hardware
 > exception mechanism, by pushing the remaining registers,
 > "upwards" towards the beginning of the structure:
 >
 > struct pt_regs {
 >          long ebx;
 >          long ecx;
 >          long edx;
 >          long esi;
 >          long edi;
 >          long ebp;
 >          long eax;
 >          int  xds;
 >          int  xes;
 >          long orig_eax;
 >          long eip;
 >          int  xcs;
 >          long eflags;
 >          long esp;
 >          int  xss;
 > };
 >
 > Right?
 >
 > Dave
 >

I don't think so. Am I misreading this:

we take a page fault at ring 0. The cpu pushes eflags, cs, eip, error-code
we enter the kernel at:
ENTRY(page_fault)
        pushl $do_page_fault
        jmp error_code

we have errror code in orig_eax


error_code:
        pushl %ds
        pushl %eax
        xorl %eax, %eax
        pushl %ebp
        pushl %edi
        pushl %esi
        pushl %edx
        decl %eax                        # eax = -1
        pushl %ecx
        pushl %ebx
        cld
        pushl %es
        UNWIND_ESPFIX_STACK
        popl %ecx
        movl ES(%esp), %edi                # get the function address
        movl ORIG_EAX(%esp), %edx        # get the error code
        movl %eax, ORIG_EAX(%esp)
        movl %ecx, ES(%esp)
        movl $(__USER_DS), %ecx
        movl %ecx, %ds
        movl %ecx, %es
        movl %esp,%eax                        # pt_regs pointer
        call *%edi
        jmp ret_from_exception


Aren't we sorting ds in the pt_regs.ES ? and therefore one register out?

Maybe I'm missing something?


This code piece does seem to change from version to version,
but I think it gets the ES register into the proper pt_regs
location by pushing it here:

 >         pushl %es

and then popping it into %ecx here:

 >         popl %ecx

and then later storing it in the pt_regs here:

 >         movl %ecx, ES(%esp)

I think...


Yeah -- that's exactly it, before jumping to error_code,
it pushes the address of the fault handler onto the stack,
essentially into the "pt_regs.xes" location:

>> ENTRY(page_fault)
>>         pushl $do_page_fault
>>         jmp error_code

Then it pushes the remaining pt_regs register values,
but with the pt_regs.xes still needing to be set up.

So then later after the popl of the ES value into %ecx,
it grabs the exception handler address from the pt_regs.xes
location, and puts it into %edi:

>>         popl %ecx
>>         movl ES(%esp), %edi                # get the function address

and then puts the ES value from %ecx into the pt_regs location:

>>         movl %ecx, ES(%esp)

and later calls the handler:

>>         call *%edi

Dave

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux