From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6764 invoked by alias); 22 May 2002 22:11:52 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 6754 invoked from network); 22 May 2002 22:11:50 -0000 Received: from unknown (HELO executor.cambridge.redhat.com) (195.224.55.237) by sources.redhat.com with SMTP; 22 May 2002 22:11:50 -0000 Received: from prospero.cambridge.redhat.com (dell-paw-2.cambridge.redhat.com [195.224.55.226]) by executor.cambridge.redhat.com (Postfix) with ESMTP id C8050ABAF8; Wed, 22 May 2002 23:11:49 +0100 (BST) Received: by prospero.cambridge.redhat.com (Postfix, from userid 4046) id 2E0A8F8D1D; Wed, 22 May 2002 23:11:48 +0100 (BST) To: "David Abrahams" Cc: "Mark Mitchell" , "Martin v. Loewis" , "H . J . Lu" , , "Ralf W. Grosse-Kunstleve" , Subject: Re: Duplicate data objects in shared libraries References: <76260000.1021912729@warlock.codesourcery.com> <60630000.1021922077@gandalf.codesourcery.com> <00ba01c20035$805388a0$6601a8c0@boostconsulting.com> From: Jason Merrill In-Reply-To: <00ba01c20035$805388a0$6601a8c0@boostconsulting.com> ("David Abrahams"'s message of "Mon, 20 May 2002 15:35:27 -0400") Message-ID: Date: Wed, 22 May 2002 16:35:00 -0000 User-Agent: Gnus/5.090007 (Oort Gnus v0.07) Emacs/21.1 (i686-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-05/txt/msg02309.txt.bz2 >>>>> "David" == David Abrahams writes: > One thing we didn't discuss in detail was what should happen in case two > of a library's dependencies are already loaded, each with its own > definition for some shared symbol S. i.e. A.so -> T.so -> U.so B.so -> U.so ? Here, if T and U both define S, refs in U will resolve to the copy in T, but refs in B won't, so we get the same problem. Hmm. This problem would be solved if T were to link against U, or vice versa, or if both were linked against a third library which defined S. The problem is that RTLD_LOCAL really wants a strict delineation of provider and user; if a DSO uses a symbol from a DSO that it doesn't depend on, this premise is violated, and users will get confused. I would further clarify my proposal #6 thus: 7) Resolution of a relocation in a DSO loaded with RTLD_LOCAL only considers definitions in the DSO itself and its dependencies. If a strong definition is seen in the normal breadth-first search of these DSOs, it is used; otherwise, a weak definition is chosen by depth-first search. Actually, I'd be inclined to adopt the second sentence for all cases, not just RTLD_LOCAL. If a library provides a weak definition of something, and the executable provides a weak definition as well, it makes sense to me to use the library version. Doing so would improve the usefulness of -Wl,--gc-sections (once it works). Anyway, adopting this proposal, T and U would each use their own definition, A would use the one from T, and B would use the one from U. So the problem would come when trying to, say, throw from U into A. It's not difficult to imagine this sort of situation arising with vague-linkage entities that are emitted when needed. For example: a library V defines a non-polymorphic class J but doesn't use its RTTI node. T and U link against V and both throw objects of type J. A catches the one thrown in T, but not the one thrown in U. We would have been fine if the RTTI node had been emitted in V, but it wasn't needed, so it wasn't emitted. I don't see any way to get ld.so to just give us the semantics we want for this subcase. If the author of V is aware of this issue, he can avoid it by making sure the RTTI node for J is emitted in V, either by using #pragma interface or (if #7 is adopted) by writing a dummy function which refers to typeid(J). The same thing is true for other static data. Unfortunately, this is much harder for template libraries, where we can't anticipate what parameters our templates might be instantiated with. If V defines a template K and T and U independently decide to throw a K, there isn't much the author of V can do about it. The author of a template library can adjust their design to avoid relying on static data members being combined properly. For instance, an allocator pool is less effective if it's partitioned, but no less correct. But there seems to be nothing anyone can do to fix throwing a K from U into A, unless we adjust RTTI in the same way. In other words, #2. We can significantly reduce the number of cases where this situation will cause problems, but can't eliminate them without abandoning our reliance on pointer comparison. Jason