From patchwork Fri Sep 18 12:11:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 40429 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D9FBB387088E; Fri, 18 Sep 2020 12:12:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D9FBB387088E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1600431127; bh=e5YGcRmZYUhC2H1FKEj4nVlKtqjHB/q4qe+bYryIewM=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=raR3i9FM/Bn5QmpqxXtlc6XNhr5ZxGzxRgOU5yRw/ztpPShn1sbiwtF8NRd6kouIQ IcNnWyhGayNsdMjGJO3FmQK35z1sElm4IYH0YskoHSjcDv8L+21RFUt+McyA6PYzhl pEhZbfiE62Po2vZHvqIm6vRLBwkUNCJnOLa3sQ8c= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id E746A3870876 for ; Fri, 18 Sep 2020 12:12:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E746A3870876 Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-237-vuWAl3aJNjGXRQTYE0NDVA-1; Fri, 18 Sep 2020 08:11:57 -0400 X-MC-Unique: vuWAl3aJNjGXRQTYE0NDVA-1 Received: by mail-wr1-f69.google.com with SMTP id h4so2072315wrb.4 for ; Fri, 18 Sep 2020 05:11:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:organization:date:message-id :user-agent:mime-version; bh=e5YGcRmZYUhC2H1FKEj4nVlKtqjHB/q4qe+bYryIewM=; b=DG4icNXYyhDWR/7VUp/exox73AcfXe8IQL+NdsjN4uq9GSFT5c5Zc8DWmj81oPTqF7 KK1lmMr2toy/uBbnrVp8yk19FtGOUMHGRQ+GkAQQTgiT9+XmLv6jDR1yyu5UTjE3571+ olxssDT6BXlORt9YkWG+4bVX5hqHzId2T/erOaH9Q0OUWPyFUI5bLXNwCjdDY22WYfeO lHbbssWQtdllsBgtwhz9F8PvYMJnjAsMryNKH2bhG5wK/kaL09qJULKGDWx3Ku6vbjMq AL9vAefl+ew1p/F25wKxifblo4pn2Res5tNUfK1ZNAV1Qt1Vkz/VMmIlxHQpKzLbpAup XsYw== X-Gm-Message-State: AOAM533Zvh2gHvorto7r+swR0dGSwpWV2c/aPm/8XNCCz/L97+zj6Q7h cmZPbO0D5FsdW+OCdtWE1W8SpB69aKN0CqOy31BiSM+yx0Rl+674QzfA/F708soaogcjhklsMzA O/MeP/P29XRZ71/z+tG5Q X-Received: by 2002:a5d:4709:: with SMTP id y9mr37790898wrq.59.1600431114624; Fri, 18 Sep 2020 05:11:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwdNPePJtLO5lpZd9cvVVnkiwCPSMggICcGSr4ekOhZMEii2bxeZ3DiOYKDR7kqVWdNEmVhVg== X-Received: by 2002:a5d:4709:: with SMTP id y9mr37790837wrq.59.1600431113756; Fri, 18 Sep 2020 05:11:53 -0700 (PDT) Received: from localhost (91-166-131-130.subs.proxad.net. [91.166.131.130]) by smtp.gmail.com with ESMTPSA id h76sm5072443wme.10.2020.09.18.05.11.51 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 18 Sep 2020 05:11:53 -0700 (PDT) Received: by localhost (Postfix, from userid 1000) id 0A4B9180088E; Fri, 18 Sep 2020 14:11:50 +0200 (CEST) To: libabigail@sourceware.org Subject: [PATCH] Make abidiff and abidw support several --headers-dir{1, 2} options Organization: Red Hat / France X-Operating-System: Red Hat Enterprise Linux Workstation 7.8 Beta X-URL: http://www.redhat.com Date: Fri, 18 Sep 2020 14:11:49 +0200 Message-ID: <87d02jqo6y.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dodji Seketeli via Libabigail From: Dodji Seketeli Reply-To: Dodji Seketeli Errors-To: libabigail-bounces@sourceware.org Sender: "Libabigail" Hello, When handling a binary with abidiff or abidw it can be useful to provide several different header files directories, for the cases where the header files of the binary are scathered in several different directories. It thus becomes possible to invoke abidiff like this: abidiff --headers-dir1 first-header-dir1 \ --headers-dir1 second-header-dir1 \ --headers-dir2 first-header-dir2 \ --headers-dir2 second-header-dir2 \ binary1 binary2 This patch adds support for that. It also modifies the tests/test-abidiff-exit.cc test harness to make it take header directories. With that modification done, a new test is added in that harness to exercise this new feature. This should close the feature request over at https://sourceware.org/bugzilla/show_bug.cgi?id=26565. * doc/manuals/abidiff.rst: Update documentation for the --headers-dir{1,2} options. * doc/manuals/abidw.rst: Likewise for the --header-dir option. * include/abg-tools-utils.h (gen_suppr_spec_from_headers): Add new overload that takes a vector of headers root dirs. * src/abg-tools-utils.cc (gen_suppr_spec_from_headers_root_dir): Define new function. (gen_suppr_spec_from_headers): Define a new overload that takes a vector of head_root_dir strings; it uses the new gen_suppr_spec_from_headers function. Use the new overload in the previous one that takes just one head_root_dir string. * tools/abidiff.cc (options::headers_dirs{1,2}): Rename option::headers_dir{1,2} into this one and make it be a vector of strings rather than just a string. (parse_command_line): Support several --headers-dir{1,2} on the command line. (set_diff_context_from_opts, set_suppressions): Adjust. * tools/abidw.cc (options::headers_dirs): Renamed options::headers_dir into this and make it be a vector of strings rather than just a string. (parse_command_line): Support several --headers-dir on the command line. (set_suppressions): Adjust. * tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v{0,1}.h: Header files of new binary test input. * tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v{0,1}.h: Likewise. * tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v{0,1}.c: Source code of new binary test input. * tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-{1,2}.txt: Reference output of new binary test input. * tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v{0,1}.o: New binary test input. * tests/data/Makefile.am: Add the new files above to source distribution. * tests/test-abidiff-exit.cc (InOutSpec::in_elfv{0,1}_path): Add new data members. (in_out_specs): Adjust the content of this array as its type changed. Also, add two new entries to run the test over the new binary test inputs above. (do_prefix_strings): Define new static function. (main): Use it the new do_prefix_strings here. Make abidiff use the --header-dir{1,2} option whenever header directories are specified in an entry of the in_out_specs array. Signed-off-by: Dodji Seketeli Applied to master. --- doc/manuals/abidiff.rst | 23 +++- doc/manuals/abidw.rst | 15 ++- include/abg-tools-utils.h | 4 + src/abg-tools-utils.cc | 88 +++++++++++---- tests/data/Makefile.am | 10 ++ .../test-headers-dirs/headers-a/header-a-v0.h | 26 +++++ .../test-headers-dirs/headers-a/header-a-v1.h | 26 +++++ .../test-headers-dirs/headers-b/header-b-v0.h | 8 ++ .../test-headers-dirs/headers-b/header-b-v1.h | 9 ++ .../test-headers-dir-report-1.txt | 3 + .../test-headers-dir-report-2.txt | 13 +++ .../test-headers-dirs/test-headers-dir-v0.c | 33 ++++++ .../test-headers-dirs/test-headers-dir-v0.o | Bin 0 -> 3840 bytes .../test-headers-dirs/test-headers-dir-v1.c | 36 ++++++ .../test-headers-dirs/test-headers-dir-v1.o | Bin 0 -> 3920 bytes tests/test-abidiff-exit.cc | 125 +++++++++++++++++++-- tools/abidiff.cc | 28 +++-- tools/abidw.cc | 6 +- 18 files changed, 402 insertions(+), 51 deletions(-) create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c create mode 100644 tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o diff --git a/doc/manuals/abidiff.rst b/doc/manuals/abidiff.rst index 6aac73b..74c3ebf 100644 --- a/doc/manuals/abidiff.rst +++ b/doc/manuals/abidiff.rst @@ -101,8 +101,18 @@ Options * ``--headers-dir1 | --hd1`` Specifies where to find the public headers of the first shared - library that the tool has to consider. The tool will thus filter - out ABI changes on types that are not defined in public headers. + library (or binary in general) that the tool has to consider. The + tool will thus filter out ABI changes on types that are not + defined in public headers. + + Note that several public header directories can be specified for + the first shared library. In that case the ``--headers-dir1`` + option should be present several times on the command line, like + in the following example: :: + + $ abidiff --headers-dir1 /some/path \ + --headers-dir1 /some/other/path \ + binary-version-1 binary-version-2 * ``--header-file1 | --hf1`` @@ -116,6 +126,15 @@ Options library that the tool has to consider. The tool will thus filter out ABI changes on types that are not defined in public headers. + Note that several public header directories can be specified for + the second shared library. In that case the ``--headers-dir2`` + option should be present several times like in the following + example: :: + + $ abidiff --headers-dir2 /some/path \ + --headers-dir2 /some/other/path \ + binary-version-1 binary-version-2 + * ``--header-file2 | --hf2`` Specifies where to find one public header of the second shared diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst index d0720a0..a67e5fa 100644 --- a/doc/manuals/abidw.rst +++ b/doc/manuals/abidw.rst @@ -128,9 +128,18 @@ Options * ``--headers-dir | --hd`` - Specifies where to find the public headers of the first shared - library that the tool has to consider. The tool will thus filter - out types that are not defined in public headers. + Specifies where to find the public headers of the binary that the + tool has to consider. The tool will thus filter out types that + are not defined in public headers. + + Note that several public header directories can be specified for + the binary to consider. In that case the ``--header-dir`` option + should be present several times on the command line, like in the + following example: :: + + $ abidw --header-dir /some/path \ + --header-dir /some/other/path \ + binary > binary.abi * ``--header-file | --hf`` diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h index c47e3f4..12651fc 100644 --- a/include/abg-tools-utils.h +++ b/include/abg-tools-utils.h @@ -91,6 +91,10 @@ suppr::type_suppression_sptr gen_suppr_spec_from_headers(const string& hdrs_root_dir, const vector& hdr_files); +suppr::type_suppression_sptr +gen_suppr_spec_from_headers(const vector& headers_root_dirs, + const vector& header_files); + suppr::suppressions_type gen_suppr_spec_from_kernel_abi_whitelists (const vector& abi_whitelist_paths); diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc index f1dc736..bc3d587 100644 --- a/src/abg-tools-utils.cc +++ b/src/abg-tools-utils.cc @@ -1842,12 +1842,44 @@ handle_fts_entry(const FTSENT *entry, } } +/// Populate a type_supression from header files found in a given +/// directory tree. +/// +/// The suppression suppresses types defined in source files that are +/// *NOT* found in the directory tree. +/// +/// This is a subroutine for gen_suppr_spect_from_headers. +/// +/// @param headers_root_dir the directory tree to consider for header +/// files. +/// +/// @param result the type_supression to populate from the content of +/// @p headers_root_dir. +static void +gen_suppr_spec_from_headers_root_dir(const string& headers_root_dir, + type_suppression_sptr &result) +{ + if (!headers_root_dir.empty()) + { + char* paths[] = {const_cast(headers_root_dir.c_str()), 0}; + + if (FTS *file_hierarchy = fts_open(paths, FTS_LOGICAL|FTS_NOCHDIR, NULL)) + { + FTSENT *entry; + while ((entry = fts_read(file_hierarchy))) + handle_fts_entry(entry, result); + fts_close(file_hierarchy); + } + } +} + /// Generate a type suppression specification that suppresses ABI /// changes for types defined in source files that are neither in a -/// given header root dir, not in a set of header files. +/// given set of header root directories nor in a set of header +/// files. /// -/// @param headers_root_dir ABI changes in types defined in files -/// *NOT* found in this directory tree are going be suppressed. +/// @param headers_root_dirs ABI changes in types defined in files +/// *NOT* found in these directory trees are going be suppressed. /// /// @param header_files a set of additional header files that define /// types that are to be kept (not supressed) by the returned type @@ -1856,29 +1888,15 @@ handle_fts_entry(const FTSENT *entry, /// @return the resulting type suppression generated, if any file was /// found in the directory tree @p headers_root_dir. type_suppression_sptr -gen_suppr_spec_from_headers(const string& headers_root_dir, +gen_suppr_spec_from_headers(const vector& headers_root_dirs, const vector& header_files) { type_suppression_sptr result; - if (headers_root_dir.empty() && header_files.empty()) - // We were given no headers root dir and no header files - // so the resulting suppression specification shall be empty. - return result; - - if (!headers_root_dir.empty()) - { - char* paths[] = {const_cast(headers_root_dir.c_str()), 0}; - - FTS *file_hierarchy = fts_open(paths, FTS_LOGICAL|FTS_NOCHDIR, NULL); - if (!file_hierarchy) - return result; - - FTSENT *entry; - while ((entry = fts_read(file_hierarchy))) - handle_fts_entry(entry, result); - fts_close(file_hierarchy); - } + for (vector::const_iterator root_dir = headers_root_dirs.begin(); + root_dir != headers_root_dirs.end(); + ++root_dir) + gen_suppr_spec_from_headers_root_dir(*root_dir, result); for (vector::const_iterator file = header_files.begin(); file != header_files.end(); @@ -1889,6 +1907,32 @@ gen_suppr_spec_from_headers(const string& headers_root_dir, } /// Generate a type suppression specification that suppresses ABI +/// changes for types defined in source files that are neither in a +/// given header root dir, not in a set of header files. +/// +/// @param headers_root_dir ABI changes in types defined in files +/// *NOT* found in this directory tree are going be suppressed. +/// +/// @param header_files a set of additional header files that define +/// types that are to be kept (not supressed) by the returned type +/// suppression. +/// +/// @return the resulting type suppression generated, if any file was +/// found in the directory tree @p headers_root_dir. +type_suppression_sptr +gen_suppr_spec_from_headers(const string& headers_root_dir, + const vector& header_files) +{ + type_suppression_sptr result; + vector root_dirs; + + if (!headers_root_dir.empty()) + root_dirs.push_back(headers_root_dir); + + return gen_suppr_spec_from_headers(root_dirs, header_files); +} + +/// Generate a type suppression specification that suppresses ABI /// changes for types defined in source files that are not in a given /// header root dir. /// diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 7334db2..8712b0c 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -174,6 +174,16 @@ test-abidiff-exit/test-net-change-report0.txt \ test-abidiff-exit/test-net-change-report1.txt \ test-abidiff-exit/test-net-change-report2.txt \ test-abidiff-exit/test-net-change-report3.txt \ +test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h \ +test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h \ +test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h \ +test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h \ +test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt \ +test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt \ +test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c \ +test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o \ +test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c \ +test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o \ \ test-diff-dwarf/test0-v0.cc \ test-diff-dwarf/test0-v0.o \ diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h b/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h new file mode 100644 index 0000000..49f956f --- /dev/null +++ b/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h @@ -0,0 +1,26 @@ +typedef struct opaque_struct * opaque_struct_pointer_type; + +typedef struct public_struct_type *public_struct_pointer_type; +typedef struct public_struct_type2 *public_struct_pointer_type2; + +typedef void (*FuncPointerType0) (public_struct_pointer_type, + public_struct_pointer_type); + +typedef void (*FuncPointerType1) (public_struct_pointer_type, int); + +typedef struct public_struct_type2 +{ + FuncPointerType0 m0; + FuncPointerType1 m1; +} public_struct_type2; + +typedef struct public_struct_type +{ + opaque_struct_pointer_type m0; + public_struct_type2 *m1; +} public_struct_type; + +void foo(public_struct_pointer_type p1); + +void bar(second_public_struct_pointer_type p1, + second_opaque_struct_pointer_type p2); diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h b/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h new file mode 100644 index 0000000..49f956f --- /dev/null +++ b/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h @@ -0,0 +1,26 @@ +typedef struct opaque_struct * opaque_struct_pointer_type; + +typedef struct public_struct_type *public_struct_pointer_type; +typedef struct public_struct_type2 *public_struct_pointer_type2; + +typedef void (*FuncPointerType0) (public_struct_pointer_type, + public_struct_pointer_type); + +typedef void (*FuncPointerType1) (public_struct_pointer_type, int); + +typedef struct public_struct_type2 +{ + FuncPointerType0 m0; + FuncPointerType1 m1; +} public_struct_type2; + +typedef struct public_struct_type +{ + opaque_struct_pointer_type m0; + public_struct_type2 *m1; +} public_struct_type; + +void foo(public_struct_pointer_type p1); + +void bar(second_public_struct_pointer_type p1, + second_opaque_struct_pointer_type p2); diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h b/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h new file mode 100644 index 0000000..1fe1b37 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h @@ -0,0 +1,8 @@ +typedef struct second_opaque_struct *second_opaque_struct_pointer_type; + +typedef struct second_public_struct * second_public_struct_pointer_type; + +struct second_public_struct +{ + int m1; +}; diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h b/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h new file mode 100644 index 0000000..cd7802d --- /dev/null +++ b/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h @@ -0,0 +1,9 @@ +typedef struct second_opaque_struct *second_opaque_struct_pointer_type; + +typedef struct second_public_struct * second_public_struct_pointer_type; + +struct second_public_struct +{ + int m1; + char m2; +}; diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt new file mode 100644 index 0000000..41fc64d --- /dev/null +++ b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt @@ -0,0 +1,3 @@ +Functions changes summary: 0 Removed, 0 Changed (2 filtered out), 0 Added functions +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt new file mode 100644 index 0000000..75d5a61 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt @@ -0,0 +1,13 @@ +Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + +1 function with some indirect sub-type change: + + [C] 'function void bar(second_public_struct_pointer_type, second_opaque_struct_pointer_type)' at test-headers-dir-v1.c:33:1 has some indirect sub-type changes: + parameter 1 of type 'typedef second_public_struct_pointer_type' has sub-type changes: + underlying type 'second_public_struct*' changed: + in pointed to type 'struct second_public_struct' at header-b-v1.h:5:1: + type size changed from 32 to 64 (in bits) + 1 data member insertion: + 'char second_public_struct::m2', at offset 32 (in bits) at header-b-v1.h:8:1 + diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c new file mode 100644 index 0000000..0784f53 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c @@ -0,0 +1,33 @@ +/* + * Compile this test with: + * gcc -c -g test-headers-dir-v0.c + * + * This test exhibits changes that are redundant in a weird way. + * The redundant path through the diff graph involves typedefs, + * function types and function parameter diff nodes. + * + */ +#include "headers-b/header-b-v0.h" +#include "headers-a/header-a-v0.h" + +struct opaque_struct +{ + int m0; + int m1; + struct public_struct_type *m2; +}; + +struct second_opaque_struct +{ + int m0; +}; + +void foo(public_struct_pointer_type p __attribute__((unused))) +{ +} + +void +bar(second_public_struct_pointer_type p1 __attribute__((unused)), + second_opaque_struct_pointer_type p2 __attribute__((unused))) +{ +} diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o new file mode 100644 index 0000000000000000000000000000000000000000..477198bc15a428381a62586991281d6a87c269dc GIT binary patch literal 3840 zcmbtWU1%It6ux(FHko9a&8A6fLu$K%ng%+vo1_h~nsjYwo1&CZtcnn~GrN=B(fxCF zHl+R)R4RQD3qo5cSkPC&N5L1N=tCdG2hmqweAgGz`k?3Bxo10jGohdt_TF>8^PQi2 z=gyhEa{Bo*Db5)U&Q{n1jZnslBQaTuMK;0qvWsiieqFov&Yv51Nm{$s{cYp!JqR)& zd4>$PBj$kz@mLDw6kmc_7%MPK&jCL9BFO1Rf${xUKmv}OgaeB(sxU{yR2t3c#vDrx zMa02@wBHOPzTnp-{|521eDqt%hrnZ!kFGq6;y}7F&-nNcAR5YDpdyT)&nr_dP(JuH6v78pm`V8Xzu>osP&PQdsfNrNe)1b%y@4QFr& zPaJ3?Z8(L)mQ*e=I1v6sX2KMi>C8CaJCuC{Nc)+{oG_m@&rLuPW6YGozyuc=(?pyD zo*sqzBGQt{*x=(pTQP+JJKD!*rjTN!8Acek`N^q>J2QnjiU)3-l7x|TFGdP3jhRS< zLXTpx@WY1?AMuM8$KM4d#ax&<|2s1ZvwRKUym-xXDqhgBTt^i}Z>gSX%|V zi~%FeauKNE%cB4%0%T3YQDwjuQ~dpfuTv?=m#?)NUcS<*yyoYteweTOuH*Vu$FJub z-Fh!s9y53H6(@A0XaT9>Z*E%NHaO{Jb=cYS7jvt*WA>7LJU3sMJ6>3vU&tM~;8k*K zP8i|V!c((3s}Xja-g4DzdVyaC)d|YAwZ~j zrSNjwOMvEC$1As*l~SK?sojE?(F-E4BnCUvZI;&~)(a52paXLhxUUSYg1$8RxkQia z;dS*T=&zieU0pqqI|AoB`|#t%n*n1oS{Q%x0^{3RKD}qi_!#cULBR2cL%yxgX0lgP ztD}RbfdClVo_7wb0*wx=He4LTQmweXapL7j3MRK!W|MNGa&*lw|r z_I8YZ@!eBq#BrA|!4JoHw8%V&Z>UoCX}D4uwREJ#pVDlMAMbZ|49ECCD*dE}|DklM zi|YJH)l<{>_?g1-VYKw>?)hJT~V7A-oFgx(-j$QHGZnfk$H(Ownvg5jex7BBM0;gH^`d#XN(<2v1!R&IY z(eU8klih5Eo(=8J>V!`Dbrr~~l{N#X;ig67zU(o$$z>M$DfAyaOUp*#fr2OA&MopFfTJT?G5uIYAs9NSP$^q{i^5|Wsb6EyV zkBMQPRF~{?RANKtu7gd-kbY137h=9B>fGl5OR7JI%?AegWBs@#z5WVddQ5=WeU<+` zRANKtmcW*je_iFLbHe-x>G|7$VN9wML^4wS?z~-$e4KbH#n=xiR)vDt}FF o6u*1;_166{jsETd#B%EXA4VlM=-ddxxJmvuRsEk4QLVcFzx`ZyR{#J2 literal 0 HcmV?d00001 diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c new file mode 100644 index 0000000..a600757 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c @@ -0,0 +1,36 @@ +/* + * Compile this test with: + * gcc -c -g test-headers-dir-v1.c + * + * This test exhibits changes that are redundant in a weird way. + * The redundant path through the diff graph involves typedefs, + * function types and function parameter diff nodes. + * + */ + +#include "headers-b/header-b-v1.h" +#include "headers-a/header-a-v1.h" + +struct opaque_struct +{ + int m0; + int m1; + struct public_struct_type *m2; + char m3; +}; + +struct second_opaque_struct +{ + int m0; + char m1; +}; + +void foo(public_struct_pointer_type p __attribute__((unused))) +{ +} + +void +bar(second_public_struct_pointer_type p1 __attribute__((unused)), + second_opaque_struct_pointer_type p2 __attribute__((unused))) +{ +} diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o new file mode 100644 index 0000000000000000000000000000000000000000..a7978e2e78677acdde0a47d75735ce8359661483 GIT binary patch literal 3920 zcmbtW-D@0G6hC)wHkovi?Ivk!LJMw+(iWWAe6%H2+eTyC6s4A8F)wAE*_~up_siMY zk}4{wRQe*VAE;1NsIS@=3xY3|zW4|DF9^OU)rS%gKhC*x?q>F8s-PG4-gAEEcRudt z>>DSZIhhdxbQ5q4HZ_d`T-~-QFDh{nCSV-SFJJj_`O0e>7w%|j`AYZhg*(4tkO9TB zRJbiMCpY6khUAP`z+PI%uveaz*yW*|ZOnj}{17D+XF*I|SA^I{)=`mGs37dDOqQ5L z%nY&59AvE6XK)}}Yeq0629XnImEtQDrS&!TD(j@k{fx58n%~SiM&dxWF$ZFN14S#_ zm=tPdzE49$MIO~=va*R1X0adzh40ti1Y8s9!L$=%_-kSe5lfit&YO4_x zE3L|lwc=VWD%NYh=hxP}TD{ol)_ci{l(|!^c#)?>2T7IM>Z%j0qmx-y2Tq+iUsx&} zbQj!1g}Is8LoqdoOo`QYQ+#|4>)Cig$#|=!@51KAc)wI#Sq=i+teU*O-n6wjJ>R z;+1nC*7IWb$dGjv4+>pfeSOvKeIl2?oLL$jJb?tZJDRxu z7!Z)DUj)K?N3_pPq9v`#_|e;9lAzw>6ntn4Mu3Fj`{4L?q%;YmDJaF!uUfxZ!bm@W z8op%swWC#vn|?WWqe{5edlA#mEIq&Uu=Zw5e#zPE%!Jb{pT{4yv3O8<2*1brP6KBZ zrdXhgle=^v!B0MVZUU$HKd^q>z(;rqd;@=<@s5EnG5(o>zsvX+2Hs)(mVs;kUkrSO z`TF4Mb^DTed)cn>+l-$uaQZ}2TQ%@G*55Jk+lmeFDdRLG*ZF$`r~K6PUXz|xNZjRF zHsiGJgBKX5oXNb42Cnmh+qu+;JRip>jK`{$qF_A&mp&HY`kfBAVNmznO5k_bO10){ z3vEjFd_N2>_L;rVYpwAw%nbg%xa|1A2NF)5?Yf6p)) zs`^Vq|2`MVDbd#XDcxWPI&Z|&Z-8ExqllR?Da;u@WH(7kG?RN4Z6-$aKiGdJ;Y*^) zeHyW}`rGs2 zYBxFmEhC{;_4q2X)BG#^Sm<|}!}jK?{oiJPZP(*_$;U>6DcnyOwh0TY6SUH||9 literal 0 HcmV?d00001 diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc index 936d1d6..6ebe2a0 100644 --- a/tests/test-abidiff-exit.cc +++ b/tests/test-abidiff-exit.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,8 @@ struct InOutSpec const char* in_elfv0_path; const char* in_elfv1_path; const char* in_suppr_path; + const char* in_elfv0_headers_dirs; + const char* in_elfv1_headers_dirs; const char* abidiff_options; abidiff_status status; const char* in_report_path; @@ -59,6 +62,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test1-voffset-change-v0.o", "data/test-abidiff-exit/test1-voffset-change-v1.o", "", + "", + "", "--no-default-suppression --no-show-locs", abigail::tools_utils::ABIDIFF_ABI_CHANGE | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, @@ -69,6 +74,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test1-voffset-change-v0.o", "data/test-abidiff-exit/test1-voffset-change-v1.o", "data/test-abidiff-exit/test1-voffset-change.abignore", + "", + "", "--no-default-suppression --no-show-locs", abigail::tools_utils::ABIDIFF_OK, "data/test-abidiff-exit/test1-voffset-change-report1.txt", @@ -78,6 +85,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test2-filtered-removed-fns-v0.o", "data/test-abidiff-exit/test2-filtered-removed-fns-v1.o", "", + "", + "", "--no-default-suppression --no-show-locs", abigail::tools_utils::ABIDIFF_ABI_CHANGE | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, @@ -88,6 +97,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test2-filtered-removed-fns-v0.o", "data/test-abidiff-exit/test2-filtered-removed-fns-v1.o", "data/test-abidiff-exit/test2-filtered-removed-fns.abignore", + "", + "", "--no-default-suppression --no-show-locs", abigail::tools_utils::ABIDIFF_OK, "data/test-abidiff-exit/test2-filtered-removed-fns-report1.txt", @@ -98,6 +109,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-loc-v1.bi", "", "", + "", + "", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-loc-with-locs-report.txt", "output/test-abidiff-exit/test-loc-with-locs-report.txt" @@ -106,6 +119,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-loc-v0.bi", "data/test-abidiff-exit/test-loc-v1.bi", "", + "", + "", "--no-show-locs", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-loc-without-locs-report.txt", @@ -115,6 +130,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-no-stray-comma-v0.o", "data/test-abidiff-exit/test-no-stray-comma-v1.o", "", + "", + "", "--leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-no-stray-comma-report.txt", @@ -124,6 +141,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-leaf-stats-v0.o", "data/test-abidiff-exit/test-leaf-stats-v1.o", "", + "", + "", "--no-show-locs --leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-leaf-stats-report.txt", @@ -133,6 +152,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-leaf-more-v0.o", "data/test-abidiff-exit/test-leaf-more-v1.o", "", + "", + "", "--no-show-locs --leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, @@ -143,6 +164,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-leaf-fun-type-v0.o", "data/test-abidiff-exit/test-leaf-fun-type-v1.o", "", + "", + "", "--no-show-locs --leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-leaf-fun-type-report.txt", @@ -152,6 +175,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-leaf-redundant-v0.o", "data/test-abidiff-exit/test-leaf-redundant-v1.o", "", + "", + "", "--leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-leaf-redundant-report.txt", @@ -161,6 +186,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-leaf-peeling-v0.o", "data/test-abidiff-exit/test-leaf-peeling-v1.o", "", + "", + "", "--leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-leaf-peeling-report.txt", @@ -170,6 +197,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-leaf-cxx-members-v0.o", "data/test-abidiff-exit/test-leaf-cxx-members-v1.o", "", + "", + "", "--leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, @@ -181,6 +210,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-member-size-v1.o", "", "", + "", + "", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-member-size-report0.txt", "output/test-abidiff-exit/test-member-size-report0.txt" @@ -189,6 +220,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-member-size-v0.o", "data/test-abidiff-exit/test-member-size-v1.o", "", + "", + "", "--leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-member-size-report1.txt", @@ -198,6 +231,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-decl-struct-v0.o", "data/test-abidiff-exit/test-decl-struct-v1.o", "", + "", + "", "--harmless", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-decl-struct-report.txt", @@ -208,6 +243,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-fun-param-v1.abi", "", "", + "", + "", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-fun-param-report.txt", "output/test-abidiff-exit/test-fun-param-report.txt" @@ -216,6 +253,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-decl-enum-v0.o", "data/test-abidiff-exit/test-decl-enum-v1.o", "", + "", + "", "--harmless", abigail::tools_utils::ABIDIFF_ABI_CHANGE, "data/test-abidiff-exit/test-decl-enum-report.txt", @@ -226,6 +265,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-decl-enum-v1.o", "", "", + "", + "", abigail::tools_utils::ABIDIFF_OK, "data/test-abidiff-exit/test-decl-enum-report-2.txt", "output/test-abidiff-exit/test-decl-enum-report-2.txt" @@ -234,6 +275,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-decl-enum-v0.o", "data/test-abidiff-exit/test-decl-enum-v1.o", "", + "", + "", "--leaf-changes-only", abigail::tools_utils::ABIDIFF_OK, "data/test-abidiff-exit/test-decl-enum-report-3.txt", @@ -243,6 +286,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-net-change-v0.o", "data/test-abidiff-exit/test-net-change-v1.o", "", + "", + "", "--no-default-suppression --no-show-locs", abigail::tools_utils::ABIDIFF_ABI_CHANGE | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, @@ -253,6 +298,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-net-change-v0.o", "data/test-abidiff-exit/test-net-change-v1.o", "data/test-abidiff-exit/test-net-change.abignore", + "", + "", "--no-default-suppression --no-show-locs", abigail::tools_utils::ABIDIFF_OK, "data/test-abidiff-exit/test-net-change-report1.txt", @@ -262,6 +309,8 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-net-change-v0.o", "data/test-abidiff-exit/test-net-change-v1.o", "", + "", + "", "--no-default-suppression --no-show-locs --leaf-changes-only", abigail::tools_utils::ABIDIFF_ABI_CHANGE | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, @@ -272,44 +321,90 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-net-change-v0.o", "data/test-abidiff-exit/test-net-change-v1.o", "data/test-abidiff-exit/test-net-change.abignore", + "", + "", "--no-default-suppression --no-show-locs --leaf-changes-only", abigail::tools_utils::ABIDIFF_OK, "data/test-abidiff-exit/test-net-change-report3.txt", "output/test-abidiff-exit/test-net-change-report3.txt" }, - {0, 0, 0 ,0, abigail::tools_utils::ABIDIFF_OK, 0, 0} + { + "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o", + "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o", + "", + "data/test-abidiff-exit/test-headers-dirs/headers-a", + "data/test-abidiff-exit/test-headers-dirs/headers-a", + "--no-default-suppression", + abigail::tools_utils::ABIDIFF_OK, + "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt", + "output/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt" + }, + { + "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o", + "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o", + "", + "data/test-abidiff-exit/test-headers-dirs/headers-a, " + "data/test-abidiff-exit/test-headers-dirs/headers-b", + "data/test-abidiff-exit/test-headers-dirs/headers-a, " + "data/test-abidiff-exit/test-headers-dirs/headers-b", + "--no-default-suppression", + abigail::tools_utils::ABIDIFF_ABI_CHANGE, + "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt", + "output/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt" + }, + {0, 0, 0 ,0, 0, 0, abigail::tools_utils::ABIDIFF_OK, 0, 0} }; +/// Prefix the strings in a vector of string. +/// +/// @param strings the strings to prefix. +/// +/// @param prefix the prefix to use. +static void +do_prefix_strings(std::vector &strings, + const std::string& prefix) +{ + for (std::vector::size_type i = 0; i < strings.size(); ++i) + strings[i] = prefix + strings[i]; +} + int main() { using std::string; + using std::vector; using std::cerr; using abigail::tests::get_src_dir; using abigail::tests::get_build_dir; using abigail::tools_utils::ensure_parent_dir_created; + using abigail::tools_utils::split_string; using abigail::tools_utils::abidiff_status; bool is_ok = true; string in_elfv0_path, in_elfv1_path, in_suppression_path, abidiff_options, abidiff, cmd, ref_diff_report_path, out_diff_report_path; + vector in_elfv0_headers_dirs, in_elfv1_headers_dirs; + string source_dir_prefix = string(get_src_dir()) + "/tests/"; + string build_dir_prefix = string(get_build_dir()) + "/tests/"; for (InOutSpec* s = in_out_specs; s->in_elfv0_path; ++s) { - in_elfv0_path = string(get_src_dir()) + "/tests/" + s->in_elfv0_path; - in_elfv1_path = string(get_src_dir()) + "/tests/" + s->in_elfv1_path; + in_elfv0_path = source_dir_prefix + s->in_elfv0_path; + in_elfv1_path = source_dir_prefix + s->in_elfv1_path; + split_string(s->in_elfv0_headers_dirs, ",", in_elfv0_headers_dirs); + split_string(s->in_elfv1_headers_dirs, ",", in_elfv1_headers_dirs); + do_prefix_strings(in_elfv0_headers_dirs, source_dir_prefix); + do_prefix_strings(in_elfv1_headers_dirs, source_dir_prefix); + if (s->in_suppr_path && strcmp(s->in_suppr_path, "")) - in_suppression_path = - string(get_src_dir()) + "/tests/" + s->in_suppr_path; + in_suppression_path = source_dir_prefix + s->in_suppr_path; else in_suppression_path.clear(); abidiff_options = s->abidiff_options; - ref_diff_report_path = - string(get_src_dir()) + "/tests/" + s->in_report_path; - out_diff_report_path = - string(get_build_dir()) + "/tests/" + s->out_report_path; + ref_diff_report_path = source_dir_prefix + s->in_report_path; + out_diff_report_path = build_dir_prefix + s->out_report_path; if (!ensure_parent_dir_created(out_diff_report_path)) { @@ -323,6 +418,18 @@ main() if (!abidiff_options.empty()) abidiff += " " + abidiff_options; + if (!in_elfv0_headers_dirs.empty()) + for (vector::const_iterator s = in_elfv0_headers_dirs.begin(); + s != in_elfv0_headers_dirs.end(); + ++s) + abidiff += " --headers-dir1 " + *s; + + if (!in_elfv1_headers_dirs.empty()) + for (vector::const_iterator s = in_elfv1_headers_dirs.begin(); + s != in_elfv1_headers_dirs.end(); + ++s) + abidiff += " --headers-dir2 " + *s; + if (!in_suppression_path.empty()) abidiff += " --suppressions " + in_suppression_path; diff --git a/tools/abidiff.cc b/tools/abidiff.cc index 162d5eb..6ac81ee 100644 --- a/tools/abidiff.cc +++ b/tools/abidiff.cc @@ -78,9 +78,9 @@ struct options vector drop_var_regex_patterns; vector keep_fn_regex_patterns; vector keep_var_regex_patterns; - string headers_dir1; + vector headers_dirs1; vector header_files1; - string headers_dir2; + vector headers_dirs2; vector header_files2; bool drop_private_types; bool linux_kernel_mode; @@ -318,7 +318,9 @@ parse_command_line(int argc, char* argv[], options& opts) opts.wrong_option = argv[i]; return true; } - opts.headers_dir1 = argv[j]; + // The user can specify several header files directories for + // the first binary. + opts.headers_dirs1.push_back(argv[j]); ++i; } else if (!strcmp(argv[i], "--header-file1") @@ -344,7 +346,9 @@ parse_command_line(int argc, char* argv[], options& opts) opts.wrong_option = argv[i]; return true; } - opts.headers_dir2 = argv[j]; + // The user can specify several header files directories for + // the first binary. + opts.headers_dirs2.push_back(argv[j]); ++i; } else if (!strcmp(argv[i], "--header-file2") @@ -720,22 +724,22 @@ set_diff_context_from_opts(diff_context_sptr ctxt, load_default_user_suppressions(supprs); } - if (!opts.headers_dir1.empty() || !opts.header_files1.empty()) + if (!opts.headers_dirs1.empty() || !opts.header_files1.empty()) { // Generate suppression specification to avoid showing ABI // changes on types that are not defined in public headers. suppression_sptr suppr = - gen_suppr_spec_from_headers(opts.headers_dir1, opts.header_files1); + gen_suppr_spec_from_headers(opts.headers_dirs1, opts.header_files1); if (suppr) ctxt->add_suppression(suppr); } - if (!opts.headers_dir2.empty() || !opts.header_files2.empty()) + if (!opts.headers_dirs2.empty() || !opts.header_files2.empty()) { // Generate suppression specification to avoid showing ABI // changes on types that are not defined in public headers. suppression_sptr suppr = - gen_suppr_spec_from_headers(opts.headers_dir2, opts.header_files2); + gen_suppr_spec_from_headers(opts.headers_dirs2, opts.header_files2); if (suppr) ctxt->add_suppression(suppr); } @@ -770,7 +774,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts) read_suppressions(*i, supprs); if (read_context_get_path(read_ctxt) == opts.file1 - && (!opts.headers_dir1.empty() || !opts.header_files1.empty())) + && (!opts.headers_dirs1.empty() || !opts.header_files1.empty())) { // Generate suppression specification to avoid showing ABI // changes on types that are not defined in public headers for @@ -780,7 +784,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts) // corpus loading, they are going to be dropped from the // internal representation altogether. suppression_sptr suppr = - gen_suppr_spec_from_headers(opts.headers_dir1, opts.header_files1); + gen_suppr_spec_from_headers(opts.headers_dirs1, opts.header_files1); if (suppr) { if (opts.drop_private_types) @@ -790,7 +794,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts) } if (read_context_get_path(read_ctxt) == opts.file2 - && (!opts.headers_dir2.empty() || !opts.header_files2.empty())) + && (!opts.headers_dirs2.empty() || !opts.header_files2.empty())) { // Generate suppression specification to avoid showing ABI // changes on types that are not defined in public headers for @@ -800,7 +804,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts) // corpus loading, they are going to be dropped from the // internal representation altogether. suppression_sptr suppr = - gen_suppr_spec_from_headers(opts.headers_dir2, opts.header_files2); + gen_suppr_spec_from_headers(opts.headers_dirs2, opts.header_files2); if (suppr) { if (opts.drop_private_types) diff --git a/tools/abidw.cc b/tools/abidw.cc index 27a9e48..756a29e 100644 --- a/tools/abidw.cc +++ b/tools/abidw.cc @@ -90,7 +90,7 @@ struct options string out_file_path; vector di_root_paths; vector prepared_di_root_paths; - string headers_dir; + vector headers_dirs; vector header_files; string vmlinux; vector suppression_paths; @@ -239,7 +239,7 @@ parse_command_line(int argc, char* argv[], options& opts) int j = i + 1; if (j >= argc) return false; - opts.headers_dir = argv[j]; + opts.headers_dirs.push_back(argv[j]); ++i; } else if (!strcmp(argv[i], "--header-file") @@ -445,7 +445,7 @@ set_suppressions(read_context& read_ctxt, options& opts) read_suppressions(*i, supprs); suppression_sptr suppr = - abigail::tools_utils::gen_suppr_spec_from_headers(opts.headers_dir, + abigail::tools_utils::gen_suppr_spec_from_headers(opts.headers_dirs, opts.header_files); if (suppr) {