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: [RFA] Artifical dwarf2 debug info


On Mon, Dec 16, 2002 at 06:25:29PM +0100, Michal Ludvig wrote:
> Daniel Jacobowitz wrote:
> >On Mon, Dec 16, 2002 at 02:58:18PM +0100, Michal Ludvig wrote:
> >>Can I put it at least to mainline?
> >
> >
> >A little way to go yet.  Please don't just export things from
> >dwarf2cfi:
> >
> >
> >But these aren't.  Add a function to link a new FDE or CIE, please.
> 
> OK, added two new functions: store_fde_unit and store_cie_unit.
> 
> Now only functions for allocation and functions for storing new units 
> are exported.
> 
> Do you like it more, now? :-)

>From a technical standpoint it looks good to me, now.  Thanks!

You still need approval for the documentation, and obviously it can't
go in until we reach consensus about the right way to solve this
problem.

> 
> Michal Ludvig
> -- 
> * SuSE CR, s.r.o     * mludvig@suse.cz
> * (+420) 296.545.373 * http://www.suse.cz

> 2002-12-16  Michal Ludvig  <mludvig@suse.cz>
> 
> 	* x86-64-tdep.c (x86_64_function_has_prologue): New function,
> 	cut off from x86_64_skip_prologue().
> 	(x86_64_skip_prologue): Call x86_64_function_has_prologue().
> 	(x86_64_dwarf2_create_fde): Brand new function.
> 	(x86_64_gdbarch_init): Call set_gdbarch_dwarf2_create_fde().
> 	* dwarf2cfi.c (struct cie_unit, struct fde_unit): Moved to
> 	dwarf2cfi.h
> 	(fde_unit_alloc, cie_unit_alloc): Made extern.
> 	(store_fde_unit, store_cie_unit): New functions.
> 	(frame_state_for): Call DWARF2_CREATE_FDE when FDE wasn't 
> 	found.
> 	(parse_frame_info): Remove duplicate line.
> 	* dwarf2cfi.h (struct cie_unit, struct fde_unit)
> 	(fde_unit_alloc, cie_unit_alloc): New, moved from dwarf2cfi.c
> 	(store_fde_unit, store_cie_unit): New prototypes.
> 	* doc/gdbint.texi: Described DWARF2_CREATE_FDE().
> 	* gdbarch.sh (dwarf2_create_fde): New function.
> 	* gdbarch.c, gdbarch.h: Regenerated.
> 	* x86-64-linux-tdep.c (linux_sigtramp_code): Moved comment.
> 
> Index: dwarf2cfi.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 dwarf2cfi.c
> --- dwarf2cfi.c	19 Jul 2002 09:40:51 -0000	1.16
> +++ dwarf2cfi.c	16 Dec 2002 17:00:51 -0000
> @@ -32,57 +32,6 @@
>  #include "dwarf2cfi.h"
>  #include "gdb_assert.h"
>  
> -/* Common Information Entry - holds information that is shared among many
> -   Frame Descriptors.  */
> -struct cie_unit
> -{
> -  /* Offset of this unit in .debug_frame or .eh_frame.  */
> -  ULONGEST offset;
> -
> -  /* A null-terminated string that identifies the augmentation to this CIE or
> -     to the FDEs that use it.  */
> -  char *augmentation;
> -
> -  /* A constant that is factored out of all advance location instructions.  */
> -  unsigned int code_align;
> -
> -  /* A constant that is factored out of all offset instructions.  */
> -  int data_align;
> -
> -  /* A constant that indicates which regiter represents the return address
> -     of a function.  */
> -  unsigned char ra;
> -
> -  /* Indicates how addresses are encoded.  */
> -  unsigned char addr_encoding;
> -
> -  /* Pointer and length of the cie program.  */
> -  char *data;
> -  unsigned int data_length;
> -
> -  struct objfile *objfile;
> -
> -  /* Next in chain.  */
> -  struct cie_unit *next;
> -};
> -
> -/* Frame Description Entry.  */
> -struct fde_unit
> -{
> -  /* Address of the first location associated with this entry.  */
> -  CORE_ADDR initial_location;
> -
> -  /* Length of program section described by this entry.  */
> -  CORE_ADDR address_range;
> -
> -  /* Pointer to asociated CIE.  */
> -  struct cie_unit *cie_ptr;
> -
> -  /* Pointer and length of the cie program.  */
> -  char *data;
> -  unsigned int data_length;
> -};
> -
>  struct fde_array
>  {
>    struct fde_unit **array;
> @@ -190,8 +139,8 @@ enum ptr_encoding
>  #define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
>  
>  
> -static struct cie_unit *cie_chunks;
> -static struct fde_array fde_chunks;
> +static struct cie_unit *cie_chunks = NULL;
> +static struct fde_array fde_chunks = { 0 };
>  /* Obstack for allocating temporary storage used during unwind operations.  */
>  static struct obstack unwind_tmp_obstack;
>  
> @@ -839,6 +783,9 @@ frame_state_for (struct context *context
>    context->lsda = 0;
>  
>    fde = get_fde_for_addr (context->ra - 1);
> +  
> +  if (fde == NULL && DWARF2_CREATE_FDE_P ())
> +    fde = DWARF2_CREATE_FDE (context->ra - 1);
>  
>    if (fde == NULL)
>      return;
> @@ -1467,8 +1414,6 @@ parse_frame_info (struct objfile *objfil
>  	      cie->next = cie_chunks;
>  	      cie_chunks = cie;
>  
> -	      cie->objfile = objfile;
> -
>  	      cie->offset = unit_offset;
>  
>  	      start++;		/* version */
> @@ -1952,3 +1897,28 @@ cfi_virtual_frame_pointer (CORE_ADDR pc,
>  
>    unwind_tmp_obstack_free ();
>  }
> +
> +void
> +store_fde_unit (struct fde_unit *fde)
> +{
> +  if (fde)
> +  {
> +    fde_chunks_need_space ();
> +    fde_chunks.array[fde_chunks.elems++] = fde;
> +
> +    qsort (fde_chunks.array, fde_chunks.elems,
> +      sizeof (struct fde_unit *), compare_fde_unit);
> +
> +  }
> +  else
> +    error ("Dwarf2 CFI error: Attempt to store NULL pointer to FDE list!");
> +}
> +
> +void
> +store_cie_unit (struct cie_unit *cie)
> +{
> +  cie->next = cie_chunks;
> +  cie_chunks = cie;
> +}
> +
> +
> Index: dwarf2cfi.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/dwarf2cfi.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 dwarf2cfi.h
> --- dwarf2cfi.h	7 Dec 2001 12:10:15 -0000	1.1
> +++ dwarf2cfi.h	16 Dec 2002 17:00:51 -0000
> @@ -22,6 +22,57 @@
>  #ifndef DWARF2CFI_H
>  #define DWARF2CFI_H
>  
> +/* Common Information Entry - holds information that is shared among many
> +   Frame Descriptors.  */
> +struct cie_unit
> +{
> +  /* Offset of this unit in .debug_frame or .eh_frame.  */
> +  ULONGEST offset;
> +
> +  /* A null-terminated string that identifies the augmentation to this CIE or
> +     to the FDEs that use it.  */
> +  char *augmentation;
> +
> +  /* A constant that is factored out of all advance location instructions.  */
> +  unsigned int code_align;
> +
> +  /* A constant that is factored out of all offset instructions.  */
> +  int data_align;
> +
> +  /* A constant that indicates which regiter represents the return address
> +     of a function.  */
> +  unsigned char ra;
> +
> +  /* Indicates how addresses are encoded.  */
> +  unsigned char addr_encoding;
> +
> +  /* Pointer and length of the cie program.  */
> +  char *data;
> +  unsigned int data_length;
> +
> +  struct objfile *objfile;
> +
> +  /* Next in chain.  */
> +  struct cie_unit *next;
> +};
> +
> +/* Frame Description Entry.  */
> +struct fde_unit
> +{
> +  /* Address of the first location associated with this entry.  */
> +  CORE_ADDR initial_location;
> +
> +  /* Length of program section described by this entry.  */
> +  CORE_ADDR address_range;
> +
> +  /* Pointer to asociated CIE.  */
> +  struct cie_unit *cie_ptr;
> +
> +  /* Pointer and length of the cie program.  */
> +  char *data;
> +  unsigned int data_length;
> +};
> +
>  /* Return the frame address.  */
>  CORE_ADDR cfi_read_fp ();
>  
> @@ -62,5 +113,11 @@ void cfi_get_saved_register (char *raw_b
>      any frame pointer offsets.  */
>  void cfi_virtual_frame_pointer (CORE_ADDR pc, int *frame_regnum,
>  				LONGEST * frame_offset);
> +
> +struct cie_unit *cie_unit_alloc (void);
> +struct fde_unit *fde_unit_alloc (void);
> +
> +void store_cie_unit (struct cie_unit *);
> +void store_fde_unit (struct fde_unit *);
>  
>  #endif
> Index: gdbarch.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.c,v
> retrieving revision 1.146
> diff -u -p -r1.146 gdbarch.c
> --- gdbarch.c	24 Aug 2002 00:21:34 -0000	1.146
> +++ gdbarch.c	16 Dec 2002 17:00:52 -0000
> @@ -263,6 +263,7 @@ struct gdbarch
>    gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p;
>    gdbarch_construct_inferior_arguments_ftype *construct_inferior_arguments;
>    gdbarch_dwarf2_build_frame_info_ftype *dwarf2_build_frame_info;
> +  gdbarch_dwarf2_create_fde_ftype *dwarf2_create_fde;
>    gdbarch_elf_make_msymbol_special_ftype *elf_make_msymbol_special;
>    gdbarch_coff_make_msymbol_special_ftype *coff_make_msymbol_special;
>  };
> @@ -419,6 +420,7 @@ struct gdbarch startup_gdbarch =
>    0,
>    0,
>    0,
> +  0,
>    /* startup_gdbarch() */
>  };
>  
> @@ -789,6 +791,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
>    /* Skip verify of in_function_epilogue_p, invalid_p == 0 */
>    /* Skip verify of construct_inferior_arguments, invalid_p == 0 */
>    /* Skip verify of dwarf2_build_frame_info, has predicate */
> +  /* Skip verify of dwarf2_create_fde, has predicate */
>    /* Skip verify of elf_make_msymbol_special, invalid_p == 0 */
>    /* Skip verify of coff_make_msymbol_special, invalid_p == 0 */
>    buf = ui_file_xstrdup (log, &dummy);
> @@ -1113,6 +1116,17 @@ gdbarch_dump (struct gdbarch *gdbarch, s
>                          (long) current_gdbarch->dwarf2_build_frame_info
>                          /*DWARF2_BUILD_FRAME_INFO ()*/);
>  #endif
> +#ifdef DWARF2_CREATE_FDE
> +  fprintf_unfiltered (file,
> +                      "gdbarch_dump: %s # %s\n",
> +                      "DWARF2_CREATE_FDE(pc)",
> +                      XSTRING (DWARF2_CREATE_FDE (pc)));
> +  if (GDB_MULTI_ARCH)
> +    fprintf_unfiltered (file,
> +                        "gdbarch_dump: DWARF2_CREATE_FDE = 0x%08lx\n",
> +                        (long) current_gdbarch->dwarf2_create_fde
> +                        /*DWARF2_CREATE_FDE ()*/);
> +#endif
>  #ifdef DWARF2_REG_TO_REGNUM
>    fprintf_unfiltered (file,
>                        "gdbarch_dump: %s # %s\n",
> @@ -4842,6 +4856,32 @@ set_gdbarch_dwarf2_build_frame_info (str
>                                       gdbarch_dwarf2_build_frame_info_ftype dwarf2_build_frame_info)
>  {
>    gdbarch->dwarf2_build_frame_info = dwarf2_build_frame_info;
> +}
> +
> +int
> +gdbarch_dwarf2_create_fde_p (struct gdbarch *gdbarch)
> +{
> +  gdb_assert (gdbarch != NULL);
> +  return gdbarch->dwarf2_create_fde != 0;
> +}
> +
> +struct fde_unit *
> +gdbarch_dwarf2_create_fde (struct gdbarch *gdbarch, CORE_ADDR pc)
> +{
> +  gdb_assert (gdbarch != NULL);
> +  if (gdbarch->dwarf2_create_fde == 0)
> +    internal_error (__FILE__, __LINE__,
> +                    "gdbarch: gdbarch_dwarf2_create_fde invalid");
> +  if (gdbarch_debug >= 2)
> +    fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf2_create_fde called\n");
> +  return gdbarch->dwarf2_create_fde (pc);
> +}
> +
> +void
> +set_gdbarch_dwarf2_create_fde (struct gdbarch *gdbarch,
> +                               gdbarch_dwarf2_create_fde_ftype dwarf2_create_fde)
> +{
> +  gdbarch->dwarf2_create_fde = dwarf2_create_fde;
>  }
>  
>  void
> Index: gdbarch.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.h,v
> retrieving revision 1.114
> diff -u -p -r1.114 gdbarch.h
> --- gdbarch.h	24 Aug 2002 00:21:34 -0000	1.114
> +++ gdbarch.h	16 Dec 2002 17:00:52 -0000
> @@ -2449,6 +2449,43 @@ extern void set_gdbarch_dwarf2_build_fra
>  #endif
>  #endif
>  
> +#if defined (DWARF2_CREATE_FDE)
> +/* Legacy for systems yet to multi-arch DWARF2_CREATE_FDE */
> +#if !defined (DWARF2_CREATE_FDE_P)
> +#define DWARF2_CREATE_FDE_P() (1)
> +#endif
> +#endif
> +
> +/* Default predicate for non- multi-arch targets. */
> +#if (!GDB_MULTI_ARCH) && !defined (DWARF2_CREATE_FDE_P)
> +#define DWARF2_CREATE_FDE_P() (0)
> +#endif
> +
> +extern int gdbarch_dwarf2_create_fde_p (struct gdbarch *gdbarch);
> +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF2_CREATE_FDE_P)
> +#error "Non multi-arch definition of DWARF2_CREATE_FDE"
> +#endif
> +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF2_CREATE_FDE_P)
> +#define DWARF2_CREATE_FDE_P() (gdbarch_dwarf2_create_fde_p (current_gdbarch))
> +#endif
> +
> +/* Default (function) for non- multi-arch platforms. */
> +#if (!GDB_MULTI_ARCH) && !defined (DWARF2_CREATE_FDE)
> +#define DWARF2_CREATE_FDE(pc) (internal_error (__FILE__, __LINE__, "DWARF2_CREATE_FDE"), 0)
> +#endif
> +
> +typedef struct fde_unit * (gdbarch_dwarf2_create_fde_ftype) (CORE_ADDR pc);
> +extern struct fde_unit * gdbarch_dwarf2_create_fde (struct gdbarch *gdbarch, CORE_ADDR pc);
> +extern void set_gdbarch_dwarf2_create_fde (struct gdbarch *gdbarch, gdbarch_dwarf2_create_fde_ftype *dwarf2_create_fde);
> +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (DWARF2_CREATE_FDE)
> +#error "Non multi-arch definition of DWARF2_CREATE_FDE"
> +#endif
> +#if GDB_MULTI_ARCH
> +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (DWARF2_CREATE_FDE)
> +#define DWARF2_CREATE_FDE(pc) (gdbarch_dwarf2_create_fde (current_gdbarch, pc))
> +#endif
> +#endif
> +
>  /* Default (function) for non- multi-arch platforms. */
>  #if (!GDB_MULTI_ARCH) && !defined (ELF_MAKE_MSYMBOL_SPECIAL)
>  #define ELF_MAKE_MSYMBOL_SPECIAL(sym, msym) (default_elf_make_msymbol_special (sym, msym))
> Index: gdbarch.sh
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.sh,v
> retrieving revision 1.158.6.1
> diff -u -p -r1.158.6.1 gdbarch.sh
> --- gdbarch.sh	20 Nov 2002 00:43:57 -0000	1.158.6.1
> +++ gdbarch.sh	16 Dec 2002 17:00:52 -0000
> @@ -656,6 +656,7 @@ m:::int:in_function_epilogue_p:CORE_ADDR
>  # ARGV is an array of strings, one per argument.
>  m::CONSTRUCT_INFERIOR_ARGUMENTS:char *:construct_inferior_arguments:int argc, char **argv:argc, argv:::construct_inferior_arguments::0
>  F:2:DWARF2_BUILD_FRAME_INFO:void:dwarf2_build_frame_info:struct objfile *objfile:objfile:::0
> +F:2:DWARF2_CREATE_FDE:struct fde_unit *:dwarf2_create_fde:CORE_ADDR pc:pc:::0
>  f:2:ELF_MAKE_MSYMBOL_SPECIAL:void:elf_make_msymbol_special:asymbol *sym, struct minimal_symbol *msym:sym, msym:::default_elf_make_msymbol_special::0
>  f:2:COFF_MAKE_MSYMBOL_SPECIAL:void:coff_make_msymbol_special:int val, struct minimal_symbol *msym:val, msym:::default_coff_make_msymbol_special::0
>  EOF
> Index: x86-64-linux-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/x86-64-linux-tdep.c,v
> retrieving revision 1.5
> diff -u -p -r1.5 x86-64-linux-tdep.c
> --- x86-64-linux-tdep.c	3 Sep 2002 13:06:33 -0000	1.5
> +++ x86-64-linux-tdep.c	16 Dec 2002 17:00:52 -0000
> @@ -35,8 +35,10 @@
>  #define LINUX_SIGTRAMP_OFFSET1 (7)
>  
>  static const unsigned char linux_sigtramp_code[] = {
> -  LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x89, 0x00, 0x00, 0x00,	/*  mov $0x89,%rax */
> -  LINUX_SIGTRAMP_INSN1, 0x05	/* syscall */
> +  /*  mov $__NR_rt_sigreturn,%rax */
> +  LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x89, 0x00, 0x00, 0x00,
> +  /* syscall */
> +  LINUX_SIGTRAMP_INSN1, 0x05
>  };
>  
>  #define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
> Index: x86-64-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
> retrieving revision 1.26
> diff -u -p -r1.26 x86-64-tdep.c
> --- x86-64-tdep.c	24 Aug 2002 00:21:35 -0000	1.26
> +++ x86-64-tdep.c	16 Dec 2002 17:00:55 -0000
> @@ -850,11 +850,31 @@ x86_64_frameless_function_invocation (st
>    return 0;
>  }
>  
> +/* We will handle only functions beginning with:
> +   55          pushq %rbp
> +   48 89 e5    movq %rsp,%rbp */
> +#define PROLOG_BUFSIZE 4
> +static int
> +x86_64_function_has_prologue (CORE_ADDR pc)
> +{
> +  int i;
> +  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 0;		/* ... no, it doesn't. Nothing to skip.  */
> +  
> +  return 1;
> +}
> +
>  /* 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)
>  {
> @@ -863,19 +883,8 @@ x86_64_skip_prologue (CORE_ADDR pc)
>    struct symbol *v_function;
>    CORE_ADDR endaddr;
>  
> -  /* 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;		/* ... no, it doesn't. Nothing to skip.  */
> +  if (! x86_64_function_has_prologue (pc))
> +    return pc;
>  
>    /* OK, we have found the prologue and want PC of the first 
>       non-prologue instruction.  */
> @@ -902,6 +911,175 @@ x86_64_skip_prologue (CORE_ADDR pc)
>    return pc;
>  }
>  
> +static struct fde_unit *
> +x86_64_dwarf2_create_fde (CORE_ADDR pc)
> +{
> +  struct fde_unit *fde;
> +  struct cie_unit *cie;
> +  struct obj_section *osection;
> +  CORE_ADDR loaddr, hiaddr;
> +  char *name;
> +
> +  if (!find_pc_partial_function (pc, &name, &loaddr, &hiaddr))
> +    return NULL;
> +	
> +  if (info_verbose)
> +    printf_filtered ("Dwarf2: Creating missing FDE for pc=%p (%s): ",
> +    		(void*)pc, name);
> +
> +  osection = find_pc_section(pc);
> +  if (! osection)
> +    return NULL;
> +
> +  /* First create CIE */
> +  cie = cie_unit_alloc ();
> +  
> +  cie->objfile = osection->objfile;
> +  cie->code_align = 1;
> +  cie->data_align = -8;
> +  cie->ra = 0x10;
> +
> +  /* Now create FDE */
> +  fde = fde_unit_alloc ();
> +  
> +  fde->initial_location = loaddr;
> +  fde->address_range = hiaddr - loaddr;
> +  fde->cie_ptr = cie;
> +  
> +  /* Now fill in data appropriate for a given function type. */
> +
> +  /* if (x86_64_linux_in_sigtramp (pc, name)) ... not yet implemented.  */
> +  if (x86_64_function_has_prologue (loaddr))
> +  {
> +    /* CIE and FDE for functions that have a valid prologue...
> +  
> +    This is the sample function:
> +      .text
> +    sample_function:
> +    .LFB1:
> +      pushq %rbp
> +    .LCFI0:
> +      movq %rsp, %rbp
> +    .LCFI1:
> +      xor %rax, %rax
> +      leave
> +      ret
> +    .LFE1:
> +
> +    This is the appropriate CIE:
> +      .section  .debug_frame
> +    .Lframe0:
> +      .long  .LECIE0-.LSCIE0  # Length of Common Information Entry
> +    .LSCIE0:
> +      .long  0xffffffff  # CIE Identifier Tag
> +      .byte  0x1       # CIE Version
> +      .ascii "\0"      # CIE Augmentation
> +      .uleb128 0x1     # CIE Code Alignment Factor
> +      .sleb128 -8      # CIE Data Alignment Factor
> +      .byte  0x10      # CIE RA Column
> +      .byte  0xc       # DW_CFA_def_cfa
> +      .uleb128 0x7
> +      .uleb128 0x8
> +      .byte  0x90      # DW_CFA_offset, column 0x10
> +      .uleb128 0x1
> +      .align 8
> +    .LECIE0:
> +  
> +    And the appropriate FDE:
> +    .LSFDE0:
> +      .long  .LEFDE0-.LASFDE0  # FDE Length
> +    .LASFDE0:
> +      .long  .Lframe0  # FDE CIE offset
> +      .quad  .LFB1     # FDE initial location
> +      .quad  .LFE1-.LFB1  # FDE address range
> +      .byte  0x4       # DW_CFA_advance_loc4
> +      .long   .LCFI0-.LFB1  # sizeof(pushq %rbp) = 1
> +      .byte   0xe      # DW_CFA_def_cfa_offset
> +      .uleb128 0x10   
> +      .byte   0x86     # DW_CFA_offset, column 0x6
> +      .uleb128 0x2
> +      .byte   0x4      # DW_CFA_advance_loc4
> +      .long   .LCFI1-.LCFI0  # sizeof(movq %rsp, %rbp) = 3
> +      .byte   0xd      # DW_CFA_def_cfa_register
> +      .uleb128 0x6
> +      .align 8
> +    .LEFDE0:
> +    */
> +    static char ciedata[] = {0x0c, 0x07, 0x08, 0x90, 0x01, 0};
> +    static char fdedata[] = {0x41, 0x0e, 0x10, 0x86, 0x02, 
> +                             0x43, 0x0d, 0x06, 0};
> +
> +    if (info_verbose)
> +      printf_filtered ("with prologue\n");
> +
> +    cie->data = ciedata;
> +    cie->data_length = sizeof(ciedata);
> +
> +    fde->data = fdedata;
> +    fde->data_length = sizeof(fdedata);
> +  }
> +  else
> +  {
> +    /* CIE and FDE for functions that don't touch stack:
> +  
> +    This is the sample function:
> +      .text
> +    sample_function:
> +    .LFB1:
> +      xor %rax, %rax
> +      ret
> +    .LFE1:
> +  
> +    This is CIE:
> +      .section  .debug_frame
> +    .Lframe0:
> +      .long  .LECIE0-.LSCIE0  # Length of Common Information Entry
> +    .LSCIE0:
> +      .long  0xffffffff  # CIE Identifier Tag
> +      .byte  0x1       # CIE Version
> +      .ascii "\0"      # CIE Augmentation
> +      .uleb128 0x1     # CIE Code Alignment Factor
> +      .sleb128 -8      # CIE Data Alignment Factor
> +      .byte  0x10      # CIE RA Column
> +      .byte  0xc       # DW_CFA_def_cfa
> +      .uleb128 0x7
> +      .uleb128 0x8
> +      .byte  0x90      # DW_CFA_offset, column 0x10
> +      .uleb128 0x1
> +      .align 8
> +    .LECIE0:
> +  
> +    And the appropriate FDE:
> +    .LSFDE0:
> +      .long  .LEFDE0-.LASFDE0  # FDE Length
> +    .LASFDE0:
> +      .long  .Lframe0  # FDE CIE offset
> +      .quad  .LFB1     # FDE initial location
> +      .quad  .LFE1-.LFB1  # FDE address range
> +      .align 8         # no instructions for CFA
> +    .LEFDE0:
> +    */
> +    static char ciedata[] = {0x0c, 0x07, 0x08, 0x90, 0x01, 0};
> +    static char fdedata[] = {0};
> +
> +    if (info_verbose)
> +      printf_filtered ("without prologue\n");
> +
> +    cie->data = ciedata;
> +    cie->data_length = sizeof(ciedata);
> +
> +    fde->data = fdedata;
> +    fde->data_length = sizeof(fdedata);
> +  }
> +  
> +  /* Store both units for future use after
> +     they are filled up with values.  */
> +  store_fde_unit (fde);
> +  store_cie_unit (cie);
> +
> +  return fde;
> +}
> +
>  /* Sequence of bytes for breakpoint instruction.  */
>  static unsigned char *
>  x86_64_breakpoint_from_pc (CORE_ADDR * pc, int *lenptr)
> @@ -1121,6 +1299,7 @@ x86_64_gdbarch_init (struct gdbarch_info
>  /* Use dwarf2 debug frame informations.  */
>    set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info);
>    set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
> +  set_gdbarch_dwarf2_create_fde (gdbarch, x86_64_dwarf2_create_fde);
>  
>    return gdbarch;
>  }
> Index: x86-64-tdep.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v
> retrieving revision 1.5
> diff -u -p -r1.5 x86-64-tdep.h
> --- x86-64-tdep.h	20 Jun 2002 13:08:12 -0000	1.5
> +++ x86-64-tdep.h	16 Dec 2002 17:00:55 -0000
> @@ -31,8 +31,8 @@ extern int x86_64_num_gregs;
>  int x86_64_register_number (const char *name);
>  const char *x86_64_register_name (int reg_nr);
>  	
> -
>  gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
>  gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;
> +int x86_64_function_has_prologue (CORE_ADDR pc);
>  
>  #endif
> Index: doc/gdbint.texinfo
> ===================================================================
> RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v
> retrieving revision 1.100
> diff -u -p -r1.100 gdbint.texinfo
> --- doc/gdbint.texinfo	24 Aug 2002 00:21:37 -0000	1.100
> +++ doc/gdbint.texinfo	16 Dec 2002 13:29:18 -0000
> @@ -3249,6 +3249,16 @@ automatically.  Thus, since the offset f
>  its first instruction is two bytes, @code{FUNCTION_START_OFFSET} would
>  be 2 on the VAX.
>  
> +@item DWARF2_CREATE_FDE (@var{pc})
> +@findex DWARF2_CREATE_FDE
> +This function is called from Dwarf2 CFI engine, when there is no FDE 
> +found for a given @var{pc}. It should create a new valid FDE 
> +(along with the corresponding CIE) regarding to the type of the function 
> +to which @var{pc} belongs and join these two structures to @var{cie_chunks} 
> +and @var{fde_chunks} respectively. If the FDE can't be created  return 
> +@code{NULL}, otherwise a pointer to the newly created @code{struct fde_unit} 
> +is returned.
> +
>  @item GCC_COMPILED_FLAG_SYMBOL
>  @itemx GCC2_COMPILED_FLAG_SYMBOL
>  @findex GCC2_COMPILED_FLAG_SYMBOL


-- 
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]