This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Managing ABI compatibility (was Re: [PATCH 2/2] jit: add switch statements)
- From: David Malcolm <dmalcolm at redhat dot com>
- To: Jeff Law <law at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org, jit at gcc dot gnu dot org
- Date: Fri, 26 Jun 2015 13:57:30 -0400
- Subject: Managing ABI compatibility (was Re: [PATCH 2/2] jit: add switch statements)
- Authentication-results: sourceware.org; auth=none
- References: <558A846C dot 70003 at starynkevitch dot net> <1435259621-45194-1-git-send-email-dmalcolm at redhat dot com> <1435259621-45194-2-git-send-email-dmalcolm at redhat dot com> <558C5398 dot 7060404 at redhat dot com>
On Thu, 2015-06-25 at 13:16 -0600, Jeff Law wrote:
> On 06/25/2015 01:13 PM, David Malcolm wrote:
> >
> > * It extends the libgccjit API. It's not clear to me yet how to
> > manage extensions of the libgccjit API: should I use symbol maps
> > and versioning, or bump the SONAME? I'm thinking of providing
> > precanned feature macros within libgccjit.h e.g:
> >
> > #define LIBGCCJIT_HAVE_SWITCH_STATEMENT
> Seems to me you should use a symbol map and bump the version.
Thanks. By "the version", do you mean the version within the symbol
map?
I've read Uli Drepper's "How To Write Shared Libraries" guide:
http://www.akkadia.org/drepper/dsohowto.pdf
and in particular section 3: "Maintaining APIs and ABIs", which suggests
versioned DSOs (though this presumably implies the use of GNU ld).
I attempted to use the symbol map to segregate the new symbols into
their own version; attached is a patch which does that (on top of the
"add switch statements" patch).
Is that the kind of thing you had in mind?
My first attempt was to keep the existing syms in an anonymous tag but I
got:
/usr/bin/ld: anonymous version tag cannot be combined with other
version tags
(which comes from binutils ld/ldlang.c:lang_register_vers_node)
Hence I put the existing symbols into a LIBGCCJIT_ABI_1 version.
With the above change, using "eu-readelf -s" I see a client program
linked against libgccjit goes from having e.g.:
GLOBAL DEFAULT UNDEF gcc_jit_context_compile
to having:
GLOBAL DEFAULT UNDEF gcc_jit_context_compile@@LIBGCCJIT_ABI_1
and one using the new symbols has:
GLOBAL DEFAULT UNDEF gcc_jit_context_compile@LIBGCCJIT_ABI_1 (2)
GLOBAL DEFAULT UNDEF gcc_jit_block_end_with_switch@LIBGCCJIT_ABI_2 (4)
Presumably I'd need to bump the SONAME to accommodate the introduction
of using symbol versioning? Am I right in hoping that with the
introduction to using symbol versioning that I'd never need to bump the
SONAME again?
Running:
objdump -p client-binary-using-just-old-symbols
gives (amongst other output):
Version References:
required from libc.so.6:
0x09691a75 0x00 03 GLIBC_2.2.5
required from libgccjit.so.0:
0x00824161 0x00 02 LIBGCCJIT_ABI_1
whereas:
objdump -p client-binary-using-some-new-symbols
gives:
Version References:
required from libc.so.6:
0x09691a75 0x00 03 GLIBC_2.2.5
required from libgccjit.so.0:
0x00824162 0x00 04 LIBGCCJIT_ABI_2
0x00824161 0x00 02 LIBGCCJIT_ABI_1
FWIW objdump -p is used by /usr/lib/rpm/find-requires, so presumably
these entries would show up in rpm metadata, so that binaries using the
new symbols get flagged at the RPM level as needing a more up-to-date
libgccjit rpm.
Hopefully other packaging systems handle symbol versioning in similar
ways.
Does this approach look sane?
I'd probably add a page about ABI to the docs, and list the ABIs there.
This doesn't cover the addition of new values to the various options
enums; I'm not sure how to handle capturing *that* within the binary
metadata without bumping the SONAME. Maybe bump the
gcc_jit_context_set_FOO_option entrypoints into new version tags each
time we add a new value to the corresponding option enum?
Would it be sane to go to a feature-based naming scheme for tags, rather
than pure numbers?
e.g.
LIBGCCJIT_ABI_INITIAL
LIBGCCJIT_ABI_WITH_SWITCH_STATEMENTS
LIGCCCJIT_ABI_WITH_BOOL_OPTION_ERROR_ON_UNREACHABLE_BLOCKS
etc (how long can they be, and is there a cost? can they include lower
case?)
Dave
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 93b19e8..7bf89f2 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -17,6 +17,9 @@
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. */
+
+# The initial release of the library.
+LIBGCCJIT_ABI_1
{
global:
# Keep this list sorted alphabetically:
@@ -29,9 +32,7 @@
gcc_jit_block_end_with_jump;
gcc_jit_block_end_with_return;
gcc_jit_block_end_with_void_return;
- gcc_jit_block_end_with_switch;
gcc_jit_block_get_function;
- gcc_jit_case_as_object;
gcc_jit_context_acquire;
gcc_jit_context_add_option;
gcc_jit_context_compile;
@@ -49,7 +50,6 @@
gcc_jit_context_new_binary_op;
gcc_jit_context_new_call;
gcc_jit_context_new_call_through_ptr;
- gcc_jit_context_new_case;
gcc_jit_context_new_cast;
gcc_jit_context_new_child_context;
gcc_jit_context_new_comparison;
@@ -109,4 +109,12 @@
gcc_jit_type_get_volatile;
local: *;
-};
\ No newline at end of file
+};
+
+# Add support for switch statements.
+LIBGCCJIT_ABI_2 {
+ global:
+ gcc_jit_block_end_with_switch;
+ gcc_jit_case_as_object;
+ gcc_jit_context_new_case;
+} LIBGCCJIT_ABI_1;