Add --vmlinux{1,2} option to abidw and kmidiff

When using abidw to generate an abixml for a Linux Kernel build tree,
usually, people have to copy the vmlinux binary into the directory
where modules are, so that the tool can find it.  This --vmlinux
option helps to avoid doing that copy.

Simarly, when comparing two Linux Kernel build trees, --vmlinux1 and
--vmlinux2 are there to make the tool find the vmlinux binaries to
compare, independantly from the directories under which the modules
are to be found.

	* include/abg-tools-utils.h
	(build_corpus_group_from_kernel_dist_under): Add a new
	vmlinux_path parameter.
	* src/abg-tools-utils.cc (find_vmlinux_and_module_paths): Do not
	try to find a vmlinux binary if we already have the path to one.
	(build_corpus_group_from_kernel_dist_under): Add a new
	vmlinux_path parameter.
	* tools/abidw.cc (options::vmlinux): New data member.
	(display_usage): Add a usage string for --vmlinux
	(parse_command_line): Parse the new --vmlinux option.
	(load_kernel_corpus_group_and_write_abixml): Fix some return code
	when the function fails.  Verify the presence of the vmlinux
	binary that was given.  Adjust.
	* tools/kmidiff.cc (options::{vmlinux1, vmlinux2}): New data
	members.
	(display_usage): Add a usage string for --vmlinux1 and --vmlinux2.
	(parse_command_line):  Parse the --vmlinux1 and --vmlinux2
	options.
	(main): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2017-05-31 09:47:26 +02:00
parent 0b2e8ae156
commit b9a7e99dda
4 changed files with 95 additions and 22 deletions

View File

@ -251,9 +251,10 @@ std::tr1::shared_ptr<char>
make_path_absolute(const char*p);
corpus_group_sptr
build_corpus_group_from_kernel_dist_under(const string& root,
vector<string>& suppr_paths,
vector<string>& kabi_wl_paths,
build_corpus_group_from_kernel_dist_under(const string& root,
const string& vmlinux_path,
vector<string>& suppr_paths,
vector<string>& kabi_wl_paths,
suppr::suppressions_type& supprs,
bool verbose,
environment_sptr& env);

View File

@ -1459,7 +1459,7 @@ is_kernel_module(const FTSENT *entry)
///
/// @param vmlinux_path output parameter. This is set to the path
/// where the vmlinux binary is found. This is set iff the returns
/// true.
/// true and if this argument was empty to begin with.
///
/// @param module_paths output parameter. This is set to the paths of
/// the linux kernel module binaries.
@ -1476,7 +1476,7 @@ find_vmlinux_and_module_paths(const string& from,
if (!file_hierarchy)
return false;
bool found_vmlinux = false;
bool found_vmlinux = !vmlinux_path.empty();
FTSENT *entry;
while ((entry = fts_read(file_hierarchy)))
{
@ -1586,22 +1586,41 @@ get_binary_paths_from_kernel_dist(const string& dist_root,
/// The main corpus of the @ref corpus_group is made of the vmlinux
/// binary. The other corpora are made of the linux kernel binaries.
///
/// @param root the path of the directory under which vmlinux and its
/// kernel modules are to be found.
/// @param root the path of the directory under which the kernel
/// kernel modules are to be found. The vmlinux can also be found
/// somewhere under that directory, but if it's not in there, its path
/// can be set to the @p vmlinux_path parameter.
///
/// @param opts the options to use during the search.
/// @param vmlinux_path the path to the vmlinux binary, if that binary
/// is not under the @p root directory. If this is empty, then it
/// means the vmlinux binary is to be found under the @p root
/// directory.
///
/// @param suppr_paths the paths to the suppression specifications to
/// apply while loading the binaries.
///
/// @param kabi_wl_path the paths to the kabi whitelist files to take
/// into account while loading the binaries.
///
/// @param supprs the suppressions resulting from parsing the
/// suppression specifications at @p suppr_paths. This is set by this
/// function.
///
/// @param verbose true if the function has to emit some verbose
/// messages.
///
/// @param env the environment to create the corpus_group in.
corpus_group_sptr
build_corpus_group_from_kernel_dist_under(const string& root,
const string& vmlinux_path,
vector<string>& suppr_paths,
vector<string>& kabi_wl_paths,
suppressions_type& supprs,
bool verbose,
environment_sptr& env)
{
string vmlinux = vmlinux_path;
corpus_group_sptr result;
string vmlinux;
vector<string> modules;
string debug_info_root_path;

View File

@ -84,6 +84,7 @@ struct options
string out_file_path;
shared_ptr<char> di_root_path;
string headers_dir;
string vmlinux;
vector<string> suppression_paths;
vector<string> kabi_whitelist_paths;
suppressions_type kabi_whitelist_supprs;
@ -147,6 +148,8 @@ display_usage(const string& prog_name, ostream& out)
"abi whitelist\n"
<< " --linux-tree|--lt emit the ABI for the union of a "
"vmlinux and its modules\n"
<< " --vmlinux <path> the path to the vmlinux binary to consider to emit "
"the ABI of the union of vmlinux and its modules\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"
@ -224,6 +227,14 @@ parse_command_line(int argc, char* argv[], options& opts)
else if (!strcmp(argv[i], "--linux-tree")
|| !strcmp(argv[i], "--lt"))
opts.corpus_group_for_linux = true;
else if (!strcmp(argv[i], "--vmlinux"))
{
int j = i + 1;
if (j >= argc)
return false;
opts.vmlinux = argv[j];
++i;
}
else if (!strcmp(argv[i], "--noout"))
opts.noout = true;
else if (!strcmp(argv[i], "--no-architecture"))
@ -489,39 +500,49 @@ load_kernel_corpus_group_and_write_abixml(char* argv[],
options& opts)
{
if (!(tools_utils::is_dir(opts.in_file_path) && opts.corpus_group_for_linux))
return 0;
return 1;
int exit_code = 0;
if (!opts.vmlinux.empty())
if (!abigail::tools_utils::check_file(opts.vmlinux, cerr, argv[0]))
return 1;
suppressions_type supprs;
corpus_group_sptr group =
build_corpus_group_from_kernel_dist_under(opts.in_file_path,
opts.vmlinux,
opts.suppression_paths,
opts.kabi_whitelist_paths,
supprs, opts.do_log, env);
if (!group)
return exit_code;
return 1;
if (!opts.write_architecture)
group->set_architecture_name("");
if (!opts.write_corpus_path)
group->set_path("");
if (!opts.out_file_path.empty())
if (!opts.noout)
{
ofstream of(opts.out_file_path.c_str(), std::ios_base::trunc);
if (!of.is_open())
if (!opts.out_file_path.empty())
{
emit_prefix(argv[0], cerr)
<< "could not open output file '"
<< opts.out_file_path << "'\n";
return 1;
ofstream of(opts.out_file_path.c_str(), std::ios_base::trunc);
if (!of.is_open())
{
emit_prefix(argv[0], cerr)
<< "could not open output file '"
<< opts.out_file_path << "'\n";
return 1;
}
exit_code = !xml_writer::write_corpus_group(group, 0, of,
opts.annotate);
}
exit_code = !xml_writer::write_corpus_group(group, 0, of, opts.annotate);
else
exit_code = !xml_writer::write_corpus_group(group, 0, cout,
opts.annotate);
}
else
exit_code = !xml_writer::write_corpus_group(group, 0, cout, opts.annotate);
return exit_code;
}

View File

@ -75,6 +75,8 @@ struct options
string wrong_option;
string kernel_dist_root1;
string kernel_dist_root2;
string vmlinux1;
string vmlinux2;
vector<string> kabi_whitelist_paths;
vector<string> suppression_paths;
suppressions_type read_time_supprs;
@ -97,11 +99,13 @@ static void
display_usage(const string& prog_name, ostream& out)
{
emit_prefix(prog_name, out)
<< "usage: " << prog_name << " [options] kernel-package1 kernel-package2\n"
<< "usage: " << prog_name << " [options] kernel-modules-dir1 kernel-modules-dir2\n"
<< " where options can be:\n"
<< " --help|-h display this message\n"
<< " --version|-v display program version information and exit\n"
<< " --verbose display verbose messages\n"
<< " --vmlinux1|--l1 <path> the path to the first vmlinux"
<< " --vmlinux2|--l2 <path> the path to the second vmlinux"
<< " --suppressions|--suppr <path> specify a suppression file\n"
<< " --kmi-whitelist|-w <path> path to a kernel module interface "
"whitelist\n";
@ -149,6 +153,32 @@ parse_command_line(int argc, char* argv[], options& opts)
opts.display_usage = true;
return true;
}
else if (!strcmp(argv[i], "--vmlinux1")
|| !strcmp(argv[i], "--l1"))
{
int j = i + 1;
if (j >= argc)
{
opts.missing_operand = true;
opts.wrong_option = argv[i];
return false;
}
opts.vmlinux1 = argv[j];
++i;
}
else if (!strcmp(argv[i], "--vmlinux2")
|| !strcmp(argv[i], "--l2"))
{
int j = i + 1;
if (j >= argc)
{
opts.missing_operand = true;
opts.wrong_option = argv[i];
return false;
}
opts.vmlinux2 = argv[j];
++i;
}
else if (!strcmp(argv[i], "--kmi-whitelist")
|| !strcmp(argv[i], "-w"))
{
@ -316,6 +346,7 @@ main(int argc, char* argv[])
{
group1 =
build_corpus_group_from_kernel_dist_under(opts.kernel_dist_root1,
opts.vmlinux1,
opts.suppression_paths,
opts.kabi_whitelist_paths,
opts.read_time_supprs,
@ -337,6 +368,7 @@ main(int argc, char* argv[])
{
group2 =
build_corpus_group_from_kernel_dist_under(opts.kernel_dist_root2,
opts.vmlinux2,
opts.suppression_paths,
opts.kabi_whitelist_paths,
opts.read_time_supprs,