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


Daniel Jacobowitz wrote:
On Sun, Dec 15, 2002 at 01:48:12AM +0100, Michal Ludvig wrote:

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).
Workaround, really - just for some particular functions...
Yes, but still better than nothing ;-)

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.
Lucky.  We can use this to solve a similar problem on i386 but that
will require an actual FDE.
I got it by compiling a sample program with 'gcc -S -g -dA'.

The patch is transparent to architectures that are not prepared to have advantage of it and shouldn't hurt anything.
Great. One big problem: gdbarch.h and gdbarch.c are generated files. Add this to gdbarch.sh instead, and regenerate them. Also it needs
documentation, as Eli said.
OK, the attached patch has a modified gdbarch.sh and regenerated gdbarch.[ch].

I've also put a description into gdbint.texinfo

It would be nice if there were routines in dwarf2cfi.[ch] for creating
FDEs instead of having hex in the tdep file but that doesn't really
bother me.  We can do that later when I need real FDEs.
Yes, that could be taken from GCC I believe. But it can wait a little longer I belive...

OK to commit to branch and mainline?
I do not believe this is appropriate for the branch, at least until
it's sat on mainline without causing problems for some time.
It shouldn't cause any problems because all the machinery is invoked if and only if the target allowed it, and then if a FDE isn't found for a particular function. Typically only two or three times on x86-64 and zero times on other archs.

Can I put it at least to mainline?

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)
	(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.
	(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)
	(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
	* 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: 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 13:26:47 -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: 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 13:26:47 -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: 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 13:26:45 -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)
@@ -839,6 +776,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;
@@ -1378,7 +1318,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 +1406,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	16 Dec 2002 13:26:45 -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: 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
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 13:26:46 -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: 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 13:26:46 -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 13:26:46 -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: 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 13:26:47 -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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]