From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5899 invoked by alias); 2 Dec 2007 20:15:28 -0000 Received: (qmail 5890 invoked by uid 22791); 2 Dec 2007 20:15:27 -0000 X-Spam-Check-By: sourceware.org Received: from smtp.nildram.co.uk (HELO smtp.nildram.co.uk) (195.149.33.74) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 02 Dec 2007 20:15:19 +0000 Received: from firetop.home (85-211-136-23.dyn.gotadsl.co.uk [85.211.136.23]) by smtp.nildram.co.uk (Postfix) with ESMTP id 273374C10B for ; Sun, 2 Dec 2007 20:15:13 +0000 (GMT) Received: from richard by firetop.home with local (Exim 4.63) (envelope-from ) id 1IyvDf-0004Iq-Kq for binutils@sourceware.org; Sun, 02 Dec 2007 20:15:15 +0000 From: Richard Sandiford To: binutils@sourceware.org Mail-Followup-To: binutils@sourceware.org, rsandifo@nildram.co.uk Subject: Fix --gc-sections for C++ MIPS ELF Date: Sun, 02 Dec 2007 20:15:00 -0000 Message-ID: <87r6i4svjg.fsf@firetop.home> User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2007-12/txt/msg00000.txt.bz2 --Wl,--gc-sections generates wrong code for C++ on MIPS ELF. The problem is that if: (a) all C++ CIEs have relocations against the personality routine itself, rather relocations against a pointer to the personality routine, and (b) as usual, there are no references to the personality routine's section outside .eh_frame then we never mark the personality routine's section as needed. The main code for marking .eh_frames is: /* Keep .gcc_except_table.* if the associated .text.* (or the associated .gnu.linkonce.t.* if .text.* doesn't exist) is marked. This isn't very nice, but the proper solution, splitting .eh_frame up and using comdat doesn't pan out easily due to needing special relocs to handle the difference of two symbols in separate sections. Don't keep code sections referenced by .eh_frame. */ #define TEXT_PREFIX ".text." #define TEXT_PREFIX2 ".gnu.linkonce.t." #define GCC_EXCEPT_TABLE_PREFIX ".gcc_except_table." for (o = sub->sections; o != NULL; o = o->next) if (!o->gc_mark && o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0) and it ignores all relocations against code. Non-PIC CIEs for targets like x86_64-linux-gnu also have direct references to the personality routines. I suspect the only reason -Wl,--gc-sections -static-libgcc works for them is that libgcc's own CIEs use an indirect reference, so the section gets marked that way. A simple fix would be to use indirect references for MIPS ELF too, but it would be nice to avoid the overhead. It would also be nice to make binutils work with older GCCs if possible. Another reason to prefer a binutils change is that the current code seems unsafe in ways that aren't explicitly mentioned in the comment above. The marking code assumes that FDEs against discarded sections will themselves be discarded, but if an .eh_frame section contains something unexpected, like a future augmentation type, elf-eh-frame.c will keep the section as-is. We would then get a link failure or silent wrong code. Has there been any talk about parsing the CIEs and FDEs and marking relocations against them individually? I couldn't find anything in the archives, so I gave it a go, and it seems to work. The main problem was that we currently don't parse the .eh_frame information until later in the link process, so a fair amount of rejigging was needed. Once we have access to the parsed information, we can mark an .eh_frame relocation if: (i) it is associated with an FDE that is itself associated with a marked section or (ii) it is associated with the CIE for such an FDE. I tested the changes by running the C++ and libstdc++-v3 testsuites on x86_64-linux-gnu and mipsisa64-elf with -Wl,--gc-sections. The C++ PCH tests failed, but the results were otherwise identical to those without -Wl,--gc-sections. There were also no regressions in the binutils, gas and ld testsuites for x86_64-linux-gnu, mipsisa64-elf and mips64-linux-gnu. Because several changes are needed, I've tried to split things up for ease of review. I'll post each patch as a follow-up. Richard