mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-03 07:52:04 +00:00
74c4f1e0b6
2705 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Aleksei Vetrov
|
dbd6db1822 |
symtab: fix getting CRC in relocatable modules
In ELF with ET_REL type symbol value holds not absolute but relative to section value. This patch applies adjustment to the address, used in CRC value extraction. * src/abg-elf-helpers.cc (get_crc_for_symbol): Rename crc_symbol_value to crc_symbol_address and adjust it for relocatable ELF types. Signed-off-by: Aleksei Vetrov <vvvvvv@google.com> |
||
Dodji Seketeli
|
bea35c9800 |
Update CTF's ctf_dict_t detection
As ctf_dict_t can be an opaque type depending on the version of ctf-api.h, using AC_CHECK_TYPE won't work to detect it because that macro invokes sizeof(ctf_dict_t). With this change, we don't require that ctf_dict_t be fully defined. * configure.ac: Use AC_COMPILE_IFELSE to try and compile a code snippet that doesn't need that ctf_dict_t be fully defined. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
554fea5e87 |
Better detect suitable libctf version
On some el9 distros, the version of libctf installed might not have all the necessary features for the libabigail CTF reader, leading to compilation errors due to missing types from the ctf-api.h header file. For instance, the ctf-api.h on some of those distros lacks the definition of the type struct ctf_dict_t. This patch adds a configure test for that struct and disables the CTF support if that type is absent. * configure.ac: If the "struct ctf_dict_t" type is not present in the version of ctf-api.h that is present, then switch the support of CTF off. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Giuliano Procida
|
e6beace109 |
DWARF reader: avoid C++20 operator!= overload ambiguity
C++20 automatically generates overloads for certain comparison operators based on others and this can create ambiguity with older code. The type expr_result has various operators defined and comparing expr_result != int becomes ambiguous. This change just avoids this comparison by extracting the underlying value, rather than making changes to the type itself. There should be no change in behaviour and no tests are affected. * (src/abg-dwarf-reader.cc) op_is_control_flow: In the DW_OP_bra case, when testing the popped value, use the expr_result's const_value explicitly. Signed-off-by: Giuliano Procida <gprocida@google.com> |
||
Dodji Seketeli
|
00e3ac8937 |
btf-reader: Use abigail::ir::canonicalize_types to canonicalize types
In the btf::reader::canonicalize_types function, this patch now uses the abigail::ir::canonicalize_types() function to canonicalize types, just like the other front-ends. The advantage of this function is that it can perform some sanity checking for type canonicalization that might be useful for later debugging purposes. * src/abg-btf-reader.cc (btf::reader::canonicalize_types): Use the abigail::ir::canonicalize_types function from abg-ir-priv.h file to canonicalize types. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
a0cc439b28 |
Update the copyright notice for the BTF reader
* include/abg-btf-reader.h: Update the copyright notice for 2023. * src/abg-btf-reader.cc: Likewise. * tests/test-read-btf.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
12641b1130 |
Add support for BTF
This adds support for the BTF debug information format. It provides a new BTF front-end which can be instantiated by the function tools::create_best_elf_based_reader(). For now, the BTF front-end supports the basic types (integers, pointers, qualified types, typedefs, struct and unions and function pointers) for functions and variables as emitted for the C language by GCC. It seems to be able to support the BTF debug information emitted for the vmlinux kernel by the pahole tool as well. When configured with the --enable-btf option, the WITH_BTF pre-processor macro is defined, enabling the BTF support. That option is turned on by default if the /usr/include/bpf/btf.h header is found on the system. To disable this, one can use the --disable-btf option. The abidw and abidiff programs have been adapted to use the BTF front-end when provided with the '--btf' option, or if BTF debug information is the only one present in the binary. * configure.ac: If the header /usr/include/bpf/btf.h exists, then define the WITH_BTF pre-processor macro, unless --disable-btf was provided. * doc/manuals/abidiff.rst: Document the new --btf option. * doc/manuals/abidw.rst: Likewise. * doc/manuals/kmidiff.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-btf-reader.h: New header file. Contains the declaration of the new btf::reader class. * src/abg-btf-reader.cc: New source file. Contains the definitions of the new btf::reader class. * include/Makefile.am: Add the new include/abg-btf-reader.h header file to source distribution. * include/abg-corpus.h (enum origin): Add a new BTF_ORIGIN enumerator. * include/abg-tools-utils.h (file_has_btf_debug_info): Declare new function. * src/abg-tools-utils.cc (file_has_btf_debug_info): Define new function. (create_best_elf_based_reader): Adapt to support BTF input. If the user requested the BTF front-end, instantiate it. Otherwise, if the input file has only BTF debug info, instantiate the BTF front end. * include/abg-elf-reader.h (elf::reader::find_btf_section): Declare new member function. (elf::reader::{function, variable}_symbol_is_exported): Add new overloads. * src/abg-elf-reader.cc (reader::priv::btf_section): New data member. (reader::find_btf_section): Define new member function. * src/Makefile.am: Add the new abg-ctf-reader.cc file to source distribution. * tools/abidw.cc (options::use_btf): New data member. (display_usage): Add a help string for the new --btf option. (parse_command_line): Support the new --btf option. (load_corpus_and_write_abixml): If the user asked to use the btf front-end then use that one. * tools/abidiff.cc (options::use_btf): New data member. (options::options): Initialize it. (display_usage):: Add a help string to the new --btf options. (parse_command_line): Support the new --btf options. (main): If the user asked to use the btf front-end, then use that one. * tools/abidw.cc (options::use_btf): New data member. (options::options): Initialize it. (parse_command_line): Add a help string to the new --btf options. (load_corpus_and_write_abixml): If the user asked to use the btf front-end, then use that one. * tools/kmidiff.cc (options::use_btf): New data member. (options::options): Initialize it. (display_usage): Add a help string to the new --btf options. (parse_command_line): Add a help string to the new --btf options. (main): If the user asked to use the btf front-end, then use that one. * tools/abipkgdiff.cc (options::use_btf): New data member. (options::options): Initialize it. (display_usage): Add a help string to the new --btf options. (parse_command_line): Add a help string to the new --btf options. (compare, compare_to_self) (compare_prepared_linux_kernel_packages): If the user asked to use the btf front-end, then use that one. * tests/data/test-read-btf/test{0,1}.o: New binary test input file. * tests/data/test-read-btf/test{0,1}.c: Source code of the binary input file above. * tests/data/test-read-btf/test{0,1}.o.abi: Reference ABIXML output. * tests/data/test-abidiff-exit/btf/test0-report-{1,2}.txt: New test reference output. * tests/data/test-abidiff-exit/btf/test0-v{0,1}.o: New binary test input. * tests/data/test-abidiff-exit/btf/test0-v{0,1}.c: The source files of the binary inputs above. * tests/test-read-btf.cc: New test file to run the btf/abixml tests. * tests/Makefile.am: Add the new test files to the source distribution. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
5d97da9755 |
configure: Enable the CTF front-end by default
The patch enables the CTF front-end by default, if the ctf.h header file and its associated libctf.so shared library are detected at configure time. That front-end can of course still be disabled by using the --disable-ctf option. * configure.ac: If --disable-ctf hasn't been passed, test for the presence of ctf.h and then for libctf.so. If both are found then enable the CTF front end. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Petr Pavlu
|
250346cace |
abidiff: Fix handling of linux-kernel-mode
This fixes |
||
Dodji Seketeli
|
24a219d905 |
fix comparing array subrange DIEs
When looking at something else in the DWARF reader, I noticed that the DIE comparison algorithm for DW_TAG_subprogram DIEs was not taking into account non-set DW_AT_upper_bound attributes. Fixed thus. * src/abg-dwarf-reader.cc (compare_dies): For DW_TAG_subprogram, non-set DW_AT_{lower,upper}_bound is not the same as when they are set to zero. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
e02d3b85e3 |
Bug 29811 - Better categorize harmless unknown array size changes
Let's compile the code snippet: $ echo "unsigned int is_basic_table[];" | gcc -g -c -o test-v0.o -x c - Let's see what abidw sees from it: $ abidw test-v0.o | cat -n 1 <abi-corpus version='2.1' path='test-v0.o' architecture='elf-amd-x86_64'> 2 <elf-variable-symbols> 3 <elf-symbol name='is_basic_table' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 4 </elf-variable-symbols> 5 <abi-instr address-size='64' path='<stdin>' comp-dir-path='/home/dodji/git/libabigail/PR29811/prtests' language='LANG_C11'> 6 <type-decl name='unsigned int' size-in-bits='32' id='type-id-1'/> 7 <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='infinite' id='type-id-2'> 8 <subrange length='infinite' id='type-id-3'/> 9 </array-type-def> 10 <var-decl name='is_basic_table' type-id='type-id-2' mangled-name='is_basic_table' visibility='default' filepath='/home/dodji/git/libabigail/PR29811/prtests/<stdin>' line='1' column='1' elf-symbol-id='is_basic_table'/> 11 </abi-instr> 12 </abi-corpus> See how the at line 7, the array type of ID 'type-id-2' has an unknown size. This is the type of the 'is_basic_table' variable defined at line 10. Note however that the symbol size of the is_basic_table symbol is 4 bytes (32 bits). Now, let's compile a similar code where the is_basic_table variable is now initialized: $ echo "unsigned int is_basic_table[] = {0};" | gcc -g -c -o test-v1.o -x c - $ $ abidw test-v1.o | cat -n 1 <abi-corpus version='2.1' path='test-v1.o' architecture='elf-amd-x86_64'> 2 <elf-variable-symbols> 3 <elf-symbol name='is_basic_table' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 4 </elf-variable-symbols> 5 <abi-instr address-size='64' path='<stdin>' comp-dir-path='/home/dodji/git/libabigail/PR29811/prtests' language='LANG_C11'> 6 <type-decl name='unsigned int' size-in-bits='32' id='type-id-1'/> 7 <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='32' id='type-id-2'> 8 <subrange length='1' type-id='type-id-3' id='type-id-4'/> 9 </array-type-def> 10 <type-decl name='unsigned long int' size-in-bits='64' id='type-id-3'/> 11 <var-decl name='is_basic_table' type-id='type-id-2' mangled-name='is_basic_table' visibility='default' filepath='/home/dodji/git/libabigail/PR29811/prtests/<stdin>' line='1' column='1' elf-symbol-id='is_basic_table'/> 12 </abi-instr> 13 </abi-corpus> Now, see like at line 7, the array type is now of 4 bytes (32 bits). Note that the size of is_basic_table is still 32 bits. Normally, abidiff-ing test-v0 and test-v1 should tell us that the two versions of the is_basic_table variable are compatible because fundamentally the structure and the size of the ELF symbol is_basic_table hasn't changed, even if in the first case, it's an array of unknown size. It's ELF symbol size was already 32 bits. Here is what abidiff says: $ abidiff test-v0.o test-v1.o Functions changes summary: 0 Removed, 0 Changed, 0 Added function Variables changes summary: 0 Removed, 1 Changed, 0 Added variable 1 Changed variable: [C] 'unsigned int is_basic_table[]' was changed to 'unsigned int is_basic_table[1]' at <stdin>:1:1: type of variable changed: type name changed from 'unsigned int[]' to 'unsigned int[1]' array type size changed from infinity to 32 array type subrange 1 changed length from infinity to 1 $ This is because the comparison engine doesn't recognize we are looking at a type change that is harmless because the ELF size hasn't changed and because this is an array of one dimension so fundamentally, the "meaning" of the type of the array hasn't fundamentally changed for ABI-related purposes. This patch teaches the diff node categorizer to recognise that we are in a case where the (one dimension) array of unknown size actually is the type of an array which symbol size is 4 bytes. In the second case, the one dimension array has a size of 4 bytes, just as its ELF symbol size. The diff node categorizer then categorizes the diff node into the existing category BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY, which is a harmless diff node category. Everything then falls into place to filter the change out. Also, the patch adapts the diff reporter to better describe this type of harmless array variable type changes. The output then becomes: $ abidiff test-v0.o test-v1.o Functions changes summary: 0 Removed, 0 Changed, 0 Added function Variables changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added variable $ The change is filtered out. To have details about the change that has been filtered out, one has to use "--harmless" option: $ abidiff --harmless test-v0.o test-v1.o Functions changes summary: 0 Removed, 0 Changed, 0 Added function Variables changes summary: 0 Removed, 1 Changed, 0 Added variable 1 Changed variable: [C] 'unsigned int is_basic_table[]' was changed to 'unsigned int is_basic_table[1]' at <stdin>:1:1: size of variable symbol ( 32 (in bits)) hasn't changed but it does have a harmless type change type of variable changed: type name changed from 'unsigned int[]' to 'unsigned int[1]' array type size changed from 'unknown' to 32 array type subrange 1 changed length from 'unknown' to 1 $ * include/abg-comp-filter.h (is_var_1_dim_unknown_size_array_change): Declare new function. * src/abg-comp-filter.cc (is_var_1_dim_unknown_size_array_change): Define new function. (has_benign_array_of_unknown_size_change): Rename has_benign_infinite_array_change into this. Make this call the new is_var_1_dim_unknown_size_array_change. (categorize_harmless_diff_node): Adjust the call to has_benign_infinite_array_change into the new has_benign_array_of_unknown_size_change. * include/abg-ir.h (var_equals_modulo_types): Declare new function. Make it friend of class decl_base. * src/abg-default-reporter.cc (default_reporter::report): In the overload for var_diff, call the new maybe_report_diff_for_variable. * src/abg-ir.cc (var_equals_modulo_types): Factorize this out of the equals() function for var_decl. (equals): In the overload for var_decl, call the new var_equals_modulo_types. * src/abg-reporter-priv.h (maybe_report_diff_for_variable): Declare new function. * src/abg-reporter-priv.cc (maybe_report_diff_for_variable): Define new function. * tests/data/test-diff-filter/test-PR29811-0-report-0.txt: Add new reference test output. * tests/data/test-diff-filter/test-PR29811-0-report-1.txt: Likewise. * tests/data/test-diff-filter/test-PR29811-0-v{0,1}.o: Add new binary test inputs. * tests/data/test-diff-filter/test-PR29811-0-v{0,1}.c: Add source code of the binary test inputs. * tests/data/Makefile.am: Add new test input files above to source distribution. * tests/test-diff-filter.cc (in_out_specs): Add new tests to harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4545e9a23a |
dwarf-reader: Bug 29811 - Support updating of variable type
Let's look at the source code reported at https://sourceware.org/bugzilla/show_bug.cgi?id=29811: extern unsigned int is_basic_table[]; unsigned int is_basic_table[] = {0}; Let's look at the DWARF output from GCC. The variable is_basic_table is described by the DIE at offset 0x51: [ 51] variable abbrev: 7 specification (ref4) [ 2f] decl_line (data1) 3 decl_column (data1) 14 type (ref4) [ 3b] location (exprloc) [ 0] addr .bss+0 <is_basic_table> The type of the variable is defined at the offset 0x3b: [ 3b] array_type abbrev: 1 type (ref4) [ 29] sibling (ref4) [ 4b] [ 44] subrange_type abbrev: 6 type (ref4) [ 4b] upper_bound (data1) 0 But then, we see that the DIE at 0x51 has a DW_AT_specification attribute that refers to the DIE at offset 0x2f: [ 2f] variable abbrev: 5 name (strp) "is_basic_table" decl_file (data1) test-v2.c (1) decl_line (data1) 1 decl_column (data1) 21 type (ref4) [ 1e] external (flag_present) yes declaration (flag_present) yes That DIE at offset 0x2f represents the first external variable declared in the source code. It's type is an array defined at offset 0x1e: [ 1e] array_type abbrev: 1 type (ref4) [ 29] sibling (ref4) [ 29] [ 27] subrange_type abbrev: 4 This array has one dimension of 'unknown' size; this is because the dimension is described by the DIE at offset 0x27 of kind DW_TAG_subrange_type and has no DW_AT_upper_bound DIE. But then, I said earlier, the real type of the is_basic_table variable is the DIE at offset 0x3b, which is an array which single dimension described by the DIE at offset 0x44 of kind DW_TAG_subrange_type with a DW_AT_upper_bound attribute of value 0. Let's see the output of abidw on this program, from the DWARF debug info: 1 <abi-corpus version='2.1' path='test-PR29811-unknown-size-array-dwarf-ctf-DWARF.o' architecture='elf-amd-x86_64'> 2 <elf-variable-symbols> 3 <elf-symbol name='is_basic_table' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 4 </elf-variable-symbols> 5 <abi-instr address-size='64' path='test-PR29811-unknown-size-array-dwarf-ctf.c' comp-dir-path='/home/dodji/git/libabigail/PR29811/prtests' language='LANG_C11'> 6 <type-decl name='unsigned int' size-in-bits='32' id='type-id-1'/> 7 <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='32' id='type-id-2'> 8 <subrange length='1' type-id='type-id-3' id='type-id-4'/> 9 </array-type-def> 10 <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='infinite' id='type-id-5'> 11 <subrange length='infinite' id='type-id-6'/> 12 </array-type-def> 13 <type-decl name='unsigned long int' size-in-bits='64' id='type-id-3'/> 14 <var-decl name='is_basic_table' type-id='type-id-5' mangled-name='is_basic_table' visibility='default' filepath='/home/dodji/git/libabigail/PR29811/prtests/test-PR29811-unknown-size-array-dwarf-ctf.c' line='10' column='1' elf-symbol-id='is_basic_table'/> 15 </abi-instr> 16 </abi-corpus> The variable is_basic_table is described by the element at line 14: 14 <var-decl name='is_basic_table' type-id='type-id-5' mangled-name='is_basic_table' visibility='default' filepath='/home/dodji/git/libabigail/PR29811/prtests/test-PR29811-unknown-size-array-dwarf-ctf.c' line='10' column='1' elf-symbol-id='is_basic_table'/> Its type has the ID 'type-id-5' which is defined at line 10: 10 <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='infinite' id='type-id-5'> 11 <subrange length='infinite' id='type-id-6'/> 12 </array-type-def> Which has an unknown size. But the, at line 7, there is another array type defined with a size of 32 bits: 7 <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='32' id='type-id-2'> 8 <subrange length='1' type-id='type-id-3' id='type-id-4'/> 9 </array-type-def> So, libabigail links the is_basic_table variable to the wrong array type. This is because when the DWARF reader builds the internal representation for the DW_TAG_variable DIE at offset 0x51, it first builds it with the type (and the other properties such as the name for instance) of the "declaration" DIE specified by the DW_AT_specification attribute. But then, this DW_TAG_variable DIE has its own type at offset 0x3b ; libabigail should update the internal representation it just built to set the type to the one referred to at offset 0x3b. It's that updating that is not being done. So the variable wrongly points to the type of the "declaration" DIE at offset 0x2f. This patch fixes build_var_decl to make it update the type of the variable when necessary. * include/abg-ir.h (var_decl::set_type): Declare new member function. * src/abg-ir.cc (var_decl::priv::set_type): Define new member function. (var_decl::set_type): Likewise. * src/abg-dwarf-reader.cc (build_var_decl): In "updating mode", update the type of the variable as well. * tests/data/test-diff-filter/test-PR29811-unknown-size-array-dwarf-ctf-CTF.o: Add new test binary input. * tests/data/test-diff-filter/test-PR29811-unknown-size-array-dwarf-ctf-DWARF.o: Likewise. * tests/data/test-diff-filter/test-PR29811-unknown-size-array-dwarf-ctf-report.txt: Add test reference output. * tests/data/test-diff-filter/test-PR29811-unknown-size-array-dwarf-ctf.c: Add source code of the new test binary input. * tests/data/Makefile.am: Add the new files above to source distribution. * tests/test-diff-filter.cc (in_out_specs): Add the input binaries to the test harness. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
aef4f0fd1b |
Don't use the "infinite" keyword for arrays of unknown size
In the ABIXML format and in diff reports, array dimensions of unknown size are described with the "infinite" keyword. This is not explicit enough. This patch uses the keyword "unknown" instead. Note that the keyword "infinite" is still recognized by the ABIXML reader. * src/abg-reader.cc (build_subrange_type, build_array_type_def): Support the "unknown" keyword, as well as the "infinite" keyword. * src/abg-reporter-priv.cc (report_size_and_alignment_changes): Emit the "unknown" keyword, not the "infinity" one. * src/abg-writer.cc (write_array_size_and_alignment): Likewise. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Adjust. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test7.so.abi: Likewise. * tests/data/test-read-ctf/test-array-size.abi: Likewise. * tests/data/test-read-ctf/test-dynamic-array.o.abi: Likewise. * tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test7.so.abi: Likewise. * tests/data/test-read-dwarf/test7.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-write/test25.xml: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
64e7901956 |
Update copyright year for 2023
Update the copyright years for 2023, using the script update-copyright.sh. * update-copyright.sh: Update the copyright years in this script. * include/abg-comp-filter.h: Update copyright year for 2023. * include/abg-comparison.h: Likewise. * include/abg-config.h: Likewise. * include/abg-corpus.h: Likewise. * include/abg-ctf-reader.h: Likewise. * include/abg-cxx-compat.h: Likewise. * include/abg-diff-utils.h: Likewise. * include/abg-dwarf-reader.h: Likewise. * include/abg-elf-based-reader.h: Likewise. * include/abg-elf-reader.h: Likewise. * include/abg-fe-iface.h: Likewise. * include/abg-fwd.h: Likewise. * include/abg-hash.h: Likewise. * include/abg-ini.h: Likewise. * include/abg-interned-str.h: Likewise. * include/abg-ir.h: Likewise. * include/abg-libxml-utils.h: Likewise. * include/abg-reader.h: Likewise. * include/abg-regex.h: Likewise. * include/abg-reporter.h: Likewise. * include/abg-sptr-utils.h: Likewise. * include/abg-suppression.h: Likewise. * include/abg-tools-utils.h: Likewise. * include/abg-traverse.h: Likewise. * include/abg-viz-common.h: Likewise. * include/abg-viz-dot.h: Likewise. * include/abg-viz-svg.h: Likewise. * include/abg-workers.h: Likewise. * include/abg-writer.h: Likewise. * src/abg-comp-filter.cc: Likewise. * src/abg-comparison-priv.h: Likewise. * src/abg-comparison.cc: Likewise. * src/abg-config.cc: Likewise. * src/abg-corpus-priv.h: Likewise. * src/abg-corpus.cc: Likewise. * src/abg-ctf-reader.cc: Likewise. * src/abg-default-reporter.cc: Likewise. * src/abg-diff-utils.cc: Likewise. * src/abg-dwarf-reader.cc: Likewise. * src/abg-elf-based-reader.cc: Likewise. * src/abg-elf-helpers.cc: Likewise. * src/abg-elf-helpers.h: Likewise. * src/abg-elf-reader.cc: Likewise. * src/abg-fe-iface.cc: Likewise. * src/abg-hash.cc: Likewise. * src/abg-ini.cc: Likewise. * src/abg-internal.h: Likewise. * src/abg-ir-priv.h: Likewise. * src/abg-ir.cc: Likewise. * src/abg-leaf-reporter.cc: Likewise. * src/abg-libxml-utils.cc: Likewise. * src/abg-reader.cc: Likewise. * src/abg-regex.cc: Likewise. * src/abg-reporter-priv.cc: Likewise. * src/abg-reporter-priv.h: Likewise. * src/abg-suppression-priv.h: Likewise. * src/abg-suppression.cc: Likewise. * src/abg-symtab-reader.cc: Likewise. * src/abg-symtab-reader.h: Likewise. * src/abg-tools-utils.cc: Likewise. * src/abg-traverse.cc: Likewise. * src/abg-viz-common.cc: Likewise. * src/abg-viz-dot.cc: Likewise. * src/abg-viz-svg.cc: Likewise. * src/abg-workers.cc: Likewise. * src/abg-writer.cc: Likewise. * tests/print-diff-tree.cc: Likewise. * tests/test-abicompat.cc: Likewise. * tests/test-abidiff-exit.cc: Likewise. * tests/test-abidiff.cc: Likewise. * tests/test-alt-dwarf-file.cc: Likewise. * tests/test-core-diff.cc: Likewise. * tests/test-cxx-compat.cc: Likewise. * tests/test-diff-dwarf-abixml.cc: Likewise. * tests/test-diff-dwarf.cc: Likewise. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tests/test-diff2.cc: Likewise. * tests/test-dot.cc: Likewise. * tests/test-elf-helpers.cc: Likewise. * tests/test-ini.cc: Likewise. * tests/test-ir-walker.cc: Likewise. * tests/test-kmi-whitelist.cc: Likewise. * tests/test-lookup-syms.cc: Likewise. * tests/test-read-ctf.cc: Likewise. * tests/test-read-dwarf.cc: Likewise. * tests/test-read-write.cc: Likewise. * tests/test-svg.cc: Likewise. * tests/test-symtab-reader.cc: Likewise. * tests/test-symtab.cc: Likewise. * tests/test-tools-utils.cc: Likewise. * tests/test-types-stability.cc: Likewise. * tests/test-utils.cc: Likewise. * tests/test-utils.h: Likewise. * tools/abicompat.cc: Likewise. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abilint.cc: Likewise. * tools/abipkgdiff.cc: Likewise. * tools/abisym.cc: Likewise. * tools/binilint.cc: Likewise. * tools/kmidiff.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
49fcc8d3ff |
ir: Add sanity checking to canonical type propagation confirmation
To understand the problem reported at https://sourceware.org/bugzilla/show_bug.cgi?id=29934 where a type was left non-canonicalized when analysing the binary /usr/lib64/dovecot/libdovecot-sieve.so.0.0.0 from https://vault.centos.org/7.6.1810/os/x86_64/Packages/dovecot-2.2.36-3.el7.x86_64.rpm and http://debuginfo.centos.org/7/x86_64/dovecot-debuginfo-2.2.36-3.el7.x86_64.rpm, I had to add some sanity checking code to ensure that types that have seen their propagated canonical cleared during the canonicalization process are fully canonicalized at the end of the canonicalization process. In order to performg that sanity checking this patch tracks the set of types which propagated canonical type has been cleared during the canonicalization of a particular type. When a type with such a cleared propagated canonical type is finally canonicalized, it is removed from the set of tracked types. At the end of the canonicalization process, the set of tracked types must be empty. This sanity check is compiled in only if the WITH_DEBUG_CT_PROPAGATION preprocessor macro is defined. That macro is defined if the --enable-debug-ct-propagation configure switch is used. * configure.ac: Add a new --enable-debug-ct-propagation configure flag that defines the WITH_DEBUG_CT_PROPAGATION preprocessor macro. * src/abg-ir-priv.h (environment::priv::types_with_cleared_propagated_ct_): Define new data member for tracking types with cleared propagated canonical type. (environment::priv::types_with_cleared_propagated_ct): Add getter and setter for the new data member above. (environment::priv::{record_type_with_cleared_propagated_canonical_type, erase_type_with_cleared_propagated_canonical_type}): Add book-keeping functions for the set of types with cleared propagated canonical type. (type_base::priv::clear_propagated_canonical_type): Make this return true if the propagated canonical type is cleared. (environment::priv::clear_propagated_canonical_type): Define a new function that takes a type_base* and clears its propagated canonical type. This also adds the type to the set of tracked types returned by environment::priv::types_with_cleared_propagated_ct(). (environment::priv::{cancel_ct_propagation_for_types_dependant_on, cancel_ct_propagation}): Call the new environment::priv::clear_propagated_canonical_type() rather than calling the now low-level type_base::priv::clear_propagated_canonical_type(). (environment::priv::propagate_ct): Remove the type which just gained a propagated canonical type from the set of tracked types returned by environment::priv::types_with_cleared_propagated_ct. (canonicalize_types): Define new function that canonicalizes all the types of the system (passed in parameter) and performs sanity checking to make sure all types with cleared propagated canonical types have been canonicalized. * include/abg-ir.h (string_type_base_sptr_map_type): Define new typedef for an unordered_map<string, type_base_sptr>. * src/abg-ir.cc (canonicalize): Remove the type which has just been canonicalized from the set of tracked types returned by environment::priv::types_with_cleared_propagated_ct. * src/abg-ctf-reader.cc (reader::types_map): Use the new string_type_base_sptr_map_type typedef for the type of this map. (reader::canonicalize_all_types): Use the new function abigail::ir::canonicalize_types to canonicalize the types of the system and perform necessary sanity checking. * src/abg-dwarf-reader.cc (reader::canonicalize_types_scheduled): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4f4ab2b1d6 |
ir: Bug 29934 - Fix propagated canonical type confirmation
When canonicalization a type T, it can happen that one subtype S of T compares equal to a type S' where S' is already canonicalized. In that case, we can deduce that the canonical type of S equals the canonical type of S', even if we are currently in the process of canonicalizing T. In other words, the canonical type of S' is "propagated to S", in the process of canonicalizing T. This optimization is called "canonical type propagation" and is meant to spead up the overall canonicalization process. However, in some cases, the propagated canonical type can be "cancelled" for the optimization to be correct. In those cases, the propagated canonical type is set to nil. When analysing the binary libdovecot-sieve.so from the problem reported at https://sourceware.org/bugzilla/show_bug.cgi?id=29934, we encounter a case where a function type's propagated type is erroneously cancelled. That leaves the canonical type of that function type not set and that later violates the assert ABG_ASSERT(is_non_canonicalized_type(t)) in abigail::ir::hash_as_canonical_type_or_constant. I tracked this down to return_comparison_result which fails to confirm a case of propagated canonical type and thus, some of them can end up being erroneously cancelled. Fixed thus. * src/abg-ir.cc (return_comparison_result): A type whose canonical type has been propagated must have its canonical type confirmed if that type is not recursive and is not dependant on any recursive type. In that case, the canonical type will never be cancelled. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
5a32ff22c2 |
ir: misc cleanups
When looking at something else, I noticed some useless friend function declaration. Namely, the "canonicalize()" function is declared friend to the decl_base and scope_decl clases, which is now useless. This patch removes those declarations. * include/abg-ir.h (decl_base, scope_decl): Remove the declaration of canonicalize() as friend to these classes. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
315dff674a |
elf-reader: Don't free CTF resources too early
elf::reader::locate_alt_ctf_debug_info frees the memory for the alternate CTF debug info too early, leading to some segmentation violation down the road, when the rest of the code tries to access the CTF section afterwards. Many thanks to the Valgrind tool and its hackers for showing me this. This patch thus keeps the file descriptor and ELF data structure of the alternate CTF debug info around for the lifetime of the reader. * src/abg-elf-reader.cc (reader::priv::{alt_ctf_fd, alt_ctf_handle}): Add new data members. (reader::priv::clear_alt_ctf_debug_info_data): Define new member function. (reader::priv::~priv): Call the new priv::clear_alt_ctf_debug_info_data (reader::priv::initialize): Likewise. Initialize the new alt_ctf_handle and alt_ctf_fd data members. (reader::priv::locate_alt_ctf_debug_info): Do not free the fd and ELF resources early here. Store them in the new reader::priv::alt_ctf_{fd,handle} instead. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
de45f1e69b |
dwarf-reader: Bug 29932 - Handle function DIE as type as needed
When building the IR for a function type, the DWARF reader considers the function DIE we are looking at as a type DIE. In dwarf::reader::lookup_fn_type_from_die_repr_per_tu, the call to get_die_pretty_representation doesn't enforce the fact that the DIE we are looking at must be considered as a type. This is usually not a problem because even if get_die_pretty_representation considers the function DIE as a decl, the representation of a function and a function type are almost the same. In this particular case, we run into a function DIE that has an empty name: [ 51e54] subprogram abbrev: 18 external (flag_present) yes name (strp) "" decl_file (data1) catgets.c (1) decl_line (data1) 89 prototyped (flag_present) yes type (ref4) [ 51ac5] low_pc (addr) +0x0000000000034cc0 high_pc (data8) 133 (+0x0000000000034d45) frame_base (exprloc) [ 0] call_frame_cfa GNU_all_call_sites (flag_present) yes sibling (ref4) [ 51edb] Note that this is from the /lib64/libc-2.17.so from the https://vault.centos.org/7.6.1810/os/x86_64/Packages/glibc-2.17-260.el7.x86_64.rpm package, associated with the debuginfo package at http://debuginfo.centos.org/7/x86_64/glibc-debuginfo-2.17-260.el7.x86_64.rpm. In that case, get_die_pretty_representation returns an empty string because it doesn't expects a function decl with an empty name. If we make dwarf::reader::lookup_fn_type_from_die_repr_per_tu explicitly be in the context of a type by invoking get_die_pretty_type_representation instead, the problem disapears as the latter function treats the DIE as a function type DIE, so it doesn't need its name. Thus, this patch makes dwarf::reader::lookup_fn_type_from_die_repr_per_tu invoke get_die_pretty_type_representation instead. * src/abg-dwarf-reader.cc (reader::lookup_fn_type_from_die_repr_per_tu): Invoke get_die_pretty_type_representation instead of get_die_pretty_representation when looking at a function DIE without a name. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
e3725f1b96 |
Bug 29934 - Handle buggy data members with empty names
When handling the changes between two ABI corpora, the diff graph building pass chokes on a data member which seems to erroneously have an empty name. The steps to reproduce the issue are explained in the problem report at https://sourceware.org/bugzilla/show_bug.cgi?id=29934. The root cause of the problem is that the "struct mailbox" data structure from the binary /usr/lib64/dovecot/libdovecot-storage.so.0 coming from the dovecot-2.2.36-3.el7.x86_64.rpm package contains a data member that has an empty name. The source code of that data structure can be browsed at https://github.com/dovecot/core/blob/release-2.2.36/src/lib-storage/mail-storage-private.h We see that the mailbox::storage data structure at line 352 ends up in the DWARF debug info with an empty name. Let's look at the DWARF dump as emitted by "eu-readelf --debug-dump=info" on the /usr/lib/debug//usr/lib64/dovecot/libdovecot-storage.so.0.debug file from the dovecot-debuginfo-2.2.36-3.el7.x86_64.rpm package. A relevant DIE for the "struct mailbox" is the following: [ 3e3e] structure_type abbrev: 9 name (strp) "mailbox" byte_size (data2) 768 decl_file (data1) mail-storage-private.h (24) decl_line (data2) 348 sibling (ref_udata) [ 41f9] [ 3e4a] member abbrev: 59 name (strp) "name" decl_file (data1) mail-storage-private.h (24) decl_line (data2) 349 type (ref_addr) [ 84] data_member_location (data1) 0 [ 3e57] member abbrev: 59 name (strp) "vname" decl_file (data1) mail-storage-private.h (24) decl_line (data2) 351 type (ref_addr) [ 84] data_member_location (data1) 8 [ 3e64] member abbrev: 47 name (strp) "" decl_file (data1) mail-storage-private.h (24) decl_line (data2) 352 type (ref_udata) [ 3bee] data_member_location (data1) 16 [...] You can see here that the DW_TAG_member DIE at offset 0x3e64 has an empty name. Its DW_AT_type attribute references the DIE at offset 0x3bee. The DIE at offset 0x3bee is this one: [ 3bee] pointer_type abbrev: 95 byte_size (data1) 8 type (ref_udata) [ 3a90] [...] It's a pointer to the type which DIE is at offset 0x3a90, which is: [ 3a90] structure_type abbrev: 48 name (strp) "mail_storage" byte_size (data2) 352 decl_file (data1) mail-storage-private.h (24) decl_line (data1) 132 sibling (ref_udata) [ 3bee] So, the data member of "struct mailbox" which has an empty name has a type "pointer to struct mail_storage", aka "struct mail_storage*". That indeed corresponds to the "storage" data member that we see at line 352 of the mail-storage-private.h file, browsable at https://github.com/dovecot/core/blob/release-2.2.36/src/lib-storage/mail-storage-private.h. The fact that this data member has an empty name seems to me as a bug of the DWARF emitter. Libabigail ought to gently handle this bug instead of choking. This patch assigns an artificial name to that empty data member to handle this kind of cases in the future. The names looks like "unnamed-@-<location>" where "location" is the location of the data member. Please note that there can be normal cases of anonymous data members where the data member has an empty name. In those cases, the data member must be of type union or struct. This is to describe the "unnamed fields" C feature described at https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html. The buggy case we are seeing here is different from the "unnamed field" case because the type of the anonymous data member is neither struct nor union. * src/abg-dwarf-reader.cc (die_is_anonymous_data_member): Define new static function. (die_member_offset): Move the declaration of this up so that it can be used more generally. (reader::build_name_for_buggy_anonymous_data_member): Define new member function. (add_or_update_class_type): Generate an artificial name for buggy data members with empty names. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Guillermo E. Martinez
|
9af85a7032 |
ctf-reader: Fix missing initializer for member in test suite
With -Werror=missing-field-initializers on, the compiler chokes on CTF test suite. Fixed thus. * tests/test-read-ctf.cc (in_out_specs): Add initializer for `option' field in test entry. * tests/data/test-read-ctf/test-alias.o.abi: Adjust. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Guillermo E. Martinez
|
4cf2ef8f97 |
ctf-front-end: Add test for alias symbols
This patch adds a new test case in the ctf-front-end test suite to to test for alias symbols support. * tests/data/test-read-ctf/test-alias.o: New binary test input file. * tests/data/test-read-ctf/test-alias.o.abi: New exported abixml file. * tests/data/Makefile.am: Add the new test input above * tests/test-read-ctf.cc: Add the new test input above to the test harness. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Xiaole He
|
83bbc679e5 |
elf-reader: reclaim fd and mem before break
In elf::reader::priv::locate_alt_ctf_debug_info from src/abg-elf-reader.cc, the resources held by the hdl and fd variables aren't necessary released because the control-flow gets out of the loop too early. This patch fixes the problem. * src/abg-elf-reader.cc (elf::reader::priv::locate_alt_ctf_debug_info): Reclaim fd and mem before break. Also, do not try to locate the debug info it's already been located. Signed-off-by: Xiaole He <hexiaole@kylinos.cn> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
e1aadfa576 |
Bug 29901 - abidiff hangs when comparing libgs.so.10 with itself
This is a follow-up patch to this one:
|
||
Dodji Seketeli
|
3c6a461bc0 |
Update website documentation for 2.2
* mainpage.txt: Update for 2.2. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
73d8782c96 |
configure: Bump version number to 2.3
* configure.ac: Bump version number to 2.3 Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
7a7a00c397 |
ChangeLog: Update for 2.2 release
* ChangeLog: Update by doing "make update-changelog". Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4e7da18a81 |
NEWS: Update for 2.2 release
* NEWS: Update for 2.2 release, with the output of `git shortlog libabigail-2.1..HEAD` Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Petr Pavlu
|
d3bc68b8d8 |
Fix de-initialization of elf::reader::priv
This fixes
|
||
Dodji Seketeli
|
2a54f0ab5e |
ir: Cache more aggregate type comparison results
In the aftermath of https://sourceware.org/bugzilla/show_bug.cgi?id=29857, I figured caching comparison results at one place (in a macro) leads to better maintainability. Also, using that macro in the equal() overload for class_decl, union_decl and function_type results in slightly more results of aggregate type comparison being cached during type canonicalization. And that might speed things up. When measuring the impact on the comparison of the bug mentionned above, comparison that takes ~ 43 minutes, we gain 30secs with this patch. We went from: $ time ~/build/tools/abidiff --d1 ghostscript-9.07-31.el7.x86_64/usr/lib/debug --d2 ghostscript-9.52-5.oe1.x86_64/usr/lib/debug/ ghostscript-9.07-31.el7.x86_64/usr/lib64/libgs.so.9 ghostscript-9.52-5.oe1.x86_64/usr/lib64/libgs.so.9 Functions changes summary: 342 Removed, 940 Changed (2084 filtered out), 586 Added functions Variables changes summary: 70 Removed, 432 Changed (333 filtered out), 81 Added variables Function symbols changes summary: 2 Removed, 19 Added function symbols not referenced by debug info Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referenced by debug info (...) real 42m33,633s user 41m54,699s sys 0m1,381s $ to: $ time ~/build/tools/abidiff --d1 ghostscript-9.07-31.el7.x86_64/usr/lib/debug --d2 ghostscript-9.52-5.oe1.x86_64/usr/lib/debug/ ghostscript-9.07-31.el7.x86_64/usr/lib64/libgs.so.9 ghostscript-9.52-5.oe1.x86_64/usr/lib64/libgs.so.9 Functions changes summary: 342 Removed, 940 Changed (2084 filtered out), 586 Added functions Variables changes summary: 70 Removed, 432 Changed (333 filtered out), 81 Added variables Function symbols changes summary: 2 Removed, 19 Added function symbols not referenced by debug info Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referenced by debug info (...) real 42m2,364s user 41m23,911s sys 0m0,326s $ * src/abg-ir.cc (CACHE_AND_RETURN_COMPARISON_RESULT): Define new macro. (equals): In the overloads for function_type, class_decl, and union_decl use the new CACHE_AND_RETURN_COMPARISON_RESULT. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
88c6e080b6 |
Bug 29857 - Better detect comparison cycles in type graph
When comparing two aggregates A and B, it can happen that has a sub-type of A is itself; similarly for B. This is a cycle in the type graph, obviously. Also, A and B are said to be recursive types. Structally comparing two recursive types (i.e, comparing them member-wise) can lead to an endless loop. So, during type canonicalization, comparison cycles must be detected to avoid those endless loop. This is currently done in the equals() overload for class_decl, union_decl, class_or_union as well as function_type. Those are the aggregate types that are subject to these cycles when comparing recursive types. Currently, detecting comparison cycles is based on ir::environment::priv::mark_as_being_compared(), ir::environment::priv::priv::unmark_as_being_compared(), ir::environment::priv::comparison_started() considering the pair of pointer to aggregate types being currently compared. If that pair appears more than once in the stack of aggregates being compared a cycle is detected. But then, watching the stack of aggregates during the analsysis of the /usr/lib64/libgs.so.9 binary from the ghostscript-9.52-5.oe1.x86_64 package from https://sourceware.org/bugzilla/show_bug.cgi?id=29857 it appears that the stack of aggregates (structs) was growing endlessly, when comparing the "struct gs_memory_s" type, and the same struct gs_memory_s aggregate was appearing several times on the right-hand side of the comparison stack. Clearly, this is a comparison cycle. The gs_memory struct is appearing several times as the right hand side operand in the stack of operands being compared, even though no pair of operands being compared was present more than once. This prompted me to use another heuristic to detect comparison cycles: If the same aggregate type is appearing several times on either the left or right hand side of the comparison stack then a cycle is detected. This fixes the cycle detection failure above and comparing the two binaries completes in ~ 43 minutes on my laptop, with a non optimized libabigail build. * src/abg-ir-priv.h (class_set_type, fn_set_type): Define new typedefs. * src/abg-ir.cc (environment::priv::{left_classes_being_compared_, right_classes_being_compared_, left_fn_types_being_compared_, right_fn_types_being_compared_}): Define new data members. (environment::priv::{classes_being_compared_, fn_types_being_compared_}): Erase data members. (environment::priv::{dump_classes_being_compared, dump_fn_types_being_compared}): Erase member functions. (environment::priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started}): Change this to use the left-hand-side and right-hand-side comparison stack introduced above. (dump_classes_being_compared, dump_fn_types_being_compared): Remove functions. Signed-off-by: Dodji Seketeli <dodji@seketeli.org> |
||
Dodji Seketeli
|
fc71e519bb |
Bug 29857 - dwarf-reader: Resolve decl-only unions
When looking at https://sourceware.org/bugzilla/show_bug.cgi?id=29857 I noticed that decl-only unions where not resolved to their definition union, unlike what is done for classes and enums. At type canonicalization, a type A defined in a translation unit TU, that depends on a decl-only union U will compare different from a type A defined in a translation unit TU', that depends on the definition of U, even though the types A should be equal. This patch teaches the decl-only class resolver to also resolve decl-only unions, as opposed to resolving just decl-only classes. * include/abg-fwd.h (typedef classes_or_unions_type): Declare new typedef. (lookup_union_types): Declare new function. * src/abg-dwarf-reader.cc (reader::decl_only_classes_map_): Change the type of this from string_classes_map to string_classes_or_unions_map. (reader::declaration_only_classes): Return a string_classes_or_unions_map, no more a string_classes_map. (reader::{maybe_schedule_declaration_only_class_for_resolution, is_decl_only_class_scheduled_for_resolution}): Handle class_or_union, not just class_decl. This is a way to make this handle unions as well as classes. (get_opaque_version_of_type): Adjust. * src/abg-ir.cc (lookup_union_types): Define new function. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
10dd604e18 |
Bug 29857 - Don't pop comparison operands that haven't been pushed
While looking at bug https://sourceware.org/bugzilla/show_bug.cgi?id=29857, I noticed a crash that is happening due to the fact that the equal overload for classes tries pop comparison operands that haven't been pushed to the stack of comparison operands. Oops. Fixed thus. * src/abg-ir.cc (equals): In the overload for class_or_union, don't try to pop, operands that haven't been pushed. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
fd821dd4db |
ir: Add a debug_comp_stack debugging function
When debugging type comparison, it can useful to see what the comparison stack is. This patch adds the a debug_comp_stack to dump the comparison stack as a string. * include/abg-fwd.h (debug_comp_stack): Declare function. * src/abg-ir.cc (debug_comp_vec, print_comp_stack): Define static functions. (debug_comp_stack): Define new function. Signed-off-by: Dodji Seketeli <dodji@seketeli.org> |
||
Dodji Seketeli
|
c2cab36429 |
ir: Improve get_debug_representation
* src/abg-ir.cc (get_debug_representation): Prefix classes/structs/unions with the 'classes/struct/union' prefix. Signed-off-by: Dodji Seketeli <dodji@seketeli.org> |
||
Dodji Seketeli
|
1f51b9e85d |
Bug 29829 - dwarf-reader: Allow DIEs to be in a lexical block
Normally, ABI-relevant DWARF DIEs (types and decls) should be at namespace level. There are real-life cases where such a DIE might be defined in a lexical block. This patch teaches the DWARF reader to handle such cases. * src/abg-dwarf-reader.cc (get_scope_for_die): Support DW_TAG_lexical_block as DIE scope. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
ac53e88bdb |
dwarf-reader: Make die_peel_{qual_ptr,typedef} always set peeled type
When die_peel_{qual_ptr,typedef} don't actually peel anything, they don't set the peeled type output argument. So callers expecting that argument to be set can be surprised by the fact the peeled argument might not be set. * src/abg-dwarf-reader.cc (die_peel_qual_ptr, die_peel_typedef): If the function returned true, then set the peeled argument even if the function hasn't peeled anything. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4bdaf30bbb |
dwarf-reader: Avoid duplicating member functions
Depending on how the DWARF DIEs are encountered, it can happen that the reader mistakenly adds the same member function several times. This is because due to DIE canonicalization, when we encounter the class DIE C' that is equivelent to a class C that we have already encountered, C' is dropped on the floor and C is kept. But then, the member functions of C' should not added to C, rather, if they are already present in C, we shouldn't add them anymore. This is what build_or_get_fn_decl_if_not_suppressed is supposed to do, but fails to do in a subtle way. This patch fixes it. * src/abg-dwarf-reader.cc (build_or_get_fn_decl_if_not_suppressed): Fix the code that is supposed to avoid duplicating a member function. * tests/data/test-annotate/test14-pr18893.so.abi: Adjust. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
d222b44733 |
dwarf-reader: Leverage ODR & DWZ
When DWARF debug info has been preprocessed with the DWZ tool, I think we can assume that if two DIEs originating from the .gnu_debugaltlink section have different offset, it means they are different, even if they represent two types of the same nature and of the same name. This is the whole point of DWZ. When we process two DIEs originating from C++, it's possible "in general" to assume that the One Definition Rule is in effect, meaning that if two types of the same nature have the same name, they ought to represent the same entity, meaning, they are the same type. These two observations can lead to faster comparison of two aggregate types of the same nature and of the same name. This patch implements these two optimizations and use them by default. The first one is used by default on binaries that contains a .gnu_debugaltlink section, which is the hint we use to detect that DWZ was used to factorize DWARF DIEs. The second of is used by default on DWARF DIEs originating from C++. These optimizations can be de-activated on abidw and abidiff using the --no-leverage-dwarf-factorization and --no-assume-odr-for-cplusplus. * doc/manuals/abidiff.rst: Add documentation for --no-leverage-dwarf-factorization and --no-assume-odr-for-cplusplus * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-fe-iface.h (options::{leverage_dwarf_factorization, assume_odr_for_cplusplus}): New data members. * src/abg-dwarf-reader.cc (reader::leverage_dwarf_factorization_): New data member. (reader::leverage_dwarf_factorization): New accessor. (compare_dies): If we are allowed to leverage the DWARF factorization and if two type DIEs coming from the .gnu_debugaltlink DWARF section have different offset, then they are different. Also, if we are allowed to assume ODR, use it to speed up class/struct/unions comparisons. * tools/abidiff.cc (options::{assume_odr_for_cplusplus, leverage_dwarf_factorization}): Define new data members. (options::options): Initialize them. (display_usage): Add new help strings for --no-leverage-dwarf-factorization and --no-assume-odr-for-cplusplus. (parse_command_line): Parse these new options. (set_generic_options): New function. (main): Use the new set_generic_options function. * tools/abidw.cc (options::{assume_odr_for_cplusplus, leverage_dwarf_factorization}): Define new data members. (options::options): Initialize them. (display_usage): Add new help strings for --no-leverage-dwarf-factorization and --no-assume-odr-for-cplusplus. (parse_command_line): Parse these new options. (set_generic_options): New function. (load_corpus_and_write_abixml): Use the new set_generic_options function. * tools/abipkgdiff.cc (options::{assume_odr_for_cplusplus, leverage_dwarf_factorization}): Define new data members. (options::options): Initialize them. (display_usage): Add new help strings for --no-leverage-dwarf-factorization and --no-assume-odr-for-cplusplus. (parse_command_line): Parse these new options. (set_generic_options): New function. (compare): Use it. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
754364d5ca |
Fix spurious deleted/added virtual destructor change report
While looking at something else, I noticed this spurious change report: 1 member function deletion: 'method virtual tbb::internal::concurrent_queue_base_v3::~concurrent_queue_base_v3(int)' at concurrent_queue.cpp:361:1 1 member function insertion: 'method virtual tbb::internal::concurrent_queue_base_v3::~concurrent_queue_base_v3(int)' at concurrent_queue.cpp:370:1 This is when running tests/runtestdiffpkg and the result is in tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt. To understand what is going on, one need to refer to the definitions of the C++ ABI at https://itanium-cxx-abi.github.io/cxx-abi/abi.html#definitions. When a class has a virtual destructor, historically, there might be 3 different and co-existing actual implementations of the destructors: the D0, D1 and D2 destructors. There might even be a D3 destructor, actually. In https://github.com/itanium-cxx-abi/cxx-abi/issues/73, one can see that there might be new D4 and D5 destructors. Each one of them might replace the set of the D0,D1,D2 destructors. So, in a new version of a binary, the virtual D4 destructor might replace the previous ones, without it being an ABI issue. The switch to the D4 virtual destructor is what libabigail is naively reporting in the change report above. This patch detects this kind of changes in the pipeline when the edit script from the diff2 algorithm is interpreted for virtual member functions and drops it on the floor. * src/abg-comparison.cc (find_virtual_dtor_in_map): Define new static function. (class_diff::ensure_lookup_tables_populated): If a virtual destructor is removed from the old binary version but is added to the new one (but through a different name), let's assume the virtual destructor is still there so there is no ABI issue from that point of view. * tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Guillermo E. Martinez via Libabigail
|
77ae314176 |
ctf-reader: Fix array size representation
A variable length array (VLA), or a flexible array member (with its size set to zero to recognize such cases) is represented in the libabigail IR as an array with "non-finite" length. This is a way to say that the length of the array is not statically known. The ABIXML array-type-def element looks like: <array-type-def dimensions='1' ... size-in-bits='infinite' ...> <subrange length='infinite' type-id='type-id-3' .../> </array-type-def> The patch teaches the ctf-reader to correctly set the size of the array for VLAs. * src/abg-ctf-reader.cc (build_array_ctf_range): Use * tests/data/Makefile.am: Add new test. `upper_bound' and number of elements to indicate infinite array size. * tests/data/test-read-ctf/test-array-size.abi: New test. * tests/data/test-read-ctf/test-array-size.c: Likewise. * tests/data/test-read-ctf/test-array-size.o: Likewise. * tests/test-read-ctf.cc: Update testsuite. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Guillermo E. Martinez
|
e33a74fb8c |
ctf-reader: Fix representation of multidimensional arrays
To build an IR for multidimensional array the CTF front-end iterates over the element types recursively. So, consider the array definition: char a[2][3][4][5]; It's represented as 'char[2][3][4] a[5]' instead of: 'char a[2][3][4][5]' It always considers multidimensional arrays as unidimensional creating a `array-type-def' node for each dimension: <array-type-def dimensions='1' type-id='type-id-1' ... > <subrange length='2' type-id='type-id-3' id='type-id-4'/> </array-type-def> <array-type-def dimensions='1' type-id='type-id-2' ... > <subrange length='3' type-id='type-id-3' id='type-id-6'/> </array-type-def> ... Instead of: <array-type-def dimensions='4' type-id='type-id-1' ... > <subrange length='2' type-id='type-id-3' id='type-id-4'/> <subrange length='3' type-id='type-id-3' id='type-id-5'/> ... </array-type-def> Fixed thus. * src/abg-ctf-reader.cc (+build_array_ctf_range): New definition. * tests/data/Makefile.am: Add new testcase. * tests/data/test-read-ctf/test-array-mdimension.abi: New testcase. * tests/data/test-read-ctf/test-array-mdimension.c: Likewise. * tests/data/test-read-ctf/test-array-mdimension.o: Likewise. * tests/data/test-read-ctf/test9.o.abi: Adjust. * tests/test-read-ctf.cc: Update testsuite. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Guillermo E. Martinez
|
916f541a9a |
ctf-reader: Strip qualification from a qualified array type
Sometimes, GCC emits some redundant const qualifiers around arrays. For instance, consider this function: $ cat -n test.c 1 const char a[32]; 2 3 char 4 foo() 5 { 6 return a[0]; 7 } $ Notice how at line 1, the type of the variable 'a' is "array of const char". Let's compile the function and emit CTF debug info: $ gcc -gctf -c test.c $ Let's see what IR libabigail emits from the CTF information: $ abidw --ctf --annotate test.o | cat -n 1 <abi-corpus version='2.1' path='test.o' architecture='elf-amd-x86_64'> 2 <elf-function-symbols> 3 <!-- foo --> 4 <elf-symbol name='foo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 5 </elf-function-symbols> 6 <elf-variable-symbols> 7 <!-- signed char --> 8 <elf-symbol name='a' size='32' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 9 </elf-variable-symbols> 10 <abi-instr address-size='64' language='LANG_C'> 11 <!-- char --> 12 <type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/> 13 <!-- const char[32] --> 14 <array-type-def dimensions='1' type-id='type-id-2' size-in-bits='256' alignment-in-bits='8' id='type-id-3'> 15 <!-- <anonymous range>[32] --> 16 <subrange length='32' type-id='type-id-4' id='type-id-5'/> 17 </array-type-def> 18 <!-- unsigned long int --> 19 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/> 20 <!-- const char --> 21 <qualified-type-def type-id='type-id-1' const='yes' id='type-id-2'/> 22 <!-- const char[32] const --> 23 <qualified-type-def type-id='type-id-3' const='yes' id='type-id-6'/> 24 <!-- const char[32] const a --> 25 <var-decl name='a' type-id='type-id-6' mangled-name='a' visibility='default' elf-symbol-id='a'/> 26 <!-- char foo() --> 27 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo'> 28 <!-- char --> 29 <return type-id='type-id-1'/> 30 </function-decl> 31 </abi-instr> 32 </abi-corpus> $ Notice how at line 25, the variable 'a' is described as having the type which ID is 'type-id-6' defined at line 23. It's a "const array of const char". GCC has thus added a redundant "const" qualifier to the array. The C language specification in paragraph [6.7.3]/8 says: If the specification of an array type includes any type qualifiers, the element type is so- qualified, not the array type. This means that a "const array of char" is the same as an "array of const char". So a "const array of const char" is the same an "array of const char". This patch performs that removal of redundant qualifier. * src/abg-ctf-reader.cc (maybe_strip_qualification): New definition. (process_ctf_qualified_type): Strip redundant qualifiers. * tests/data/test-read-ctf/test-const-array.abi: New test. * tests/data/test-read-ctf/test-const-array.c: Likewise. * tests/data/test-read-ctf/test-const-array.o: Likewise. * tests/Makefile.am: Add the new test material to source distribution. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
5efe2247c3 |
test-read-ctf: Update tests for fixing size and name for underlying types
When applying the patch "217f579b ctf-reader: Fix size and name for underlying types" the testing parts felt through the cracks. Oops. This patch adds back the testing parts of the original patch. Here is the link to the initial post: https://inbox.sourceware.org/libabigail/871qpmou3k.fsf@seketeli.org/T/#m5f37b419e580a2a4ea9d91a9394382d886358809 * src/abg-ctf-reader.cc (process_ctf_{base_type,enum_type}): Look at ctf refence type to build the underlying type if present. * tests/data/Makefile.am: New test cases. * tests/data/test-read-ctf/PR27700/test-PR27700.abi: New test input. * tests/data/test-read-ctf/test-bitfield-enum.abi: Likewise. * tests/data/test-read-ctf/test-bitfield-enum.c: Likewise. * tests/data/test-read-ctf/test-bitfield-enum.o: Likewise. * tests/data/test-read-ctf/test-bitfield.abi: Likewise. * tests/data/test-read-ctf/test-bitfield.c: Likewise. * tests/data/test-read-ctf/test-bitfield.o: Likewise. * tests/data/test-read-ctf/test-enum-many.o.hash.abi: Adjust. * tests/data/test-read-ctf/test-enum-symbol.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum.o.abi: Likewise: * tests/data/test-read-ctf/test0.abi: Likewise. * tests/data/test-read-ctf/test0.hash.abi: Likewise. * tests/data/test-read-ctf/test1.so.abi: Likewise. * tests/data/test-read-ctf/test1.so.hash.abi: Likewise. * tests/data/test-read-ctf/test5.o.abi: Likewise. * tests/test-read-ctf.cc: Update test suite. Signed-off-by: Dodji Seketeli <dodji@redhat.com> Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> |
||
Guillermo E. Martinez
|
217f579bf7 |
ctf-reader: Fix size and name for underlying types
This patch fixes an incorrect representation in size and name of the underlying type of enums as well as underlying types of bitfield data members types. For instance, consider this struct. struct foo { unsigned bar : 2; unsigned baz : 1; }; The data members bar and baz have an underlying type that is "unsigned int". Yet, the CTF front-end represents the underlying type of these data members as: <type-decl name='' is-anonymous='yes' size-in-bits='2' id='type-id-1'/> The name property is empty, and it should be "unsigned int". The size in bit is '2', but it should be the size of the underlying "unsigned int", in bits, which is 32. In other words, the underlying type of bar and baz should be: <type-decl name='unsigned int' size-in-bits='32' id='type-id-4'/> Note that today, libabigail doesn't represent the bitfield properties of the data member. Those bitfield properties are properties of the data member, not of their type. This is a known "Not Yet Implemented" feature request that has been filed upstream at https://sourceware.org/bugzilla/show_bug.cgi?id=27334. Similarly, the underlying type of enums is not properly represented by the CTF front-end. Fixed thus. * src/abg-ctf-reader.cc (process_ctf_{base_type,enum_type}): Look at ctf refence type to build the underlying type if present. * tests/data/Makefile.am: New test cases. * tests/data/test-read-ctf/PR27700/test-PR27700.abi: New test input. * tests/data/test-read-ctf/test-bitfield-enum.abi: Likewise. * tests/data/test-read-ctf/test-bitfield-enum.c: Likewise. * tests/data/test-read-ctf/test-bitfield-enum.o: Likewise. * tests/data/test-read-ctf/test-bitfield.abi: Likewise. * tests/data/test-read-ctf/test-bitfield.c: Likewise. * tests/data/test-read-ctf/test-bitfield.o: Likewise. * tests/data/test-read-ctf/test-enum-many.o.hash.abi: Adjust. * tests/data/test-read-ctf/test-enum-symbol.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum.o.abi: Likewise: * tests/data/test-read-ctf/test0.abi: Likewise. * tests/data/test-read-ctf/test0.hash.abi: Likewise. * tests/data/test-read-ctf/test1.so.abi: Likewise. * tests/data/test-read-ctf/test1.so.hash.abi: Likewise. * tests/data/test-read-ctf/test5.o.abi: Likewise. * tests/test-read-ctf.cc: Update test suite. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Guillermo E. Martinez
|
8b832a9edf |
ctf-reader: Set alignment-in-bits property to 0
When comparing the IR generated with the CTF front-end against the one generated with the DWARF front-end, the report shows changes in type alignments: 1 Changed variable: [C] 'int a' was changed at test-abi.c:8:1: type of variable changed: type size hasn't changed type alignment changed from 32 to 0 For the sake of consistency, this patch makes the CTF front-end set the alignment to `0' for base types, function types and struct types similarly to what the DWARF front-end does. * src/abg-ctf-reader.cc (process_ctf_base_type) (process_ctf_function_type, process_ctf_struct_type): Adjust `align_in_bits' argument to `0'. * tests/data/test-diff-pkg-ctf/dirpkg-3-report-1.txt: Adjust test. * tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt: Likewise. * tests/data/test-diff-pkg-ctf/gmp-6.x.x86_64-report-0.txt: Likewise. * tests/data/test-read-ctf/PR27700/test-PR27700.abi: Likewise. * tests/data/test-read-ctf/test-PR26568-1.o.abi: Likewise. * tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise. * tests/data/test-read-ctf/test-array-of-pointers.abi: Likewise. * tests/data/test-read-ctf/test-callback.abi: Likewise. * tests/data/test-read-ctf/test-callback2.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-dynamic-array.o.abi: Likewise. * tests/data/test-read-ctf/test-fallback.abi: Likewise. * tests/data/test-read-ctf/test-forward-type-decl.abi: Likewise. * tests/data/test-read-ctf/test-functions-declaration.abi: Likewise. * tests/data/test-read-ctf/test-linux-module.abi: Likewise. * tests/data/test-read-ctf/test-linux-module.abi: Likewise. * tests/data/test-read-ctf/test-list-struct.abi: Likewise. * tests/data/test-read-ctf/test0.abi: Likewise. * tests/data/test-read-ctf/test0.hash.abi: Likewise. * tests/data/test-read-ctf/test1.so.abi: Likewise. * tests/data/test-read-ctf/test1.so.hash.abi: Likewise. * tests/data/test-read-ctf/test2.so.abi: Likewise. * tests/data/test-read-ctf/test2.so.hash.abi: Likewise. * tests/data/test-read-ctf/test3.so.abi: Likewise. * tests/data/test-read-ctf/test3.so.hash.abi: Likewise. * tests/data/test-read-ctf/test4.so.abi: Likewise. * tests/data/test-read-ctf/test4.so.hash.abi: Likewise. * tests/data/test-read-ctf/test5.o.abi: Likewise. * tests/data/test-read-ctf/test7.o.abi: Likewise. * tests/data/test-read-ctf/test8.o.abi: Likewise. * tests/data/test-read-ctf/test9.o.abi: Likewise. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Guillermo E. Martinez
|
8fd02e0a10 |
Use the CTF reader by default when applicable
At the moment, the tools abidw, abidiff, abipkgdiff and kmidiff all use the DWARF front-end by default. When the "--ctf" option is added to the command line, they use the CTF front-end. This patch changes that behaviour in the way described below. If the "--ctf" command line option is passed to the tool and if the binary to analyze contains CTF debug info, then the CTF front-end is used. If the binary contains ONLY CTF debug info, then the CTF front-end is used, even if no "--ctf" option was provided. In all the other cases, the DWARF front-end is used. Of course, the CTF front-end is not used at all if the CTF functionality hasn't been enabled at configure time. This new behaviour is effective for user space and Linux kernel binaries. * doc/manuals/abidiff.rst: Adjust. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * doc/manuals/kmidiff.rst: Likewise. * include/abg-elf-based-reader.h (initialize): Add member function. * include/abg-elf-reader.h (has_{dwarf,ctf}_debug_info): Add predicate functions. * include/abg-tools-utils.h (create_best_elf_based_reader): Add arguments. * src/abg-ctf-reader.cc (process_ctf_typedef, process_ctf_base_type) (process_ctf_function_type, process_ctf_sou_members, process_ctf_forward_type) (process_ctf_struct_type, process_ctf_union_type, process_ctf_array_type) (process_ctf_qualified_type, process_ctf_pointer_type, process_ctf_enum_type): Remove arguments. Using getters to access required information instead. (reader::cur_tu_): Add data member. (initialize): Add arguments. (cur_transl_unit): Add {get,set)ter. (slurp_elf_info): Clear `STATUS_DEBUG_INFO_NOT_FOUND' if corpus is `LINUX_KERNEL_BINARY_ORIGIN'. (reader::lookup_type): Remove. (reader::build_type): New member function. * src/abg-elf-reader.cc (reader::reader): Locate ctf debug info from binary file. (reader::reader): Reset base `fe_iface' constructor. (reader::has_{dwarf,ctf}_debug_info): New definitions. (reader::read_corpus): Set `STATUS_DEBUG_INFO_NOT_FOUND' according to corpus::origin. * src/abg-tools-utils.cc (dir_contains_ctf_archive): Define new member. (file_has_ctf_debug_info): Looks for kernel ctf debug information archive. (maybe_load_vmlinux_{dwarf,ctf}_corpus): Remove. (load_vmlinux_corpus): Define function to load IR from kernel regardless of the corpus::origin. (build_corpus_group_from_kernel_dist_under): Use create_best_elf_based_reader to select the front-end. (create_best_elf_based_reader): Adjust to allow fallback behaviour for different front-ends. * tests/data/Makefile.am: Add tests. * tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt: Adjust. * tests/data/test-read-ctf/test-fallback.abi: New test case. * tests/data/test-read-ctf/test-fallback.c: Likewise. * tests/data/test-read-ctf/test-fallback.o: Likewise. * tests/data/test-read-dwarf/test-fallback.abi: Likewise. * tests/data/test-read-dwarf/test-fallback.c: Likewise. * tests/data/test-read-dwarf/test-fallback.o: Likewise. * tests/test-diff-pkg.cc: Adjust. * tests/test-read-common.cc (test_task::run_abidw): Use the `options:option' field. * tests/test-read-common.h (InOutSpec): Add new member. * tests/test-read-ctf.cc (in_out_specs): Add option field to test suite. Add new test case. * tests/test-read-dwarf.cc: Likewise. * tools/abidiff.cc (main): Use create_best_elf_based_reader. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
7bd6983052 |
Make Front Ends first class citizens
This patch is a reorganization of the code to better support the need for having several different front-ends. In the libabigail pipeline of operation, a front-end is the part of the pipeline that analyses the input file. For instance, to analyse an ELF file, there is going to be one front-end. To analyse an ABIXML file, there is going to be another front-end. The middle-end is the part of the pipeline that interacts with the internal representation of ABIs. The middle-end knows how to analyse, compare ABI corpora provide an internal representation of the comparison result and analyse it as well. The back-end would be the part of the front-end that knows how to serialize internal representations of ABIs and ABI comparison results. One could thus imagine a front-end that understands the DWARF debug info format embedded in an ELF file. Another front-end would be dedicated to the CTF debug info format, and so on. Front-ends can share capabilities. For instance, DWARF and CTF front-ends are ELF based front end. As such, they share capabilities to understand the ELF format. They don't share much with the ABIXML front-end, however, as it's based on XML, which has almost nothing in common with ELF. To support this organization of concepts, this patch introduces a new hierarchy of types in the form of C++ classes. All front-ends implements the "Front End Interface". As such, they all inherit the abigail::fe_iface class. That class provides properties and behaviours that are shared by all front-ends that libabigail supports today. Namely, that class provides access to some of the options that are relevant to operating the front-end, to the ABI corpus or corpus group being constructed and to the suppression specifications that are considered. It also provides an abstract interface to perform the actual loading of the ABI corpus. That abstract interface has to be implemented by every single concrete front-end that is provided in libabigail. Then, there is the "ELF Reader" front-end. Its class name is abigail:🧝:reader. It inherits the abigail::fe_iface class and implements the fe_iface::load_corpus() so that the ELF properties of the ELF file be loaded and exposed in the ABI corpus as returned by the fe_iface::corpus() accessor. This ELF reader front-end also provides lots of capabilities that are specific to accessing ELF content. Then, there is a common base class for ELF-based front-ends to come, named abigail::elf_based_reader, which inherits the abigail:🧝:reader class. The purpose of this base class is to provide common properties and behaviours that are necessary to implement things like a DWARF or a CTF front-end, or any other front-end to support an ELF-based debug info format. Then, there is a CTF front-end which class is named abigail::ctf::reader. It inherits the abigail::elf_based_reader class and implements the fe_iface::load_corpus() interface to load and analyse the CTF-specific properties of the ELF file. To do this, abigail::ctf::reader::load_corpus() re-uses the abigail:🧝:load_corpus() member function to load the generic ELF parts of the ABI corpus. This reader then constructs the internal representation of the ABI corpus and passes it to the middle-end for further analysis. Then, there is a DWARF front-end which class is named abigail::dwarf::reader. It inherits the abigail::elf_based_reader class and implements the fe_iface::load_corpus() interface to load and analyse the DWARF-specific properties of the ELF file. To do this, abigail::dwarf::reader re-uses the abigail:🧝:load_corpus() member function to load the generic ELF parts of the ABI corpus, just like what the CTF front-end does. And then, just like the CTF front-end, this reader then constructs the internal representation of the ABI corpus and passes it to the middle-end for further analysis. Lastly, there is an ABIXML front-end which class is named abigail::abixml::reader. It inherits the abigail::fe_iface class directly. Note that unlike the two previous front-ends, this one doesn't inherit the elf_based_reader base class, for reasons that should be obvious to the astute reader by now. So, this front-end implements the abigail::fe_iface::load_corpus() abstract interface to load the properties for the ABI corpus represented in the ABIXML format, construct the internal representation and pass it to the middle-end for further analysis. The code of the tools got adapted to use these front-ends. The support of CTF is still guarded by #ifdef WITH_CTF pre-processor macros, but the one cool side effect is that the amount of guarded code is reduced. Basically, it's only the creation of the CTF front-end that is guarded. After its creation, what is returned is an instance of abigail::elf_based_reader::reader, exactly like what is returned by the creation of a DWARF front-end. Thus, the rest of the code is exactly the same, regardless of the kind of front-end. I believe this results in a more elegant and maintainable code. As a proof-of-concept, this patch also provides the create_best_elf_based_reader function. This function analyses the ELF file and depending on the kind of debug info it provides, returns the right front-end for it. Maybe at some point, all the #ifdef WITH_CTF guard pre-processing macros will be constrained in a single function like this one that will take the decision of instantiating the right front-end. The rest of the code will be as generic as it gets. The patch adjusts the reference abixml files produced by the CTF front-end because it now emits the <elf-needed> XML element which was not emitted before. This is done because the CTF front-end inherits the elf-reader which reads the "elf-needed" property from the binary, without explicit intervention from the CTF front-end. The patch passes 'make distcheck' on all the supported platforms. * include/abg-fwd.h (build_internal_underlying_enum_type_name): Move this here from src/abg-dwarf-reader.cc. * include/abg-elf-reader-common.h: Delete this file. Its content is going to be put in the new include/abg-elf-reader.h. * src/abg-elf-reader-common.cc: Likewise. * include/abg-{elf-based-reader, elf-reader, fe-iface}.h: Add new files. * src/abg-fe-iface.cc: Likewise. * include/Makefile.am: Add the new file abg-fe-iface.h, abg-elf-based-reader.h and abg-elf-reader.h to source distribution and remove include/abg-elf-reader-common.h from source distribution. * src/abg-ir.cc (build_internal_underlying_enum_type_name): Move this here from abg-dwarf-reader.cc so that it can be used by other readers. * include/abg-reader.h (abigail::abixml::reader): Rename the namespace abigail::xml_reader into this one. (read_context, create_native_xml_read_context) (read_context_get_path, read_corpus_from_native_xml) (read_corpus_from_native_xml_file) (read_corpus_group_from_native_xml) (read_corpus_group_from_native_xml_file): Remove. (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream) (read_translation_unit) (consider_types_not_reachable_from_public_interfaces) (get_types_from_type_id, get_artifact_used_by_relation_map) (load_canonical_type_ids): Take an fe_iface&, not a read_context. (create_reader): Declare new function that returns a fe_iface_sptr. (read_corpus_from_abixml, read_corpus_from_abixml_file) (read_corpus_group_from_abixml) (read_corpus_group_from_abixml_file): Declare new functions. * src/abg-reader.cc (namespace abixml): Rename the xml_reader namespace into this. (abixml::reader_sptr): New typedef. (abixml::reader): Rename read_context into this. Make it inherit the fe_iface interface. (abixml::reader::{m_path, m_env, m_corpus, m_corpus_group, m_exported_decls_builder, m_supprs}): Remove these data members that are now part of the fe_iface parent type. (abixml::reader::{set_environment, get_corpus, set_corpus, set_corpus_group, maybe_add_fn_to_exported_decls, maybe_add_var_to_exported_decls, maybe_check_abixml_canonical_type_stability, suppression_matches_function_sym_name, suppression_matches_variable_name, suppression_matches_variable_sym_name}): Remove. (read_corpus_from_input): Remove. Actually the code of this went into abixml::reader::read_context(). (abixml::reader::get_libxml_reader): Rename the get_reader member function into this. (abixml::add_reader_suppressions): Rename add_read_context_suppressions into this. (abixml::reader::read_corpus): Implement this virtual member function if the fe_iface parent interface. (maybe_set_naming_typedef, advance_cursor) (handle_version_attribute, walk_xml_node_to_map_type_ids) (read_elf_needed_from_input, read_symbol_db_from_input) (get_or_read_and_add_translation_unit, build_needed) (read_elf_needed_from_input, add_read_context_suppressions) (maybe_set_artificial_location, maybe_set_naming_typedef) (build_namespace_decl, build_elf_symbol) (build_elf_symbol_from_reference, build_elf_symbol_db) (build_function_parameter, build_function_decl) (build_function_decl_if_not_suppressed, function_is_suppressed) (type_is_suppressed, build_var_decl_if_not_suppressed) (variable_is_suppressed, variable_is_suppressed, build_var_decl) (build_type_decl, build_qualified_type_decl) (build_pointer_type_def, build_reference_type_def) (build_function_type, build_subrange_type, build_array_type_def) (build_enum_type_decl_if_not_suppressed, build_enum_type_decl) (build_typedef_decl, build_class_decl_if_not_suppressed) (build_union_decl_if_not_suppressed, build_class_decl) (build_union_decl, build_function_tdecl, build_class_tdecl) (build_type_tparameter, build_type_composition) (build_non_type_tparameter, build_non_type_tparameter) (build_template_tparameter, build_template_parameter, build_type) (handle_type_decl, handle_namespace_decl) (handle_qualified_type_decl, handle_pointer_type_def) (handle_reference_type_def, handle_function_type) (handle_array_type_def, handle_enum_type_decl) (handle_typedef_decl, handle_var_decl, handle_function_decl) (handle_class_decl, handle_union_decl, handle_function_tdecl) (read_translation_unit_from_istream): Take or use an abixml::reader rather than a read_context. (read_translation_unit, read_translation_unit_from_input) (consider_types_not_reachable_from_public_interfaces) (get_types_from_type_id, get_artifact_used_by_relation_map) (read_corpus_group_from_input, read_translation_unit) (handle_element_node, read_location, read_artificial_location) (load_canonical_type_ids) : Take an fe_iface&, not a read_context. (create_abixml_reader): Rename create_native_xml_read_context into this. Make it return a fe_iface_sptr. (read_corpus_from_abixml): Rename read_corpus_from_abixml into this. (read_corpus_from_abixml_file): Rename read_corpus_from_native_xml_file into this. (read_context_get_path): Remove. * include/abg-tools-utils.h (abigail::tools_utils::{file_has_dwarf_debug_info, file_has_ctf_debug_info}): Declare new functions. (create_best_elf_based_reader): Declare new function. * include/abg-corpus.h (corpus::add): Pass the translation unit by reference. (corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns): Take a const parameter. * src/abg-corpus-priv.h (corpus::exported_decls_builder::priv::add_{fn,var}_to_exported): Take a const parameter and adjust. * src/abg-corpus.cc (corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns): Take a const parameter. (corpus::add): Take a reference to translation_unit_sptr. * include/abg-suppression.h (abigail::fe_iface): Forward-declare this. (abigail::{suppression_sptr, suppressions_type}): Declare these types here. (abigail::suppr::{suppression_can_match, suppression_matches_function_name, suppression_matches_function_sym_name, suppression_matches_variable_name, suppression_matches_variable_sym_name, suppression_matches_type_name_or_location, is_elf_symbol_suppressed, is_elf_symbol_suppressed, is_function_suppressed, is_variable_suppressed, is_type_suppressed}): Declare these functions here. * src/abg-suppression-priv.h (function_is_suppressed) (variable_is_suppressed, type_is_suppressed) (is_elf_symbol_suppressed): Remove these template functions. * src/abg-suppression.cc (suppression_matches_function_name) (suppression_matches_function_sym_name): Remove. (variable_is_suppressed, suppression_can_match) (suppression_matches_function_name) (suppression_matches_function_sym_name) (suppression_matches_variable_name) (suppression_matches_variable_sym_name) (suppression_matches_type_name_or_location) (is_elf_symbol_suppressed, is_elf_symbol_suppressed) (is_function_suppressed, is_variable_suppressed) (is_type_suppressed): New functions. * include/abg-ctf-reader.h (abigail::ctf::{read_context, create_read_context, read_corpus, read_and_add_corpus_to_group_from_elf, set_read_context_corpus_group, reset_read_context, dic_type_key}): Remove. (ctf::{create_reader, reset_reader}): Declare new functions. * src/abg-ctf-reader.cc (read_context): Remove. (process_ctf_typedef, process_ctf_base_type) (build_ir_node_for_variadic_parameter_type) (process_ctf_function_type, process_ctf_sou_members) (process_ctf_forward_type, process_ctf_struct_type) (process_ctf_union_type, process_ctf_array_type) (process_ctf_qualified_type, process_ctf_pointer_type) (process_ctf_enum_type, fill_ctf_section) (lookup_symbol_in_ctf_archive, dic_type_key): Forward-declare these static functions. (ctf::reader): New class that is the abstraction of the CTF reader. It extends the abigail::elf_based_reader class. This is a renaming of the abigail::ctf::read_context class. (ctf::reader::{elf_handler, elf_fd, elf_handler_dbg, elf_fd_dbg, symtab, debug_info_root_paths_, debug_info_root_paths_}): Remove these data members as they are now properties of the abigail::elf_reader class, which is a parent class of this abigail::ctf::reader class. (ctf::reader::{exported_decls_builder, maybe_add_fn_to_exported_decls, current_corpus_group, has_corpus_group, main_corpus_from_current_group, current_corpus_is_main_corpus_from_current_group, should_reuse_type_from_corpus_group}): Remove these accessors that can now be used from the parent classes abigail::{elf_reader, elf_based_reader}. (ctf::reader::reader): This now delegates to the constructor of elf_based_reader. It doesn't pass any argument to initialize() anymore. (ctf::reader::initialize): Add an overload with no parameter. In the other overload, do not take a pointer to an environment as no new environment can be passed to the instance of reader that is being reset. Adjust the code of the initializer to reflect all the data members that got removed. (ctf::{env, find_ctfa_file, slurp_elf_info, process_ctf_archive, process_ctf_type, lookup_type, read_corpus, ~reader}): New member functions. Most of these were free-form functions that took ctf::read_context as first parameter. In read_corpus, do not set the corpus::LINUX_KERNEL_BINARY_ORIGIN origin as that is now done by elf::reader when it reads the binary. (lookup_type): Remove. These are now member functions of the ctf::reader class. (process_ctf_typedef, process_ctf_base_type) (build_ir_node_for_variadic_parameter_type) (process_ctf_function_type, process_ctf_sou_members) (process_ctf_forward_type, process_ctf_struct_type) (process_ctf_union_type, process_ctf_array_type) (process_ctf_qualified_type, process_ctf_pointer_type): Take a ctf::reader rather an ctf::read_context. Adjust the content of the functions. (process_ctf_type, lookup_type, process_ctf_archive): Remove these and turn them into member functions of ctf::reader. (open_elf_handler, close_elf_handler, find_alt_debuginfo): Remove these ELF handling functions as ELF handling is now done by the elf_reader parent class. (fill_ctf_section): Take a const pointer to Elf_Scn. (slurp_elf_info, find_ctfa_file): Remove this and make it be a member of ctf::reader. Also, make it handle only CTF reader specific pieces. slurp_elf_info now delegates the reading of generic ELF properties to elf::reader by calling elf::reader::read_corpus(). (create_read_context, read_corpus, set_read_context_corpus_group) (read_and_add_corpus_to_group_from_elf): Remove these functions. (create_reader, reset_reader): Create new functions (dic_type_key): Make this static. * include/abg-dwarf-reader.h (abigail::dwarf::elf_type): Move this enum into the namespace abigail::elf_reader in the file include/abg-elf-reader.h. (abigail::dwarf::{read_context, read_context_sptr, create_read_context, read_context_get_path, reset_read_context, add_read_context_suppressions, set_read_context_corpus_group, read_corpus_from_elf, read_and_add_corpus_to_group_from_elf, read_and_add_corpus_to_group_from_elf, add_read_context_suppressions, refers_to_alt_debug_info, has_alt_debug_info, get_soname_of_elf_file, get_type_of_elf_file, set_debug_info_root_path, get_debug_info_root_path, get_show_stats, set_show_stats, set_drop_undefined_syms, set_do_log, set_environment, get_environment}): Remove. * src/abg-dwarf-reader.cc (struct dwfl_deleter, dwfl_sptr) (addr_elf_symbol_sptr_map_type, address_set_type) (address_set_sptr): Delete these types. (read_context::options_type): Remove. The data members of this type got moved to struct fe_iface::options_type. (find_alt_debug_info_link, find_alt_debug_info_path) (find_alt_debug_info, lookup_data_tag_from_dynamic_segment) (elf_file_type, refers_to_alt_debug_info, has_alt_debug_info) (get_soname_of_elf_file, get_type_of_elf_file) : Remove these ELF specific functions from here; move them to the elf_reader namespace. (dwarf::reader): Create new class that extends elf_based_reader. dwarf::read_context is renamed into this type, actually. (dwarf::reader::die_source_dependant_container_set::get_container): Adjust. (dwarf::reader::{supprs_, dwarf_version_, offline_callbacks_, debug_info_root_paths_, handle_, dwarf_, alt_fd_, alt_dwarf_, alt_debug_info_path_, elf_module_, elf_handle_, elf_path_, symtab_section_, cur_corpus_group_, cur_corpus_, dt_needed_, dt_soname_, elf_architecture_, exported_decls_builder_, options_, drop_undefined_syms_}): Remove these ELF-related data members to move them into the elf_reader namespace. (maybe_propagate_canonical_type) (build_translation_unit_and_add_to_ir, build_ir_node_from_die) (add_or_update_class_type, add_or_update_union_type) (build_ir_node_for_void_type) (build_ir_node_for_variadic_parameter_type, build_function_decl) (function_is_suppressed, build_or_get_fn_decl_if_not_suppressed) (build_var_decl, build_or_get_var_decl_if_not_suppressed) (variable_is_suppressed) (propagate_canonical_type) (get_parent_die, get_scope_die, die_is_at_class_scope) (die_location, die_qualified_type_name, die_qualified_name) (die_qualified_type_name_empty) (die_return_and_parm_names_from_fn_type_die) (die_function_signature, die_function_type_is_method_type) (die_pretty_print_type, die_pretty_print_decl, die_pretty_print) (maybe_canonicalize_type, build_subrange_type) (build_subranges_from_array_type_die, compare_dies, die_location) (die_loc_and_name, die_is_effectively_public_decl) (maybe_cache_type_comparison_result) (get_cached_type_comparison_result) (maybe_get_cached_type_comparison_result, die_is_at_class_scope) (die_function_type_is_method_type, die_member_offset) (die_qualified_type_name, die_qualified_decl_name) (die_qualified_name, die_qualified_type_name_empty) (die_return_and_parm_names_from_fn_type_die) (die_function_signature, die_pretty_print_type) (die_pretty_print_decl, die_pretty_print) (at_least_one_decl_only_among_odr_relevant_dies) (compare_as_type_dies, compare_as_decl_and_type_dies) (fn_die_equal_by_linkage_name, try_canonical_die_comparison) (maybe_propagate_canonical_type, propagate_canonical_type) (compare_dies, compare_dies_during_canonicalization) (find_import_unit_point_between_dies, get_parent_die) (get_scope_die, find_lower_bound_in_imported_unit_points) (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_underlying_type, build_enum_type) (finish_member_function_reading) (maybe_finish_function_decl_reading) (lookup_class_or_typedef_from_corpus) (is_function_for_die_a_member_of_class) (add_or_update_member_function, add_or_update_class_type) (add_or_update_union_type, build_qualified_type) (schedule_array_tree_for_late_canonicalization) (maybe_strip_qualification, build_pointer_type_def) (build_reference_type, build_function_type, build_subrange_type) (build_subranges_from_array_type_die, build_array_type) (build_typedef_type, build_or_get_var_decl_if_not_suppressed) (build_var_decl, function_is_suppressed) (build_or_get_fn_decl_if_not_suppressed, variable_is_suppressed) (type_is_suppressed, type_is_suppressed) (get_opaque_version_of_type, create_default_fn_sym) (build_function_decl, maybe_canonicalize_type) (build_ir_node_from_die) (build_ir_node_for_variadic_parameter_type): Take a reference to the new dwarf::reader rather than to the previous read_context. Adjust the function body. (return_comparison_result): Adjust. (dwarf::reader::reader): Adjust this from read_context::read_context. (dwarf::reader::initialize): Adjust from dwarf::read_context::initialize. (dwarf::reader::create): New factory static member function. (dwarf::reader::~reader): This doesn't have to clear anything for now. (dwarf::reader::read_corpus): New virtual member function which implements the fe_iface::read_corpus pure virtual interface. This now delegates the reading of the generic ELF properties to elf::reader by calling elf::reader::read_corpus(). Newer front-ends will be able to do the same. (dwarf::reader::reset_corpus): New member function. (dwarf::reader::read_debug_info_into_corpus): Adjust. This is now a member function. Also, do not set the corpus::LINUX_KERNEL_BINARY_ORIGIN here as it's now set by the elf::reader when it loads the binary. (dwarf::reader::{env, drop_undefined_syms, drop_undefined_syms, dwarf_elf_handle, dwarf_per_die_source, elf_path, compute_canonical_die_offset, get_die_source, get_die_from_offset, get_die_qualified_name, get_die_pretty_type_representation, get_die_qualified_type_name, get_die_pretty_representation, odr_is_relevant, set_canonical_die_offset, get_canonical_die_offset, erase_canonical_die_offset, die_wip_classes_map, die_wip_function_types_map, compare_before_canonicalisation, resolve_declaration_only_classes, resolve_declaration_only_enums, symbol_already_belongs_to_a_function, fixup_functions_with_no_symbols, canonicalize_types_scheduled, tu_die_imported_unit_points_map, die_parent_map, find_symbol_table_section, get_variable_address, exported_decls_builder, load_all_types, load_in_linux_kernel_mode, show_stats, do_log, build_die_parent_maps): Adjust. (offset_pairs_stack_type::rdr_): Changed the ctxt_ into this. (offset_pairs_stack_type::offset_pairs_stack_type): Adjust. (offset_pairs_stack_type::{erase_redundant_type_pair_entry, cancel_canonical_propagated_type}): Adjust. (dwarf::reader::{get_suppressions, offline_callbacks, create_default_dwfl, dwfl_handle, elf_module, elf_handle, add_debug_info_root_paths, add_debug_info_root_path, find_alt_debug_info, dwarf, alt_dwarf, alt_debug_info_path, current_corpus, reset_current_corpus, current_corpus_group, has_corpus_group, main_corpus_from_current_group, current_corpus_is_main_corpus_from_current_group, should_reuse_type_from_corpus_group, function_symbol_is_exported, variable_symbol_is_exported, symtab, dt_needed, dt_soname, elf_architecture, is_elf_symbol_suppressed, load_dt_soname_and_needed, load_elf_architecture, load_elf_properties, maybe_add_fn_to_exported_decls, maybe_add_var_to_exported_decls}): Remove these member functions as they got moved into the elf_reader namespace or into the fe_iface class. (dwarf::read_context::{suppression_can_match, suppression_matches_function_sym_name, suppression_matches_function_name, suppression_matches_variable_name, suppression_matches_variable_sym_name, suppression_matches_type_name_or_location}): Move these into the suppr namespace. Make it take an additional parameter that is reference fe_iface. (dwarf::reader::load_debug_info): Remove. This became merged into dwarf::read_debug_info_into_corpus. (dwarf::{set_debug_info_root_path, get_debug_info_root_path, get_show_stats, set_drop_undefined_syms, set_do_log}): Remove. (add_read_context_suppressions) (set_read_context_corpus_group, read_corpus_from_elf): Remove. (read_debug_info_into_corpus): This became a member function of dwarf::reader. (create_reader): Renamed create_read_context into this. Make it return an elf_based_reader_sptr, like the other front-end factory functions. Adjust. (reset_dwarf_reader): Renamed reset_read_context into this. Adjust. (read_corpus_from_elf): Adjust. * src/abg-elf-based-reader.cc: New file. * src/abg-elf-helpers.h (struct dwfl_deleter, dwfl_sptr) (addr_elf_symbol_sptr_map_type, address_set_sptr): Move these types here from abg-dwarf-reader.cc (initialize_dwfl_callbacks, lookup_data_tag_from_dynamic_segment): * src/abg-elf-helpers.cc (lookup_data_tag_from_dynamic_segment) (lookup_data_tag_from_dynamic_segment, initialize_dwfl_callbacks) (create_new_dwfl_handle, get_soname_of_elf_file): New functions that got moved here from the factorizing of abg-dwarf-reader.cc and abg-ctf-reader.cc. * src/abg-tools-utils.cc (file_has_dwarf_debug_info) (file_has_ctf_debug_info): New functions. (load_generate_apply_suppressions): Take an elf_based_reader, not a dwarf::read_context. (maybe_load_vmlinux_dwarf_corpus): Adjust the body to use the new front-end types. * src/Makefile.am: Add the new files src/abg-{fe-iface, elf-based-reader, elf-reader}.cc to source distribution. Remove src/abg-elf-reader-common.cc. * tools/Makefile.am: Factorize linking to libabigail.so by using LDADD. * tools/abicompat.cc (read_corpus, main): Adjust. * tools/abidiff.cc (set_suppressions) (set_native_xml_reader_options, handle_error, main): Adjust. * tools/abidw.cc (set_suppressions, load_corpus_and_write_abixml) (load_kernel_corpus_group_and_write_abixml): Adjust. * tools/abilint.cc (build_type_use_tree, show_how_type_is_used) (set_suppressions, main): Adjust. * tools/abipkgdiff.cc (elf_file::type, compare, compare_to_self) (create_maps_of_package_content) (compare_prepared_userspace_packages) (self_compare_prepared_userspace_package): Adjust. * tools/abisym.cc: Adjust invocation to abigail::dwarf::lookup_symbol_from_elf, from abigail::dwarf_reader::lookup_symbol_from_elf. * tools/kmidiff.cc (main): Adjust. * tests/print-diff-tree.cc (main): Adjust. * tests/test-abidiff.cc (main): Likewise. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-ir-walker.cc (main): Likewise. * tests/test-read-ctf.cc (test_task_ctf::perform): Likewise. * tests/test-read-dwarf.cc: Remove the useless "using" statements. * tests/test-read-write.cc: Likewise. * tests/test-symtab.cc (read_corpus, TEST_CASE) (assert_symbol_count): Adjust. * tests/data/test-read-ctf/test0.abi: Adjust. * tests/data/test-read-ctf/test0.hash.abi: Likewise. * tests/data/test-read-ctf/test1.so.abi: Likewise. * tests/data/test-read-ctf/test1.so.hash.abi: Likewise. * tests/data/test-read-ctf/test2.so.abi: Likewise. * tests/data/test-read-ctf/test2.so.hash.abi: Likewise. * tests/data/test-read-ctf/test3.so.abi: Likewise. * tests/data/test-read-ctf/test3.so.hash.abi: Likewise. * tests/data/test-read-ctf/test4.so.abi: Likewise. * tests/data/test-read-ctf/test4.so.hash.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
2bb45265d3 |
Use environment by reference.
This patch simplifies how the environment is created and passed around the functions that create front ends. With this change, the environment can simply be allocated on the stack and passed by reference to the libabigail pipeline. At the core of this change, type_or_decl_base::priv now carries a const reference to an environment rather than a pointer. The side effect is that type_or_decl_base can no longer be copied. This is not a problem because throughout the years I could see that the use case to copy ABI artifacts is just not there. Similarly, elf_symbol::priv carries a const reference to environment now, no more a pointer. Getters, setters and code that use the environment from the ABI artifacts are updated accordingly. The DWARF front-end can now be created by code that looks like this, for instance: vector<char**> debug_info_paths; abigail::ir::environment env; abigail::ctf_reader::read_context_sptr reader = abigail::dwarf_reader::create_read_context("elf/file/to/analyze", debug_info_paths, env); elf_reader::status reading_status; corpus_sptr abi_corpus = abigail::dwarf_reader::read_corpus_from_elf(reader, reading_status); /* then do something with the resulting abi_corpus*/ Note how, you don't need to use the "new" operator to instantiate the "env" object of type environment. It can sit on the stack and it's passed to the read_corpus_from_elf function by reference. In other words, the internal representation types have been changed to refer to the environment by reference, rather than requiring a pointer to it. * include/abg-corpus.h (corpus::corpus) (corpus_group::corpus_group): Take environment&, not environment* as parameter. (corpus::{get_environment, set_environment}): Take or return environment&, not environment*. * src/abg-corpus.cc (corpus::corpus): Likewise. (corpus::{get_environment, set_environment}): Likewise. (corpus::add): Don't update the environment of the translation unit. (corpus::{record_type_as_reachable_from_public_interfaces, type_is_reachable_from_public_interfaces, init_format_version, add_corpus}): Adjust for accessing a reference to environment, rather than a pointer. * include/abg-ctf-reader.h (create_read_context): Take or return environment&, not environment*. * src/abg-ctf-reader.cc (read_context::ir_env): Make this a reference to environment, not pointer anymore. (read_context::read_context): Initialize the reference to environment. (read_context::initialize): Do not re-set the environment. (process_ctf_base_type) (build_ir_node_for_variadic_parameter_type) (process_ctf_enum_type, read_corpus): Adjust for accessing a reference to environment, rather than a pointer. (create_read_context, reset_read_context): Take environment&, not environment*. * include/abg-dwarf-reader.h (create_read_context) (reset_read_context, read_corpus_from_elf) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf): Likewise. (read_context::options_type::env): Make this be a reference to environment, not a pointer. (read_context::options::options): Remove the default constructor. Add a new one to initialize the environment data member. (read_context::read_context): Take environment&, not environment*. Initialize the options_ data member. (read_context::initialize): Do not take or initialize an environment anymore. (read_context::env): Return or take environment&, not environment*. (read_context::{get_die_qualified_name, get_die_qualified_type_name, get_die_pretty_type_representation, get_die_pretty_representation, compare_before_canonicalisation}) (build_translation_unit_and_add_to_ir, build_function_type) (build_typedef_type, read_debug_info_into_corpus) (read_debug_info_into_corpus, build_ir_node_from_die) (build_ir_node_for_variadic_parameter_type, has_alt_debug_info): Adjust to use an environment&, not a pointer. (create_default_fn_sym, create_read_context) (read_corpus_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take environment&, not environment*. (reset_read_context): Do not take or reset environment* anymore. * include/abg-fwd.h (type_or_void): Likewise. * include/abg-ir.h (translation_unit::translation_unit): Likewise. (translation_unit::{get_environment, set_environment}): Likewise. (elf_symbol::elf_symbol): Likewise. (elf_symbol::create): Remove the overload that takes no parameter. Then for overload that take parameters then take environment&, not environment*. (elf_symbol::get_environment): Take environment&, not environment*. (type_or_decl_base::type_or_decl_base): Make the copy constructor and assignment operator private. (type_or_decl_base::{s,g}et_environment): Take or return environment& not environment*. (type_or_decl_base::set_environment_for_artifact): Erase these methods. (decl_base::decl_base): Make copy constructor private. Take or return environment&, not environment* for the other constructors. (scope_decl::scope_decl): Take or return environment&, not environment*. (type_base::type_base): Likewise. (scope_type_decl::scope_type_decl): Likewise. (namespace_decl::namespace_decl): Likewise. (qualified_type_def::qualified_type_def): Likewise. (pointer_type_def::pointer_type_def): Likewise. (reference_type_def::reference_type_def): Likewise. (array_type_def::subrange_type::subrange_type): Likewise. (enum_type_def::enumerator::enumerator): Likewise. (enum_type_def::enumerator::{get_name, get_qualified_name}): Return a string&, no more interned_string&. As the enumerator don't have an enumerator anymore, there is no way to intern the string anymore. Hopefully this won't incur a performance loss. (typedef_decl::typedef_decl, function_type::function_type) (method_type::method_type, template_decl::template_decl) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (class_or_union::class_or_union, class_decl::class_decl) (union_decl::union_decl): Take or return environment&, not environment*. * include/abg-reader.h (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream) (create_native_xml_read_context, create_native_xml_read_context) (read_corpus_from_native_xml, read_corpus_from_native_xml_file) (read_corpus_group_from_native_xml) (read_corpus_group_from_native_xml_file): Likewise. * include/abg-tools-utils.h (build_corpus_group_from_kernel_dist_under): Likewise. * src/abg-tools-utils.cc (maybe_load_vmlinux_dwarf_corpus) (maybe_load_vmlinux_ctf_corpus) (build_corpus_group_from_kernel_dist_under): Likewise. * include/abg-writer.h (create_write_context): Likewise. * src/abg-writer.cc (id_manager::m_env, id_manager::id_manager) (id_manager::get_environment, id_manager::get_id) (id_manager::get_id_with_prefix): Adjust. (write_context::m_env, write_context::write_context) (write_context::get_environment, write_context::get_config) (write_context::get_id_for_type, write_context::decl_is_emitted) (write_context::record_decl_as_emitted, create_write_context) (write_class_decl): Likewise. * src/abg-comparison.cc (compute_diff): Stop ensuring that the two artifacts being compare are in the same environment. Now that the environment is passed by reference, the potential for accendentally comparing artifacts coming from different environments is very low, given how the API is used in practice. This is in the overloads for decl_base_sptr, type_base_sptr, var_decl_sptr, pointer_type_def_sptr, array_type_def_sptr, reference_type_def_sptr, qualified_type_def_sptr, enum_type_decl_sptr, class_decl_sptr, class_decl::base_spec_sptr, union_decl_sptr, scope_decl_sptr, function_decl::parameter_sptr, function_type_sptr, function_decl_sptr, type_decl_sptr, typedef_decl_sptr, translation_unit_sptr, corpus_sptr. * src/abg-corpus-priv.h (corpus::priv::env): Make this be a reference to environments, not a pointer. (corpus::priv::priv): Pass environment&, not environment*. * src/abg-ir-priv.h (translation_unit::priv::env_): Make this an environment&, not an environment* anymore. (translation_unit::priv::priv): Take an environment&, not an environment*. (environment::priv::{confirm_ct_propagation_for_types_dependant_on, confirm_ct_propagation, cancel_ct_propagation_for_types_dependant_on, mark_as_being_compared, unmark_as_being_compared, comparison_started, mark_as_being_compared, comparison_started}): Adjust to use an environment&, not a pointer. * src/abg-ir.cc (class environment_setter): Remove this class. (push_composite_type_comparison_operands) (pop_composite_type_comparison_operands, try_canonical_compare) (return_comparison_result, translation_unit::{get_global_scope, bind_function_type_life_time}): Adjust. (translation_unit::{translation_unit, get_environment}): Take or get an environment&, not an environment*. Remove the getter that returns an environment*. (elf_symbol::priv::env_): Make this an environment&, not an environment*. (elf_symbol::priv::priv): Adjust. (elf_symbol::elf_symbol): Remove the default constructor. Change the one that takes an environment. (elf_symbol::create): Remove the default one. Adjust the one that takes an environment. (elf_symbol::get_environment): Adjust. (elf_symbol::set_environment_for_artifact): Remove. (environment::{get_void_type, get_variadic_parameter_type}): Adjust. (type_or_decl_base::priv::env_): Make this be a const environment&, not a const environment*. (type_or_decl_base::priv::priv): Adjust. (type_or_decl_base::type_or_decl_base): Remove the default and copy constructor. (type_or_decl_base::{set_environment, operator=}) (set_environment_for_artifact): Remove. (type_or_decl_base::get_environment): Adjust. (decl_base::{decl_base, set_name, set_naming_typedef, set_linkage_name}): Adjust. (get_decl_name_for_comparison, strip_typedef) (strip_useless_const_qualification): Adjust. (scope_decl::{scope_decl, add_member_decl, insert_member_decl}): Adjust. (get_generic_anonymous_internal_type_name, get_type_name) (get_name_of_pointer_to_type, get_name_of_reference_to_type) (get_name_of_qualified_type, get_function_type_name) (get_method_type_name, is_void_pointer_type, lookup_basic_type) (lookup_union_type, lookup_union_type_per_location) (lookup_enum_type, lookup_typedef_type, lookup_pointer_type) (lookup_type, lookup_basic_type_per_location) (lookup_basic_type_per_location, lookup_basic_type) (lookup_class_type, lookup_class_types) (lookup_class_type_per_location, lookup_union_type) (lookup_enum_type, lookup_enum_types) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, maybe_update_types_lookup_map) (maybe_update_types_lookup_map) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (demangle_cplus_mangled_name, type_or_void) (types_defined_same_linux_kernel_corpus_public) (compare_types_during_canonicalization) (type_base::get_canonical_type_for, type_base::type_base) (type_base::get_cached_pretty_representation) (type_decl::type_decl, type_decl::get_qualified_name): Adjust. (scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl, qualified_type_def::build_name) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (qualified_type_def::set_underlying_type) (pointer_type_def::pointer_type_def) (pointer_type_def::set_pointed_to_type) (reference_type_def::reference_type_def) (reference_type_def::set_pointed_to_type) (array_type_def::subrange_type::subrange_type) (array_type_def::array_type_def, array_type_def::update_size) (array_type_def::set_element_type) (array_type_def::append_subranges) (array_type_def::get_qualified_name, enum_has_non_name_change): Adjust. (enum_type_decl::enumerator::priv::env_): Remove this pointer to env. This is because the enumerator must be copy-able. As the enumerator doesn't have an env anymore, it can't intern strings. So the enumerator name and qualified name is not going to be interned. If that incurs a performance hit, we'll reconsider this decision. For now, it seems to work OK. As it simplifies things, I am keeping this for now. (enum_type_decl::enumerator::priv::{name, qualified_name}): Make this be string, not interned_string. (enum_type_decl::enumerator::get_environment): Remove. (enum_type_decl::enumerator::priv::priv): Adjust. (enum_type_decl::enumerator::enumerator) (enum_type_decl::enumerator::operator=) (enum_type_decl::enumerator::get_name) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name): Likewise. (typedef_decl::typedef_decl): Adjust. (var_decl::get_id, var_decl::get_qualified_name): Adjust. (function_type::function_type, method_type::method_type) (function_decl::get_pretty_representation_of_declarator) (function_decl::set_symbol): Likewise. (function_decl::get_id, function_decl::parameter::get_type) (function_decl::parameter::get_type_name) (function_decl::parameter::get_type_pretty_representation) (function_decl::parameter::get_name_id) (class_or_union::class_or_union, class_decl::class_decl) (class_decl::add_base_specifier, union_decl::union_decl) (union_decl::union_decl, template_decl::template_decl) (class_tdecl::class_tdecl) (maybe_cancel_propagated_canonical_type) (dump_classes_being_compared) (dump_fn_types_being_compared, copy_member_function) (maybe_propagate_canonical_type, keep_type_alive) (is_non_canonicalized_type, qualified_name_setter::do_update): Likewise. (equals): Adjust the overloads for var_decl, function_type, class_or_union, class_decl, union_decl. * src/abg-reader.cc (read_context::m_env): Make this be an environment&, not an environment*. (read_context::read_context): Adjust (read_context::set_environment): Remove. (read_context::{get_environment, maybe_check_abixml_canonical_type_stability}): Adjust. (read_corpus_from_input, read_corpus_group_from_native_xml) (read_corpus_group_from_native_xml_file) (read_translation_unit_from_file) (read_translation_unit_from_buffer, read_translation_unit) (maybe_map_type_with_type_id, build_namespace_decl) (build_elf_symbol, build_function_parameter, build_function_decl) (build_function_type, build_enum_type_decl, build_class_decl) (build_union_decl, build_function_tdecl, build_class_tdecl) (build_type_tparameter, read_translation_unit_from_istream) (create_native_xml_read_context, read_corpus_from_native_xml): Likewise. * src/abg-symtab-reader.h (symtab::load): Likewise. * src/abg-symtab-reader.cc (symtab::load): Likewise. * tests/print-diff-tree.cc (main): Likewise. * tests/test-abidiff.cc (main): Likewise. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-ir-walker.cc (main): Likewise. * tests/test-read-ctf.cc (test_task_ctf::perform): Likewise. * tests/test-symtab.cc (read_corpus): Likewise. * tools/abicompat.cc (read_corpus, main): Likewise. * tools/abidiff.cc (main): Likewise. * tools/abidw.cc (load_corpus_and_write_abixml) (load_kernel_corpus_group_and_write_abixml, main): Likewise. * tools/abilint.cc (main): Likewise. * tools/abipkgdiff.cc (compare, compare_to_self) (compare_prepared_linux_kernel_packages, compare_task::perform): Likewise. * tools/abisym.cc (main): Likewise. * tools/kmidiff.cc (main): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Aleksei Vetrov
|
c6ac7db457 |
symtab: add support for CRC values from __kcrctab
New kernels changed the format of storing CRC values from absolute symbol value to the address in __kcrctab or __kcrctab_gpl section. This change adds support for CRC values described in this format. * src/abg-elf-helpers.h (get_crc_for_symbol): Defined new helper function to extract CRC from ELF symbol. * src/abg-elf-helpers.cc (get_crc_for_symbol): Implemented this function with support of old and new CRC values format. * src/abg-symtab-reader.cc (symtab::load_): Used the new function when building CRC values map. Change-Id: I7de5c737d5caaef0c5b7b2ea0d448368889a16be Signed-off-by: Aleksei Vetrov <vvvvvv@google.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |