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] Runtime Dwarf2 CFI engine cleanup


Hi all,
the attached is a fix for the problem described here:
http://sources.redhat.com/ml/gdb/2002-12/msg00246.html

I've created a new function cleanup_cfi() in dwarf2cfi.c that deletes all CIEs and FDEs of objfiles removed later by objfile_purge_solibs().
So far it works fine but I don't know how should I correctly call it.
For now I put the call directly to run_command():

static void
run_command (char *args, int from_tty)
{
[...]
clear_breakpoint_hit_counts ();

cleanup_cfi (); /* <=== HERE */

objfile_purge_solibs ();

do_run_cleanups (NULL);

reopen_exec_file ();
reread_symbols ();
[...]
}

I know it isn't the right solution because it would require linking of dwarf2cfi.o to all targets. If I would wrap it by #ifdef X86_64 ... #endif it still isn't perfect, because other archs will hopefully use CFI in the future as well.

I was thinking about defining something like USE_DWARF2CFI for each target that use it in their config/whatever file...? Is it a way to go?

I can't attach this function to run_cleanup_chain, because I need to call cleanup_cfi() before objfile_purge_solibs() and also because do_run_cleanups() finally destroys the contents of run_cleanup_chain and finally because I don't know how (when/where) to attach cleanup_cfi() to run_cleanup_chain.

Could someone please tell me what is the cleanest way to call cleanup_cfi()? Thanks.

Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* (+420) 296.545.373 * http://www.suse.cz
Index: dwarf2cfi.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v
retrieving revision 1.16
diff -u -p -r1.16 dwarf2cfi.h
--- dwarf2cfi.h	19 Jul 2002 09:40:51 -0000	1.16
+++ dwarf2cfi.h	20 Dec 2002 15:14:21 -0000
@@ -64,6 +64,12 @@ struct cie_unit
 
   /* Next in chain.  */
   struct cie_unit *next;
+
+  /* Keep or destroy this CIE on a new run? */
+  int keep;
+
+  /* How many FDEs refer to this CIE? */
+  int refs;
 };
 
 /* Frame Description Entry.  */
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	20 Dec 2002 15:14:21 -0000
@@ -317,6 +326,86 @@ frame_state_alloc (void)
     (struct frame_state_reg *) obstack_alloc (&unwind_tmp_obstack, regs_size);
   memset (fs->regs.reg, 0, regs_size);
   return fs;
+}
+
+void
+cleanup_cfi (void *name)
+{
+  struct objfile *ofp;
+  struct cie_unit *cie, *cie_prev;
+  int fde_index=0, fde_free=0;
+  
+  cie = cie_chunks;
+  while (cie)
+  {
+	  cie->refs = 0;
+	  cie->keep = 0;
+	  cie = cie->next;
+  }
+
+  /* Mark all unwanted CIEs. */
+  ALL_OBJFILES (ofp)
+  {
+	  if (!(ofp->flags & OBJF_USERLOADED) && (ofp->flags & OBJF_SHARED))
+		  printf ("\tRemoving %s...\n", ofp->name);
+	  else
+	  {
+		  printf ("\tKeeping %s...\n", ofp->name);
+		  cie = cie_chunks;
+		  while(cie)
+		  {
+			  if (cie->objfile == ofp)
+				  cie->keep = 1;
+			  cie = cie->next;
+		  }
+	  }
+  }
+
+  /* Remove all FDEs pointing to unwanted CIEs. */
+  for (fde_index = 0, fde_free=0; 
+	fde_index < fde_chunks.elems; 
+	fde_index++, fde_free++)
+  {
+	  if (!fde_chunks.array[fde_index]->cie_ptr->keep)
+	  {
+		  fde_free--;
+		  continue;
+	  }
+	  else if (fde_free < fde_index)
+		  fde_chunks.array[fde_free] = fde_chunks.array[fde_index];
+	  fde_chunks.array[fde_free]->cie_ptr->refs++;
+  }
+  fde_chunks.elems = fde_free;
+
+  /* Remove all unwanted CIEs. */
+  cie = cie_chunks;
+  cie_prev = NULL;
+  while (cie)
+  {
+	  struct cie_unit *cie_tmp;
+	  
+	  if (! cie->keep || !cie->refs)
+	  {
+		  cie_tmp = cie;
+		  if (cie_prev == NULL)
+		  {
+			  cie_chunks = cie->next;
+			  cie = cie_chunks;
+		  }
+		  else 
+		  {
+			  cie_prev->next = cie->next;
+			  cie = cie->next;
+		  }
+		  /* cie_prev must remain unchanged. */
+		  xfree (cie_tmp);
+	  }
+	  else
+	  {
+		  cie_prev = cie;
+		  cie = cie->next;
+	  }
+  }
 }
 
 static void

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