1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2020 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 /// @file compare the ABI of an an elf binary and an abixml file.
9 
10 #include <sys/wait.h>
11 #include <string>
12 #include <fstream>
13 #include <iostream>
14 #include <cstdlib>
15 #include "abg-tools-utils.h"
16 #include "test-utils.h"
17 
18 
19 using std::string;
20 using std::ofstream;
21 using std::cerr;
22 using abigail::tests::get_build_dir;
23 
24 /// Specifies where a test should get its inputs from, and where it
25 /// should write its output to.
26 struct InOutSpec
27 {
28   const char* in_elf_path;
29   const char* in_abi_path;
30   const char* in_report_path;
31   const char* out_report_path;
32 };
33 
34 InOutSpec in_out_specs[] =
35 {
36   {
37     "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1",
38     "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi",
39     "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1-report-0.txt",
40     "output/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1-report-0.txt",
41   },
42   {
43     "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0",
44     "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi",
45     "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0-report-0.txt",
46     "output/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0-report-0.txt"
47   },
48   // This should be the last entry
49   {0, 0, 0, 0}
50 };
51 
52 int
main()53 main()
54 {
55   using abigail::tests::get_src_dir;
56   using abigail::tests::get_build_dir;
57   using abigail::tools_utils::ensure_parent_dir_created;
58   using abigail::tools_utils::abidiff_status;
59 
60   bool is_ok = true;
61   string in_elf_path, in_abi_path,
62     abidiff, cmd, ref_diff_report_path, out_diff_report_path;
63 
64   for (InOutSpec* s = in_out_specs; s->in_elf_path; ++s)
65     {
66       in_elf_path = string(get_src_dir()) + "/tests/" + s->in_elf_path;
67       in_abi_path = string(get_src_dir()) + "/tests/"+ s->in_abi_path;
68       ref_diff_report_path =
69 	string(get_src_dir()) + "/tests/" + s->in_report_path;
70       out_diff_report_path =
71 	string(get_build_dir()) + "/tests/" + s->out_report_path;
72 
73       if (!ensure_parent_dir_created(out_diff_report_path))
74 	{
75 	  cerr << "could not create parent directory for "
76 	       << out_diff_report_path;
77 	  is_ok = false;
78 	  continue;
79 	}
80 
81       abidiff = string(get_build_dir()) + "/tools/abidiff";
82       cmd = abidiff + " --no-default-suppression --no-architecture "
83 	+ in_elf_path + " " + in_abi_path;
84       cmd += " > " + out_diff_report_path;
85 
86       bool abidiff_ok = true;
87       int code = system(cmd.c_str());
88       if (!WIFEXITED(code))
89 	abidiff_ok = false;
90       else
91 	{
92 	  abidiff_status status =
93 	    static_cast<abidiff_status>(WEXITSTATUS(code));
94 	  if (abigail::tools_utils::abidiff_status_has_error(status))
95 	    abidiff_ok = false;
96 	}
97       if (abidiff_ok)
98 	{
99 	  cmd = "diff -u " + ref_diff_report_path
100 	    + " " + out_diff_report_path;
101 	  if (system(cmd.c_str()))
102 	    is_ok = false;
103 	}
104       else
105 	is_ok = false;
106     }
107 
108   return !is_ok;
109 }
110