ARM v7 BKPT instruction doesn't work correctly on Linux 2.6.35 -


i have problem connected bkpt instruction on arm v7 on linux 2.6.35. main reason address of fault instruction (bkpt) not correct , not correspond arm v7 manual.

here steps reproducing:

  1. redefine os sigbus handler sigbus handler:

    void initsigbushandler() {       struct sigaction sa;       memset(&sa, 0, sizeof(sa));         sa.sa_flags = sa_siginfo;       sigfillset(&sa.sa_mask);       sa.sa_sigaction = sigbushandler;       sigaction(sigbus, &sa, null);     }  
  2. use inline _asm , put "bkpt" instruction code in main() function:

    int main(int argc, char **argv)   {      initsigbushandler();      __asm      (           "bkpt\n\t"      );       return 0; } 
  3. here sigbus handler:

    void sigbushandler(         int         signum,       siginfo_t   *pact,       void        *poldact       ) {     write(2,          (const char *)msg_sigbus_in_handler,             strlen((const char *)msg_sigbus_in_handler)             );      uint32_t faultaddr = (uint32_t)pact->si_addr;       memcpy((void *)buffer,             (void *)msg_sigbus_fault_addr,             strlen(msg_sigbus_fault_addr)             );      write(2,            (const char *)msg_sigbus_fault_addr,             strlen((const char *)msg_sigbus_fault_addr)             );        sprintf(buffer, "%x\n", faultaddr);       write(2, buffer, strlen(buffer)); }    
  4. the problem fault adress of instruction (bkpt) wrong , not correspond arm v7 specification. here console output after program worked:

    in sigbus handler:
    fault address: 86b0
    in sigbus handler:
    fault address: 86c0
    in sigbus handler:
    fault address: 86c0
    in sigbus handler:
    fault address: 86c0
    in sigbus handler:
    fault address: 86c0
    in sigbus handler:
    fault address: 86b0
    in sigbus handler:
    fault address: 86a8
    in sigbus handler:
    fault address: 86f0

on x86 architecture sample works correctly. on arm v7 architecture sample has strange behavior.

if use gdb on arm v7, catches bkpt instruction correct address.

maybe knows wrong ?

the assumption si_addr precise (i.e. actual address operated on when fault occurred) breakpoint trap not true / portable.

you need inspect saved register state, i.e. third parameter signal handler, can cast ucontext_t*. state not portable between cpus , hence generic interface passes void *; gdb inspects (so info registers works) , extracts program counter of fault there, that's why it's able point breakpoint instruction.

the situation you're encountering on arm here similar you'd on 64bit x86 if tried:

volatile char *ptr = (char*)0x1234567890abcdef; char crashme = *ptr; 

and expect fault address in si_addr 0x1234567890abcdef. won't case because address on access create #gpf not #pf fault, , former doesn't set fault address register on x86. if program counter saved part of ucontext_t / struct sigcontext (embedded in there) you'll see faulting instruction address though, , that'll precise.

change signal handler to:

void sigbushandler(      int  signum,        siginfo_t  *pact,        void  *context     ) {     struct sigcontext *ctx = &(((ucontext_t*)context)->uc_mcontext);     uintptr_t fault_address = ctx->arm_pc;    /* that's you'll see on arm */     ... } 

problem, said, figuring out cpu register state gives cpu-dependent code. you'll have make adaptations / wrappers keep portable, like:

#if defined(arm) #define get_pc_from_context(c) (((ucontext_t *)(c))->uc_mcontext.arm_pc) #elsif defined(__i386__) define get_pc_from_context(c) (((ucontext_t *)(c))->uc_mcontext.eip) #elsif defined(__amd64__) define get_pc_from_context(c) (((ucontext_t *)(c))->uc_mcontext.rip) #endif  uintptr_t instr_address = get_pc_from_context(context); 

hope helps !


Comments

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -