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


Hi all,
this long patch provides a fix for a very annoying fact, that GDB on x86-64 can't do backtraces from hand-optimized assembler functions (that applies for example to glibc's memset, str*, etc as well as to syscall wrappers).
This is caused by the lack of a valid debug_frame/eh_frame FDE entry for such a function (noone really writes .debug_frame section in his assembler code :-)

My approach to fix this behaviour is based on the fortunate fact, that most of those affected glibc's functions don't touch the stack at all, so creating an artifical FDE for them is easy.

Since this debug info is hardware dependent, I introduce a new gdbarch item: dwarf2_create_fde. Any architecture using Dwarf2 CFI that will like to profit from it must have it's own <whtever>_dwarf2_create_fde() function, very similar to the one I did for x86-64.

In x86_64_dwarf2_create_fde() I handle two cases: functions that have a prologue and those that don't (the most usual case). Soon I'll try to create FDE for signal handler caller there as well.

Advantages of this approach are simplicity and cleanliness. There is no need to "manually" fill in values in CFI's context structure - just provide a valid, simple FDE and everything else will be done automagically. This new FDE is of course joined to all other FDEs read from the file before and is automatically used when needed again.

The patch is transparent to architectures that are not prepared to have advantage of it and shouldn't hurt anything.

OK to commit to branch and mainline?

Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* (+420) 296.545.373 * http://www.suse.cz
2002-12-15  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)
	(struct fde_array): Moved to dwarf2cfi.h
	(cie_chunks, fde_chunks): Made extern.
	(fde_unit_alloc, cie_unit_alloc, fde_chunks_need_space)
	(compare_fde_unit): Made extern.
	(guess_generic_fde): New function.
	(frame_state_for): Call guess_generic_fde if FDE wasn't 
	found.
	(parse_frame_info): Remove duplicate line.
	* dwarf2cfi.h (struct cie_unit, struct fde_unit)
	(struct fde_array, cie_chunks, fde_chunks)
	(fde_unit_alloc, cie_unit_alloc, fde_chunks_need_space)
	(compare_fde_unit): New, moved from dwarf2cfi.c
	* gdbarch.h (gdbarch_dwarf2_create_fde_ftype): New type.
	(gdbarch_dwarf2_create_fde_p, gdbarch_dwarf2_create_fde)
	(set_gdbarch_dwarf2_create_fde): New prototypes.
	* gdbarch.h (struct gdbarch): Added dwarf2_create_fde.
	(startup_gdbarch): Initialization for dwarf2_create_fde.
	(gdbarch_dwarf2_create_fde_p, gdbarch_dwarf2_create_fde)
	(set_gdbarch_dwarf2_create_fde): New functions.
	
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	14 Dec 2002 23:51:12 -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,178 @@ 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->next = cie_chunks;
+  cie_chunks = cie;
+
+  cie->code_align = 1;
+  cie->data_align = -8;
+  cie->ra = 0x10;
+
+  /* Now create FDE */
+  fde_chunks_need_space ();
+  fde = fde_unit_alloc ();
+  
+  fde_chunks.array[fde_chunks.elems++] = fde;
+  
+  fde->initial_location = loaddr;
+  fde->address_range = hiaddr - loaddr;
+  
+  fde->cie_ptr = cie;
+  
+  /* 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);
+  }
+  
+  /* Finally sort FDEs for future use.  */
+  qsort (fde_chunks.array, fde_chunks.elems,
+	sizeof (struct fde_unit *), compare_fde_unit);
+
+  return fde;
+}
+
 /* Sequence of bytes for breakpoint instruction.  */
 static unsigned char *
 x86_64_breakpoint_from_pc (CORE_ADDR * pc, int *lenptr)
@@ -1121,6 +1302,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: 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	14 Dec 2002 23:51:11 -0000
@@ -32,64 +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;
-  int elems;
-  int array_size;
-};
-
 struct context_reg
 {
   union
@@ -190,8 +132,8 @@ enum ptr_encoding
 #define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
 
 
-static struct cie_unit *cie_chunks;
-static struct fde_array fde_chunks;
+struct cie_unit *cie_chunks = NULL;
+struct fde_array fde_chunks = { 0 };
 /* Obstack for allocating temporary storage used during unwind operations.  */
 static struct obstack unwind_tmp_obstack;
 
@@ -204,10 +146,6 @@ extern unsigned int dwarf_eh_frame_size;
 extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset,
 				  unsigned int size);
 
-static struct fde_unit *fde_unit_alloc (void);
-static struct cie_unit *cie_unit_alloc (void);
-static void fde_chunks_need_space ();
-
 static struct context *context_alloc ();
 static struct frame_state *frame_state_alloc ();
 static void unwind_tmp_obstack_init ();
@@ -235,7 +173,6 @@ static ULONGEST read_length (bfd * abfd,
 			     int dwarf64);
 
 static int is_cie (ULONGEST cie_id, int dwarf64);
-static int compare_fde_unit (const void *a, const void *b);
 void dwarf2_build_frame_info (struct objfile *objfile);
 
 static void execute_cfa_program (struct objfile *objfile, char *insn_ptr,
@@ -253,7 +190,7 @@ static void update_context (struct conte
 
 
 /* Memory allocation functions.  */
-static struct fde_unit *
+struct fde_unit *
 fde_unit_alloc (void)
 {
   struct fde_unit *fde;
@@ -263,7 +200,7 @@ fde_unit_alloc (void)
   return fde;
 }
 
-static struct cie_unit *
+struct cie_unit *
 cie_unit_alloc (void)
 {
   struct cie_unit *cie;
@@ -273,7 +210,7 @@ cie_unit_alloc (void)
   return cie;
 }
 
-static void
+void
 fde_chunks_need_space (void)
 {
   if (fde_chunks.elems < fde_chunks.array_size)
@@ -829,6 +766,15 @@ get_fde_for_addr (CORE_ADDR pc)
   return 0;
 }
 
+static struct fde_unit *
+guess_generic_fde (CORE_ADDR pc)
+{
+  if (gdbarch_dwarf2_create_fde_p (current_gdbarch))
+    return gdbarch_dwarf2_create_fde (current_gdbarch, pc);
+  else
+    return NULL;
+}
+
 static void
 frame_state_for (struct context *context, struct frame_state *fs)
 {
@@ -839,6 +785,9 @@ frame_state_for (struct context *context
   context->lsda = 0;
 
   fde = get_fde_for_addr (context->ra - 1);
+  
+  if (fde == NULL)
+    fde = guess_generic_fde (context->ra - 1);
 
   if (fde == NULL)
     return;
@@ -1378,7 +1327,7 @@ is_cie (ULONGEST cie_id, int dwarf64)
   return dwarf64 ? (cie_id == 0xffffffffffffffff) : (cie_id == 0xffffffff);
 }
 
-static int
+int
 compare_fde_unit (const void *a, const void *b)
 {
   struct fde_unit **first, **second;
@@ -1466,8 +1415,6 @@ parse_frame_info (struct objfile *objfil
 	      cie->objfile = objfile;
 	      cie->next = cie_chunks;
 	      cie_chunks = cie;
-
-	      cie->objfile = objfile;
 
 	      cie->offset = unit_offset;
 
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	14 Dec 2002 23:51:11 -0000
@@ -22,6 +22,67 @@
 #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;
+};
+
+struct fde_array
+{
+  struct fde_unit **array;
+  int elems;
+  int array_size;
+};
+
+extern struct cie_unit *cie_chunks;
+extern struct fde_array fde_chunks;
+
 /* Return the frame address.  */
 CORE_ADDR cfi_read_fp ();
 
@@ -62,5 +123,10 @@ 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 fde_chunks_need_space (void);
+int compare_fde_unit (const void *a, const void *b);
 
 #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	14 Dec 2002 23:51:12 -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() */
 };
 
@@ -649,6 +651,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of print_registers_info, invalid_p == 0 */
   /* Skip verify of print_float_info, has predicate */
   /* Skip verify of print_vector_info, has predicate */
+  /* Skip verify of dwarf2_create_fde, has predicate */
   /* Skip verify of register_sim_regno, invalid_p == 0 */
   /* Skip verify of register_bytes_ok, has predicate */
   /* Skip verify of cannot_fetch_register, invalid_p == 0 */
@@ -3110,6 +3113,32 @@ set_gdbarch_print_vector_info (struct gd
                                gdbarch_print_vector_info_ftype print_vector_info)
 {
   gdbarch->print_vector_info = print_vector_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;
 }
 
 int
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	14 Dec 2002 23:51:12 -0000
@@ -831,6 +831,14 @@ typedef void (gdbarch_print_vector_info_
 extern void gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args);
 extern void set_gdbarch_print_vector_info (struct gdbarch *gdbarch, gdbarch_print_vector_info_ftype *print_vector_info);
 
+/* Target specific functions for creating debug info 
+   for functions that miss it (mostly pure assembler 
+   objects.  */
+typedef struct fde_unit *(gdbarch_dwarf2_create_fde_ftype) (CORE_ADDR pc);
+extern int gdbarch_dwarf2_create_fde_p (struct gdbarch *gdbarch);
+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 *create_fde);
+
 /* MAP a GDB RAW register number onto a simulator register number.  See
    also include/...-sim.h. */
 

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