This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] x86_64_skip_prologue


Hi all,
I have written a new x86_64_skip_prologue() function. The approach is,
1) Detect, wherher the function seems to have a prolog (ie. starts with 
instructions push %rbp and mov %rsp,%rbp). If not, return pc and exit.
2) Try to get debuginfo. If not, just return pc.
3) Now pc points to the first line of the sourcecode of the function 
(usually opening '{'). If the next line with debuginfo has pc within 
bounds of this function, we will return this pc instead.

Is this correct? For me it seems to work...

Anyway I'm not sure, wherher the lines in linetab _must_ grow up 
monotonically (I assume so). Also perhaps there are some macros for 
those horrible long nested structures, but I don't know about them.

Index: ChangeLog
	* x86-64-tdep.c (x86_64_skip_prologue): Rewritten from scratch.

Michal Ludvig
-- 
* SuSE CR, s.r.o     * mludvig@suse.cz
* +420 2 9654 5373   * http://www.suse.cz
Index: x86-64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 x86-64-tdep.c
*** x86-64-tdep.c	2002/03/04 11:08:28	1.10
--- x86-64-tdep.c	2002/03/15 18:07:16
*************** x86_64_frameless_function_invocation (st
*** 759,769 ****
    return 0;
  }
  
! /* On x86_64 there are no reasonable prologs.  */
  CORE_ADDR
  x86_64_skip_prologue (CORE_ADDR pc)
  {
!   return pc;
  }
  
  /* Sequence of bytes for breakpoint instruction.  */
--- 759,815 ----
    return 0;
  }
  
! /* If a function with debugging information and known beginning
!    is detected, we will return pc of the next line in the source 
!    code. With this approach we effectively skip the prolog.  */
! 
! #define PROLOG_BUFSIZE 4
  CORE_ADDR
  x86_64_skip_prologue (CORE_ADDR pc)
  {
!    int i, firstline, currline;
!    struct symtab *v_symtab;
!    struct symbol *v_function;
!    CORE_ADDR      startaddr=0, endaddr=0;
!    
!    /* We will handle only functions beginning with:
!       55          pushq %rbp
!       48 89 e5    movq %rsp,%rbp 
!    */
!    unsigned char  prolog_expect[PROLOG_BUFSIZE]={0x55, 0x48, 0x89, 0xe5},
!                   prolog_buf[PROLOG_BUFSIZE];
!   
!    read_memory (pc, (char *) prolog_buf, PROLOG_BUFSIZE);
!   
!    /* First check, whether pc points to pushq %rbp, movq %rsp,%rbp.  */
!    for(i=0; i<PROLOG_BUFSIZE; i++)
!       if(prolog_expect[i] != prolog_buf[i])
!          return pc;
!   
!    v_symtab=find_pc_symtab(pc);
!    v_function=find_pc_function(pc);
!   
!    /* If pc doesn't point to a function with debuginfo, 
!       some of the following may be NULL.  */
!    if(!v_function || !v_symtab || !v_symtab->linetable || 
!       !v_function->ginfo.value.block)
!          return pc;
!    
!    firstline=v_function->line;
!    currline=firstline;
!    startaddr=v_function->ginfo.value.block->startaddr;
!    endaddr=v_function->ginfo.value.block->endaddr;
! 
!    for(i=0; i < v_symtab->linetable->nitems; i++)
!       if(v_symtab->linetable->item[i].line > firstline && 
!          v_symtab->linetable->item[i].pc < endaddr)
!       {
!          pc=v_symtab->linetable->item[i].pc;
!          currline=v_symtab->linetable->item[i].line;
!          break;
!       }
!  
!    return pc;
  }
  
  /* Sequence of bytes for breakpoint instruction.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]