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`` + + 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`` + + 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 +#include +#include +#include + +#include +#include + +/* 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 00000000..c5e458ae Binary files /dev/null and b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23.1 differ 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 new file mode 120000 index 00000000..2e18247d --- /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 00000000..7b85edcc Binary files /dev/null and b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23.1 differ 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 new file mode 120000 index 00000000..d6a36307 --- /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 00000000..a2842367 Binary files /dev/null and b/tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23.1 differ 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 new file mode 100644 index 00000000..6d2b0856 --- /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 +#include +#include +#include + +#include +#include + +/* 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 00000000..512053dc Binary files /dev/null and b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23.2 differ 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 new file mode 120000 index 00000000..2e18247d --- /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 00000000..7a89226d Binary files /dev/null and b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23.2 differ 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 new file mode 120000 index 00000000..54af832a --- /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 00000000..0b82cc7d Binary files /dev/null and b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23.2 differ 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 new file mode 120000 index 00000000..d6a36307 --- /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 00000000..d7017185 Binary files /dev/null and b/tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23.2 differ 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 new file mode 100644 index 00000000..c468b29d --- /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 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 #include #include +#include #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 di_root_paths2; vector prepared_di_root_paths1; vector prepared_di_root_paths2; + vector added_bins_dirs1; + vector added_bins_dirs2; + vector added_bins1; + vector 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 the path to one header of file1\n" << " --headers-dir2|--hd2 the path to headers of file2\n" << " --header-file2|--hf2 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 . build corpus groups with " + "extra binaries added to the first one and compare them\n" + << " --add-binaries2 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& deps1, + const set& 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) @@ -1449,105 +1659,6 @@ main(int argc, char* argv[]) diff->report(cout); - if (opts.do_log) - { - t.stop(); - std::cerr << "Report computed!:" << t << "\n"; - } - } - } - else if (c1) - { - if (opts.show_symtabs) - { - display_symtabs(c1, c2, cout); - 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, - c1_version, - opts.file2, - c2_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); - - tools_utils::timer t; - if (opts.do_log) - { - t.start(); - std::cerr << "Compute diff ...\n"; - } - - corpus_diff_sptr diff = compute_diff(c1, c2, ctxt); - - if (opts.do_log) - { - t.stop(); - std::cerr << "diff computed!:" << t << "\n"; - } - - if (opts.do_log) - { - t.start(); - std::cerr << "Computing net changes ...\n"; - } - - if (diff->has_net_changes()) - { - if (opts.do_log) - { - t.stop(); - std::cerr << "net changes computed!: "<< t << "\n"; - } - status = abigail::tools_utils::ABIDIFF_ABI_CHANGE; - } - - if (opts.do_log) - { - t.start(); - std::cerr << "Computing incompatible changes ...\n"; - } - - if (diff->has_incompatible_changes()) - { - 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) - { - t.start(); - std::cerr << "Computing changes ...\n"; - } - - if (diff->has_changes()) - { - if (opts.do_log) - { - t.stop(); - std::cerr << "changes computed!: "<< t << "\n"; - } - - if (opts.do_log) - { - t.start(); - std::cerr << "Computing report ...\n"; - } - - diff->report(cout); - if (opts.do_log) { t.stop(); @@ -1658,6 +1769,120 @@ main(int argc, char* argv[]) } } + if (opts.list_dependencies) + { + set 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 (c1) + { + if (opts.show_symtabs) + { + display_symtabs(c1, c2, cout); + return abigail::tools_utils::ABIDIFF_OK; + } + + if (opts.list_dependencies) + { + set 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, + c1_version, + opts.file2, + c2_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); + + tools_utils::timer t; + if (opts.do_log) + { + t.start(); + std::cerr << "Compute diff ...\n"; + } + + corpus_diff_sptr diff = compute_diff(c1, c2, ctxt); + + if (opts.do_log) + { + t.stop(); + std::cerr << "diff computed!:" << t << "\n"; + } + + if (opts.do_log) + { + t.start(); + std::cerr << "Computing net changes ...\n"; + } + + if (diff->has_net_changes()) + { + if (opts.do_log) + { + t.stop(); + std::cerr << "net changes computed!: "<< t << "\n"; + } + status = abigail::tools_utils::ABIDIFF_ABI_CHANGE; + } + + if (opts.do_log) + { + t.start(); + std::cerr << "Computing incompatible changes ...\n"; + } + + if (diff->has_incompatible_changes()) + { + 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) + { + t.start(); + std::cerr << "Computing changes ...\n"; + } + + if (diff->has_changes()) + { + if (opts.do_log) + { + t.stop(); + std::cerr << "changes computed!: "<< t << "\n"; + } + + if (opts.do_log) + { + t.start(); + std::cerr << "Computing report ...\n"; + } + + diff->report(cout); + + if (opts.do_log) + { + t.stop(); + std::cerr << "Report computed!:" << t << "\n"; + } + } } else status = abigail::tools_utils::ABIDIFF_ERROR;