1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2022 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 using abigail::tests::emit_test_status_and_update_counters;
24 using abigail::tests::emit_test_summary;
25
26 /// Specifies where a test should get its inputs from, and where it
27 /// should write its output to.
28 struct InOutSpec
29 {
30 const char* in_elf_path;
31 const char* in_abi_path;
32 const char* in_report_path;
33 const char* out_report_path;
34 };
35
36 InOutSpec in_out_specs[] =
37 {
38 {
39 "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1",
40 "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi",
41 "data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1-report-0.txt",
42 "output/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1-report-0.txt",
43 },
44 {
45 "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0",
46 "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi",
47 "data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0-report-0.txt",
48 "output/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0-report-0.txt"
49 },
50 // This should be the last entry
51 {0, 0, 0, 0}
52 };
53
54 int
main()55 main()
56 {
57 using abigail::tests::get_src_dir;
58 using abigail::tests::get_build_dir;
59 using abigail::tools_utils::ensure_parent_dir_created;
60 using abigail::tools_utils::abidiff_status;
61
62 unsigned int total_count = 0, passed_count = 0, failed_count = 0;
63
64 string in_elf_path, in_abi_path,
65 abidiff, cmd, diff_cmd, ref_diff_report_path, out_diff_report_path;
66
67 for (InOutSpec* s = in_out_specs; s->in_elf_path; ++s)
68 {
69 bool is_ok = true;
70 in_elf_path = string(get_src_dir()) + "/tests/" + s->in_elf_path;
71 in_abi_path = string(get_src_dir()) + "/tests/"+ s->in_abi_path;
72 ref_diff_report_path =
73 string(get_src_dir()) + "/tests/" + s->in_report_path;
74 out_diff_report_path =
75 string(get_build_dir()) + "/tests/" + s->out_report_path;
76
77 if (!ensure_parent_dir_created(out_diff_report_path))
78 {
79 cerr << "could not create parent directory for "
80 << out_diff_report_path;
81 is_ok = false;
82 continue;
83 }
84
85 abidiff = string(get_build_dir()) + "/tools/abidiff";
86 cmd = abidiff + " --no-default-suppression --no-architecture "
87 + in_elf_path + " " + in_abi_path;
88 cmd += " > " + out_diff_report_path;
89
90 bool abidiff_ok = true;
91 int code = system(cmd.c_str());
92 if (!WIFEXITED(code))
93 {
94 cerr << "test failed: '" << cmd << "'\n";
95 abidiff_ok = false;
96 }
97 else
98 {
99 abidiff_status status =
100 static_cast<abidiff_status>(WEXITSTATUS(code));
101 if (abigail::tools_utils::abidiff_status_has_error(status))
102 {
103 cerr << "test failed: '" << cmd << "'\n";
104 abidiff_ok = false;
105 }
106 }
107 if (abidiff_ok)
108 {
109 diff_cmd = "diff -u " + ref_diff_report_path
110 + " " + out_diff_report_path;
111 if (system(diff_cmd.c_str()))
112 is_ok = false;
113 }
114 else
115 is_ok = false;
116
117 emit_test_status_and_update_counters(is_ok, cmd, passed_count,
118 failed_count, total_count);
119 }
120
121 emit_test_summary(total_count, passed_count, failed_count);
122
123 return failed_count;
124 }
125