* Russ Allbery:

> I'm currently working on the Policy modification to document (and
> recommend) use of symbols instead of shlibs, but I'd only personally used
> symbols with C libraries.  Today I decided that I should try adding a
> symbols file to a C++ library, particularly if I'm going to recommend
> everyone do it.  I tried this exercise with xml-security-c, which is, I
> think, a reasonably typical C++ library.

Symbols just don't work for C++.  Large parts of a library ABI are not
expressed in terms of exported symbols.

Let's start with this:

struct Foo {
  long a;
  virtual void foo();
};

Foo *
f()
{
  return new Foo;
}

void
g(Foo *p)
{
  p->foo();
}

It is compiled to:

.globl _Z1gP3Foo
        .type   _Z1gP3Foo, @function
_Z1gP3Foo:
.LFB4:
        .cfi_startproc
        movq    (%rdi), %rax
        movq    (%rax), %rax
        jmp     *%rax
        .cfi_endproc
.LFE4:
        .size   _Z1gP3Foo, .-_Z1gP3Foo
        .p2align 4,,15
.globl _Z1fv
        .type   _Z1fv, @function
_Z1fv:
.LFB0:
        .cfi_startproc
        subq    $8, %rsp
        .cfi_def_cfa_offset 16
        movl    $16, %edi
        call    _Znwm
        movq    $_ZTV3Foo+16, (%rax)
        addq    $8, %rsp
        ret
        .cfi_endproc
.LFE0:
        .size   _Z1fv, .-_Z1fv

Now we threw new members to struct Foo and use Foo::bar() in g():

struct Foo {
  long a, b, c;
  virtual void foo();
  virtual void bar();
};

Foo *
f()
{
  return new Foo;
}

void
g(Foo *p)
{
  p->bar();
}

This does not change the symbols at all:

.globl _Z1gP3Foo
        .type   _Z1gP3Foo, @function
_Z1gP3Foo:
.LFB4:
        .cfi_startproc
        movq    (%rdi), %rax
        movq    8(%rax), %rax
        jmp     *%rax
        .cfi_endproc
.LFE4:
        .size   _Z1gP3Foo, .-_Z1gP3Foo
        .p2align 4,,15
.globl _Z1fv
        .type   _Z1fv, @function
_Z1fv:
.LFB0:
        .cfi_startproc
        subq    $8, %rsp
        .cfi_def_cfa_offset 16
        movl    $32, %edi
        call    _Znwm
        movq    $_ZTV3Foo+16, (%rax)
        addq    $8, %rsp
        ret
        .cfi_endproc
.LFE0:
        .size   _Z1fv, .-_Z1fv

Two constants change in an incompatible way, but the set of symbols
remains the same.  Of course, this is similar to C code where the size
of structs is not covered by symbol versioning, either.  For the Foo
struct itself, the size dependency can be hidden by only handing out
pointers to application code.  For Foo's vtable (which grows in size
to accommodate the Foo::bar() method), this is more difficult, and
downright impossible if application code needs to derive from Foo and
actually needs the method to be virtual.

In some isolated cases, symbols may still make sense for C++ (e.g., if
the library ABI is really stable and all you need to detect is use of
newly added classes to bump dependencies), but I don't think they work
in general.


-- 
To UNSUBSCRIBE, email to debian-devel-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/8762fy3cin....@mid.deneb.enyo.de

Reply via email to