• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 read ELF binaries containing DWARF, save them in XML corpus
9 /// files and diff the corpus files against reference XML corpus
10 /// files.
11 
12 #include <cstdlib>
13 #include <fstream>
14 #include <iostream>
15 #include <memory>
16 #include <string>
17 #include <vector>
18 #include "test-read-common.h"
19 #include "abg-dwarf-reader.h"
20 
21 using std::vector;
22 using std::string;
23 using std::cerr;
24 
25 using abigail::tests::read_common::InOutSpec;
26 using abigail::tests::read_common::test_task;
27 using abigail::tests::read_common::display_usage;
28 using abigail::tests::read_common::options;
29 using abigail::tests::get_build_dir;
30 
31 using abigail::xml_writer::SEQUENCE_TYPE_ID_STYLE;
32 using abigail::xml_writer::HASH_TYPE_ID_STYLE;
33 using abigail::xml_writer::type_id_style_kind;
34 using abigail::tools_utils::emit_prefix;
35 
36 using namespace abigail;
37 
38 static InOutSpec in_out_specs[] =
39 {
40   {
41     "data/test-read-dwarf/test0",
42     "",
43     "",
44     SEQUENCE_TYPE_ID_STYLE,
45     "data/test-read-dwarf/test0.abi",
46     "output/test-read-dwarf/test0.abi",
47     NULL,
48   },
49   {
50     "data/test-read-dwarf/test0",
51     "",
52     "",
53     HASH_TYPE_ID_STYLE,
54     "data/test-read-dwarf/test0.hash.abi",
55     "output/test-read-dwarf/test0.hash.abi",
56     NULL,
57   },
58   {
59     "data/test-read-dwarf/test1",
60     "",
61     "",
62     SEQUENCE_TYPE_ID_STYLE,
63     "data/test-read-dwarf/test1.abi",
64     "output/test-read-dwarf/test1.abi",
65     NULL,
66   },
67   {
68     "data/test-read-dwarf/test1",
69     "",
70     "",
71     HASH_TYPE_ID_STYLE,
72     "data/test-read-dwarf/test1.hash.abi",
73     "output/test-read-dwarf/test1.hash.abi",
74     NULL,
75   },
76   {
77     "data/test-read-dwarf/test2.so",
78     "",
79     "",
80     SEQUENCE_TYPE_ID_STYLE,
81     "data/test-read-dwarf/test2.so.abi",
82     "output/test-read-dwarf/test2.so.abi",
83     NULL,
84   },
85   {
86     "data/test-read-dwarf/test2.so",
87     "",
88     "",
89     HASH_TYPE_ID_STYLE,
90     "data/test-read-dwarf/test2.so.hash.abi",
91     "output/test-read-dwarf/test2.so.hash.abi",
92     NULL,
93   },
94   {
95     "data/test-read-common/test3.so",
96     "",
97     "",
98     SEQUENCE_TYPE_ID_STYLE,
99     "data/test-read-dwarf/test3.so.abi",
100     "output/test-read-dwarf/test3.so.abi",
101     NULL,
102   },
103   {
104     "data/test-read-common/test3.so",
105     "",
106     "",
107     HASH_TYPE_ID_STYLE,
108     "data/test-read-dwarf/test3.so.hash.abi",
109     "output/test-read-dwarf/test3.so.hash.abi",
110     NULL,
111   },
112   // suppress all except the main symbol of a group of aliases
113   {
114     "data/test-read-common/test3.so",
115     "data/test-read-common/test3-alias-1.suppr",
116     "",
117     HASH_TYPE_ID_STYLE,
118     "data/test-read-dwarf/test3-alias-1.so.hash.abi",
119     "output/test-read-dwarf/test3-alias-1.so.hash.abi",
120     NULL,
121   },
122   // suppress the main symbol of a group of aliases
123   {
124     "data/test-read-common/test3.so",
125     "data/test-read-common/test3-alias-2.suppr",
126     "",
127     HASH_TYPE_ID_STYLE,
128     "data/test-read-dwarf/test3-alias-2.so.hash.abi",
129     "output/test-read-dwarf/test3-alias-2.so.hash.abi",
130     NULL,
131   },
132   // suppress all except one non main symbol of a group of aliases
133   {
134     "data/test-read-common/test3.so",
135     "data/test-read-common/test3-alias-3.suppr",
136     "",
137     HASH_TYPE_ID_STYLE,
138     "data/test-read-dwarf/test3-alias-3.so.hash.abi",
139     "output/test-read-dwarf/test3-alias-3.so.hash.abi",
140     NULL,
141   },
142   // suppress all symbols of a group of aliases
143   {
144     "data/test-read-common/test3.so",
145     "data/test-read-common/test3-alias-4.suppr",
146     "",
147     HASH_TYPE_ID_STYLE,
148     "data/test-read-dwarf/test3-alias-4.so.hash.abi",
149     "output/test-read-dwarf/test3-alias-4.so.hash.abi",
150     NULL,
151   },
152   // suppress the main symbols with alias (function+variable) in .o file
153   {
154     "data/test-read-dwarf/test-suppressed-alias.o",
155     "data/test-read-dwarf/test-suppressed-alias.suppr",
156     "",
157     HASH_TYPE_ID_STYLE,
158     "data/test-read-dwarf/test-suppressed-alias.o.abi",
159     "output/test-read-dwarf/test-suppressed-alias.o.abi",
160     NULL,
161   },
162   {
163     "data/test-read-common/test4.so",
164     "",
165     "",
166     SEQUENCE_TYPE_ID_STYLE,
167     "data/test-read-dwarf/test4.so.abi",
168     "output/test-read-dwarf/test4.so.abi",
169     NULL,
170   },
171   {
172     "data/test-read-common/test4.so",
173     "",
174     "",
175     HASH_TYPE_ID_STYLE,
176     "data/test-read-dwarf/test4.so.hash.abi",
177     "output/test-read-dwarf/test4.so.hash.abi",
178     NULL,
179   },
180   {
181     "data/test-read-dwarf/test5.o",
182     "",
183     "",
184     SEQUENCE_TYPE_ID_STYLE,
185     "data/test-read-dwarf/test5.o.abi",
186     "output/test-read-dwarf/test5.o.abi",
187     NULL,
188   },
189   {
190     "data/test-read-dwarf/test5.o",
191     "",
192     "",
193     HASH_TYPE_ID_STYLE,
194     "data/test-read-dwarf/test5.o.hash.abi",
195     "output/test-read-dwarf/test5.o.hash.abi",
196     NULL,
197   },
198   {
199     "data/test-read-dwarf/test6.so",
200     "",
201     "",
202     SEQUENCE_TYPE_ID_STYLE,
203     "data/test-read-dwarf/test6.so.abi",
204     "output/test-read-dwarf/test6.so.abi",
205     NULL,
206   },
207   {
208     "data/test-read-dwarf/test6.so",
209     "",
210     "",
211     HASH_TYPE_ID_STYLE,
212     "data/test-read-dwarf/test6.so.hash.abi",
213     "output/test-read-dwarf/test6.so.hash.abi",
214     NULL,
215   },
216   {
217     "data/test-read-dwarf/test7.so",
218     "",
219     "",
220     SEQUENCE_TYPE_ID_STYLE,
221     "data/test-read-dwarf/test7.so.abi",
222     "output/test-read-dwarf/test7.so.abi",
223     NULL,
224   },
225   {
226     "data/test-read-dwarf/test7.so",
227     "",
228     "",
229     HASH_TYPE_ID_STYLE,
230     "data/test-read-dwarf/test7.so.hash.abi",
231     "output/test-read-dwarf/test7.so.hash.abi",
232     NULL,
233   },
234   {
235     "data/test-read-dwarf/test8-qualified-this-pointer.so",
236     "",
237     "",
238     SEQUENCE_TYPE_ID_STYLE,
239     "data/test-read-dwarf/test8-qualified-this-pointer.so.abi",
240     "output/test-read-dwarf/test8-qualified-this-pointer.so.abi",
241     NULL,
242   },
243   {
244     "data/test-read-dwarf/test8-qualified-this-pointer.so",
245     "",
246     "",
247     HASH_TYPE_ID_STYLE,
248     "data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi",
249     "output/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi",
250     NULL,
251   },
252   {
253     "data/test-read-dwarf/test9-pr18818-clang.so",
254     "",
255     "",
256     SEQUENCE_TYPE_ID_STYLE,
257     "data/test-read-dwarf/test9-pr18818-clang.so.abi",
258     "output/test-read-dwarf/test9-pr18818-clang.so.abi",
259     NULL,
260   },
261   {
262     "data/test-read-dwarf/test10-pr18818-gcc.so",
263     "",
264     "",
265     SEQUENCE_TYPE_ID_STYLE,
266     "data/test-read-dwarf/test10-pr18818-gcc.so.abi",
267     "output/test-read-dwarf/test10-pr18818-gcc.so.abi",
268     NULL,
269   },
270   {
271     "data/test-read-dwarf/test11-pr18828.so",
272     "",
273     "",
274     SEQUENCE_TYPE_ID_STYLE,
275     "data/test-read-dwarf/test11-pr18828.so.abi",
276     "output/test-read-dwarf/test11-pr18828.so.abi",
277     NULL,
278   },
279   {
280     "data/test-read-dwarf/test12-pr18844.so",
281     "",
282     "",
283     SEQUENCE_TYPE_ID_STYLE,
284     "data/test-read-dwarf/test12-pr18844.so.abi",
285     "output/test-read-dwarf/test12-pr18844.so.abi",
286     NULL,
287   },
288   {
289     "data/test-read-dwarf/test13-pr18894.so",
290     "",
291     "",
292     SEQUENCE_TYPE_ID_STYLE,
293     "data/test-read-dwarf/test13-pr18894.so.abi",
294     "output/test-read-dwarf/test13-pr18894.so.abi",
295     NULL,
296   },
297   {
298     "data/test-read-dwarf/test14-pr18893.so",
299     "",
300     "",
301     SEQUENCE_TYPE_ID_STYLE,
302     "data/test-read-dwarf/test14-pr18893.so.abi",
303     "output/test-read-dwarf/test14-pr18893.so.abi",
304     NULL,
305   },
306   {
307     "data/test-read-dwarf/test15-pr18892.so",
308     "",
309     "",
310     SEQUENCE_TYPE_ID_STYLE,
311     "data/test-read-dwarf/test15-pr18892.so.abi",
312     "output/test-read-dwarf/test15-pr18892.so.abi",
313     NULL,
314   },
315   {
316     "data/test-read-dwarf/test16-pr18904.so",
317     "",
318     "",
319     SEQUENCE_TYPE_ID_STYLE,
320     "data/test-read-dwarf/test16-pr18904.so.abi",
321     "output/test-read-dwarf/test16-pr18904.so.abi",
322     NULL,
323   },
324   {
325     "data/test-read-dwarf/test17-pr19027.so",
326     "",
327     "",
328     SEQUENCE_TYPE_ID_STYLE,
329     "data/test-read-dwarf/test17-pr19027.so.abi",
330     "output/test-read-dwarf/test17-pr19027.so.abi",
331     NULL,
332   },
333   {
334     "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so",
335     "",
336     "",
337     SEQUENCE_TYPE_ID_STYLE,
338     "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
339     "output/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
340     NULL,
341   },
342   {
343     "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so",
344     "",
345     "",
346     SEQUENCE_TYPE_ID_STYLE,
347     "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
348     "output/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
349     NULL,
350   },
351   {
352     "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so",
353     "",
354     "",
355     SEQUENCE_TYPE_ID_STYLE,
356     "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
357     "output/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
358     NULL,
359   },
360   {
361     "data/test-read-dwarf/test21-pr19092.so",
362     "",
363     "",
364     SEQUENCE_TYPE_ID_STYLE,
365     "data/test-read-dwarf/test21-pr19092.so.abi",
366     "output/test-read-dwarf/test21-pr19092.so.abi",
367     NULL,
368   },
369   {
370     "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so",
371     "",
372     "",
373     SEQUENCE_TYPE_ID_STYLE,
374     "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi",
375     "output/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi",
376     NULL,
377   },
378   {
379     "data/test-read-dwarf/libtest23.so",
380     "",
381     "",
382     SEQUENCE_TYPE_ID_STYLE,
383     "data/test-read-dwarf/libtest23.so.abi",
384     "output/test-read-dwarf/libtest23.so.abi",
385     NULL,
386   },
387   {
388     "data/test-read-dwarf/libtest24-drop-fns.so",
389     "data/test-read-dwarf/test24-drop-fns-0.suppr",
390     "",
391     SEQUENCE_TYPE_ID_STYLE,
392     "data/test-read-dwarf/libtest24-drop-fns.so.abi",
393     "output/test-read-dwarf/libtest24-drop-fns.so.abi",
394     NULL,
395   },
396   {
397     "data/test-read-dwarf/libtest24-drop-fns.so",
398     "",
399     "",
400     SEQUENCE_TYPE_ID_STYLE,
401     "data/test-read-dwarf/libtest24-drop-fns-2.so.abi",
402     "output/test-read-dwarf/libtest24-drop-fns-2.so.abi",
403     NULL,
404   },
405   {
406     "data/test-read-dwarf/PR22015-libboost_iostreams.so",
407     "",
408     "",
409     SEQUENCE_TYPE_ID_STYLE,
410     "data/test-read-dwarf/PR22015-libboost_iostreams.so.abi",
411     "output/test-read-dwarf/PR22015-libboost_iostreams.so.abi",
412     NULL,
413   },
414   {
415     "data/test-read-dwarf/PR22122-libftdc.so",
416     "",
417     "",
418     SEQUENCE_TYPE_ID_STYLE,
419     "data/test-read-dwarf/PR22122-libftdc.so.abi",
420     "output/test-read-dwarf/PR22122-libftdc.so.abi",
421     NULL,
422   },
423   {
424     "data/test-read-dwarf/PR24378-fn-is-not-scope.o",
425     "",
426     "",
427     SEQUENCE_TYPE_ID_STYLE,
428     "data/test-read-dwarf/PR24378-fn-is-not-scope.abi",
429     "output/test-read-dwarf/PR24378-fn-is-not-scope.abi",
430     NULL,
431   },
432 #if defined(HAVE_R_AARCH64_ABS64_MACRO) && defined(HAVE_R_AARCH64_PREL32_MACRO)
433   {
434     "data/test-read-dwarf/PR25007-sdhci.ko",
435     "",
436     "",
437     SEQUENCE_TYPE_ID_STYLE,
438     "data/test-read-dwarf/PR25007-sdhci.ko.abi",
439     "output/test-read-dwarf/PR25007-sdhci.ko.abi",
440     NULL,
441   },
442 #endif
443 #if defined HAVE_DW_FORM_strx
444   {
445     "data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0",
446     "",
447     "",
448     SEQUENCE_TYPE_ID_STYLE,
449     "data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
450     "output/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
451     NULL,
452   },
453 #endif
454   {
455     "data/test-read-dwarf/test25-bogus-binary.elf",
456     "",
457     "",
458     SEQUENCE_TYPE_ID_STYLE,
459     NULL,
460     NULL,
461     NULL,
462   },
463   {
464     "data/test-read-dwarf/test26-bogus-binary.elf",
465     "",
466     "",
467     SEQUENCE_TYPE_ID_STYLE,
468     NULL,
469     NULL,
470     NULL,
471   },
472   {
473     "data/test-read-dwarf/test27-bogus-binary.elf",
474     "",
475     "",
476     SEQUENCE_TYPE_ID_STYLE,
477     NULL,
478     NULL,
479     NULL,
480   },
481   {
482     "data/test-read-common/PR26261/PR26261-exe",
483     "",
484     "",
485     SEQUENCE_TYPE_ID_STYLE,
486     "data/test-read-dwarf/PR26261/PR26261-exe.abi",
487     "output/test-read-dwarf/PR26261/PR26261-exe.abi",
488     NULL,
489   },
490   {
491     "data/test-read-common/test-PR26568-1.o",
492     "",
493     "",
494     SEQUENCE_TYPE_ID_STYLE,
495     "data/test-read-dwarf/test-PR26568-1.o.abi",
496     "output/test-read-dwarf/test-PR26568-1.o.abi",
497     NULL,
498   },
499   {
500     "data/test-read-common/test-PR26568-2.o",
501     "",
502     "",
503     SEQUENCE_TYPE_ID_STYLE,
504     "data/test-read-dwarf/test-PR26568-2.o.abi",
505     "output/test-read-dwarf/test-PR26568-2.o.abi",
506     NULL,
507   },
508   {
509     "data/test-read-dwarf/test-libandroid.so",
510     "",
511     "",
512     HASH_TYPE_ID_STYLE,
513     "data/test-read-dwarf/test-libandroid.so.abi",
514     "output/test-read-dwarf/test-libandroid.so.abi",
515     NULL,
516   },
517   {
518     "data/test-read-common/PR27700/test-PR27700.o",
519     "",
520     "data/test-read-common/PR27700/pub-incdir",
521     HASH_TYPE_ID_STYLE,
522     "data/test-read-dwarf/PR27700/test-PR27700.abi",
523     "output/test-read-dwarf/PR27700/test-PR27700.abi",
524     NULL,
525   },
526   {
527     "data/test-read-dwarf/test-libaaudio.so",
528     "",
529     "",
530     HASH_TYPE_ID_STYLE,
531     "data/test-read-dwarf/test-libaaudio.so.abi",
532     "output/test-read-dwarf/test-libaaudio.so.abi",
533     NULL,
534   },
535   {
536     "data/test-read-dwarf/PR28584/PR28584-smv.clang.o",
537     "",
538     "",
539     SEQUENCE_TYPE_ID_STYLE,
540     "data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi",
541     "output/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi",
542     NULL,
543   },
544   {
545     "data/test-read-dwarf/PR29443-missing-xx.o",
546     "",
547     "",
548     SEQUENCE_TYPE_ID_STYLE,
549     "data/test-read-dwarf/PR29443-missing-xx.o.abi",
550     "output/test-read-dwarf/PR29443-missing-xx.o.abi",
551     NULL,
552   },
553   // DWARF fallback feature.
554   {
555     "data/test-read-dwarf/test-fallback.o",
556     "",
557     "",
558     SEQUENCE_TYPE_ID_STYLE,
559     "data/test-read-dwarf/test-fallback.abi",
560     "output/test-read-dwarf/test-fallback.abi",
561 #ifdef WITH_CTF
562     "--ctf",
563 #else
564     NULL,
565 #endif
566   },
567 
568   // This should be the last entry.
569   {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL}
570 };
571 
572 using abigail::suppr::suppression_sptr;
573 using abigail::suppr::suppressions_type;
574 using abigail::suppr::read_suppressions;
575 
576 /// Task specialization to perform DWARF tests.
577 struct test_task_dwarf : public test_task
578 {
579   test_task_dwarf(const InOutSpec &s,
580                 string& a_out_abi_base,
581                 string& a_in_elf_base,
582                 string& a_in_abi_base);
583   virtual void
584   perform();
585 
586   virtual
~test_task_dwarftest_task_dwarf587   ~test_task_dwarf()
588   {}
589 }; // end struct test_task_dwarf
590 
591 /// Constructor.
592 ///
593 /// Task to be executed for each DWARF test entry in @ref
594 /// abigail::tests::read_common::InOutSpec.
595 ///
596 /// @param InOutSpec the array containing set of tests.
597 ///
598 /// @param a_out_abi_base the output base directory for abixml files.
599 ///
600 /// @param a_in_elf_base the input base directory for object files.
601 ///
602 /// @param a_in_elf_base the input base directory for expected
603 /// abixml files.
test_task_dwarf(const InOutSpec & s,string & a_out_abi_base,string & a_in_elf_base,string & a_in_abi_base)604 test_task_dwarf::test_task_dwarf(const InOutSpec &s,
605                              string& a_out_abi_base,
606                              string& a_in_elf_base,
607                              string& a_in_abi_base)
608         : test_task(s, a_out_abi_base, a_in_elf_base, a_in_abi_base)
609   {}
610 
611 /// The thread function to execute each DWARF test entry in @ref
612 /// abigail::tests::read_common::InOutSpec.
613 ///
614 /// This reads the corpus into memory, saves it to disk, loads it
615 /// again and compares the new in-memory representation against the
616 void
perform()617 test_task_dwarf::perform()
618 {
619   set_in_elf_path();
620   set_in_suppr_spec_path();
621   set_in_public_headers_path();
622 
623   if (!set_out_abi_path()
624       || in_elf_path.empty())
625     return;
626 
627   string abidw = string(get_build_dir()) + "/tools/abidw";
628   string drop_private_types;
629   if (!in_public_headers_path.empty())
630     drop_private_types += "--headers-dir " + in_public_headers_path +
631       " --drop-private-types";
632   string type_id_style = "sequence";
633   if (spec.type_id_style == HASH_TYPE_ID_STYLE)
634     type_id_style = "hash";
635 
636   string cmd = abidw + " --no-architecture "
637     + " --type-id-style " + type_id_style
638     + " --no-corpus-path "
639     + drop_private_types + " " + in_elf_path
640     +" > " + out_abi_path;
641 
642   if (system(cmd.c_str()))
643     {
644       error_message = string("abidw failed:\n")
645 	+ "command was: '" + cmd + "'\n";
646       return;
647     }
648 
649   if (!(is_ok = run_abidw()))
650     return;
651 
652   if (!(is_ok = run_diff()))
653       return;
654 }
655 
656 /// Create a new DWARF instance for task to be execute by the testsuite.
657 ///
658 /// @param s the @ref abigail::tests::read_common::InOutSpec
659 /// tests container.
660 ///
661 /// @param a_out_abi_base the output base directory for abixml files.
662 ///
663 /// @param a_in_elf_base the input base directory for object files.
664 ///
665 /// @param a_in_abi_base the input base directory for abixml files.
666 ///
667 /// @return abigail::tests::read_common::test_task instance.
668 static test_task*
new_task(const InOutSpec * s,string & a_out_abi_base,string & a_in_elf_base,string & a_in_abi_base)669 new_task(const InOutSpec* s, string& a_out_abi_base,
670          string& a_in_elf_base, string& a_in_abi_base)
671 {
672   return new test_task_dwarf(*s, a_out_abi_base,
673                              a_in_elf_base, a_in_abi_base);
674 }
675 
676 int
main(int argc,char * argv[])677 main(int argc, char *argv[])
678 {
679   options opts;
680   if (!parse_command_line(argc, argv, opts))
681     {
682       if (!opts.wrong_option.empty())
683         emit_prefix(argv[0], cerr)
684           << "unrecognized option: " << opts.wrong_option << "\n";
685       display_usage(argv[0], cerr);
686       return 1;
687     }
688 
689   // compute number of tests to be executed.
690   const size_t num_tests = sizeof(in_out_specs) / sizeof(InOutSpec) - 1;
691 
692   return run_tests(num_tests, in_out_specs, opts, new_task);
693 }
694