@@ -268,6 +268,11 @@ Options
the --enable-debug-type-canonicalization option.
+ * ``--ctf``
+
+ Extract ABI information from CTF debug information, if present in
+ the given object.
+
* ``--annotate``
Annotate the ABIXML output with comments above most elements. The
@@ -26,6 +26,9 @@
#include "abg-tools-utils.h"
#include "abg-corpus.h"
#include "abg-dwarf-reader.h"
+#ifdef WITH_CTF
+#include "abg-ctf-reader.h"
+#endif
#include "abg-writer.h"
#include "abg-reader.h"
#include "abg-comparison.h"
@@ -64,10 +67,6 @@ using abigail::xml_writer::write_context_sptr;
using abigail::xml_writer::write_corpus;
using abigail::xml_reader::read_corpus_from_native_xml_file;
using abigail::xml_reader::create_native_xml_read_context;
-using abigail::dwarf_reader::read_context;
-using abigail::dwarf_reader::read_context_sptr;
-using abigail::dwarf_reader::read_corpus_from_elf;
-using abigail::dwarf_reader::create_read_context;
using namespace abigail;
struct options
@@ -99,6 +98,9 @@ struct options
bool corpus_group_for_linux;
bool show_stats;
bool noout;
+#ifdef WITH_CTF
+ bool use_ctf;
+#endif
bool show_locs;
bool abidiff;
#ifdef WITH_DEBUG_SELF_COMPARISON
@@ -133,6 +135,9 @@ struct options
corpus_group_for_linux(false),
show_stats(),
noout(),
+#ifdef WITH_CTF
+ use_ctf(false),
+#endif
show_locs(true),
abidiff(),
#ifdef WITH_DEBUG_SELF_COMPARISON
@@ -208,6 +213,9 @@ display_usage(const string& prog_name, ostream& out)
#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
<< " --debug-tc debug the type canonicalization process\n"
#endif
+#ifdef WITH_CTF
+ << " --ctf use CTF instead of DWARF in ELF files\n"
+#endif
<< " --annotate annotate the ABI artifacts emitted in the output\n"
<< " --stats show statistics about various internal stuff\n"
<< " --verbose show verbose messages about internal stuff\n";
@@ -306,6 +314,10 @@ parse_command_line(int argc, char* argv[], options& opts)
}
else if (!strcmp(argv[i], "--noout"))
opts.noout = true;
+#ifdef WITH_CTF
+ else if (!strcmp(argv[i], "--ctf"))
+ opts.use_ctf = true;
+#endif
else if (!strcmp(argv[i], "--no-architecture"))
opts.write_architecture = false;
else if (!strcmp(argv[i], "--no-corpus-path"))
@@ -462,7 +474,7 @@ maybe_check_header_files(const options& opts)
/// @param opts the options where to get the suppression
/// specifications from.
static void
-set_suppressions(read_context& read_ctxt, options& opts)
+set_suppressions(dwarf_reader::read_context& read_ctxt, options& opts)
{
suppressions_type supprs;
for (vector<string>::const_iterator i = opts.suppression_paths.begin();
@@ -498,8 +510,6 @@ set_suppressions(read_context& read_ctxt, options& opts)
///
/// @param env the environment the ABI artifacts are being created in.
///
-/// @param context the context of the ELF reading.
-///
/// @param opts the options of the program.
///
/// @return the exit code: 0 if everything went fine, non-zero
@@ -507,7 +517,6 @@ set_suppressions(read_context& read_ctxt, options& opts)
static int
load_corpus_and_write_abixml(char* argv[],
environment_sptr& env,
- read_context_sptr& context,
options& opts)
{
int exit_code = 0;
@@ -523,24 +532,90 @@ load_corpus_and_write_abixml(char* argv[],
env->debug_type_canonicalization_is_on(true);
#endif
- read_context& ctxt = *context;
+ // First of all, read a libabigail IR corpus from the file specified
+ // in OPTS.
corpus_sptr corp;
elf_reader::status s = elf_reader::STATUS_UNKNOWN;
- t.start();
- corp = read_corpus_from_elf(ctxt, s);
- t.stop();
- if (opts.do_log)
- emit_prefix(argv[0], cerr)
- << "read corpus from elf file in: " << t << "\n";
+#ifdef WITH_CTF
+ if (opts.use_ctf)
+ {
+ abigail::ctf_reader::read_context *ctxt
+ = abigail::ctf_reader::create_read_context (opts.in_file_path,
+ env.get());
- t.start();
- context.reset();
- t.stop();
+ assert (ctxt);
+ t.start();
+ corp = abigail::ctf_reader::read_corpus (ctxt, s);
+ t.stop();
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "read corpus from elf file in: " << t << "\n";
+ }
+ else
+#endif
+ {
+ dwarf_reader::read_context_sptr c
+ = abigail::dwarf_reader::create_read_context(opts.in_file_path,
+ opts.prepared_di_root_paths,
+ env.get(),
+ opts.load_all_types,
+ opts.linux_kernel_mode);
+ dwarf_reader::read_context& ctxt = *c;
+ set_drop_undefined_syms(ctxt, opts.drop_undefined_syms);
+ set_show_stats(ctxt, opts.show_stats);
+ set_suppressions(ctxt, opts);
+ abigail::dwarf_reader::set_do_log(ctxt, opts.do_log);
- if (opts.do_log)
- emit_prefix(argv[0], cerr)
- << "reset read context in: " << t << "\n";
+ if (opts.check_alt_debug_info_path)
+ {
+ bool has_alt_di = false;
+ string alt_di_path;
+ abigail::elf_reader::status status =
+ abigail::dwarf_reader::has_alt_debug_info(ctxt,
+ has_alt_di,
+ alt_di_path);
+ if (status & abigail::elf_reader::STATUS_OK)
+ {
+ if (alt_di_path.empty())
+ ;
+ else
+ {
+ cout << "found the alternate debug info file";
+ if (opts.show_base_name_alt_debug_info_path)
+ {
+ tools_utils::base_name(alt_di_path, alt_di_path);
+ cout << " '" << alt_di_path << "'";
+ }
+ cout << "\n";
+ }
+ return 0;
+ }
+ else
+ {
+ emit_prefix(argv[0], cerr)
+ << "could not find alternate debug info file\n";
+ return 1;
+ }
+ }
+ t.start();
+ corp = dwarf_reader::read_corpus_from_elf(ctxt, s);
+ t.stop();
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "read corpus from elf file in: " << t << "\n";
+
+ t.start();
+ c.reset();
+ t.stop();
+
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "reset read context in: " << t << "\n";
+ }
+
+ // If we couldn't create a corpus, emit some (hopefully) useful
+ // diagnostics and return and error.
if (!corp)
{
if (s == elf_reader::STATUS_DEBUG_INFO_NOT_FOUND)
@@ -580,122 +655,122 @@ load_corpus_and_write_abixml(char* argv[],
return 1;
}
- else
- {
- t.start();
- const write_context_sptr& write_ctxt
- = create_write_context(corp->get_environment(), cout);
- set_common_options(*write_ctxt, opts);
- t.stop();
- if (opts.do_log)
- emit_prefix(argv[0], cerr)
- << "created & initialized write context in: "
- << t << "\n";
+ // Now create a write context and write out an ABI XML description
+ // of the read corpus.
+ t.start();
+ const write_context_sptr& write_ctxt
+ = create_write_context(corp->get_environment(), cout);
+ set_common_options(*write_ctxt, opts);
+ t.stop();
- if (opts.abidiff)
- {
- // Save the abi in abixml format in a temporary file, read
- // it back, and compare the ABI of what we've read back
- // against the ABI of the input ELF file.
- temp_file_sptr tmp_file = temp_file::create();
- set_ostream(*write_ctxt, tmp_file->get_stream());
- write_corpus(*write_ctxt, corp, 0);
- tmp_file->get_stream().flush();
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "created & initialized write context in: "
+ << t << "\n";
+
+ if (opts.abidiff)
+ {
+ // Save the abi in abixml format in a temporary file, read
+ // it back, and compare the ABI of what we've read back
+ // against the ABI of the input ELF file.
+ temp_file_sptr tmp_file = temp_file::create();
+ set_ostream(*write_ctxt, tmp_file->get_stream());
+ write_corpus(*write_ctxt, corp, 0);
+ tmp_file->get_stream().flush();
#ifdef WITH_DEBUG_SELF_COMPARISON
- if (opts.debug_abidiff)
- {
- opts.type_id_file_path = tmp_file->get_path() + string(".typeid");
- write_canonical_type_ids(*write_ctxt, opts.type_id_file_path);
- }
+ if (opts.debug_abidiff)
+ {
+ opts.type_id_file_path = tmp_file->get_path() + string(".typeid");
+ write_canonical_type_ids(*write_ctxt, opts.type_id_file_path);
+ }
#endif
- xml_reader::read_context_sptr read_ctxt =
- create_native_xml_read_context(tmp_file->get_path(), env.get());
+ xml_reader::read_context_sptr read_ctxt =
+ create_native_xml_read_context(tmp_file->get_path(), env.get());
#ifdef WITH_DEBUG_SELF_COMPARISON
- if (opts.debug_abidiff
- && !opts.type_id_file_path.empty())
- load_canonical_type_ids(*read_ctxt, opts.type_id_file_path);
+ if (opts.debug_abidiff
+ && !opts.type_id_file_path.empty())
+ load_canonical_type_ids(*read_ctxt, opts.type_id_file_path);
#endif
- t.start();
- corpus_sptr corp2 =
- read_corpus_from_input(*read_ctxt);
- t.stop();
- if (opts.do_log)
- emit_prefix(argv[0], cerr)
- << "Read corpus in: " << t << "\n";
+ t.start();
+ corpus_sptr corp2 =
+ read_corpus_from_input(*read_ctxt);
+ t.stop();
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "Read corpus in: " << t << "\n";
- if (!corp2)
- {
- emit_prefix(argv[0], cerr)
- << "Could not read temporary XML representation of "
- "elf file back\n";
- return 1;
- }
+ if (!corp2)
+ {
+ emit_prefix(argv[0], cerr)
+ << "Could not read temporary XML representation of "
+ "elf file back\n";
+ return 1;
+ }
- diff_context_sptr ctxt(new diff_context);
- set_diff_context(ctxt);
- ctxt->show_locs(opts.show_locs);
- t.start();
- corpus_diff_sptr diff = compute_diff(corp, corp2, ctxt);
- t.stop();
- if (opts.do_log)
- emit_prefix(argv[0], cerr)
- << "computed diff in: " << t << "\n";
+ diff_context_sptr ctxt(new diff_context);
+ set_diff_context(ctxt);
+ ctxt->show_locs(opts.show_locs);
+ t.start();
+ corpus_diff_sptr diff = compute_diff(corp, corp2, ctxt);
+ t.stop();
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "computed diff in: " << t << "\n";
- bool has_error = diff->has_changes();
- if (has_error)
- {
- t.start();
- diff->report(cerr);
- t.stop();
- if (opts.do_log)
- emit_prefix(argv[0], cerr)
- << "emitted report in: " << t << "\n";
- return 1;
- }
- return 0;
- }
+ bool has_error = diff->has_changes();
+ if (has_error)
+ {
+ t.start();
+ diff->report(cerr);
+ t.stop();
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "emitted report in: " << t << "\n";
+ return 1;
+ }
+ return 0;
+ }
#ifdef WITH_DEBUG_SELF_COMPARISON
- if (opts.debug_abidiff
- && !opts.type_id_file_path.empty())
- remove(opts.type_id_file_path.c_str());
+ if (opts.debug_abidiff
+ && !opts.type_id_file_path.empty())
+ remove(opts.type_id_file_path.c_str());
#endif
- if (opts.noout)
- return 0;
+ if (opts.noout)
+ return 0;
- if (!opts.out_file_path.empty())
- {
- 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;
- }
- set_ostream(*write_ctxt, of);
- t.start();
- write_corpus(*write_ctxt, corp, 0);
- t.stop();
- if (opts.do_log)
- emit_prefix(argv[0], cerr)
- << "emitted abixml output in: " << t << "\n";
- of.close();
- return 0;
- }
- else
- {
- t.start();
- exit_code = !write_corpus(*write_ctxt, corp, 0);
- t.stop();
- if (opts.do_log)
- emit_prefix(argv[0], cerr)
- << "emitted abixml out in: " << t << "\n";
- }
+ if (!opts.out_file_path.empty())
+ {
+ 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;
+ }
+ set_ostream(*write_ctxt, of);
+ t.start();
+ write_corpus(*write_ctxt, corp, 0);
+ t.stop();
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "emitted abixml output in: " << t << "\n";
+ of.close();
+ return 0;
+ }
+ else
+ {
+ t.start();
+ exit_code = !write_corpus(*write_ctxt, corp, 0);
+ t.stop();
+ if (opts.do_log)
+ emit_prefix(argv[0], cerr)
+ << "emitted abixml out in: " << t << "\n";
}
return exit_code;
@@ -884,51 +959,7 @@ main(int argc, char* argv[])
int exit_code = 0;
if (tools_utils::is_regular_file(opts.in_file_path))
- {
- read_context_sptr c = create_read_context(opts.in_file_path,
- opts.prepared_di_root_paths,
- env.get(),
- opts.load_all_types,
- opts.linux_kernel_mode);
- read_context& ctxt = *c;
- set_drop_undefined_syms(ctxt, opts.drop_undefined_syms);
- set_show_stats(ctxt, opts.show_stats);
- set_suppressions(ctxt, opts);
- abigail::dwarf_reader::set_do_log(ctxt, opts.do_log);
-
- if (opts.check_alt_debug_info_path)
- {
- bool has_alt_di = false;
- string alt_di_path;
- abigail::elf_reader::status status =
- abigail::dwarf_reader::has_alt_debug_info(ctxt,
- has_alt_di,
- alt_di_path);
- if (status & abigail::elf_reader::STATUS_OK)
- {
- if (alt_di_path.empty())
- ;
- else
- {
- cout << "found the alternate debug info file";
- if (opts.show_base_name_alt_debug_info_path)
- {
- tools_utils::base_name(alt_di_path, alt_di_path);
- cout << " '" << alt_di_path << "'";
- }
- cout << "\n";
- }
- return 0;
- }
- else
- {
- emit_prefix(argv[0], cerr)
- << "could not find alternate debug info file\n";
- return 1;
- }
- }
- exit_code = load_corpus_and_write_abixml(argv, env, c, opts);
- }
+ exit_code = load_corpus_and_write_abixml(argv, env, opts);
else
exit_code = load_kernel_corpus_group_and_write_abixml(argv, env, opts);