-======
-abidw
-======
+====== abidw ======
abidw reads a shared library in `ELF`_ format and emits an XML
representation of its ABI to standard output. The emitted
taken into account. ABI artifacts matched by the suppression
specifications are suppressed from the output of this tool.
+
+ * ``--kmi-whitelist | -kaw`` <*path-to-whitelist*>
+
+ When analyzing a Linux kernel binary, this option points to the
+ white list of names of ELF symbols of functions and variables
+ which ABI must be written out. That white list is called a "
+ Kernel Module Interface white list". This is because for the
+ Kernel, we don't talk about the ABI; we rather talk about the
+ interface between the Kernel and its module. Hence the term
+ ``KMI`` rather than ``ABI``
+
+ Any other function or variable which ELF symbol are not present in
+ that white list will not be considered by the KMI writing process.
+
+ If this option is not provided -- thus if no white list is
+ provided -- then the entire KMI, that is, all publicly defined and
+ exported functions and global variables by the Linux Kernel
+ binaries is emitted.
+
* ``--headers-dir | --hd`` <headers-directory-path-1>
Specifies where to find the public headers of the first shared
shared_ptr<char> di_root_path;
string headers_dir;
vector<string> suppression_paths;
+ vector<string> kabi_whitelist_paths;
+ suppressions_type kabi_whitelist_supprs;
bool display_version;
bool check_alt_debug_info_path;
bool show_base_name_alt_debug_info_path;
"exported declarations\n"
<< " --no-linux-kernel-mode don't consider the input binary as "
"a Linux Kernel binary\n"
+ << " --kmi-whitelist|-w path to a linux kernel "
+ "abi whitelist\n"
<< " --abidiff compare the loaded ABI against itself\n"
<< " --annotate annotate the ABI artifacts emitted in the output\n"
<< " --stats show statistics about various internal stuff\n"
opts.suppression_paths.push_back(argv[j]);
++i;
}
+ else if (!strcmp(argv[i], "--kmi-whitelist")
+ || !strcmp(argv[i], "-w"))
+ {
+ int j = i + 1;
+ if (j >= argc)
+ return false;
+ opts.kabi_whitelist_paths.push_back(argv[j]);
+ ++i;
+ }
else if (!strcmp(argv[i], "--noout"))
opts.noout = true;
else if (!strcmp(argv[i], "--no-architecture"))
for (vector<string>::const_iterator i = opts.suppression_paths.begin();
i != opts.suppression_paths.end();
++i)
- if (!check_file(*i, cerr, "abidiff"))
+ if (!check_file(*i, cerr, "abidw"))
+ return false;
+
+ for (vector<string>::const_iterator i =
+ opts.kabi_whitelist_paths.begin();
+ i != opts.kabi_whitelist_paths.end();
+ ++i)
+ if (!check_file(*i, cerr, "abidw"))
return false;
return true;
/// @param opts the options where to get the suppression
/// specifications from.
static void
-set_suppressions(read_context& read_ctxt, const options& opts)
+set_suppressions(read_context& read_ctxt, options& opts)
{
suppressions_type supprs;
for (vector<string>::const_iterator i = opts.suppression_paths.begin();
if (suppr)
supprs.push_back(suppr);
+ using abigail::tools_utils::gen_suppr_spec_from_kernel_abi_whitelist;
+ for (vector<string>::const_iterator i =
+ opts.kabi_whitelist_paths.begin();
+ i != opts.kabi_whitelist_paths.end();
+ ++i)
+ gen_suppr_spec_from_kernel_abi_whitelist(*i, opts.kabi_whitelist_supprs);
+
add_read_context_suppressions(read_ctxt, supprs);
+ add_read_context_suppressions(read_ctxt, opts.kabi_whitelist_supprs);
}
int
set_show_stats(ctxt, opts.show_stats);
set_suppressions(ctxt, opts);
abigail::dwarf_reader::set_do_log(ctxt, opts.do_log);
+ if (!opts.kabi_whitelist_supprs.empty())
+ set_ignore_symbol_table(ctxt, true);
if (opts.check_alt_debug_info_path)
{
string alt_di_path;
abigail::dwarf_reader::status status =
abigail::dwarf_reader::has_alt_debug_info(ctxt,
- has_alt_di, alt_di_path);
+ has_alt_di,
+ alt_di_path);
if (status & abigail::dwarf_reader::STATUS_OK)
{
if (alt_di_path.empty())