From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19041 invoked by alias); 10 Sep 2014 22:52:43 -0000 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 Received: (qmail 19024 invoked by uid 89); 10 Sep 2014 22:52:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: topped-with-meat.com Received: from toast.topped-with-meat.com (HELO topped-with-meat.com) (204.197.218.159) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 10 Sep 2014 22:52:40 +0000 Received: by topped-with-meat.com (Postfix, from userid 5281) id 0B6362C39CF; Wed, 10 Sep 2014 15:52:37 -0700 (PDT) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: Roland McGrath To: Cary Coutant Cc: Ian Lance Taylor , Alan Modra , "GNU C. Library" , Binutils , =?UTF-8?Q?Rafael_=C3=81vila_de_Esp=C3=ADndola?= Subject: Re: gold vs libc In-Reply-To: Cary Coutant's message of Wednesday, 10 September 2014 13:56:51 -0700 References: <20140330042516.1A88E74481@topped-with-meat.com> <20140330045552.GX18201@bubble.grove.modra.org> <20140330050615.7DC5774481@topped-with-meat.com> <20140331200446.A09B074430@topped-with-meat.com> <20140331214025.E61517447E@topped-with-meat.com> Message-Id: <20140910225238.0B6362C39CF@topped-with-meat.com> Date: Wed, 10 Sep 2014 22:52:00 -0000 X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=SvUDtp+0 c=1 sm=1 tr=0 a=WkljmVdYkabdwxfqvArNOQ==:117 a=14OXPxybAAAA:8 a=8rIOUStOCdkA:10 a=Z6MIti7PxpgA:10 a=kj9zAlcOel0A:10 a=hOe2yjtxAAAA:8 a=CCpqsmhAAAAA:8 a=iYpcyjF12WKxwdooreUA:9 a=FwbN19vRCckC7dj_:21 a=AphIl4168WdZT8AK:21 a=CjuIK1q_8ugA:10 a=JV7wAzz88X0A:10 a=0NEgF6jSnGwA:10 a=4-QRsTONmGMA:10 X-SW-Source: 2014-09/txt/msg00082.txt.bz2 > Have we identified a fix? I had to re-read the old discussion to come back up to speed on the details. See https://sourceware.org/ml/libc-alpha/2014-03/msg00971.html for the full old thread (Ian's last message is in the April archive and so doesn't get included in the thread link chain from there). (Just to make this revival of the thread a bit more self-contained so people don't have to find all the old bits I did, I'll note here that https://sourceware.org/bugzilla/show_bug.cgi?id=14675 is a report of this same issue.) In https://sourceware.org/ml/libc-alpha/2014-03/msg01012.html I said: IMHO it would be acceptable to simply disable .eh_frame optimization when there are any symbols in input .eh_frame sections that will survive to affect the output of anything except the .eh_frame output section's contents. (That tortured wording is to distinguish __EH_FRAME_BEGIN__, whose value is used by relocs in other sections like .text, from the various .L* symbols used within individual input sections that are only used in arithmetic producing values inside the section.) What's not acceptable is breaking the core semantics of linking that would apply if nobody had ever thought of .eh_frame optimization. and also, in response to the cited suggestion from Ian: > The current code has a simple algorithm that usually produces the > result we want: we simply copy .eh_frame sections until we find one we > can optimize. Perhaps we could change to a different algorithm: put > all unoptimized .eh_frame sections first, then all optimized .eh_frame > sections. In the concrete scenario, that would violate the abstract principles I described but would deliver an even better practical result. The empty .eh_frame section (and its __EH_FRAME_BEGIN__ symbol) from crtbeginT.o count as "unoptimized", while the .eh_frame content from crt1.o could count as "optimized". So it would place the emptiness and __EH_FRAME_BEGIN__ first, and everything else (including crt1.o's contributions) after, even though crt1.o appears before crtbeginT.o in the link. I think either this or disabling the optimization entirely are acceptable resolutions to the bug. I think that when Ian said, "we've identified a fix," he was referring to, "put all unoptimized .eh_frame sections first, then all optimized .eh_frame sections." > From my point of view, the proper fix is to reorder the crt files so that > the __EH_FRAME_BEGIN__ symbol *precedes* any non-empty .eh_frame > sections. Why is this not possible? Don't we all agree that it's silly to > have the start symbol follow some actual content? I think everyone agrees that putting crt1.o before crtbegin.o is undesireable. It's certainly possible to change that. But it's one of those nasty interactions between our loosely-coordinated components: it's GCC (or another compiler driver) that both provides crtbegin.o and decides on the link order; it's glibc (or another C library) that provides crt1.o and decides whether it should or does contain CFI; it's the linker (whichever one) that the compiler and libc together rely on to do The Right Thing. AFAIK nothing prevents us from changing GCC. But it will be years before we can rely on people using a GCC so changed. That's no reason to avoid changing GCC so that (eventually) no other fixes or workarounds will be required; but it is a key reason why "pass the buck to GCC" is not an acceptable resolution to the situation today. The fundamental mindset of my part of this conversation has been that Gold is billed as a drop-in replacement for BFD ld and this is a situation in which it does not fit that bill. It might well be right to call this a "bug-compatibility" situation and argue that Gold is more Right than BFD ld is. But that doesn't deliver a practical solution to the real problem. > If you want to disable .eh_frame optimization in this case, what are > the specific conditions under which we should not do it? When > --eh-frame-hdr is not specified? When we're doing static linking? When > we see a zero-length section with a symbol that comes after a > non-zero-length section, but isn't an end bracket? (How should we tell > the start bracket apart from the end bracket?) When we see a non-zero > length section in a file named "crt1.o"? None of these strikes me as > particularly elegant (or future-proof). Of the things you listed above, off hand the only thing that seems approximately sensible to me is not to optimize when not using --eh-frame-hdr. (The rationale there is that --eh-frame-hdr is an explicit request for the linker to grok .eh_frame's format completely and produce "optimal, semantically equivalent" results with the clear expectation that PT_GNU_EH_FRAME will be the only means of bootstrapping access to the data. Otherwise, the implicit expectation is that the linker just behave like a linker and paste together input sections and their symbols in their input order.) The other predicates you listed are indeed too picayune and fragile. In March I suggested a predicate that I think is the closest to "exactly right" for the general case of things like bracket symbols; that's cited at the top of this message. That might well be overly fragile as well, and the notion that people really care about optimizing the space use of .eh_frame at all when they aren't bothering to optimize its runtime access cost seems dubious. > If the .eh_frame data in crt1.o really does need to come before > __EH_FRAME_BEGIN__, another thing you could do is simply make it so > gold treats it as non-optimizable. Adding a null relocation to the > first word of the section should do it; inserting a zero-length entry > anywhere but the end would do it (if that doesn't have adverse affects > elsewhere). It doesn't need to and in fact it's undesireable that it do so. That is one reason in favor of Ian's suggestion: though it doesn't adhere to any clear abstract principle I can see, as a pragmatic solution to the actual case in point, it magically makes something even better in practice than the status quo ante (ante as in before switching linkers) long before a fix for the underlying wrongness (in GCC's link order) will be available. OTOH, it certainly seems like it has more risk of unintended consequences we aren't now able to predict than does simply disabling optimization. Incidentally, Ian mentioned Gold having had a special case for the __EH_FRAME_BEGIN__ symbol. But 'git log -G__EH_FRAME_BEGIN -- gold' finds no point in the history where Gold's source code mentioned that symbol. Do you know what Ian was referring to? From https://sourceware.org/ml/libc-alpha/2014-04/msg00021.html: I freely grant that GCC's crtbegin.o file tries this trick in a number of different ways--even worse, crtend.o has trailing symbols. Because of this existing behaviour, gold has various special cases to make it continue to work. One of those special cases is for __EH_FRAME_BEGIN__. As you've seen, the existing special case does not work any more. This is an unfortunate interaction. I don't think it's an obvious bug. In that vein, there is Rafael's suggestion: > Since the problem comes from an optimizations that knows what > .eh_frame is, maybe it could learn that __EH_FRAME_BEGIN__ and > __EH_FRAME_END__ are special symbols marking the start and end of the > section? I think that would be acceptable too. It would have the same benefits of "magically fixing" the crt1/crtbegin ordering snafu, but it seems much simpler and thus it seems that predicting possible downsides would be easier (I haven't thought of any). I've said a lot in this thread about abstract principles for how a linker should behave and how those boil down for Gold in this case, and as to abstraction and principles I stick by everything I've said so far. But the bottom line is that from the glibc perspective, we'll be happy with any solution that makes Gold deliver results as usable or more usable than BFD ld's results for the scenario we know about without depending on GCC to change the link order. Thanks, Roland