From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27488 invoked by alias); 6 Jan 2003 12:55:04 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 27102 invoked from network); 6 Jan 2003 12:54:52 -0000 Received: from unknown (HELO kerberos.suse.cz) (195.47.106.10) by 209.249.29.67 with SMTP; 6 Jan 2003 12:54:52 -0000 Received: from chimera.suse.cz (chimera.suse.cz [10.20.0.2]) by kerberos.suse.cz (SuSE SMTP server) with ESMTP id CF39059D351 for ; Mon, 6 Jan 2003 13:54:39 +0100 (CET) Received: from suse.cz (naga.suse.cz [10.20.1.16]) by chimera.suse.cz (8.11.0/8.11.0/SuSE Linux 8.11.0-0.4) with ESMTP id h06CsdX07355 for ; Mon, 6 Jan 2003 13:54:39 +0100 X-Authentication-Warning: chimera.suse.cz: Host naga.suse.cz [10.20.1.16] claimed to be suse.cz Message-ID: <3E197C8F.3010903@suse.cz> Date: Mon, 06 Jan 2003 12:55:00 -0000 From: Michal Ludvig Organization: SuSE CR User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021130 X-Accept-Language: cs, cz, en MIME-Version: 1.0 To: GDB Patches Subject: [RFA] Runtime Dwarf2 CFI engine cleanup Content-Type: multipart/mixed; boundary="------------090107080903020405080301" X-SW-Source: 2003-01/txt/msg00203.txt.bz2 This is a multi-part message in MIME format. --------------090107080903020405080301 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1506 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 --------------090107080903020405080301 Content-Type: text/plain; name="rerun-3.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rerun-3.diff" Content-length: 2562 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 --------------090107080903020405080301--