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]

Re: [CRIS] dwarf2 frame sniffer problem?


On Fri, Mar 12, 2004 at 11:22:34AM +0100, Orjan Friberg wrote:
> Daniel Jacobowitz wrote:
> >
> >The beauty of using the CFI data is that it _is_ supposed to work in
> >the prologue.  It sounds like the CFI is wrong.  Could you post both
> >assembly and CFI data for the same testcase?  I don't know CRIS
> >assembly but I imagine I can interpret it well enough to see what's
> >going on.
> 
> I have attached the test program, dissassembly (objdump -d -S) and the 
> dwarf2 info (readelf -w).  (Crash course in CRIS assembly, if at all 
> needed: r8 holds the frame pointer and srp holds the return address, 
> pushed only in non-leaf functions.)

OK, let's see what we have.  I can see that your unwind information is
definitely wrong.  Take a look at this:

00080080 <foo>:
void foo(void)
{  
   80080:       fce1 7ebe               push $srp
   80084:       fce1 ee8f               push $r8
   80088:       6e86                    move.d $sp,$r8
  bar();
   8008a:       3fbd 7400 0800          jsr 80074 <bar>
}  
   80090:       68e6                    move.d $r8,$sp
   80092:       6e8e                    pop $r8
   80094:       3e0d                    jump [$sp+]

00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
  DW_CFA_advance_loc: 0 to 00080080
  DW_CFA_def_cfa: r8 ofs 8
  DW_CFA_offset: r16 at cfa-4
  DW_CFA_offset: r8 at cfa-8

That says, at 0x80080, CFA is r8 + 8 and both r16 and r8 are saved. 
Which is obviously untrue.

I see that your GCC port uses textual prologues.  As it happens, I just
implemented dwarf generation for that mechanism (for Thumb), so I know
how it's supposed to work.  Here's your problem.  First you have:

      /* FIXME: Slightly redundant calculation, as we do the same in
         pieces below.  This offset must be the total adjustment of the
         stack-pointer.  We can then def_cfa call at the end of this
         function with the current implementation of execute_cfa_insn, but
         that wouldn't really be clean.  */

      cfa_label = dwarf2out_cfi_label ();
      dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);

but that label is at the beginning of the function, so this is
incorrect.  That's not what the CFA is at the beginning of the
function.

What it really ought to be, if I'm reading this right, is (I'll use the
gas CFI pseudo-ops to write this, but you'd use GCC's internal
mechanism to emit it...)

00080080 <foo>:
.cfi_startproc
.cfi_def_cfa $sp, 0	# Set the CFA to $sp + 0
   80080:       fce1 7ebe               push $srp
.cfi_def_cfa_offset 4
.cfi_offset $srp, -4
   80084:       fce1 ee8f               push $r8
.cfi_def_cfa_offset 8
.cfi_offset $r8, -8
   80088:       6e86                    move.d $sp,$r8
.cfi_def_cfa $r8, 0

With that sequence, assuming that I didn't make any silly mistakes, the
CFI is correct at every instruction.

> 
> >It also sounds like your DWARF2_REG_TO_REGNUM may need work, if the
> >unwinder thinks r16 is the return address column and GDB thinks it's an
> >8-bit register.
> 
> Ugh, I had totally missed that (i.e. I don't even have a CRIS-specific 
> DWARF2_REG_TO_REGNUM).  Looking at the other targets' implementations I 
> don't understand where they got the dwarf2 register mapping from (though 
> amd64-tdep.c mentions System V psABI), and the dwarf2 spec says in 
> "2.4.2 Register Name Operators" it should be in the architecture's ABI 
> spec.  I'll go bug my compiler guy, or go look in gcc myself.
> 
> -- 
> Orjan Friberg
> Axis Communications
> 


> 
> test:     file format elf32-cris
> 
> Disassembly of section .text:
> 
> 00080074 <bar>:
> void bar(void) {}
>    80074:	fce1 ee8f           	push $r8
>    80078:	6e86                	move.d $sp,$r8
>    8007a:	68e6                	move.d $r8,$sp
>    8007c:	7fb6                	ret 
>    8007e:	6e8e                	pop $r8
> 
> 00080080 <foo>:
> void foo(void) 
> {
>    80080:	fce1 7ebe           	push $srp
>    80084:	fce1 ee8f           	push $r8
>    80088:	6e86                	move.d $sp,$r8
>   bar();
>    8008a:	3fbd 7400 0800      	jsr 80074 <bar>
> }
>    80090:	68e6                	move.d $r8,$sp
>    80092:	6e8e                	pop $r8
>    80094:	3e0d                	jump [$sp+]
> 
> 00080096 <main>:
> int main ()
> {
>    80096:	fce1 7ebe           	push $srp
>    8009a:	fce1 ee8f           	push $r8
>    8009e:	6e86                	move.d $sp,$r8
>   foo();
>    800a0:	3fbd 8000 0800      	jsr 80080 <foo>
>   return 0;
>    800a6:	7986                	clear.d $r9
> }
>    800a8:	69a6                	move.d $r9,$r10
>    800aa:	68e6                	move.d $r8,$sp
>    800ac:	6e8e                	pop $r8
>    800ae:	3e0d                	jump [$sp+]

> The section .debug_aranges contains:
> 
>   Length:                   28
>   Version:                  2
>   Offset into .debug_info:  0
>   Pointer Size:             4
>   Segment Size:             0
> 
>     Address  Length
>     00080074 60
> 
> Contents of the .debug_pubnames section:
> 
>   Length:                              39
>   Version:                             2
>   Offset into .debug_info section:     0
>   Size of area in .debug_info section: 105
> 
>     Offset	Name
>     37		bar
>     56		foo
>     75		main
> 
> The section .debug_info contains:
> 
>   Compilation Unit @ 0:
>    Length:        101
>    Version:       2
>    Abbrev Offset: 0
>    Pointer Size:  4
>  <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
>      DW_AT_stmt_list   : 0	
>      DW_AT_high_pc     : 0x800b0 524464	
>      DW_AT_low_pc      : 0x80074 524404	
>      DW_AT_name        : (indirect string, offset: 0x34): test.c	
>      DW_AT_comp_dir    : (indirect string, offset: 0x0): /home/orjanf	
>      DW_AT_producer    : (indirect string, offset: 0xd): GNU C 3.2.1 Axis release R55/1.55	
>      DW_AT_language    : 1	(ANSI C)
>  <1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
>      DW_AT_external    : 1	
>      DW_AT_name        : bar	
>      DW_AT_decl_file   : 1	
>      DW_AT_decl_line   : 1	
>      DW_AT_prototyped  : 1	
>      DW_AT_low_pc      : 0x80074 524404	
>      DW_AT_high_pc     : 0x80080 524416	
>      DW_AT_frame_base  : 1 byte block: 58 	(DW_OP_reg8; )
>  <1><38>: Abbrev Number: 2 (DW_TAG_subprogram)
>      DW_AT_external    : 1	
>      DW_AT_name        : foo	
>      DW_AT_decl_file   : 1	
>      DW_AT_decl_line   : 3	
>      DW_AT_prototyped  : 1	
>      DW_AT_low_pc      : 0x80080 524416	
>      DW_AT_high_pc     : 0x80096 524438	
>      DW_AT_frame_base  : 1 byte block: 58 	(DW_OP_reg8; )
>  <1><4b>: Abbrev Number: 3 (DW_TAG_subprogram)
>      DW_AT_external    : 1	
>      DW_AT_name        : (indirect string, offset: 0x2f): main	
>      DW_AT_decl_file   : 1	
>      DW_AT_decl_line   : 7	
>      DW_AT_type        : <61>	
>      DW_AT_low_pc      : 0x80096 524438	
>      DW_AT_high_pc     : 0x800b0 524464	
>      DW_AT_frame_base  : 1 byte block: 58 	(DW_OP_reg8; )
>  <1><61>: Abbrev Number: 4 (DW_TAG_base_type)
>      DW_AT_name        : int	
>      DW_AT_byte_size   : 4	
>      DW_AT_encoding    : 5	(signed)
> 
> Contents of the .debug_abbrev section:
> 
>   Number TAG
>    1      DW_TAG_compile_unit    [has children]
>     DW_AT_stmt_list    DW_FORM_data4
>     DW_AT_high_pc      DW_FORM_addr
>     DW_AT_low_pc       DW_FORM_addr
>     DW_AT_name         DW_FORM_strp
>     DW_AT_comp_dir     DW_FORM_strp
>     DW_AT_producer     DW_FORM_strp
>     DW_AT_language     DW_FORM_data1
>    2      DW_TAG_subprogram    [no children]
>     DW_AT_external     DW_FORM_flag
>     DW_AT_name         DW_FORM_string
>     DW_AT_decl_file    DW_FORM_data1
>     DW_AT_decl_line    DW_FORM_data1
>     DW_AT_prototyped   DW_FORM_flag
>     DW_AT_low_pc       DW_FORM_addr
>     DW_AT_high_pc      DW_FORM_addr
>     DW_AT_frame_base   DW_FORM_block1
>    3      DW_TAG_subprogram    [no children]
>     DW_AT_external     DW_FORM_flag
>     DW_AT_name         DW_FORM_strp
>     DW_AT_decl_file    DW_FORM_data1
>     DW_AT_decl_line    DW_FORM_data1
>     DW_AT_type         DW_FORM_ref4
>     DW_AT_low_pc       DW_FORM_addr
>     DW_AT_high_pc      DW_FORM_addr
>     DW_AT_frame_base   DW_FORM_block1
>    4      DW_TAG_base_type    [no children]
>     DW_AT_name         DW_FORM_string
>     DW_AT_byte_size    DW_FORM_data1
>     DW_AT_encoding     DW_FORM_data1
> 
> 
> Dump of debug contents of section .debug_line:
> 
>   Length:                      52
>   DWARF Version:               2
>   Prologue Length:             26
>   Minimum Instruction Length:  2
>   Initial value of 'is_stmt':  1
>   Line Base:                   -5
>   Line Range:                  14
>   Opcode Base:                 10
> 
>  Opcodes:
>   Opcode 1 has 0 args
>   Opcode 2 has 1 args
>   Opcode 3 has 1 args
>   Opcode 4 has 1 args
>   Opcode 5 has 1 args
>   Opcode 6 has 0 args
>   Opcode 7 has 0 args
>   Opcode 8 has 0 args
>   Opcode 9 has 1 args
> 
>  The Directory Table is empty.
> 
>  The File Name Table:
>   Entry	Dir	Time	Size	Name
>   1	0	0	0	test.c
> 
>  Line Number Statements:
>   Extended opcode 2: set Address to 0x80074
>   Special opcode 5: advance Address by 0 to 0x80074 and Line by 0 to 1
>   Special opcode 91: advance Address by 12 to 0x80080 and Line by 2 to 3
>   Special opcode 76: advance Address by 10 to 0x8008a and Line by 1 to 4
>   Special opcode 48: advance Address by 6 to 0x80090 and Line by 1 to 5
>   Special opcode 49: advance Address by 6 to 0x80096 and Line by 2 to 7
>   Special opcode 76: advance Address by 10 to 0x800a0 and Line by 1 to 8
>   Special opcode 48: advance Address by 6 to 0x800a6 and Line by 1 to 9
>   Special opcode 20: advance Address by 2 to 0x800a8 and Line by 1 to 10
>   Advance PC by 8 to 800b0
>   Extended opcode 1: End of Sequence
> 
> 
> The section .debug_frame contains:
> 
> 00000000 0000000c ffffffff CIE
>   Version:               1
>   Augmentation:          ""
>   Code alignment factor: 1
>   Data alignment factor: -1
>   Return address column: 16
> 
>   DW_CFA_def_cfa: r14 ofs 0
> 
> 00000010 00000014 00000000 FDE cie=00000000 pc=00080074..00080080
>   DW_CFA_advance_loc: 0 to 00080074
>   DW_CFA_def_cfa: r8 ofs 4
>   DW_CFA_offset: r8 at cfa-4
>   DW_CFA_nop
>   DW_CFA_nop
> 
> 00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
>   DW_CFA_advance_loc: 0 to 00080080
>   DW_CFA_def_cfa: r8 ofs 8
>   DW_CFA_offset: r16 at cfa-4
>   DW_CFA_offset: r8 at cfa-8
> 
> 00000040 00000014 00000000 FDE cie=00000000 pc=00080096..000800b0
>   DW_CFA_advance_loc: 0 to 00080096
>   DW_CFA_def_cfa: r8 ofs 8
>   DW_CFA_offset: r16 at cfa-4
>   DW_CFA_offset: r8 at cfa-8
> 
> Contents of the .debug_str section:
> 
>   0x00000000 2f686f6d 652f6f72 6a616e66 00474e55 /home/orjanf.GNU
>   0x00000010 20432033 2e322e31 20417869 73207265  C 3.2.1 Axis re
>   0x00000020 6c656173 65205235 352f312e 3535006d lease R55/1.55.m
>   0x00000030 61696e00 74657374 2e6300            ain.test.c.


-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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