dwarf-reader: Better handle the absence of a die->parent map
authorDodji Seketeli <dodji@redhat.com>
Fri, 26 Aug 2022 13:14:37 +0000 (15:14 +0200)
committerDodji Seketeli <dodji@redhat.com>
Mon, 29 Aug 2022 09:03:43 +0000 (11:03 +0200)
When analysing the ld.so binary, the DWARF reader drops the
description of the rtld_global_ro global variable on the floor.  This
is because it fails to get the decl that the rtld_global_ro variable
belongs to.  So it doesn't know where the put the description of
rtld_global_ro, in the IR.

The root cause is that the DWARF partial_unit that contains the
description of the type of the rtld_global_ro variable doesn't contain
any description of the language its types originate from.  The DWARF
reader needs to know the type, to know if it needs to construct a map
that associates each type/decl DIE to their parent DIE.  This is
useful to determine which namespace a given DIE belongs to.  But then
this is needed only for languages that support naming organising
devices like namespaces, namely, C++, Ada, Java etc.  For C, the DWARF
reader knows that by default, all decls/types belong to the global
namespace.  But then in this particular case, the partial_unit doesn't
carry any language information, so libabigail just drops the ball on
the floor, so there is no information for the rtld_global_ro variable.

The fix is thus to consider the absence of a DIE->PARENT map as
implying that all decls are defined in the global namespace.

* src/abg-dwarf-reader.cc (get_scope_for_die): Consider that in
the absence of the DIE->PARENT map, all decls are in the global.
namespace.
* tests/data/test-abidiff-exit/ld-2.28-210.so: New test.
* tests/data/test-abidiff-exit/ld-2.28-211.so: Likewise.
* tests/data/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt: New reference test output.
* tests/test-abidiff-exit.cc (in_out_specs): Add the test above to
the harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
src/abg-dwarf-reader.cc
tests/data/test-abidiff-exit/ld-2.28-210.so [new file with mode: 0755]
tests/data/test-abidiff-exit/ld-2.28-211.so [new file with mode: 0755]
tests/data/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt [new file with mode: 0644]
tests/test-abidiff-exit.cc

index e5159c8930b1977334cf9915d14c77d035873987..32eaacba4eda2e6705c0c830b7cb832b760abf6f 100644 (file)
@@ -11648,8 +11648,12 @@ get_scope_for_die(read_context& ctxt,
 
   translation_unit::language die_lang = translation_unit::LANG_UNKNOWN;
   ctxt.get_die_language(die, die_lang);
-  if (is_c_language(die_lang))
+  if (is_c_language(die_lang)
+      || ctxt.die_parent_map(source_of_die).empty())
     {
+      // In units for the C languages all decls belong to the global
+      // namespace.  This is generally the case if Libabigail
+      // determined that no DIE -> parent map was needed.
       ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
       return ctxt.global_scope();
     }
diff --git a/tests/data/test-abidiff-exit/ld-2.28-210.so b/tests/data/test-abidiff-exit/ld-2.28-210.so
new file mode 100755 (executable)
index 0000000..a38a9ad
Binary files /dev/null and b/tests/data/test-abidiff-exit/ld-2.28-210.so differ
diff --git a/tests/data/test-abidiff-exit/ld-2.28-211.so b/tests/data/test-abidiff-exit/ld-2.28-211.so
new file mode 100755 (executable)
index 0000000..a245b2b
Binary files /dev/null and b/tests/data/test-abidiff-exit/ld-2.28-211.so differ
diff --git a/tests/data/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt b/tests/data/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt
new file mode 100644 (file)
index 0000000..16d4dc9
--- /dev/null
@@ -0,0 +1,16 @@
+Functions changes summary: 0 Removed, 0 Changed, 0 Added function
+Variables changes summary: 0 Removed, 1 Changed, 0 Added variable
+
+1 Changed variable:
+
+  [C] 'rtld_global_ro _rtld_global_ro' was changed at ldsodefs.h:675:1:
+    type of variable changed:
+      type size hasn't changed
+      6 data member changes:
+        'int (const char**, const char**, bool*, void (void*)*, void*)* _dl_catch_error' offset changed from 5120 to 5376 (in bits) (by +256 bits)
+        'void (void*)* _dl_error_free' offset changed from 5184 to 5440 (in bits) (by +256 bits)
+        'void* (link_map*)* _dl_tls_get_addr_soft' offset changed from 5248 to 5120 (in bits) (by -128 bits)
+        'int ()* _dl_discover_osversion' offset changed from 5312 to 5184 (in bits) (by -128 bits)
+        'audit_ifaces* _dl_audit' offset changed from 5376 to 5248 (in bits) (by -128 bits)
+        'unsigned int _dl_naudit' offset changed from 5440 to 5312 (in bits) (by -128 bits)
+
index 12c3ec935f790bcb9ce78a03bbecfa1f28a6a3ec..0ba99992b6721cff8d4c3e442fdb22f0d48e0406 100644 (file)
@@ -448,6 +448,17 @@ InOutSpec in_out_specs[] =
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-PR29144-report-2.txt",
     "output/test-abidiff-exit/test-PR29144-report-2.txt"
+  },
+    {
+    "data/test-abidiff-exit/ld-2.28-210.so",
+    "data/test-abidiff-exit/ld-2.28-211.so",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt",
+    "output/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt"
   },
   {0, 0, 0 ,0, 0, 0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
 };