• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2023 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 #include <cstring>
9 #include <iostream>
10 #include "abg-comparison.h"
11 #include "abg-dwarf-reader.h"
12 
13 using std::cout;
14 using std::cerr;
15 using std::ostream;
16 using std::string;
17 
18 using abigail::comparison::diff;
19 using abigail::comparison::diff_sptr;
20 using abigail::ir::environment;
21 using abigail::ir::environment_sptr;
22 using abigail::comparison::corpus_diff_sptr;
23 using abigail::comparison::compute_diff;
24 using abigail::comparison::print_diff_tree;
25 using abigail::comparison::apply_filters;
26 using namespace abigail;
27 
28 struct options
29 {
30   bool display_help;
31   bool categorize_redundancy;
32   bool apply_filters;
33   string elf1;
34   string elf2;
35 
optionsoptions36   options()
37     : display_help(false),
38       categorize_redundancy(false),
39       apply_filters(false)
40   {}
41 };
42 
43 static void
display_help(const string & prog_name,ostream & out)44 display_help(const string& prog_name,
45 	     ostream& out)
46 {
47   out << prog_name << " [options] <elf lib1> <elf lib2>\n"
48       << " where options can be:\n"
49       << " --categorize-redundancy  categorize diff node redundancy\n"
50       << " --apply-filters  apply the generic categorization filters\n"
51       << " --help  display this message\n";
52 }
53 
54 static bool
parse_command_line(int argc,char * argv[],options & opts)55 parse_command_line(int argc, char* argv[], options& opts)
56 {
57     if (argc < 2)
58     return false;
59 
60   for (int i = 1; i < argc; ++i)
61     {
62       if (argv[i][0] != '-')
63 	{
64 	  if (opts.elf1.empty())
65 	    opts.elf1 = argv[i];
66 	  else if (opts.elf2.empty())
67 	    opts.elf2 = argv[i];
68 	  else
69 	    return false;
70 	}
71       else if (!strcmp(argv[i], "--help"))
72 	opts.display_help = true;
73       else if (!strcmp(argv[i], "--categorize-redundancy"))
74 	opts.categorize_redundancy = true;
75       else if (!strcmp(argv[i], "--apply-filters"))
76 	opts.apply_filters = true;
77       else
78 	return false;
79     }
80   return true;
81 }
82 
83 int
main(int argc,char * argv[])84 main(int argc, char* argv[])
85 {
86   options opts;
87 
88   if (!parse_command_line(argc, argv, opts))
89     {
90       cerr << "unrecognized option\n"
91 	"try the --help option for more information\n";
92       return 1;
93     }
94 
95   if (opts.display_help)
96     {
97       display_help(argv[0], cout);
98       return 0;
99     }
100 
101   if (!opts.elf1.empty() && !opts.elf2.empty())
102     {
103       fe_iface::status c1_status, c2_status;
104       corpus_sptr c1, c2;
105 
106       environment env;
107       vector<char**> di_roots;
108       c1 = dwarf::read_corpus_from_elf(opts.elf1, di_roots, env,
109 				       /*load_all_types=*/false,
110 				       c1_status);
111       if (c1_status != fe_iface::STATUS_OK)
112 	{
113 	  cerr << "Failed to read elf file " << opts.elf1 << "\n";
114 	  return 1;
115 	}
116 
117       c2 = dwarf::read_corpus_from_elf(opts.elf2, di_roots, env,
118 				       /*load_all_types=*/false,
119 				       c2_status);
120       if (c2_status != fe_iface::STATUS_OK)
121 	{
122 	  cerr << "Failed to read elf file " << opts.elf2 << "\n";
123 	  return 1;
124 	}
125 
126       corpus_diff_sptr diff = compute_diff(c1, c2);
127       if (!diff)
128 	{
129 	  cerr << "Could not compute ABI diff between elf files "
130 	       << opts.elf1 << " and " << opts.elf2;
131 	  return 1;
132 	}
133 
134       if (opts.categorize_redundancy)
135 	categorize_redundancy(diff);
136 
137       if (opts.apply_filters)
138 	apply_filters(diff);
139 
140       print_diff_tree(diff, cout);
141       return 0;
142     }
143   return 1;
144 }
145 
146 void
print_diff_tree(abigail::comparison::corpus_diff * diff_tree)147 print_diff_tree(abigail::comparison::corpus_diff* diff_tree)
148 {
149   print_diff_tree(diff_tree, std::cout);
150 }
151 
152 void
print_diff_tree(abigail::comparison::corpus_diff_sptr diff_tree)153 print_diff_tree(abigail::comparison::corpus_diff_sptr diff_tree)
154 {
155   print_diff_tree(diff_tree, std::cout);
156 }
157