Surprising behavior of suppress_type drop = yes

Mark Wielaard mark@klomp.org
Sun Apr 5 14:38:28 GMT 2020


Hi,

In my project we have a lot of large private structures that the user
can never access directly, they will always be referenced through
opaque pointers. And we don't guarantee the data layout of those
private data structures. So we suppress them with [suppress_type]
source_location_not_in = list.h, of.h, public.h, headers.h.

Since they are not necessary and they make the xml abi files pretty big
we also remove them from the abi files with drop = yes.

But now we cannot use any opaque handles anymore since any function
parameter that uses a pointer to an opaque typedef/structure will also
be dropped from the abi. This is highly confusing (at least to me). I
had assumed they would just be treated as void pointers instead.

As an example of what I had hoped would work consider the foolib
project as attached. The initial version uses void pointers. But a new
version adds some type safety to the library by replacing the void
pointers by opaque Foo pointers. This should be abi compatible, but
gives the following surprising abi diff:

$ make
gcc -fPIC -g -O2 -Wall -Wextra   -c -o foo.o foo.c
gcc -fPIC -g -O2 -Wall -Wextra -shared foo.o -o libfoo.so
$ make libfoo.abi
abidw --no-show-locs --no-corpus-path --no-comp-dir-path \
      --suppressions libfoo.supp \
      --out-file libfoo.abi libfoo.so
$ cp libfoo.abi{,.orig}
$ patch -p1 < 0001-Add-Foo-handle-to-replace-generic-void.patch
$ make
gcc -fPIC -g -O2 -Wall -Wextra   -c -o foo.o foo.c
gcc -fPIC -g -O2 -Wall -Wextra -shared foo.o -o libfoo.so
$ make libfoo.abi
abidw --no-show-locs --no-corpus-path --no-comp-dir-path \
      --suppressions libfoo.supp \
      --out-file libfoo.abi libfoo.so
$ abidiff --suppressions libfoo.supp libfoo.abi{.orig,}
Functions changes summary: 0 Removed, 4 Changed, 0 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

4 functions with some indirect sub-type change:

  [C]'function void* create_foo()' has some indirect sub-type changes:
    return type changed:
      entity changed from 'void*' to 'void'
      type size changed from 64 to 0 (in bits)

  [C]'function void destroy_foo(void*)' has some indirect sub-type changes:
    parameter 1 of type 'void*' was removed


  [C]'function int get_foo(void*)' has some indirect sub-type changes:
    parameter 1 of type 'void*' was removed


  [C]'function void set_foo(void*, int)' has some indirect sub-type changes:
    parameter 1 of type 'void*' changed:
      entity changed from 'void*' to 'int'
      type size changed from 64 to 32 (in bits)
    parameter 2 of type 'int' was removed

Note how abidiff treats the function return type and parameters changed
from void * to Foo * as disappearing.

Is there another way to achieve what I want/need? Or can we have a
"drop mode" that treats handles to dropped types a simple void pointers
instead?

Thanks,

Mark

P.S. If we leave off the drop = yes, but keep the [suppress_type]
     source_location_not_in = foo.h we still get a report on the
     type change, even though I think it is abi compatible:

$ abidiff --suppressions libfoo.supp libfoo.abi{.orig,}
Functions changes summary: 0 Removed, 4 Changed, 0 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

4 functions with some indirect sub-type change:

  [C]'function void* create_foo()' has some indirect sub-type changes:
    return type changed:
      in pointed to type 'void':
        entity changed from 'void' to 'typedef Foo'
        type size changed from 0 to 32 (in bits)

  [C]'function void destroy_foo(void*)' has some indirect sub-type changes:
    parameter 1 of type 'void*' changed:
      in pointed to type 'void':
        entity changed from 'void' to 'typedef Foo'
        type size changed from 0 to 32 (in bits)

  [C]'function int get_foo(void*)' has some indirect sub-type changes:
    parameter 1 of type 'void*' changed:
      in pointed to type 'void':
        entity changed from 'void' to 'typedef Foo'
        type size changed from 0 to 32 (in bits)

  [C]'function void set_foo(void*, int)' has some indirect sub-type changes:
    parameter 1 of type 'void*' changed:
      in pointed to type 'void':
        entity changed from 'void' to 'typedef Foo'
        type size changed from 0 to 32 (in bits)

How would I tell abidw/diff that an (opaque) pointer change like that
isn't an ABI break?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: foo.c
Type: text/x-csrc
Size: 360 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libabigail/attachments/20200405/2c7c4c5e/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: foo.h
Type: text/x-chdr
Size: 116 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libabigail/attachments/20200405/2c7c4c5e/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fooP.h
Type: text/x-chdr
Size: 45 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libabigail/attachments/20200405/2c7c4c5e/attachment-0002.bin>
-------------- next part --------------
[suppress_type]
  source_location_not_in = foo.h
  drop = yes
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Makefile
Type: text/x-makefile
Size: 489 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libabigail/attachments/20200405/2c7c4c5e/attachment-0003.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-Foo-handle-to-replace-generic-void.patch
Type: text/x-patch
Size: 1339 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libabigail/attachments/20200405/2c7c4c5e/attachment-0004.bin>


More information about the Libabigail mailing list