public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
From: Mark Wielaard <mark@klomp.org>
To: libabigail@sourceware.org
Subject: Surprising behavior of suppress_type drop = yes
Date: Sun, 05 Apr 2020 16:38:28 +0200	[thread overview]
Message-ID: <fe4fc88c2c59fcca65c6445f3f7064ce6b0720de.camel@klomp.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 4477 bytes --]

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?

[-- Attachment #2: foo.c --]
[-- Type: text/x-csrc, Size: 360 bytes --]

#include "fooP.h"
#include <stdlib.h>

void *
create_foo (void)
{
  return malloc (sizeof (struct foo));
}

void
destroy_foo (void *foo)
{
  free (foo);
}

void
set_foo (void *foo, int num)
{
  struct foo *instance = (struct foo *) foo;
  instance->num = num;
}

int
get_foo (void *foo)
{
  struct foo *instance = (struct foo *) foo;
  return instance->num;
}

[-- Attachment #3: foo.h --]
[-- Type: text/x-chdr, Size: 116 bytes --]

void *create_foo (void);
void destroy_foo (void *foo);
void set_foo (void *foo, int num);
int  get_foo (void *foo);

[-- Attachment #4: fooP.h --]
[-- Type: text/x-chdr, Size: 45 bytes --]

#include "foo.h"

struct foo
{
  int num;
};

[-- Attachment #5: libfoo.supp --]
[-- Type: text/plain, Size: 62 bytes --]

[suppress_type]
  source_location_not_in = foo.h
  drop = yes

[-- Attachment #6: Makefile --]
[-- Type: text/x-makefile, Size: 489 bytes --]

SOURCES = foo.c
OBJECTS = $(SOURCES:.c=.o)
TARGET = libfoo.so
TARGETABI = $(TARGET:.so=.abi)
ABISUPPRESSION = $(TARGETABI:.abi=.supp)

CC = gcc
CFLAGS = -fPIC -g -O2 -Wall -Wextra
LDFLAGS = -shared

all: $(TARGET)

$(TARGET): $(OBJECTS)
	$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@

$(TARGETABI): $(TARGET)
	abidw --no-show-locs --no-corpus-path --no-comp-dir-path \
	      --suppressions $(ABISUPPRESSION) \
	      --out-file $@ $<

clean:
	rm -f $(OBJECTS) $(TARGET) $(TARGETABI)

.PHONY: clean

[-- Attachment #7: 0001-Add-Foo-handle-to-replace-generic-void.patch --]
[-- Type: text/x-patch, Size: 1339 bytes --]

From bed1888184cfcb69c1332980591fc2a9af20d8de Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Sun, 5 Apr 2020 15:46:52 +0200
Subject: [PATCH] Add Foo handle to replace generic void *

---
 foo.c | 16 +++++++---------
 foo.h | 10 ++++++----
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/foo.c b/foo.c
index 74b6310..50ba43d 100644
--- a/foo.c
+++ b/foo.c
@@ -1,28 +1,26 @@
 #include "fooP.h"
 #include <stdlib.h>
 
-void *
+Foo *
 create_foo (void)
 {
-  return malloc (sizeof (struct foo));
+  return (Foo *) malloc (sizeof (struct foo));
 }
 
 void
-destroy_foo (void *foo)
+destroy_foo (Foo *foo)
 {
   free (foo);
 }
 
 void
-set_foo (void *foo, int num)
+set_foo (Foo *foo, int num)
 {
-  struct foo *instance = (struct foo *) foo;
-  instance->num = num;
+  foo->num = num;
 }
 
 int
-get_foo (void *foo)
+get_foo (Foo *foo)
 {
-  struct foo *instance = (struct foo *) foo;
-  return instance->num;
+  return foo->num;
 }
diff --git a/foo.h b/foo.h
index 67a197d..0b80354 100644
--- a/foo.h
+++ b/foo.h
@@ -1,4 +1,6 @@
-void *create_foo (void);
-void destroy_foo (void *foo);
-void set_foo (void *foo, int num);
-int  get_foo (void *foo);
+typedef struct foo Foo;
+
+Foo *create_foo (void);
+void destroy_foo (Foo *foo);
+void set_foo (Foo *foo, int num);
+int  get_foo (Foo *foo);
-- 
2.18.2


             reply	other threads:[~2020-04-05 14:38 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-05 14:38 Mark Wielaard [this message]
2020-04-06 17:15 ` Dodji Seketeli
2020-04-08 14:32   ` Mark Wielaard
2020-04-09 13:52     ` Dodji Seketeli
2020-04-12  1:44       ` Mark Wielaard
2020-04-12  1:47         ` [PATCH 1/2] Add --header-file option to add individual public header files Mark Wielaard
2020-04-12  1:47           ` [PATCH 2/2] Add --drop-private-types to abidw Mark Wielaard
2020-04-14 15:37             ` Dodji Seketeli
2020-04-14 15:19           ` [PATCH 1/2] Add --header-file option to add individual public header files Dodji Seketeli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fe4fc88c2c59fcca65c6445f3f7064ce6b0720de.camel@klomp.org \
    --to=mark@klomp.org \
    --cc=libabigail@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).