* [RFA] x86_64_skip_prologue
@ 2002-03-15 10:22 Michal Ludvig
2002-03-15 10:41 ` Kevin Buettner
0 siblings, 1 reply; 5+ messages in thread
From: Michal Ludvig @ 2002-03-15 10:22 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 901 bytes --]
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
[-- Attachment #2: x8664-03.diff --]
[-- Type: text/plain, Size: 2397 bytes --]
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. */
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [RFA] x86_64_skip_prologue
2002-03-15 10:22 [RFA] x86_64_skip_prologue Michal Ludvig
@ 2002-03-15 10:41 ` Kevin Buettner
2002-03-19 8:01 ` Michal Ludvig
0 siblings, 1 reply; 5+ messages in thread
From: Kevin Buettner @ 2002-03-15 10:41 UTC (permalink / raw)
To: Michal Ludvig, gdb-patches
On Mar 15, 7:22pm, Michal Ludvig wrote:
> 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.
You might want to take a look at some of the other prologue analyzers.
In particular, you might want to consider calling find_pc_line() instead
of accessing the data structures directly.
> Anyway I'm not sure, wherher the lines in linetab _must_ grow up
> monotonically (I assume so).
I believe it can be non-monotonic for optimized code.
BTW, you might want to run your code through indent.
Kevin
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [RFA] x86_64_skip_prologue
2002-03-15 10:41 ` Kevin Buettner
@ 2002-03-19 8:01 ` Michal Ludvig
2002-03-22 2:57 ` Michal Ludvig
2002-03-23 11:01 ` Andrew Cagney
0 siblings, 2 replies; 5+ messages in thread
From: Michal Ludvig @ 2002-03-19 8:01 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1124 bytes --]
Kevin Buettner wrote:
>>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.
>
> You might want to take a look at some of the other prologue analyzers.
> In particular, you might want to consider calling find_pc_line() instead
> of accessing the data structures directly.
Most of other *_skip_prologue functions pretend, that prolog is an
always-the-same sequence of instructions, what is not the case on
x86-64. I can't see an approach other than the one I have chosen.
Of course I can use other structures and maybe some macros, but the
concept will remain. Or is there another way?
Why should I preferably use find_pc_line()? It gives me the same symtab
as find_pc_symtab() does... Anyway I have rewritten the code to use it.
> BTW, you might want to run your code through indent.
Sorry, I'm not yet used to follow GNU coding style. Hopefully now it is
better ;-)
Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* +420 2 9654 5373 * http://www.suse.cz
[-- Attachment #2: x8664-04.diff --]
[-- Type: text/plain, Size: 2245 bytes --]
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/19 15:29:24
*************** x86_64_frameless_function_invocation (st
*** 759,768 ****
return 0;
}
! /* On x86_64 there are no reasonable prologs. */
CORE_ADDR
x86_64_skip_prologue (CORE_ADDR pc)
{
return pc;
}
--- 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_and_line v_sal;
+ struct symbol *v_function;
+ CORE_ADDR salendaddr = 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_function = find_pc_function (pc);
+ v_sal = find_pc_line (pc, 0);
+
+ /* If pc doesn't point to a function with debuginfo,
+ some of the following may be NULL. */
+ if (!v_function || !v_function->ginfo.value.block
+ || !v_sal.symtab)
+ return pc;
+
+ firstline = v_sal.line;
+ currline = firstline;
+ salendaddr = v_sal.end;
+ endaddr = v_function->ginfo.value.block->endaddr;
+
+ for (i = 0; i < v_sal.symtab->linetable->nitems; i++)
+ if (v_sal.symtab->linetable->item[i].line > firstline
+ && v_sal.symtab->linetable->item[i].pc >= salendaddr
+ && v_sal.symtab->linetable->item[i].pc < endaddr)
+ {
+ pc = v_sal.symtab->linetable->item[i].pc;
+ currline = v_sal.symtab->linetable->item[i].line;
+ break;
+ }
+
return pc;
}
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [RFA] x86_64_skip_prologue
2002-03-19 8:01 ` Michal Ludvig
@ 2002-03-22 2:57 ` Michal Ludvig
2002-03-23 11:01 ` Andrew Cagney
1 sibling, 0 replies; 5+ messages in thread
From: Michal Ludvig @ 2002-03-22 2:57 UTC (permalink / raw)
To: gdb-patches
Michal Ludvig wrote:
> Kevin Buettner wrote:
>
>>> 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.
>> You might want to take a look at some of the other prologue analyzers.
>> In particular, you might want to consider calling find_pc_line() instead
>> of accessing the data structures directly.
> Most of other *_skip_prologue functions pretend, that prolog is an
> always-the-same sequence of instructions, what is not the case on
> x86-64. I can't see an approach other than the one I have chosen.
> Of course I can use other structures and maybe some macros, but the
> concept will remain. Or is there another way?
>
> Why should I preferably use find_pc_line()? It gives me the same symtab
> as find_pc_symtab() does... Anyway I have rewritten the code to use it.
Any comments, complains, suggestions, whatever? Can I commit?
Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* +420 2 9654 5373 * http://www.suse.cz
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [RFA] x86_64_skip_prologue
2002-03-19 8:01 ` Michal Ludvig
2002-03-22 2:57 ` Michal Ludvig
@ 2002-03-23 11:01 ` Andrew Cagney
1 sibling, 0 replies; 5+ messages in thread
From: Andrew Cagney @ 2002-03-23 11:01 UTC (permalink / raw)
To: Michal Ludvig; +Cc: gdb-patches
> Kevin Buettner wrote:
> 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.
>
> You might want to take a look at some of the other prologue analyzers.
> In particular, you might want to consider calling find_pc_line() instead
> of accessing the data structures directly.
>
> Most of other *_skip_prologue functions pretend, that prolog is an always-the-same sequence of instructions, what is not the case on x86-64. I can't see an approach other than the one I have chosen.
> Of course I can use other structures and maybe some macros, but the concept will remain. Or is there another way?
>
> Why should I preferably use find_pc_line()? It gives me the same symtab as find_pc_symtab() does... Anyway I have rewritten the code to use it.
>
> BTW, you might want to run your code through indent.
>
> Sorry, I'm not yet used to follow GNU coding style. Hopefully now it is better ;-)
> Michal Ludvig
The script gdb_indent.sh will always fix any problems :-)
Yes, ok. (Don't forget the changelog when posting patches).
Andrew
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-03-23 19:01 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-15 10:22 [RFA] x86_64_skip_prologue Michal Ludvig
2002-03-15 10:41 ` Kevin Buettner
2002-03-19 8:01 ` Michal Ludvig
2002-03-22 2:57 ` Michal Ludvig
2002-03-23 11:01 ` Andrew Cagney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox