diff --git a/doc/manuals/abidiff.rst b/doc/manuals/abidiff.rst
index 0c965c41..9773e1dd 100644
--- a/doc/manuals/abidiff.rst
+++ b/doc/manuals/abidiff.rst
@@ -177,6 +177,72 @@ 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.
 
+  * ``--add-binaries1`` <*bin1,bin2,bin3,..*>
+
+    For each of the comma-separated binaries given in argument to this
+    option, if the binary is found in the directory specified by the
+    ``--added-binaries-dir1`` option, then ``abidiff`` loads the ABI
+    corpus of the binary and adds it to a set of corpora (called an
+    ABI Corpus Group) that includes the first argument of ``abidiff``.
+
+    That ABI corpus group is then compared against the second corpus
+    group given in argument to ``abidiff``.
+
+  * ``--add-binaries2`` <*bin1,bin2,bin3,..*>
+
+    For each of the comma-separated binaries given in argument to this
+    option, if the binary is found in the directory specified by the
+    ``--added-binaries-dir2`` option, then ``abidiff`` loads the ABI
+    corpus of the binary and adds it to a set of corpora(called an ABI
+    Corpus Group) that includes the second argument of ``abidiff``.
+
+    That ABI corpus group is then compared against the first corpus
+    group given in argument to ``abidiff``.
+
+  * ``--follow-dependencies | --fdeps``
+
+    For each dependency of the first argument of ``abidiff``, if it's
+    found in the directory specified by the ``--added-binaries-dir1``
+    option, then construct an ABI corpus out of the dependency, add it
+    to a set of corpora (called an ABI Corpus Group) that includes the
+    first argument of ``abidiff``.
+
+    Similarly, for each dependency of the second argument of
+    ``abidiff``, if it's found in the directory specified by the
+    ``--added-binaries-dir2`` option, then construct an ABI corpus out
+    of the dependency, add it to an ABI corpus group that includes the
+    second argument of ``abidiff``.
+
+    These two ABI corpus groups are then compared against each other.
+
+    Said otherwise, this makes ``abidiff`` compare the set of its
+    first input and its dependencies against the set of its second
+    input and its dependencies.
+
+  * ``list-dependencies | --ldeps``
+
+    This option lists all the dependencies of the input arguments of
+    ``abidiff`` that are found in the directories specified by the
+    options ``--added-binaries-dir1`` and ``--added-binaries-dir2``
+
+  * ``--added-binaries-dir1 | --abd1`` <added-binaries-directory-1>
+
+    This option is to be used in conjunction with the
+    ``--add-binaries1``, ``--follow-dependencies`` and
+    ``--list-dependencies`` options.  Binaries referred to by these
+    options, if found in the directory `added-binaries-directory-1`,
+    are loaded as ABI corpus and are added to the first ABI corpus group
+    that is to be used in the comparison.
+
+  * ``--added-binaries-dir2 | --abd2`` <added-binaries-directory-2>
+
+    This option is to be used in conjunction with the
+    ``--add-binaries2``, ``--follow-dependencies`` and
+    ``--list-dependencies`` options.  Binaries referred to by these
+    options, if found in the directory `added-binaries-directory-2`,
+    are loaded as ABI corpus and are added to the second ABI corpus
+    group to be used in the comparison.
+
   * ``--no-linux-kernel-mode``
 
     Without this option, if abidiff detects that the binaries it is
@@ -845,6 +911,30 @@ Usage examples
 
 	$
 
+  4. Comparing two sets of binaries that are passed on the command line: ::
+
+           $ abidiff --add-binaries1=file2-v1              \
+                     --add-binaries2=file2-v2,file2-v1     \
+	             --added-binaries-dir1 dir1 	   \
+	             --added-binaries-dir2 dir2	           \
+	             file1-v1 file1-v2
+
+     Note that the files ``file2-v1``, and ``file2-v2`` are to be
+     found in ``dir1`` and ``dir2`` or in the current directory.
+
+
+  5. Compare two libraries and their dependencies: ::
+
+           $ abidiff --follow-dependencies			\
+	             --added-binaries-dir1 /some/where		\
+	             --added-binaries-dir2 /some/where/else	\
+	             foo bar
+
+     This compares the set of binaries comprised by ``foo`` and its
+     dependencies against the set of binaries comprised by ``bar`` and
+     its dependencies.
+
+
 .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
 .. _DWARF: http://www.dwarfstd.org
 .. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index e754e6dc..03361fab 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -326,6 +326,31 @@ test-abidiff-exit/PR30503/libsdl/1.2.60/lib64/libSDL-1.2.so.1.2.60.debug \
 test-abidiff-exit/PR30503/libsdl/1.2.64/lib64/libSDL-1.2.so.1.2.64 \
 test-abidiff-exit/PR30503/libsdl/1.2.64/lib64/libSDL-1.2.so.1.2.64.debug \
 test-abidiff-exit/PR30503/libsdl/libsdl-1.2.60-1.2.64-report.txt \
+test-abidiff-exit/test-PR30034/libabigail.abignore \
+test-abidiff-exit/test-PR30034/reference/include/rte_log.h \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23 \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23.1 \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23 \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23.1 \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23 \
+test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23.1 \
+test-abidiff-exit/test-PR30034/split/include/rte_log.h \
+test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so \
+test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23 \
+test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23.2 \
+test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so \
+test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23 \
+test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23.2 \
+test-abidiff-exit/test-PR30034/split/lib64/librte_log.so \
+test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23 \
+test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23.2 \
+test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so \
+test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23 \
+test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23.2 \
+test-abidiff-exit/test-PR30034/test-PR30034-report-1.txt \
 \
 test-diff-dwarf/test0-v0.cc		\
 test-diff-dwarf/test0-v0.o			\
diff --git a/tests/data/test-abidiff-exit/test-PR30034/libabigail.abignore b/tests/data/test-abidiff-exit/test-PR30034/libabigail.abignore
new file mode 100644
index 00000000..03bfbce2
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/libabigail.abignore
@@ -0,0 +1,47 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Core suppression rules: DO NOT TOUCH ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[suppress_function]
+        symbol_version = EXPERIMENTAL
+[suppress_variable]
+        symbol_version = EXPERIMENTAL
+
+[suppress_function]
+        symbol_version = INTERNAL
+[suppress_variable]
+        symbol_version = INTERNAL
+
+; Ignore generated PMD information strings
+[suppress_variable]
+        name_regexp = _pmd_info$
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Special rules to skip libraries ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; This is not a libabigail rule (see check-abi.sh).
+; This is used for driver removal and other special cases like mlx glue libs.
+;
+; SKIP_LIBRARY=librte_common_mlx5_glue
+; SKIP_LIBRARY=librte_net_mlx4_glue
+; SKIP_LIBRARY=librte_net_liquidio
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Experimental APIs exceptions ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Ignore changes to asymmetric crypto API which is experimental
+[suppress_type]
+        name = rte_crypto_asym_op
+[suppress_type]
+        type_kind = enum
+        changed_enumerators = RTE_CRYPTO_ASYM_XFORM_ECPM, RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Temporary exceptions till next major ABI version ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Ignore changes to rte_security_ops which are internal to PMD.
+[suppress_type]
+        name = rte_security_ops
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/include/rte_log.h b/tests/data/test-abidiff-exit/test-PR30034/reference/include/rte_log.h
new file mode 100644
index 00000000..6d2b0856
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/reference/include/rte_log.h
@@ -0,0 +1,409 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#ifndef _RTE_LOG_H_
+#define _RTE_LOG_H_
+
+/**
+ * @file
+ *
+ * RTE Logs API
+ *
+ * This file provides a log API to RTE applications.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+
+#include <rte_common.h>
+#include <rte_config.h>
+
+/* SDK log type */
+#define RTE_LOGTYPE_EAL        0 /**< Log related to eal. */
+#define RTE_LOGTYPE_MALLOC     1 /**< Log related to malloc. */
+#define RTE_LOGTYPE_RING       2 /**< Log related to ring. */
+#define RTE_LOGTYPE_MEMPOOL    3 /**< Log related to mempool. */
+#define RTE_LOGTYPE_TIMER      4 /**< Log related to timers. */
+#define RTE_LOGTYPE_PMD        5 /**< Log related to poll mode driver. */
+#define RTE_LOGTYPE_HASH       6 /**< Log related to hash table. */
+#define RTE_LOGTYPE_LPM        7 /**< Log related to LPM. */
+#define RTE_LOGTYPE_KNI        8 /**< Log related to KNI. */
+#define RTE_LOGTYPE_ACL        9 /**< Log related to ACL. */
+#define RTE_LOGTYPE_POWER     10 /**< Log related to power. */
+#define RTE_LOGTYPE_METER     11 /**< Log related to QoS meter. */
+#define RTE_LOGTYPE_SCHED     12 /**< Log related to QoS port scheduler. */
+#define RTE_LOGTYPE_PORT      13 /**< Log related to port. */
+#define RTE_LOGTYPE_TABLE     14 /**< Log related to table. */
+#define RTE_LOGTYPE_PIPELINE  15 /**< Log related to pipeline. */
+#define RTE_LOGTYPE_MBUF      16 /**< Log related to mbuf. */
+#define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
+#define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
+#define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
+#define RTE_LOGTYPE_GSO       20 /**< Log related to GSO. */
+
+/* these log types can be used in an application */
+#define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
+#define RTE_LOGTYPE_USER2     25 /**< User-defined log type 2. */
+#define RTE_LOGTYPE_USER3     26 /**< User-defined log type 3. */
+#define RTE_LOGTYPE_USER4     27 /**< User-defined log type 4. */
+#define RTE_LOGTYPE_USER5     28 /**< User-defined log type 5. */
+#define RTE_LOGTYPE_USER6     29 /**< User-defined log type 6. */
+#define RTE_LOGTYPE_USER7     30 /**< User-defined log type 7. */
+#define RTE_LOGTYPE_USER8     31 /**< User-defined log type 8. */
+
+/** First identifier for extended logs */
+#define RTE_LOGTYPE_FIRST_EXT_ID 32
+
+/* Can't use 0, as it gives compiler warnings */
+#define RTE_LOG_EMERG    1U  /**< System is unusable.               */
+#define RTE_LOG_ALERT    2U  /**< Action must be taken immediately. */
+#define RTE_LOG_CRIT     3U  /**< Critical conditions.              */
+#define RTE_LOG_ERR      4U  /**< Error conditions.                 */
+#define RTE_LOG_WARNING  5U  /**< Warning conditions.               */
+#define RTE_LOG_NOTICE   6U  /**< Normal but significant condition. */
+#define RTE_LOG_INFO     7U  /**< Informational.                    */
+#define RTE_LOG_DEBUG    8U  /**< Debug-level messages.             */
+#define RTE_LOG_MAX RTE_LOG_DEBUG /**< Most detailed log level.     */
+
+/**
+ * Change the stream that will be used by the logging system.
+ *
+ * This can be done at any time. The f argument represents the stream
+ * to be used to send the logs. If f is NULL, the default output is
+ * used (stderr).
+ *
+ * @param f
+ *   Pointer to the stream.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_openlog_stream(FILE *f);
+
+/**
+ * Retrieve the stream used by the logging system (see rte_openlog_stream()
+ * to change it).
+ *
+ * @return
+ *   Pointer to the stream.
+ */
+FILE *rte_log_get_stream(void);
+
+/**
+ * Set the global log level.
+ *
+ * After this call, logs with a level lower or equal than the level
+ * passed as argument will be displayed.
+ *
+ * @param level
+ *   Log level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ */
+void rte_log_set_global_level(uint32_t level);
+
+/**
+ * Get the global log level.
+ *
+ * @return
+ *   The current global log level.
+ */
+uint32_t rte_log_get_global_level(void);
+
+/**
+ * Get the log level for a given type.
+ *
+ * @param logtype
+ *   The log type identifier.
+ * @return
+ *   0 on success, a negative value if logtype is invalid.
+ */
+int rte_log_get_level(uint32_t logtype);
+
+/**
+ * For a given `logtype`, check if a log with `loglevel` can be printed.
+ *
+ * @param logtype
+ *   The log type identifier
+ * @param loglevel
+ *   Log level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @return
+ * Returns 'true' if log can be printed and 'false' if it can't.
+ */
+bool rte_log_can_log(uint32_t logtype, uint32_t loglevel);
+
+/**
+ * Set the log level for a given type based on globbing pattern.
+ *
+ * @param pattern
+ *   The globbing pattern identifying the log type.
+ * @param level
+ *   The level to be set.
+ * @return
+ *   0 on success, a negative value if level is invalid.
+ */
+int rte_log_set_level_pattern(const char *pattern, uint32_t level);
+
+/**
+ * Set the log level for a given type based on regular expression.
+ *
+ * @param regex
+ *   The regular expression identifying the log type.
+ * @param level
+ *   The level to be set.
+ * @return
+ *   0 on success, a negative value if level is invalid.
+ */
+int rte_log_set_level_regexp(const char *regex, uint32_t level);
+
+/**
+ * Set the log level for a given type.
+ *
+ * @param logtype
+ *   The log type identifier.
+ * @param level
+ *   The level to be set.
+ * @return
+ *   0 on success, a negative value if logtype or level is invalid.
+ */
+int rte_log_set_level(uint32_t logtype, uint32_t level);
+
+/**
+ * Get the current loglevel for the message being processed.
+ *
+ * Before calling the user-defined stream for logging, the log
+ * subsystem sets a per-lcore variable containing the loglevel and the
+ * logtype of the message being processed. This information can be
+ * accessed by the user-defined log output function through this
+ * function.
+ *
+ * @return
+ *   The loglevel of the message being processed.
+ */
+int rte_log_cur_msg_loglevel(void);
+
+/**
+ * Get the current logtype for the message being processed.
+ *
+ * Before calling the user-defined stream for logging, the log
+ * subsystem sets a per-lcore variable containing the loglevel and the
+ * logtype of the message being processed. This information can be
+ * accessed by the user-defined log output function through this
+ * function.
+ *
+ * @return
+ *   The logtype of the message being processed.
+ */
+int rte_log_cur_msg_logtype(void);
+
+/**
+ * Register a dynamic log type
+ *
+ * If a log is already registered with the same type, the returned value
+ * is the same than the previous one.
+ *
+ * @param name
+ *   The string identifying the log type.
+ * @return
+ *   - >0: success, the returned value is the log type identifier.
+ *   - (-ENOMEM): cannot allocate memory.
+ */
+int rte_log_register(const char *name);
+
+/**
+ * Register a dynamic log type and try to pick its level from EAL options
+ *
+ * rte_log_register() is called inside. If successful, the function tries
+ * to search for matching regexp in the list of EAL log level options and
+ * pick the level from the last matching entry. If nothing can be applied
+ * from the list, the level will be set to the user-defined default value.
+ *
+ * @param name
+ *    Name for the log type to be registered
+ * @param level_def
+ *    Fallback level to be set if the global list has no matching options
+ * @return
+ *    - >=0: the newly registered log type
+ *    - <0: rte_log_register() error value
+ */
+int rte_log_register_type_and_pick_level(const char *name, uint32_t level_def);
+
+/**
+ * Dump name of each logtype, one per line.
+ *
+ * @param out
+ *   Stream where the list is sent.
+ * @param prefix
+ *   String preceding each logtype in the output.
+ */
+void rte_log_list_types(FILE *out, const char *prefix);
+
+/**
+ * Dump log information.
+ *
+ * Dump the global level and the registered log types.
+ *
+ * @param f
+ *   The output stream where the dump should be sent.
+ */
+void rte_log_dump(FILE *f);
+
+/**
+ * Generates a log message.
+ *
+ * The message will be sent in the stream defined by the previous call
+ * to rte_openlog_stream().
+ *
+ * The level argument determines if the log should be displayed or
+ * not, depending on the loglevel settings.
+ *
+ * The preferred alternative is the RTE_LOG() because it adds the
+ * level and type in the logged string.
+ *
+ * @param level
+ *   Log level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @param logtype
+ *   The log type, for example, RTE_LOGTYPE_EAL.
+ * @param format
+ *   The format string, as in printf(3), followed by the variable arguments
+ *   required by the format.
+ * @return
+ *   - 0: Success.
+ *   - Negative on error.
+ */
+int rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
+#ifdef __GNUC__
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2))
+	__rte_cold
+#endif
+#endif
+	__rte_format_printf(3, 4);
+
+/**
+ * Generates a log message.
+ *
+ * The message will be sent in the stream defined by the previous call
+ * to rte_openlog_stream().
+ *
+ * The level argument determines if the log should be displayed or
+ * not, depending on the loglevel settings. A trailing
+ * newline may be added if needed.
+ *
+ * The preferred alternative is the RTE_LOG() because it adds the
+ * level and type in the logged string.
+ *
+ * @param level
+ *   Log level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @param logtype
+ *   The log type, for example, RTE_LOGTYPE_EAL.
+ * @param format
+ *   The format string, as in printf(3), followed by the variable arguments
+ *   required by the format.
+ * @param ap
+ *   The va_list of the variable arguments required by the format.
+ * @return
+ *   - 0: Success.
+ *   - Negative on error.
+ */
+int rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)
+	__rte_format_printf(3, 0);
+
+/**
+ * Generates a log message.
+ *
+ * The RTE_LOG() is a helper that prefixes the string with the log level
+ * and type, and call rte_log().
+ *
+ * @param l
+ *   Log level. A value between EMERG (1) and DEBUG (8). The short name is
+ *   expanded by the macro, so it cannot be an integer value.
+ * @param t
+ *   The log type, for example, EAL. The short name is expanded by the
+ *   macro, so it cannot be an integer value.
+ * @param ...
+ *   The fmt string, as in printf(3), followed by the variable arguments
+ *   required by the format.
+ * @return
+ *   - 0: Success.
+ *   - Negative on error.
+ */
+#define RTE_LOG(l, t, ...)					\
+	 rte_log(RTE_LOG_ ## l,					\
+		 RTE_LOGTYPE_ ## t, # t ": " __VA_ARGS__)
+
+/**
+ * Generates a log message for data path.
+ *
+ * Similar to RTE_LOG(), except that it is removed at compilation time
+ * if the RTE_LOG_DP_LEVEL configuration option is lower than the log
+ * level argument.
+ *
+ * @param l
+ *   Log level. A value between EMERG (1) and DEBUG (8). The short name is
+ *   expanded by the macro, so it cannot be an integer value.
+ * @param t
+ *   The log type, for example, EAL. The short name is expanded by the
+ *   macro, so it cannot be an integer value.
+ * @param ...
+ *   The fmt string, as in printf(3), followed by the variable arguments
+ *   required by the format.
+ * @return
+ *   - 0: Success.
+ *   - Negative on error.
+ */
+#define RTE_LOG_DP(l, t, ...)					\
+	(void)((RTE_LOG_ ## l <= RTE_LOG_DP_LEVEL) ?		\
+	 rte_log(RTE_LOG_ ## l,					\
+		 RTE_LOGTYPE_ ## t, # t ": " __VA_ARGS__) :	\
+	 0)
+
+#define RTE_LOG_REGISTER_IMPL(type, name, level)			    \
+int type;								    \
+RTE_INIT(__##type)							    \
+{									    \
+	type = rte_log_register_type_and_pick_level(name, RTE_LOG_##level); \
+	if (type < 0)                                                       \
+		type = RTE_LOGTYPE_EAL;                                     \
+}
+
+/**
+ * Register a dynamic log type in constructor context with its name and level.
+ *
+ * It is a wrapper macro for declaring the logtype, register the log and
+ * sets it's level in the constructor context.
+ *
+ * @param type
+ *   The log type identifier
+ * @param name
+ *    Name for the log type to be registered
+ * @param level
+ *   Log level. A value between EMERG (1) and DEBUG (8).
+ */
+#define RTE_LOG_REGISTER(type, name, level) \
+	RTE_LOG_REGISTER_IMPL(type, RTE_STR(name), level)
+
+/**
+ * This is an equivalent to RTE_LOG_REGISTER, but relying on the build system
+ * to select the right format for the logtype.
+ */
+#define RTE_LOG_REGISTER_DEFAULT(type, level) \
+	RTE_LOG_REGISTER_IMPL(type, RTE_STR(RTE_LOG_DEFAULT_LOGTYPE), level)
+
+/**
+ * This is an equivalent to RTE_LOG_REGISTER, but relying on the build system
+ * to select the right prefix for the logtype.
+ */
+#define RTE_LOG_REGISTER_SUFFIX(type, suffix, level)			      \
+	RTE_LOG_REGISTER_IMPL(type,					      \
+		 RTE_STR(RTE_LOG_DEFAULT_LOGTYPE) "." RTE_STR(suffix), level)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_LOG_H_ */
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so
new file mode 120000
index 00000000..ff0e41f1
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so
@@ -0,0 +1 @@
+librte_eal.so.23
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23 b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23
new file mode 120000
index 00000000..5c4e797e
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23
@@ -0,0 +1 @@
+librte_eal.so.23.1
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23.1 b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23.1
new file mode 100755
index 0000000000000000000000000000000000000000..c5e458ae3979781c7dbd9e449560a75fc4061a86
GIT binary patch
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so
@@ -0,0 +1 @@
+librte_kvargs.so.23
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23 b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23
new file mode 120000
index 00000000..1b0d96d3
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23
@@ -0,0 +1 @@
+librte_kvargs.so.23.1
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23.1 b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23.1
new file mode 100755
index 0000000000000000000000000000000000000000..7b85edcc6723df1dde39c166571c1ae9d5c6ce7a
GIT binary patch
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so
@@ -0,0 +1 @@
+librte_telemetry.so.23
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23 b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23
new file mode 120000
index 00000000..d5f42b8a
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23
@@ -0,0 +1 @@
+librte_telemetry.so.23.1
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23.1 b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23.1
new file mode 100755
index 0000000000000000000000000000000000000000..a284236713862466c3e10a68310001894dd2c2fc
GIT binary patch
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/include/rte_log.h b/tests/data/test-abidiff-exit/test-PR30034/split/include/rte_log.h
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/include/rte_log.h
@@ -0,0 +1,409 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#ifndef _RTE_LOG_H_
+#define _RTE_LOG_H_
+
+/**
+ * @file
+ *
+ * RTE Logs API
+ *
+ * This file provides a log API to RTE applications.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+
+#include <rte_common.h>
+#include <rte_config.h>
+
+/* SDK log type */
+#define RTE_LOGTYPE_EAL        0 /**< Log related to eal. */
+#define RTE_LOGTYPE_MALLOC     1 /**< Log related to malloc. */
+#define RTE_LOGTYPE_RING       2 /**< Log related to ring. */
+#define RTE_LOGTYPE_MEMPOOL    3 /**< Log related to mempool. */
+#define RTE_LOGTYPE_TIMER      4 /**< Log related to timers. */
+#define RTE_LOGTYPE_PMD        5 /**< Log related to poll mode driver. */
+#define RTE_LOGTYPE_HASH       6 /**< Log related to hash table. */
+#define RTE_LOGTYPE_LPM        7 /**< Log related to LPM. */
+#define RTE_LOGTYPE_KNI        8 /**< Log related to KNI. */
+#define RTE_LOGTYPE_ACL        9 /**< Log related to ACL. */
+#define RTE_LOGTYPE_POWER     10 /**< Log related to power. */
+#define RTE_LOGTYPE_METER     11 /**< Log related to QoS meter. */
+#define RTE_LOGTYPE_SCHED     12 /**< Log related to QoS port scheduler. */
+#define RTE_LOGTYPE_PORT      13 /**< Log related to port. */
+#define RTE_LOGTYPE_TABLE     14 /**< Log related to table. */
+#define RTE_LOGTYPE_PIPELINE  15 /**< Log related to pipeline. */
+#define RTE_LOGTYPE_MBUF      16 /**< Log related to mbuf. */
+#define RTE_LOGTYPE_CRYPTODEV 17 /**< Log related to cryptodev. */
+#define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
+#define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
+#define RTE_LOGTYPE_GSO       20 /**< Log related to GSO. */
+
+/* these log types can be used in an application */
+#define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
+#define RTE_LOGTYPE_USER2     25 /**< User-defined log type 2. */
+#define RTE_LOGTYPE_USER3     26 /**< User-defined log type 3. */
+#define RTE_LOGTYPE_USER4     27 /**< User-defined log type 4. */
+#define RTE_LOGTYPE_USER5     28 /**< User-defined log type 5. */
+#define RTE_LOGTYPE_USER6     29 /**< User-defined log type 6. */
+#define RTE_LOGTYPE_USER7     30 /**< User-defined log type 7. */
+#define RTE_LOGTYPE_USER8     31 /**< User-defined log type 8. */
+
+/** First identifier for extended logs */
+#define RTE_LOGTYPE_FIRST_EXT_ID 32
+
+/* Can't use 0, as it gives compiler warnings */
+#define RTE_LOG_EMERG    1U  /**< System is unusable.               */
+#define RTE_LOG_ALERT    2U  /**< Action must be taken immediately. */
+#define RTE_LOG_CRIT     3U  /**< Critical conditions.              */
+#define RTE_LOG_ERR      4U  /**< Error conditions.                 */
+#define RTE_LOG_WARNING  5U  /**< Warning conditions.               */
+#define RTE_LOG_NOTICE   6U  /**< Normal but significant condition. */
+#define RTE_LOG_INFO     7U  /**< Informational.                    */
+#define RTE_LOG_DEBUG    8U  /**< Debug-level messages.             */
+#define RTE_LOG_MAX RTE_LOG_DEBUG /**< Most detailed log level.     */
+
+/**
+ * Change the stream that will be used by the logging system.
+ *
+ * This can be done at any time. The f argument represents the stream
+ * to be used to send the logs. If f is NULL, the default output is
+ * used (stderr).
+ *
+ * @param f
+ *   Pointer to the stream.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_openlog_stream(FILE *f);
+
+/**
+ * Retrieve the stream used by the logging system (see rte_openlog_stream()
+ * to change it).
+ *
+ * @return
+ *   Pointer to the stream.
+ */
+FILE *rte_log_get_stream(void);
+
+/**
+ * Set the global log level.
+ *
+ * After this call, logs with a level lower or equal than the level
+ * passed as argument will be displayed.
+ *
+ * @param level
+ *   Log level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ */
+void rte_log_set_global_level(uint32_t level);
+
+/**
+ * Get the global log level.
+ *
+ * @return
+ *   The current global log level.
+ */
+uint32_t rte_log_get_global_level(void);
+
+/**
+ * Get the log level for a given type.
+ *
+ * @param logtype
+ *   The log type identifier.
+ * @return
+ *   0 on success, a negative value if logtype is invalid.
+ */
+int rte_log_get_level(uint32_t logtype);
+
+/**
+ * For a given `logtype`, check if a log with `loglevel` can be printed.
+ *
+ * @param logtype
+ *   The log type identifier
+ * @param loglevel
+ *   Log level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @return
+ * Returns 'true' if log can be printed and 'false' if it can't.
+ */
+bool rte_log_can_log(uint32_t logtype, uint32_t loglevel);
+
+/**
+ * Set the log level for a given type based on globbing pattern.
+ *
+ * @param pattern
+ *   The globbing pattern identifying the log type.
+ * @param level
+ *   The level to be set.
+ * @return
+ *   0 on success, a negative value if level is invalid.
+ */
+int rte_log_set_level_pattern(const char *pattern, uint32_t level);
+
+/**
+ * Set the log level for a given type based on regular expression.
+ *
+ * @param regex
+ *   The regular expression identifying the log type.
+ * @param level
+ *   The level to be set.
+ * @return
+ *   0 on success, a negative value if level is invalid.
+ */
+int rte_log_set_level_regexp(const char *regex, uint32_t level);
+
+/**
+ * Set the log level for a given type.
+ *
+ * @param logtype
+ *   The log type identifier.
+ * @param level
+ *   The level to be set.
+ * @return
+ *   0 on success, a negative value if logtype or level is invalid.
+ */
+int rte_log_set_level(uint32_t logtype, uint32_t level);
+
+/**
+ * Get the current loglevel for the message being processed.
+ *
+ * Before calling the user-defined stream for logging, the log
+ * subsystem sets a per-lcore variable containing the loglevel and the
+ * logtype of the message being processed. This information can be
+ * accessed by the user-defined log output function through this
+ * function.
+ *
+ * @return
+ *   The loglevel of the message being processed.
+ */
+int rte_log_cur_msg_loglevel(void);
+
+/**
+ * Get the current logtype for the message being processed.
+ *
+ * Before calling the user-defined stream for logging, the log
+ * subsystem sets a per-lcore variable containing the loglevel and the
+ * logtype of the message being processed. This information can be
+ * accessed by the user-defined log output function through this
+ * function.
+ *
+ * @return
+ *   The logtype of the message being processed.
+ */
+int rte_log_cur_msg_logtype(void);
+
+/**
+ * Register a dynamic log type
+ *
+ * If a log is already registered with the same type, the returned value
+ * is the same than the previous one.
+ *
+ * @param name
+ *   The string identifying the log type.
+ * @return
+ *   - >0: success, the returned value is the log type identifier.
+ *   - (-ENOMEM): cannot allocate memory.
+ */
+int rte_log_register(const char *name);
+
+/**
+ * Register a dynamic log type and try to pick its level from EAL options
+ *
+ * rte_log_register() is called inside. If successful, the function tries
+ * to search for matching regexp in the list of EAL log level options and
+ * pick the level from the last matching entry. If nothing can be applied
+ * from the list, the level will be set to the user-defined default value.
+ *
+ * @param name
+ *    Name for the log type to be registered
+ * @param level_def
+ *    Fallback level to be set if the global list has no matching options
+ * @return
+ *    - >=0: the newly registered log type
+ *    - <0: rte_log_register() error value
+ */
+int rte_log_register_type_and_pick_level(const char *name, uint32_t level_def);
+
+/**
+ * Dump name of each logtype, one per line.
+ *
+ * @param out
+ *   Stream where the list is sent.
+ * @param prefix
+ *   String preceding each logtype in the output.
+ */
+void rte_log_list_types(FILE *out, const char *prefix);
+
+/**
+ * Dump log information.
+ *
+ * Dump the global level and the registered log types.
+ *
+ * @param f
+ *   The output stream where the dump should be sent.
+ */
+void rte_log_dump(FILE *f);
+
+/**
+ * Generates a log message.
+ *
+ * The message will be sent in the stream defined by the previous call
+ * to rte_openlog_stream().
+ *
+ * The level argument determines if the log should be displayed or
+ * not, depending on the loglevel settings.
+ *
+ * The preferred alternative is the RTE_LOG() because it adds the
+ * level and type in the logged string.
+ *
+ * @param level
+ *   Log level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @param logtype
+ *   The log type, for example, RTE_LOGTYPE_EAL.
+ * @param format
+ *   The format string, as in printf(3), followed by the variable arguments
+ *   required by the format.
+ * @return
+ *   - 0: Success.
+ *   - Negative on error.
+ */
+int rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
+#ifdef __GNUC__
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2))
+	__rte_cold
+#endif
+#endif
+	__rte_format_printf(3, 4);
+
+/**
+ * Generates a log message.
+ *
+ * The message will be sent in the stream defined by the previous call
+ * to rte_openlog_stream().
+ *
+ * The level argument determines if the log should be displayed or
+ * not, depending on the loglevel settings. A trailing
+ * newline may be added if needed.
+ *
+ * The preferred alternative is the RTE_LOG() because it adds the
+ * level and type in the logged string.
+ *
+ * @param level
+ *   Log level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @param logtype
+ *   The log type, for example, RTE_LOGTYPE_EAL.
+ * @param format
+ *   The format string, as in printf(3), followed by the variable arguments
+ *   required by the format.
+ * @param ap
+ *   The va_list of the variable arguments required by the format.
+ * @return
+ *   - 0: Success.
+ *   - Negative on error.
+ */
+int rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)
+	__rte_format_printf(3, 0);
+
+/**
+ * Generates a log message.
+ *
+ * The RTE_LOG() is a helper that prefixes the string with the log level
+ * and type, and call rte_log().
+ *
+ * @param l
+ *   Log level. A value between EMERG (1) and DEBUG (8). The short name is
+ *   expanded by the macro, so it cannot be an integer value.
+ * @param t
+ *   The log type, for example, EAL. The short name is expanded by the
+ *   macro, so it cannot be an integer value.
+ * @param ...
+ *   The fmt string, as in printf(3), followed by the variable arguments
+ *   required by the format.
+ * @return
+ *   - 0: Success.
+ *   - Negative on error.
+ */
+#define RTE_LOG(l, t, ...)					\
+	 rte_log(RTE_LOG_ ## l,					\
+		 RTE_LOGTYPE_ ## t, # t ": " __VA_ARGS__)
+
+/**
+ * Generates a log message for data path.
+ *
+ * Similar to RTE_LOG(), except that it is removed at compilation time
+ * if the RTE_LOG_DP_LEVEL configuration option is lower than the log
+ * level argument.
+ *
+ * @param l
+ *   Log level. A value between EMERG (1) and DEBUG (8). The short name is
+ *   expanded by the macro, so it cannot be an integer value.
+ * @param t
+ *   The log type, for example, EAL. The short name is expanded by the
+ *   macro, so it cannot be an integer value.
+ * @param ...
+ *   The fmt string, as in printf(3), followed by the variable arguments
+ *   required by the format.
+ * @return
+ *   - 0: Success.
+ *   - Negative on error.
+ */
+#define RTE_LOG_DP(l, t, ...)					\
+	(void)((RTE_LOG_ ## l <= RTE_LOG_DP_LEVEL) ?		\
+	 rte_log(RTE_LOG_ ## l,					\
+		 RTE_LOGTYPE_ ## t, # t ": " __VA_ARGS__) :	\
+	 0)
+
+#define RTE_LOG_REGISTER_IMPL(type, name, level)			    \
+int type;								    \
+RTE_INIT(__##type)							    \
+{									    \
+	type = rte_log_register_type_and_pick_level(name, RTE_LOG_##level); \
+	if (type < 0)                                                       \
+		type = RTE_LOGTYPE_EAL;                                     \
+}
+
+/**
+ * Register a dynamic log type in constructor context with its name and level.
+ *
+ * It is a wrapper macro for declaring the logtype, register the log and
+ * sets it's level in the constructor context.
+ *
+ * @param type
+ *   The log type identifier
+ * @param name
+ *    Name for the log type to be registered
+ * @param level
+ *   Log level. A value between EMERG (1) and DEBUG (8).
+ */
+#define RTE_LOG_REGISTER(type, name, level) \
+	RTE_LOG_REGISTER_IMPL(type, RTE_STR(name), level)
+
+/**
+ * This is an equivalent to RTE_LOG_REGISTER, but relying on the build system
+ * to select the right format for the logtype.
+ */
+#define RTE_LOG_REGISTER_DEFAULT(type, level) \
+	RTE_LOG_REGISTER_IMPL(type, RTE_STR(RTE_LOG_DEFAULT_LOGTYPE), level)
+
+/**
+ * This is an equivalent to RTE_LOG_REGISTER, but relying on the build system
+ * to select the right prefix for the logtype.
+ */
+#define RTE_LOG_REGISTER_SUFFIX(type, suffix, level)			      \
+	RTE_LOG_REGISTER_IMPL(type,					      \
+		 RTE_STR(RTE_LOG_DEFAULT_LOGTYPE) "." RTE_STR(suffix), level)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_LOG_H_ */
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so
new file mode 120000
index 00000000..ff0e41f1
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so
@@ -0,0 +1 @@
+librte_eal.so.23
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23 b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23
new file mode 120000
index 00000000..f10112f9
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23
@@ -0,0 +1 @@
+librte_eal.so.23.2
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23.2 b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23.2
new file mode 100755
index 0000000000000000000000000000000000000000..512053dc76680795a378a59747d06415b5eeb776
GIT binary patch
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so
@@ -0,0 +1 @@
+librte_kvargs.so.23
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23 b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23
new file mode 120000
index 00000000..34d498fa
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23
@@ -0,0 +1 @@
+librte_kvargs.so.23.2
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23.2 b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23.2
new file mode 100755
index 0000000000000000000000000000000000000000..7a89226de48f859c3e23d8fccd2f6234e991edad
GIT binary patch
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so
@@ -0,0 +1 @@
+librte_log.so.23
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23 b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23
new file mode 120000
index 00000000..0ce50648
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23
@@ -0,0 +1 @@
+librte_log.so.23.2
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23.2 b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23.2
new file mode 100755
index 0000000000000000000000000000000000000000..0b82cc7d662d073a4fe1bb69a35d94be5ddf2054
GIT binary patch
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so
@@ -0,0 +1 @@
+librte_telemetry.so.23
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23 b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23
new file mode 120000
index 00000000..80a81bab
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23
@@ -0,0 +1 @@
+librte_telemetry.so.23.2
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23.2 b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23.2
new file mode 100755
index 0000000000000000000000000000000000000000..d7017185967b570aef57d1bb9fd32289109f51a9
GIT binary patch
diff --git a/tests/data/test-abidiff-exit/test-PR30034/test-PR30034-report-1.txt b/tests/data/test-abidiff-exit/test-PR30034/test-PR30034-report-1.txt
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-PR30034/test-PR30034-report-1.txt
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added (12 filtered out) functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc
index da43b826..a6d54e5c 100644
--- a/tests/test-abidiff-exit.cc
+++ b/tests/test-abidiff-exit.cc
@@ -39,6 +39,8 @@ struct InOutSpec
   const char*   in_elfv1_headers_dirs;
   const char*   in_elfv0_debug_dir;
   const char*   in_elfv1_debug_dir;
+  const char*   in_elfv0_added_bins_dir;
+  const char*   in_elfv1_added_bins_dir;
   const char*	abidiff_options;
   abidiff_status status;
   const char*	in_report_path;
@@ -55,6 +57,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -69,6 +73,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test1-voffset-change-report1.txt",
@@ -82,6 +88,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -96,6 +104,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test2-filtered-removed-fns-report1.txt",
@@ -110,6 +120,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     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"
@@ -122,6 +134,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-show-locs",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-loc-without-locs-report.txt",
@@ -135,6 +149,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-no-stray-comma-report.txt",
@@ -148,6 +164,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-leaf-stats-report.txt",
@@ -161,6 +179,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -175,6 +195,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-leaf-fun-type-report.txt",
@@ -188,6 +210,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-leaf-redundant-report.txt",
@@ -201,6 +225,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-leaf-peeling-report.txt",
@@ -214,6 +240,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -229,6 +257,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-member-size-report0.txt",
     "output/test-abidiff-exit/test-member-size-report0.txt"
@@ -241,6 +271,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-member-size-report1.txt",
@@ -254,6 +286,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--harmless",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-decl-struct-report.txt",
@@ -268,6 +302,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-fun-param-report.txt",
     "output/test-abidiff-exit/test-fun-param-report.txt"
@@ -280,6 +316,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--harmless",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-decl-enum-report.txt",
@@ -294,6 +332,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     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"
@@ -306,6 +346,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-decl-enum-report-3.txt",
@@ -319,6 +361,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -333,6 +377,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-net-change-report1.txt",
@@ -346,6 +392,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -360,6 +408,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-net-change-report3.txt",
@@ -373,6 +423,8 @@ InOutSpec in_out_specs[] =
     "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",
@@ -388,6 +440,8 @@ InOutSpec in_out_specs[] =
     "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",
@@ -402,6 +456,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/qualifier-typedef-array-report-0.txt",
     "output/test-abidiff-exit/qualifier-typedef-array-report-0.txt"
@@ -414,6 +470,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--harmless",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/qualifier-typedef-array-report-1.txt",
@@ -427,6 +485,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/qualifier-typedef-array-report-2.txt",
@@ -440,6 +500,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--harmless --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/qualifier-typedef-array-report-3.txt",
@@ -453,6 +515,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-non-leaf-array-report.txt",
@@ -467,6 +531,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-crc-report.txt",
     "output/test-abidiff-exit/test-crc-report.txt"
@@ -480,6 +546,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-missing-alias-report.txt",
     "output/test-abidiff-exit/test-missing-alias-report.txt"
@@ -492,6 +560,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --harmless",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-PR28316-report.txt",
@@ -505,6 +575,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --harmless",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-PR29144-report.txt",
@@ -518,6 +590,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--leaf-changes-only --no-default-suppression --harmless",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-PR29144-report-2.txt",
@@ -531,6 +605,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt",
@@ -544,6 +620,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-rhbz2114909-report-1.txt",
@@ -557,6 +635,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/PR30048-test-report-0.txt",
@@ -570,6 +650,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/PR30048-test-2-report-1.txt",
@@ -583,6 +665,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt",
@@ -596,6 +680,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-allow-type-array-v0--v1-report-2.txt",
@@ -609,6 +695,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-array-v0--v2-report-1.txt",
@@ -622,6 +710,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-array-v0--v2-report-2.txt",
@@ -635,6 +725,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt",
@@ -648,6 +740,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-allow-type-array-v0--v3-report-2.txt",
@@ -661,6 +755,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v1-report-1.txt",
@@ -674,6 +770,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-allow-type-region-v0--v1-report-2.txt",
@@ -687,6 +785,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt",
@@ -700,6 +800,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt",
@@ -713,6 +815,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v2-report-2.txt",
@@ -726,6 +830,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v3-report-1.txt",
@@ -739,6 +845,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v3-report-2.txt",
@@ -752,6 +860,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v4-report-1.txt",
@@ -765,6 +875,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-allow-type-region-v0--v4-report-2.txt",
@@ -778,6 +890,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v5-report-1.txt",
@@ -791,6 +905,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-allow-type-region-v0--v5-report-2.txt",
@@ -804,6 +920,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-1.txt",
@@ -817,6 +935,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-2.txt",
@@ -830,6 +950,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-1.txt",
@@ -843,6 +965,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-2.txt",
@@ -856,6 +980,8 @@ InOutSpec in_out_specs[] =
     "",
     "data/test-abidiff-exit/PR30329/old-image/usr/lib/debug",
     "data/test-abidiff-exit/PR30329/new-image/usr/lib/debug",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/PR30329/PR30329-report-1.txt",
@@ -869,11 +995,28 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/PR30503/libsdl/libsdl-1.2.60-1.2.64-report.txt",
     "output/test-abidiff-exit/PR30503/libsdl/libsdl-1.2.60-1.2.64-report.txt"
   },
+  {
+    "data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23.1",
+    "data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23.2",
+    "data/test-abidiff-exit/test-PR30034/libabigail.abignore",
+    "data/test-abidiff-exit/test-PR30034/reference/include",
+    "data/test-abidiff-exit/test-PR30034/split/include",
+    "",
+    "",
+    "data/test-abidiff-exit/test-PR30034/reference/lib64",
+    "data/test-abidiff-exit/test-PR30034/split/lib64",
+    "--no-default-suppression --no-added-syms --follow-dependencies",
+    abigail::tools_utils::ABIDIFF_OK,
+    "data/test-abidiff-exit/test-PR30034/test-PR30034-report-1.txt",
+    "output/test-abidiff-exit/test-PR30034/test-PR30034-report-1.txt"
+  },
 #ifdef WITH_BTF
   {
     "data/test-abidiff-exit/btf/test0-v0.o",
@@ -883,6 +1026,8 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --btf",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/btf/test0-report-1.txt",
@@ -896,13 +1041,15 @@ InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
+    "",
     "--no-default-suppression --harmless --btf",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/btf/test0-report-2.txt",
     "output/test-abidiff-exit/btf/test0-report-2.txt"
   },
 #endif
-  {0, 0, 0 ,0, 0, 0, 0, 0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
+  {0, 0, 0 ,0, 0, 0, 0, 0, 0, 0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
 };
 
 /// Prefix the strings in a vector of string.
@@ -935,7 +1082,7 @@ main()
   string in_elfv0_path, in_elfv1_path,
     in_suppression_path, abidiff_options, abidiff, cmd, diff_cmd,
     ref_diff_report_path, out_diff_report_path, in_elfv0_debug_dir,
-    in_elfv1_debug_dir;
+    in_elfv1_debug_dir, in_elfv0_added_bins_dir, in_elfv1_added_bins_dir;
   vector<string> 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/";
@@ -949,6 +1096,9 @@ main()
 	in_elfv1_debug_dir = source_dir_prefix + s->in_elfv1_debug_dir;
 	in_elfv0_headers_dirs.clear();
 	in_elfv1_headers_dirs.clear();
+	in_elfv0_added_bins_dir.clear();
+	in_elfv1_added_bins_dir.clear();
+
 	if (s->in_elfv0_headers_dirs && strcmp(s->in_elfv0_headers_dirs, ""))
 	  {
 	    split_string(s->in_elfv0_headers_dirs, ",", in_elfv0_headers_dirs);
@@ -966,6 +1116,16 @@ main()
 	else
 	  in_suppression_path.clear();
 
+	if (s->in_elfv0_added_bins_dir
+	    && strcmp(s->in_elfv0_added_bins_dir, ""))
+	  in_elfv0_added_bins_dir =
+	    source_dir_prefix + s->in_elfv0_added_bins_dir;
+
+	if (s->in_elfv1_added_bins_dir
+	    && strcmp(s->in_elfv1_added_bins_dir, ""))
+	  in_elfv1_added_bins_dir =
+	    source_dir_prefix + s->in_elfv1_added_bins_dir;
+
 	abidiff_options = s->abidiff_options;
 	ref_diff_report_path = source_dir_prefix + s->in_report_path;
 	out_diff_report_path = build_dir_prefix + s->out_report_path;
@@ -983,6 +1143,12 @@ main()
 	if (!abidiff_options.empty())
 	  abidiff += " " + abidiff_options;
 
+	if (!in_elfv0_added_bins_dir.empty())
+	  abidiff += " --added-binaries-dir1 " + in_elfv0_added_bins_dir;
+
+	if (!in_elfv1_added_bins_dir.empty())
+	  abidiff += " --added-binaries-dir2 " + in_elfv1_added_bins_dir;
+
 	if (!in_elfv0_debug_dir.empty())
 	  abidiff += " --debug-info-dir1 " + in_elfv0_debug_dir;
 
diff --git a/tools/abidiff.cc b/tools/abidiff.cc
index 0e6538eb..95b3474b 100644
--- a/tools/abidiff.cc
+++ b/tools/abidiff.cc
@@ -13,6 +13,7 @@
 #include <memory>
 #include <string>
 #include <vector>
+#include <set>
 #include "abg-config.h"
 #include "abg-comp-filter.h"
 #include "abg-suppression.h"
@@ -28,6 +29,7 @@
 #endif
 
 using std::vector;
+using std::set;
 using std::string;
 using std::ostream;
 using std::cout;
@@ -60,6 +62,10 @@ using abigail::tools_utils::load_default_system_suppressions;
 using abigail::tools_utils::load_default_user_suppressions;
 using abigail::tools_utils::abidiff_status;
 using abigail::tools_utils::create_best_elf_based_reader;
+using abigail::tools_utils::stick_corpus_and_dependencies_into_corpus_group;
+using abigail::tools_utils::stick_corpus_and_binaries_into_corpus_group;
+using abigail::tools_utils::add_dependencies_into_corpus_group;
+using abigail::tools_utils::get_dependencies;
 
 using namespace abigail;
 
@@ -115,6 +121,8 @@ struct options
   bool			assume_odr_for_cplusplus;
   bool			leverage_dwarf_factorization;
   bool			perform_change_categorization;
+  bool			follow_dependencies;
+  bool			list_dependencies;
   bool			dump_diff_tree;
   bool			show_stats;
   bool			do_log;
@@ -134,6 +142,10 @@ struct options
   vector<char*> di_root_paths2;
   vector<char**> prepared_di_root_paths1;
   vector<char**> prepared_di_root_paths2;
+  vector<string> added_bins_dirs1;
+  vector<string> added_bins_dirs2;
+  vector<string> added_bins1;
+  vector<string> added_bins2;
 
   options()
     : display_usage(),
@@ -172,6 +184,8 @@ struct options
       assume_odr_for_cplusplus(true),
       leverage_dwarf_factorization(true),
       perform_change_categorization(true),
+      follow_dependencies(),
+      list_dependencies(),
       dump_diff_tree(),
       show_stats(),
       do_log()
@@ -224,6 +238,15 @@ display_usage(const string& prog_name, ostream& out)
     << " --header-file1|--hf1 <path>  the path to one header of file1\n"
     << " --headers-dir2|--hd2 <path>  the path to headers of file2\n"
     << " --header-file2|--hf2 <path>  the path to one header of file2\n"
+    << " --added-binaries-dir1  the path to the dependencies of file1\n"
+    << " --added-binaries-dir2  the path to the dependencies of file2\n"
+    << " --add-binaries1 <bin1,bin2,.>. build corpus groups with "
+    "extra binaries added to the first one and compare them\n"
+    << " --add-binaries2 <bin1,bin2,..> build corpus groups with "
+    "extra binaries added to the second one and compare them\n"
+    << " --follow-dependencies|--fdeps build corpus groups with the "
+    "dependencies of the input files\n"
+    << " --list-dependencies|--ldeps show the dependencies of the input files\n"
     << " --drop-private-types  drop private types from "
     "internal representation\n"
     << "  --exported-interfaces-only  analyze exported interfaces only\n"
@@ -423,6 +446,80 @@ parse_command_line(int argc, char* argv[], options& opts)
 	  opts.header_files2.push_back(argv[j]);
 	  ++i;
 	}
+      else if (!strcmp(argv[i], "--follow-dependencies")
+	       || !strcmp(argv[i], "--fdeps"))
+	opts.follow_dependencies = true;
+      else if (!strcmp(argv[i], "--list-dependencies")
+	       || !strcmp(argv[i], "--ldeps"))
+	opts.list_dependencies = true;
+      else if (!strcmp(argv[i], "--added-binaries-dir1")
+	       || !strcmp(argv[i], "--abd1"))
+	{
+	  int j = i + 1;
+	  if (j >= argc)
+	    {
+	      opts.missing_operand = true;
+	      opts.wrong_option = argv[i];
+	      return true;
+	    }
+	  opts.added_bins_dirs1.push_back(argv[j]);
+	  ++i;
+	}
+      else if (!strcmp(argv[i], "--added-binaries-dir2")
+	       || !strcmp(argv[i], "--abd2"))
+	{
+	  int j = i + 1;
+	  if (j >= argc)
+	    {
+	      opts.missing_operand = true;
+	      opts.wrong_option = argv[i];
+	      return true;
+	    }
+	  opts.added_bins_dirs2.push_back(argv[j]);
+	  ++i;
+	}
+      else if (!strncmp(argv[i], "--add-binaries1=",
+			strlen("--add-binaries1=")))
+	tools_utils::get_comma_separated_args_of_option(argv[i],
+							"--add-binaries1=",
+							opts.added_bins1);
+      else if (!strcmp(argv[i], "--add-binaries1"))
+	{
+	  int j = i + 1;
+	  if (j >= argc)
+	    {
+	      opts.missing_operand = true;
+	      opts.wrong_option = argv[i];
+	      return true;
+	    }
+	  string s = argv[j];
+	  if (s.find(','))
+	    tools_utils::split_string(s, ",", opts.added_bins1);
+	  else
+	    opts.added_bins1.push_back(s);
+	  ++i;
+	}
+      else if (!strncmp(argv[i], "--add-binaries2=",
+			strlen("--add-binaries2=")))
+	tools_utils::get_comma_separated_args_of_option(argv[i],
+							"--add-binaries2=",
+							opts.added_bins2);
+      else if (!strcmp(argv[i], "--add-binaries2"))
+	{
+	  int j = i + 1;
+	  if (j >= argc)
+	    {
+	      opts.missing_operand = true;
+	      opts.wrong_option = argv[i];
+	      return true;
+	    }
+	  string s = argv[j];
+	  if (s.find(','))
+	    tools_utils::split_string(s, ",", opts.added_bins2);
+	  else
+	    opts.added_bins2.push_back(s);
+	  ++i;
+	}
       else if (!strcmp(argv[i], "--kmi-whitelist")
 	       || !strcmp(argv[i], "-w"))
 	{
@@ -1156,6 +1253,63 @@ emit_incompatible_format_version_error_message(const string& file_path1,
     << "'" << file_path2 << "' (" << version2 << ")\n";
 }
 
+/// Display the dependencies of two corpora.
+///
+/// @param prog_name the name of the current abidiff program.
+///
+/// @param corp1 the first corpus to consider.
+///
+/// @param corp2 the second corpus to consider.
+///
+/// @param deps1 the dependencies to display.
+///
+/// @param deps2 the dependencies to display.
+static void
+display_dependencies(const string& prog_name,
+		     const corpus_sptr& corp1,
+		     const corpus_sptr& corp2,
+		     const set<string>& deps1,
+		     const set<string>& deps2)
+{
+  if (deps1.empty())
+    emit_prefix(prog_name, cout)
+    << "No dependencies found for '" << corp1->get_path() << "':\n";
+  else
+    {
+      emit_prefix(prog_name, cout)
+	<< "dependencies of '" << corp1->get_path() << "':\n\t";
+
+      int n = 0;
+      for (const auto& dep : deps1)
+	{
+	  if (n)
+	    cout << ", ";
+	  cout << dep;
+	  ++n;
+	}
+      cout << "\n";
+    }
+
+  if (deps2.empty())
+    emit_prefix(prog_name, cout)
+      << "No dependencies found for '" << corp2->get_path() << "':\n";
+  else
+    {
+      emit_prefix(prog_name, cout)
+	<< "dependencies of '" << corp2->get_path() << "':\n\t";
+
+      int n = 0;
+      for (const auto& dep : deps2)
+	{
+	  if (n)
+	    cout << ", ";
+	  cout << dep;
+	  ++n;
+	}
+      cout << "\n";
+    }
+}
+
 int
 main(int argc, char* argv[])
 {
@@ -1287,6 +1441,20 @@ main(int argc, char* argv[])
 	      return handle_error(c1_status, rdr.get(),
 				  argv[0], opts);
 
+	    if (!opts.added_bins1.empty())
+	      g1 = stick_corpus_and_binaries_into_corpus_group(rdr, c1,
+							       opts.added_bins1,
+							       opts.added_bins_dirs1);
+	    if (opts.follow_dependencies)
+	      {
+		if (g1)
+		  add_dependencies_into_corpus_group(rdr, *c1,
+						     opts.added_bins_dirs1,
+						     *g1);
+		else
+		  g1 = stick_corpus_and_dependencies_into_corpus_group(rdr, c1,
+								       opts.added_bins_dirs1);
+	      }
 	  }
 	  break;
 	case abigail::tools_utils::FILE_TYPE_XML_CORPUS:
@@ -1304,8 +1472,7 @@ main(int argc, char* argv[])
 	case abigail::tools_utils::FILE_TYPE_XML_CORPUS_GROUP:
 	  {
 	    abigail::fe_iface_sptr rdr =
-	      abixml::create_reader(opts.file1,
-							   env);
+	      abixml::create_reader(opts.file1, env);
 	    assert(rdr);
 	    set_suppressions(*rdr, opts);
 	    set_native_xml_reader_options(*rdr, opts);
@@ -1364,6 +1531,21 @@ main(int argc, char* argv[])
 		    && (c2_status & abigail::fe_iface::STATUS_ALT_DEBUG_INFO_NOT_FOUND)
 		    && (c2_status & abigail::fe_iface::STATUS_DEBUG_INFO_NOT_FOUND)))
 	      return handle_error(c2_status, rdr.get(), argv[0], opts);
+
+	  if (!opts.added_bins2.empty())
+	    g2 = stick_corpus_and_binaries_into_corpus_group(rdr, c2,
+							     opts.added_bins2,
+							     opts.added_bins_dirs2);
+	  if (opts.follow_dependencies)
+	    {
+	      if (g2)
+		add_dependencies_into_corpus_group(rdr, *c2,
+						   opts.added_bins_dirs2,
+						   *g2);
+	      else
+		g2 = stick_corpus_and_dependencies_into_corpus_group(rdr, c2,
+								     opts.added_bins_dirs2);
+	    }
 	  }
 	  break;
 	case abigail::tools_utils::FILE_TYPE_XML_CORPUS:
@@ -1397,6 +1579,34 @@ main(int argc, char* argv[])
 	  break;
 	}
 
+      if (!opts.added_bins1.empty()
+	  || !opts.added_bins2.empty())
+	{
+	  // We were requested to compare a set of binaries against
+	  // another set of binaries.  Let's make sure we construct
+	  // two ABI construct groups in all cases.
+
+	  if (!g1 && c1)
+	    {
+	      // We don't have a corpus group for the first argument.
+	      // Let's build one and stick the ABI corpus at hand in
+	      // it.
+	      g1.reset(new corpus_group(c1->get_environment(),
+					c1->get_path()));
+	      g1->add_corpus(c1);
+	    }
+
+	  if (!g2 && c2)
+	    {
+	      // We don't have a corpus group for the second argument.
+	      // Let's build one and stick the ABI corpus at hand in
+	      // it.
+	      g2.reset(new corpus_group(c2->get_environment(),
+					c2->get_path()));
+	      g2->add_corpus(c1);
+	    }
+	}
+
       if (!!c1 != !!c2
 	  || !!t1 != !!t2
 	  || !!g1 != !!g2)
@@ -1456,7 +1666,7 @@ main(int argc, char* argv[])
 		}
 	    }
 	}
-      else if (c1)
+      else if (g1)
 	{
 	  if (opts.show_symtabs)
 	    {
@@ -1464,21 +1674,19 @@ main(int argc, char* argv[])
 	      return abigail::tools_utils::ABIDIFF_OK;
 	    }
 
-	  const auto c1_version = c1->get_format_major_version_number();
-	  const auto c2_version = c2->get_format_major_version_number();
-	  if (c1_version != c2_version)
+	  const auto g1_version = g1->get_format_major_version_number();
+	  const auto g2_version = g2->get_format_major_version_number();
+	  if (g1_version != g2_version)
 	    {
 	      emit_incompatible_format_version_error_message(opts.file1,
-							     c1_version,
+							     g1_version,
 							     opts.file2,
-							     c2_version,
+							     g2_version,
 							     argv[0]);
 	      return abigail::tools_utils::ABIDIFF_ERROR;
 	    }
 
-	  set_corpus_keep_drop_regex_patterns(opts, c1);
-	  set_corpus_keep_drop_regex_patterns(opts, c2);
-
+	  adjust_diff_context_for_kmidiff(*ctxt);
 	  tools_utils::timer t;
 	  if (opts.do_log)
 	    {
@@ -1486,28 +1694,27 @@ main(int argc, char* argv[])
 	      std::cerr << "Compute diff ...\n";
 	    }
 
-	  corpus_diff_sptr diff = compute_diff(c1, c2, ctxt);
+	  corpus_diff_sptr diff = compute_diff(g1, g2, ctxt);
 
 	  if (opts.do_log)
 	    {
 	      t.stop();
+	      diff->do_log(true);
 	      std::cerr << "diff computed!:" << t << "\n";
 	    }
 
 	  if (opts.do_log)
 	    {
-	      t.start();
 	      std::cerr << "Computing net changes ...\n";
+	      t.start();
 	    }
 
 	  if (diff->has_net_changes())
+	    status = abigail::tools_utils::ABIDIFF_ABI_CHANGE;
+	  if (opts.do_log)
 	    {
-	      if (opts.do_log)
-		{
-		  t.stop();
-		  std::cerr << "net changes computed!: "<< t << "\n";
-		}
-	      status = abigail::tools_utils::ABIDIFF_ABI_CHANGE;
+	      t.stop();
+	      std::cerr << "net changes computed!: "<< t << "\n";
 	    }
 
 	  if (opts.do_log)
@@ -1517,13 +1724,12 @@ main(int argc, char* argv[])
 	    }
 
 	  if (diff->has_incompatible_changes())
+	    status |= abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE;
+
+	  if (opts.do_log)
 	    {
-	      if (opts.do_log)
-		{
-		  t.stop();
-		  std::cerr << "incompatible changes computed!: "<< t << "\n";
-		}
-	      status |= abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE;
+	      t.stop();
+	      std::cerr << "incompatible changes computed!: "<< t << "\n";
 	    }
 
 	  if (opts.do_log)
@@ -1554,8 +1760,24 @@ main(int argc, char* argv[])
 		  std::cerr << "Report computed!:" << t << "\n";
 		}
 	    }
+	  else
+	    {
+	      if (opts.do_log)
+		{
+		  t.stop();
+		  std::cerr << "changes computed!: "<< t << "\n";
+		}
+	    }
+
+	  if (opts.list_dependencies)
+	    {
+	      set<string> deps1, deps2;
+	      get_dependencies(*c1, opts.added_bins_dirs1, deps1);
+	      get_dependencies(*c2, opts.added_bins_dirs2, deps2);
+	      display_dependencies(argv[0], c1, c2, deps1, deps2);
+	    }
 	}
-      else if (g1)
+      else if (c1)
 	{
 	  if (opts.show_symtabs)
 	    {
@@ -1563,19 +1785,29 @@ main(int argc, char* argv[])
 	      return abigail::tools_utils::ABIDIFF_OK;
 	    }
 
-	  const auto g1_version = g1->get_format_major_version_number();
-	  const auto g2_version = g2->get_format_major_version_number();
-	  if (g1_version != g2_version)
+	  if (opts.list_dependencies)
+	    {
+	      set<string> deps1, deps2;
+	      get_dependencies(*c1, opts.added_bins_dirs1, deps1);
+	      get_dependencies(*c2, opts.added_bins_dirs2, deps2);
+	      display_dependencies(argv[0], c1, c2, deps1, deps2);
+	      return abigail::tools_utils::ABIDIFF_OK;
+	    }
+	  const auto c1_version = c1->get_format_major_version_number();
+	  const auto c2_version = c2->get_format_major_version_number();
+	  if (c1_version != c2_version)
 	    {
 	      emit_incompatible_format_version_error_message(opts.file1,
-							     g1_version,
+							     c1_version,
 							     opts.file2,
-							     g2_version,
+							     c2_version,
 							     argv[0]);
 	      return abigail::tools_utils::ABIDIFF_ERROR;
 	    }
 
-	  adjust_diff_context_for_kmidiff(*ctxt);
+	  set_corpus_keep_drop_regex_patterns(opts, c1);
+	  set_corpus_keep_drop_regex_patterns(opts, c2);
+
 	  tools_utils::timer t;
 	  if (opts.do_log)
 	    {
@@ -1583,27 +1815,28 @@ main(int argc, char* argv[])
 	      std::cerr << "Compute diff ...\n";
 	    }
 
-	  corpus_diff_sptr diff = compute_diff(g1, g2, ctxt);
+	  corpus_diff_sptr diff = compute_diff(c1, c2, ctxt);
 
 	  if (opts.do_log)
 	    {
 	      t.stop();
-	      diff->do_log(true);
 	      std::cerr << "diff computed!:" << t << "\n";
 	    }
 
 	  if (opts.do_log)
 	    {
-	      std::cerr << "Computing net changes ...\n";
 	      t.start();
+	      std::cerr << "Computing net changes ...\n";
 	    }
 
 	  if (diff->has_net_changes())
-	    status = abigail::tools_utils::ABIDIFF_ABI_CHANGE;
-	  if (opts.do_log)
 	    {
-	      t.stop();
-	      std::cerr << "net changes computed!: "<< t << "\n";
+	      if (opts.do_log)
+		{
+		  t.stop();
+		  std::cerr << "net changes computed!: "<< t << "\n";
+		}
+	      status = abigail::tools_utils::ABIDIFF_ABI_CHANGE;
 	    }
 
 	  if (opts.do_log)
@@ -1613,12 +1846,13 @@ main(int argc, char* argv[])
 	    }
 
 	  if (diff->has_incompatible_changes())
-	    status |= abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE;
-
-	  if (opts.do_log)
 	    {
-	      t.stop();
-	      std::cerr << "incompatible changes computed!: "<< t << "\n";
+	      if (opts.do_log)
+		{
+		  t.stop();
+		  std::cerr << "incompatible changes computed!: "<< t << "\n";
+		}
+	      status |= abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE;
 	    }
 
 	  if (opts.do_log)
@@ -1649,15 +1883,6 @@ main(int argc, char* argv[])
 		  std::cerr << "Report computed!:" << t << "\n";
 		}
 	    }
-	  else
-	    {
-	      if (opts.do_log)
-		{
-		  t.stop();
-		  std::cerr << "changes computed!: "<< t << "\n";
-		}
-	    }
-
 	}
       else
 	status = abigail::tools_utils::ABIDIFF_ERROR;
