public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Stable type ids
@ 2020-06-12  9:59 Giuliano Procida
  2020-06-12  9:59 ` [PATCH 1/2] abg-writer: Add support for stable hash " Giuliano Procida
  2020-06-12  9:59 ` [PATCH 2/2] Add tests for abidw --type-id-style hash Giuliano Procida
  0 siblings, 2 replies; 8+ messages in thread
From: Giuliano Procida @ 2020-06-12  9:59 UTC (permalink / raw)
  To: libabigail; +Cc: dodji, kernel-team, gprocida

Following up on
https://sourceware.org/pipermail/libabigail/2020q2/001973.html and
https://sourceware.org/pipermail/libabigail/2020q2/002308.html, this
patch series adds support for stable type ids in the form of a hash of
libabigail's internal type names.

The hash function used is 32-bit FNV-1a, resulting in 8 hex digit type
ids - shorter than the existing (default) counter-based ids. mjw's
suggestion could be accomodated as a third style.

Hash collisions are resolved by linear probing. Tests so far have only
found collisions caused by hashing identically-named distinct types.
If anonymous structs, unions and enums are given unique but stable
(internal) names, then the quality of this naming scheme will improve.

In general, it takes about 77k distinct names to reach a probability
of 0.5 of there being at least one collision.

https://en.wikipedia.org/wiki/Birthday_problem#Probability_table

FNV can accommodate other bit lengths.

http://www.isthe.com/chongo/tech/comp/fnv

Regards,
Giuliano.

Giuliano Procida (2):
  abg-writer: Add support for stable hash type ids.
  Add tests for abidw --type-id-style hash.

 doc/manuals/abidw.rst                         |  15 +-
 include/abg-writer.h                          |  10 ++
 src/abg-writer.cc                             |  95 ++++++++++++-
 tests/data/Makefile.am                        |   9 ++
 tests/data/test-read-dwarf/test0.hash.abi     |  70 ++++++++++
 tests/data/test-read-dwarf/test1.hash.abi     | 129 ++++++++++++++++++
 tests/data/test-read-dwarf/test2.so.hash.abi  |  79 +++++++++++
 tests/data/test-read-dwarf/test3.so.hash.abi  |  19 +++
 tests/data/test-read-dwarf/test4.so.hash.abi  |  23 ++++
 tests/data/test-read-dwarf/test5.o.hash.abi   |  13 ++
 tests/data/test-read-dwarf/test6.so.hash.abi  |  42 ++++++
 tests/data/test-read-dwarf/test7.so.hash.abi  |  77 +++++++++++
 .../test8-qualified-this-pointer.so.hash.abi  |  37 +++++
 tests/test-read-dwarf.cc                      | 107 ++++++++++++++-
 tools/abidw.cc                                |  20 ++-
 15 files changed, 728 insertions(+), 17 deletions(-)
 create mode 100644 tests/data/test-read-dwarf/test0.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test1.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test2.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test3.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test4.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test5.o.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test6.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test7.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi

-- 
2.27.0.290.gba653c62da-goog


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] abg-writer: Add support for stable hash type ids.
  2020-06-12  9:59 [PATCH 0/2] Stable type ids Giuliano Procida
@ 2020-06-12  9:59 ` Giuliano Procida
  2020-06-15 17:18   ` Dodji Seketeli
                     ` (2 more replies)
  2020-06-12  9:59 ` [PATCH 2/2] Add tests for abidw --type-id-style hash Giuliano Procida
  1 sibling, 3 replies; 8+ messages in thread
From: Giuliano Procida @ 2020-06-12  9:59 UTC (permalink / raw)
  To: libabigail; +Cc: dodji, kernel-team, gprocida

The type ids currently emitted by the XML writer are simply type-id-1,
type-id-2 etc. Additions or removals of types early in this sequence
result in cascading changes to many other XML elements.

This commit adds support for stable type ids in the form of hashes of
libabigail's internal type names. On fairly rare occasions (typically
involving unnamed types), the names of two distinct types can be the
same. In any case, if there is a hash collision the XML writer will
find the next unused id and so preserve uniqueness.

Diffs between XML files produced using --type-id-style hash will be
much smaller and easier to review.

	* doc/manuals/abidw.rst: Replace stray documentation of
	--named-type-ids with documention of new --type-id-style
	option.
	* include/abg-writer.h (type_id_style_kind): Add new enum.
	(set_type_id_style): Add new write_context setter.
	(set_common_options): Set type id style in write context.
	* src/abg-writer.cc (stable_hash): Add new 32-bit FNV-1a hash
	function. (write_context): Add m_type_id_style member to
	record type style to use, defaulting to COUNTER. Add
	m_used_type_id_hashes to record already used hashes.
	(write_context::get_type_id_style): Add new getter.
	(write_context::set_type_id_style): Add new setter.
	(get_id_for_type): Add support for HASH style.
	(set_type_id_style): Add new helper function.
	* tools/abidw.cc (options): Add type_id_style member.
	(display_usage): Add description of --type-id-style option.
	(parse_command_line): Parse --type-id-style option.

Signed-off-by: Giuliano Procida <gprocida@google.com>
---
 doc/manuals/abidw.rst | 15 +++----
 include/abg-writer.h  | 10 +++++
 src/abg-writer.cc     | 95 +++++++++++++++++++++++++++++++++++++++----
 tools/abidw.cc        | 20 ++++++++-
 4 files changed, 125 insertions(+), 15 deletions(-)

diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst
index e1fce997..9472cfe8 100644
--- a/doc/manuals/abidw.rst
+++ b/doc/manuals/abidw.rst
@@ -197,13 +197,14 @@ Options
     1.8 will not set the default size and will interpret types without
     a size-in-bits attribute as zero sized.
 
-  * ``--named-type-ids``
-
-    Without this option ids used to reference types in the XML file
-    use simple numbers.  With this option the ids used are derived
-    from the type name to make it easier to see which type is
-    referenced and make the XML file more stable in case new types are
-    added (without this option that might mean all id numbers change).
+  * ``--type-id-style`` ( ``counter`` | ``hash`` )
+
+    This option controls how types are idenfied in the generated XML
+    files.  The default ``counter`` style just numbers (with
+    ``type-id-`` as prefix) the types in the order they are
+    encountered.  The ``hash`` style uses a (stable, portable) hash of
+    the type names that libabigail uses internally and is intended
+    to make the XML files easier to diff.
 
   * ``--check-alternate-debug-info-base-name`` <*elf-path*>
 
diff --git a/include/abg-writer.h b/include/abg-writer.h
index 8086d828..021a95b7 100644
--- a/include/abg-writer.h
+++ b/include/abg-writer.h
@@ -38,6 +38,12 @@ namespace xml_writer
 
 using namespace abigail::ir;
 
+enum type_id_style_kind
+{
+  COUNTER,
+  HASH
+};
+
 class write_context;
 
 /// A convenience typedef for a shared pointer to write_context.
@@ -74,6 +80,9 @@ set_short_locs(write_context& ctxt, bool flag);
 void
 set_write_parameter_names(write_context& ctxt, bool flag);
 
+void
+set_type_id_style(write_context& ctxt, type_id_style_kind style);
+
 /// A convenience generic function to set common options (usually used
 /// by Libabigail tools) from a generic options carrying-object, into
 /// a given @ref write_context.
@@ -96,6 +105,7 @@ set_common_options(write_context& ctxt, const OPTS& opts)
   set_write_parameter_names(ctxt, opts.write_parameter_names);
   set_short_locs(ctxt, opts.short_locs);
   set_write_default_sizes(ctxt, opts.default_sizes);
+  set_type_id_style(ctxt, opts.type_id_style);
 }
 
 void
diff --git a/src/abg-writer.cc b/src/abg-writer.cc
index bafa3024..f0dbd096 100644
--- a/src/abg-writer.cc
+++ b/src/abg-writer.cc
@@ -27,6 +27,7 @@
 
 #include "config.h"
 #include <assert.h>
+#include <iomanip>
 #include <iostream>
 #include <fstream>
 #include <sstream>
@@ -56,6 +57,39 @@ ABG_BEGIN_EXPORT_DECLARATIONS
 ABG_END_EXPORT_DECLARATIONS
 // </headers defining libabigail's API>
 
+namespace
+{
+/// Compute a stable string hash.
+///
+/// std::hash has no portability or stability guarantees so is
+/// unsuitable where reproducibility is a requirement.
+///
+/// This is the 32-bit FNV-1a algorithm. The algorithm, reference code
+/// and constants are all unencumbered. It is fast and has reasonable
+/// distribution properties.
+///
+/// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
+///
+/// @param str the string to hash.
+///
+/// @return an unsigned 32 bit hash value.
+uint32_t
+stable_hash(const std::string& str)
+{
+  const uint32_t prime = 0x01000193;
+  const uint32_t offset_basis = 0x811c9dc5;
+  uint32_t hash = offset_basis;
+  for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
+    {
+      uint8_t byte = *i;
+      hash = hash ^ byte;
+      hash = hash * prime;
+    }
+  return hash;
+}
+
+} // namespace
+
 namespace abigail
 {
 using std::cerr;
@@ -177,7 +211,9 @@ class write_context
   bool					m_write_parameter_names;
   bool					m_short_locs;
   bool					m_write_default_sizes;
+  type_id_style_kind			m_type_id_style;
   mutable type_ptr_map			m_type_id_map;
+  mutable std::unordered_set<uint32_t>	m_used_type_id_hashes;
   mutable type_ptr_set_type		m_emitted_type_set;
   type_ptr_set_type			m_emitted_decl_only_set;
   // A map of types that are referenced by emitted pointers,
@@ -214,7 +250,8 @@ public:
       m_write_elf_needed(true),
       m_write_parameter_names(true),
       m_short_locs(false),
-      m_write_default_sizes(true)
+      m_write_default_sizes(true),
+      m_type_id_style(COUNTER)
   {}
 
   /// Getter of the environment we are operating from.
@@ -374,6 +411,24 @@ public:
   set_show_locs(bool f)
   {m_show_locs = f;}
 
+  /// Getter of the "type-id-style" option.
+  ///
+  /// This option controls the kind of type ids used in XML output.
+  ///
+  /// @return the value of the "type-id-style" option.
+  type_id_style_kind
+  get_type_id_style() const
+  {return m_type_id_style;}
+
+  /// Setter of the "type-id-style" option.
+  ///
+  /// This option controls the kind of type ids used in XML output.
+  ///
+  /// @param style the new value of the "type-id-style" option.
+  void
+  set_type_id_style(type_id_style_kind style)
+  {m_type_id_style = style;}
+
   /// Getter of the @ref id_manager.
   ///
   /// @return the @ref id_manager used by the current instance of @ref
@@ -421,14 +476,29 @@ public:
       c = const_cast<type_base*>(t);
 
     type_ptr_map::const_iterator it = m_type_id_map.find(c);
-    if (it == m_type_id_map.end())
+    if (it != m_type_id_map.end())
+      return it->second;
+
+    switch (m_type_id_style)
       {
-	interned_string id =
-	  get_id_manager().get_id_with_prefix("type-id-");
-	m_type_id_map[c] = id;
-	return id;
+      case COUNTER:
+        {
+          interned_string id = get_id_manager().get_id_with_prefix("type-id-");
+          return m_type_id_map[c] = id;
+        }
+      case HASH:
+        {
+          interned_string pretty = c->get_cached_pretty_representation(true);
+          size_t hash = stable_hash(*pretty.raw());
+          while (!m_used_type_id_hashes.insert(hash).second)
+            ++hash;
+          std::ostringstream os;
+          os << std::hex << std::setfill('0') << std::setw(8) << hash;
+          return m_type_id_map[c] = c->get_environment()->intern(os.str());
+        }
       }
-    return it->second;
+    ABG_ASSERT_NOT_REACHED;
+    return interned_string();
   }
 
   string
@@ -2131,6 +2201,17 @@ void
 set_write_default_sizes(write_context& ctxt, bool flag)
 {ctxt.set_write_default_sizes(flag);}
 
+/// Set the 'type-id-style' property.
+///
+/// This property controls the kind of type ids used in XML output.
+///
+/// @param ctxt the context to set this property on.
+///
+/// @param style the new value of the 'type-id-style' property.
+void
+set_type_id_style(write_context& ctxt, type_id_style_kind style)
+{ctxt.set_type_id_style(style);}
+
 /// Serialize the canonical types of a given scope.
 ///
 /// @param scope the scope to consider.
diff --git a/tools/abidw.cc b/tools/abidw.cc
index 9aec3112..7de31737 100644
--- a/tools/abidw.cc
+++ b/tools/abidw.cc
@@ -70,7 +70,10 @@ using abigail::comparison::corpus_diff_sptr;
 using abigail::comparison::compute_diff;
 using abigail::comparison::diff_context_sptr;
 using abigail::comparison::diff_context;
+using abigail::xml_writer::COUNTER;
+using abigail::xml_writer::HASH;
 using abigail::xml_writer::create_write_context;
+using abigail::xml_writer::type_id_style_kind;
 using abigail::xml_writer::write_context_sptr;
 using abigail::xml_writer::write_corpus;
 using abigail::xml_reader::read_corpus_from_native_xml_file;
@@ -114,6 +117,7 @@ struct options
   bool			do_log;
   bool			drop_private_types;
   bool			drop_undefined_syms;
+  type_id_style_kind	type_id_style;
 
   options()
     : display_version(),
@@ -136,7 +140,8 @@ struct options
       annotate(),
       do_log(),
       drop_private_types(false),
-      drop_undefined_syms(false)
+      drop_undefined_syms(false),
+      type_id_style(COUNTER)
   {}
 
   ~options()
@@ -175,6 +180,7 @@ display_usage(const string& prog_name, ostream& out)
     << "  --no-write-default-sizes  do not emit pointer size when it equals"
     " the default address size of the translation unit\n"
     << "  --no-parameter-names  do not show names of function parameters\n"
+    << "  --type-id-style (counter|hash)  type-id style (counter(default): type-id-number; hash: hexdigits\n"
     << "  --check-alternate-debug-info <elf-path>  check alternate debug info "
     "of <elf-path>\n"
     << "  --check-alternate-debug-info-base-name <elf-path>  check alternate "
@@ -301,6 +307,18 @@ parse_command_line(int argc, char* argv[], options& opts)
 	opts.default_sizes = false;
       else if (!strcmp(argv[i], "--no-parameter-names"))
 	opts.write_parameter_names = false;
+      else if (!strcmp(argv[i], "--type-id-style"))
+        {
+          ++i;
+          if (i >= argc)
+            return false;
+          if (!strcmp(argv[i], "counter"))
+            opts.type_id_style = COUNTER;
+          else if (!strcmp(argv[i], "hash"))
+            opts.type_id_style = HASH;
+          else
+            return false;
+        }
       else if (!strcmp(argv[i], "--check-alternate-debug-info")
 	       || !strcmp(argv[i], "--check-alternate-debug-info-base-name"))
 	{
-- 
2.27.0.290.gba653c62da-goog


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/2] Add tests for abidw --type-id-style hash.
  2020-06-12  9:59 [PATCH 0/2] Stable type ids Giuliano Procida
  2020-06-12  9:59 ` [PATCH 1/2] abg-writer: Add support for stable hash " Giuliano Procida
@ 2020-06-12  9:59 ` Giuliano Procida
  1 sibling, 0 replies; 8+ messages in thread
From: Giuliano Procida @ 2020-06-12  9:59 UTC (permalink / raw)
  To: libabigail; +Cc: dodji, kernel-team, gprocida

This commit adds some test cases to verify that the hashing is
actually stable across architectures.

	* tests/data/Makefile.am: Add new hash type id ABI files.
	* tests/test-read-dwarf.cc: (InOutSpec): Add type_id_style
	member. (in_out_specs): Set type_id_style to COUNTER in
	existing test specifications. Duplicate first 9 test cases
	with type_id_style set to HASH.
	* tests/data/test-read-dwarf/test0.hash.abi: New ABI XML file
	with hash type ids.
	* tests/data/test-read-dwarf/test1.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test3.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test4.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test5.o.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test6.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test7.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Ditto.

Signed-off-by: Giuliano Procida <gprocida@google.com>
---
 tests/data/Makefile.am                        |   9 ++
 tests/data/test-read-dwarf/test0.hash.abi     |  70 ++++++++++
 tests/data/test-read-dwarf/test1.hash.abi     | 129 ++++++++++++++++++
 tests/data/test-read-dwarf/test2.so.hash.abi  |  79 +++++++++++
 tests/data/test-read-dwarf/test3.so.hash.abi  |  19 +++
 tests/data/test-read-dwarf/test4.so.hash.abi  |  23 ++++
 tests/data/test-read-dwarf/test5.o.hash.abi   |  13 ++
 tests/data/test-read-dwarf/test6.so.hash.abi  |  42 ++++++
 tests/data/test-read-dwarf/test7.so.hash.abi  |  77 +++++++++++
 .../test8-qualified-this-pointer.so.hash.abi  |  37 +++++
 tests/test-read-dwarf.cc                      | 107 ++++++++++++++-
 11 files changed, 603 insertions(+), 2 deletions(-)
 create mode 100644 tests/data/test-read-dwarf/test0.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test1.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test2.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test3.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test4.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test5.o.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test6.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test7.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi

diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 6592ba32..8ccd50a0 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -395,33 +395,42 @@ test-diff-dwarf/PR25058-liblttng-ctl2.10.so \
 \
 test-read-dwarf/test0			\
 test-read-dwarf/test0.abi			\
+test-read-dwarf/test0.hash.abi		\
 test-read-dwarf/test0.cc			\
 test-read-dwarf/test1			\
 test-read-dwarf/test1.abi			\
+test-read-dwarf/test1.hash.abi		\
 test-read-dwarf/test1.cc			\
 test-read-dwarf/test2.h		\
 test-read-dwarf/test2-0.cc		\
 test-read-dwarf/test2-1.cc		\
 test-read-dwarf/test2.so		\
 test-read-dwarf/test2.so.abi		\
+test-read-dwarf/test2.so.hash.abi	\
 test-read-dwarf/test3.c		\
 test-read-dwarf/test3.so		\
 test-read-dwarf/test3.so.abi		\
+test-read-dwarf/test3.so.hash.abi	\
 test-read-dwarf/test4.c		\
 test-read-dwarf/test4.so		\
 test-read-dwarf/test4.so.abi		\
+test-read-dwarf/test4.so.hash.abi	\
 test-read-dwarf/test5.cc		\
 test-read-dwarf/test5.o		\
 test-read-dwarf/test5.o.abi		\
+test-read-dwarf/test5.o.hash.abi	\
 test-read-dwarf/test6.cc		\
 test-read-dwarf/test6.so		\
 test-read-dwarf/test6.so.abi		\
+test-read-dwarf/test6.so.hash.abi	\
 test-read-dwarf/test7.cc		\
 test-read-dwarf/test7.so		\
 test-read-dwarf/test7.so.abi		\
+test-read-dwarf/test7.so.hash.abi	\
 test-read-dwarf/test8-qualified-this-pointer.cc		\
 test-read-dwarf/test8-qualified-this-pointer.so		\
 test-read-dwarf/test8-qualified-this-pointer.so.abi		\
+test-read-dwarf/test8-qualified-this-pointer.so.hash.abi	\
 test-read-dwarf/test9-pr18818-clang.so  \
 test-read-dwarf/test10-pr18818-gcc.so \
 test-read-dwarf/test9-pr18818-clang.so.abi  \
diff --git a/tests/data/test-read-dwarf/test0.hash.abi b/tests/data/test-read-dwarf/test0.hash.abi
new file mode 100644
index 00000000..3d34a9de
--- /dev/null
+++ b/tests/data/test-read-dwarf/test0.hash.abi
@@ -0,0 +1,70 @@
+<abi-corpus path='data/test-read-dwarf/test0'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_ZN3ns03barEiz' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN3ns03bazERi' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN3ns03fooEPcl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN3ns04bar2ERNS_1EE' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN3ns04baz2ERi' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__libc_csu_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__libc_csu_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <elf-variable-symbols>
+    <elf-symbol name='_IO_stdin_used' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='global' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-variable-symbols>
+  <abi-instr version='1.0' address-size='64' path='test0.cc' comp-dir-path='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='char' size-in-bits='8' id='a84c031d'/>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <type-decl name='long int' size-in-bits='64' id='bd54fe1a'/>
+    <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
+    <type-decl name='unnamed-enum-underlying-type' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='6406df84'/>
+    <type-decl name='void' id='48b5725f'/>
+    <pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
+    <reference-type-def kind='lvalue' type-id='95e97e5e' size-in-bits='64' id='769216e8'/>
+    <reference-type-def kind='lvalue' type-id='383eb5fc' size-in-bits='64' id='b176607d'/>
+    <namespace-decl name='ns0'>
+      <function-decl name='bar' mangled-name='_ZN3ns03barEiz' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns03barEiz'>
+        <parameter type-id='95e97e5e'/>
+        <parameter is-variadic='yes'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='baz' mangled-name='_ZN3ns03bazERi' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns03bazERi'>
+        <parameter type-id='769216e8'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <enum-decl name='E' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='19' column='1' id='383eb5fc'>
+        <underlying-type type-id='6406df84'/>
+        <enumerator name='e0' value='0'/>
+        <enumerator name='e1' value='1'/>
+      </enum-decl>
+      <function-decl name='bar2' mangled-name='_ZN3ns04bar2ERNS_1EE' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns04bar2ERNS_1EE'>
+        <parameter type-id='b176607d'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <typedef-decl name='long_long' type-id='1eb56b1e' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='25' column='1' id='0eabcaca'/>
+      <function-decl name='baz2' mangled-name='_ZN3ns04baz2ERi' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns04baz2ERi'>
+        <parameter type-id='769216e8'/>
+        <return type-id='0eabcaca'/>
+      </function-decl>
+      <function-decl name='foo' mangled-name='_ZN3ns03fooEPcl' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='45' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns03fooEPcl'>
+        <parameter type-id='26a90f95'/>
+        <parameter type-id='bd54fe1a'/>
+        <return type-id='bd54fe1a'/>
+      </function-decl>
+    </namespace-decl>
+    <function-decl name='main' mangled-name='main' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='49' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='main'>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+    <var-decl name='global' type-id='95e97e5e' mangled-name='global' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='3' column='1' elf-symbol-id='global'/>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test1.hash.abi b/tests/data/test-read-dwarf/test1.hash.abi
new file mode 100644
index 00000000..0bd86868
--- /dev/null
+++ b/tests/data/test-read-dwarf/test1.hash.abi
@@ -0,0 +1,129 @@
+<abi-corpus path='data/test-read-dwarf/test1'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_Z3fooR2s0' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2b0C1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2b0C2Ev' type='func-type' binding='weak-binding' visibility='default-visibility' alias='_ZN2b0C1Ev' is-defined='yes'/>
+    <elf-symbol name='_ZN2b1C1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' alias='_ZN2b1C2Ev' is-defined='yes'/>
+    <elf-symbol name='_ZN2b1C2Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2s07mem_funEv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2s0C1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2s0D1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__libc_csu_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__libc_csu_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <elf-variable-symbols>
+    <elf-symbol name='_IO_stdin_used' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTI2b0' size='16' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTI2b1' size='16' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTI2s0' size='56' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTS2b0' size='4' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTS2b1' size='4' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTS2s0' size='4' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTT2s0' size='8' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTV2s0' size='32' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3' size='88' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTVN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3' size='88' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-variable-symbols>
+  <abi-instr version='1.0' address-size='64' path='test1.cc' comp-dir-path='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='char' size-in-bits='8' id='a84c031d'/>
+    <type-decl name='double' size-in-bits='64' id='a0eb0f08'/>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
+    <type-decl name='unsigned char' size-in-bits='8' id='002ac4a6'/>
+    <type-decl name='void' id='48b5725f'/>
+    <class-decl name='b0' size-in-bits='128' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='1' column='1' id='96c6f7f7'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='m0' type-id='1eb56b1e' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='3' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='64'>
+        <var-decl name='m1' type-id='a84c031d' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='4' column='1'/>
+      </data-member>
+    </class-decl>
+    <class-decl name='b1' size-in-bits='128' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='7' column='1' id='95c6f664'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='m0' type-id='a0eb0f08' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='9' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='64'>
+        <var-decl name='m1' type-id='a84c031d' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='10' column='1'/>
+      </data-member>
+    </class-decl>
+    <class-decl name='s0' size-in-bits='384' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='13' column='1' id='10ec88de'>
+      <base-class access='public' layout-offset-in-bits='192' is-virtual='yes' type-id='96c6f7f7'/>
+      <base-class access='public' layout-offset-in-bits='256' is-virtual='yes' type-id='95c6f664'/>
+
+        <member-type access='public'>
+          <typedef-decl name='integer' type-id='95e97e5e' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='15' column='1' id='61814d27'/>
+        </member-type>
+
+        <member-type access='public'>
+          <typedef-decl name='byte' type-id='002ac4a6' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='16' column='1' id='92bf8355'/>
+        </member-type>
+      <data-member access='public' layout-offset-in-bits='64'>
+        <var-decl name='m0' type-id='61814d27' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='18' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='96'>
+        <var-decl name='m1' type-id='92bf8355' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='19' column='1'/>
+      </data-member>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='s0' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='21' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <parameter type-id='95e97e5e' is-artificial='yes'/>
+          <parameter type-id='63e171df' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' destructor='yes'>
+        <function-decl name='~s0' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='27' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <parameter type-id='95e97e5e' is-artificial='yes'/>
+          <parameter type-id='63e171df' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public'>
+        <function-decl name='mem_fun' mangled-name='_ZN2s07mem_funEv' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN2s07mem_funEv'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <return type-id='61814d27'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='s0' mangled-name='_ZN2s0C1Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN2s0C1Ev'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <parameter type-id='95e97e5e' is-artificial='yes'/>
+          <parameter type-id='63e171df' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' destructor='yes'>
+        <function-decl name='~s0' mangled-name='_ZN2s0D1Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN2s0D1Ev'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <parameter type-id='95e97e5e' is-artificial='yes'/>
+          <parameter type-id='63e171df' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <qualified-type-def type-id='95a32e30' id='95a32e31'/>
+    <reference-type-def kind='lvalue' type-id='10ec88de' size-in-bits='64' id='95a32e30'/>
+    <pointer-type-def type-id='10ec88de' size-in-bits='64' id='a1a34114'/>
+    <pointer-type-def type-id='48b5725f' size-in-bits='64' id='eaa32e2f'/>
+    <pointer-type-def type-id='eaa32e2f' size-in-bits='64' id='63e171df'/>
+    <function-decl name='foo' mangled-name='_Z3fooR2s0' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3fooR2s0'>
+      <parameter type-id='95a32e31' name='s' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='42' column='1'/>
+      <return type-id='48b5725f'/>
+    </function-decl>
+    <function-decl name='main' mangled-name='main' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='48' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='main'>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test2.so.hash.abi b/tests/data/test-read-dwarf/test2.so.hash.abi
new file mode 100644
index 00000000..bb814f73
--- /dev/null
+++ b/tests/data/test-read-dwarf/test2.so.hash.abi
@@ -0,0 +1,79 @@
+<abi-corpus path='data/test-read-dwarf/test2.so'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_ZN10first_typeC1Ev' type='func-type' binding='global-binding' visibility='default-visibility' alias='_ZN10first_typeC2Ev' is-defined='yes'/>
+    <elf-symbol name='_ZN10first_typeC2Ev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN11second_typeC1Ev' type='func-type' binding='global-binding' visibility='default-visibility' alias='_ZN11second_typeC2Ev' is-defined='yes'/>
+    <elf-symbol name='_ZN11second_typeC2Ev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN1a16build_first_typeEv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN1a17build_second_typeEv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test2-0.cc' comp-dir-path='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <typedef-decl name='character' type-id='002ac4a6' id='8ec86933'/>
+    <typedef-decl name='integer' type-id='95e97e5e' id='c2cab9c6'/>
+    <type-decl name='unsigned char' size-in-bits='8' id='002ac4a6'/>
+    <type-decl name='void' id='48b5725f'/>
+    <class-decl name='first_type' size-in-bits='64' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='4' column='1' id='55265432'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='member0' type-id='c2cab9c6' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='6' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='32'>
+        <var-decl name='member1' type-id='8ec86933' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='7' column='1'/>
+      </data-member>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='first_type' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='82c95d70' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='first_type' mangled-name='_ZN10first_typeC2Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN10first_typeC1Ev'>
+          <parameter type-id='82c95d70' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <pointer-type-def type-id='55265432' size-in-bits='64' id='82c95d70'/>
+    <namespace-decl name='a'>
+      <function-decl name='build_first_type' mangled-name='_ZN1a16build_first_typeEv' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2-0.cc' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN1a16build_first_typeEv'>
+        <return type-id='82c95d70'/>
+      </function-decl>
+    </namespace-decl>
+  </abi-instr>
+  <abi-instr version='1.0' address-size='64' path='test2-1.cc' comp-dir-path='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <class-decl name='second_type' size-in-bits='64' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='12' column='1' id='cf111fae'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='member0' type-id='c2cab9c6' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='14' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='32'>
+        <var-decl name='member1' type-id='8ec86933' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='15' column='1'/>
+      </data-member>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='second_type' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='fc0abc74' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='second_type' mangled-name='_ZN11second_typeC2Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN11second_typeC1Ev'>
+          <parameter type-id='fc0abc74' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <pointer-type-def type-id='cf111fae' size-in-bits='64' id='fc0abc74'/>
+    <namespace-decl name='a'>
+      <function-decl name='build_second_type' mangled-name='_ZN1a17build_second_typeEv' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2-1.cc' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN1a17build_second_typeEv'>
+        <return type-id='fc0abc74'/>
+      </function-decl>
+    </namespace-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test3.so.hash.abi b/tests/data/test-read-dwarf/test3.so.hash.abi
new file mode 100644
index 00000000..e01f3959
--- /dev/null
+++ b/tests/data/test-read-dwarf/test3.so.hash.abi
@@ -0,0 +1,19 @@
+<abi-corpus path='data/test-read-dwarf/test3.so' soname='test3.so.1'>
+  <elf-needed>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='__foo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__foo__' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='foo' type='func-type' binding='weak-binding' visibility='default-visibility' alias='foo__,__foo__,__foo' is-defined='yes'/>
+    <elf-symbol name='foo__' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test3.c' comp-dir-path='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf' language='LANG_C89'>
+    <type-decl name='void' id='48b5725f'/>
+    <function-decl name='__foo' mangled-name='foo' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test3.c' line='8' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='foo'>
+      <return type-id='48b5725f'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test4.so.hash.abi b/tests/data/test-read-dwarf/test4.so.hash.abi
new file mode 100644
index 00000000..446df1da
--- /dev/null
+++ b/tests/data/test-read-dwarf/test4.so.hash.abi
@@ -0,0 +1,23 @@
+<abi-corpus path='data/test-read-dwarf/test4.so'>
+  <elf-needed>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='cpy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test4.c' comp-dir-path='/home/mark/src/tests' language='LANG_C89'>
+    <type-decl name='char' size-in-bits='8' id='a84c031d'/>
+    <type-decl name='unsigned int' size-in-bits='32' id='f0981eeb'/>
+    <pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
+    <qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/>
+    <qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/>
+    <pointer-type-def type-id='9b45d938' size-in-bits='64' id='80f4b756'/>
+    <qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
+    <function-decl name='cpy' mangled-name='cpy' filepath='/home/mark/src/tests/test4.c' line='2' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cpy'>
+      <parameter type-id='266fe297' name='s1' filepath='/home/mark/src/tests/test4.c' line='2' column='1'/>
+      <parameter type-id='9d26089a' name='s2' filepath='/home/mark/src/tests/test4.c' line='2' column='1'/>
+      <parameter type-id='f0981eeb' name='n' filepath='/home/mark/src/tests/test4.c' line='2' column='1'/>
+      <return type-id='26a90f95'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test5.o.hash.abi b/tests/data/test-read-dwarf/test5.o.hash.abi
new file mode 100644
index 00000000..9ed9932a
--- /dev/null
+++ b/tests/data/test-read-dwarf/test5.o.hash.abi
@@ -0,0 +1,13 @@
+<abi-corpus path='data/test-read-dwarf/test5.o'>
+  <elf-function-symbols>
+    <elf-symbol name='_Z3barPv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test.cc' comp-dir-path='/home/dodji/libabigailtests' language='LANG_C_plus_plus'>
+    <type-decl name='void' id='48b5725f'/>
+    <pointer-type-def type-id='48b5725f' size-in-bits='64' id='eaa32e2f'/>
+    <function-decl name='bar' mangled-name='_Z3barPv' filepath='/home/dodji/libabigailtests/test.cc' line='2' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3barPv'>
+      <parameter type-id='eaa32e2f'/>
+      <return type-id='48b5725f'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test6.so.hash.abi b/tests/data/test-read-dwarf/test6.so.hash.abi
new file mode 100644
index 00000000..7867a28f
--- /dev/null
+++ b/tests/data/test-read-dwarf/test6.so.hash.abi
@@ -0,0 +1,42 @@
+<abi-corpus path='data/test-read-dwarf/test6.so'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_Z3barv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_Z4blehv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN1B3fooEv' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <elf-variable-symbols>
+    <elf-symbol name='_ZN1CIiE3barE' size='4' type='object-type' binding='gnu-unique-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZZN1B3fooEvE1a' size='4' type='object-type' binding='gnu-unique-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-variable-symbols>
+  <abi-instr version='1.0' address-size='64' path='test6.cc' comp-dir-path='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <class-decl name='B' size-in-bits='8' is-struct='yes' visibility='default' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='9' column='1' id='41d98c5d'>
+      <member-function access='public'>
+        <function-decl name='foo' mangled-name='_ZN1B3fooEv' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN1B3fooEv'>
+          <parameter type-id='06dd347d' is-artificial='yes'/>
+          <return type-id='95e97e5e'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <class-decl name='C&lt;int&gt;' size-in-bits='8' is-struct='yes' visibility='default' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='26' column='1' id='923eef9f'>
+      <data-member access='public' static='yes'>
+        <var-decl name='bar' type-id='95e97e5e' mangled-name='_ZN1CIiE3barE' visibility='default' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='31' column='1' elf-symbol-id='_ZN1CIiE3barE'/>
+      </data-member>
+    </class-decl>
+    <pointer-type-def type-id='41d98c5d' size-in-bits='64' id='06dd347d'/>
+    <function-decl name='bar' mangled-name='_Z3barv' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3barv'>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+    <function-decl name='bleh' mangled-name='_Z4blehv' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z4blehv'>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test7.so.hash.abi b/tests/data/test-read-dwarf/test7.so.hash.abi
new file mode 100644
index 00000000..a04025f6
--- /dev/null
+++ b/tests/data/test-read-dwarf/test7.so.hash.abi
@@ -0,0 +1,77 @@
+<abi-corpus path='data/test-read-dwarf/test7.so'>
+  <elf-function-symbols>
+    <elf-symbol name='_Z3fooR1S' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test7.cc' comp-dir-path='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+
+
+
+
+
+
+
+    <type-decl name='char' size-in-bits='8' id='a84c031d'/>
+    <array-type-def dimensions='1' type-id='26a90f95' size-in-bits='448' id='0626c76e'>
+      <subrange length='7' type-id='4c87fef4' id='16fc326e'/>
+
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='8' id='89feb1ec'>
+      <subrange length='1' type-id='4c87fef4' id='52f813b4'/>
+
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='infinite' id='e84913bd'>
+      <subrange length='infinite' type-id='4c87fef4' id='031f2035'/>
+
+    </array-type-def>
+    <type-decl name='double' size-in-bits='64' id='a0eb0f08'/>
+    <array-type-def dimensions='2' type-id='a0eb0f08' size-in-bits='960' id='9ba86d8c'>
+      <subrange length='5' type-id='4c87fef4' id='53010e10'/>
+
+      <subrange length='3' type-id='4c87fef4' id='56f209d2'/>
+
+    </array-type-def>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <array-type-def dimensions='1' type-id='7292109c' size-in-bits='256' id='5abcdf1a'>
+      <subrange length='4' type-id='4c87fef4' id='16fe7105'/>
+
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='07535890' size-in-bits='640' id='bea34bd7'>
+      <subrange length='10' type-id='4c87fef4' id='487da03a'/>
+
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='95e97e5e' size-in-bits='160' id='e41e1db9'>
+      <subrange length='5' type-id='4c87fef4' id='53010e10'/>
+
+    </array-type-def>
+    <type-decl name='sizetype' size-in-bits='64' id='4c87fef4'/>
+    <class-decl name='S' size-in-bits='2304' is-struct='yes' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='1' column='1' id='50d9a3fa'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='a' type-id='e41e1db9' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='3' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='192'>
+        <var-decl name='b' type-id='0626c76e' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='4' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='640'>
+        <var-decl name='c' type-id='9ba86d8c' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='5' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='1600'>
+        <var-decl name='d' type-id='bea34bd7' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='6' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='2240'>
+        <var-decl name='e' type-id='89feb1ec' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='7' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='2248'>
+        <var-decl name='f' type-id='e84913bd' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='8' column='1'/>
+      </data-member>
+    </class-decl>
+    <qualified-type-def type-id='f901ef4c' id='f901ef4d'/>
+    <reference-type-def kind='lvalue' type-id='50d9a3fa' size-in-bits='64' id='f901ef4c'/>
+    <pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
+    <pointer-type-def type-id='95e97e5e' size-in-bits='64' id='7292109c'/>
+    <pointer-type-def type-id='5abcdf1a' size-in-bits='64' id='07535890'/>
+    <function-decl name='foo' mangled-name='_Z3fooR1S' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3fooR1S'>
+      <parameter type-id='f901ef4d'/>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi b/tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi
new file mode 100644
index 00000000..7197425d
--- /dev/null
+++ b/tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi
@@ -0,0 +1,37 @@
+<abi-corpus path='data/test-read-dwarf/test8-qualified-this-pointer.so'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_ZNK1S3fooEv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test8-qualified-this-pointer.cc' comp-dir-path='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <type-decl name='void' id='48b5725f'/>
+    <class-decl name='S' size-in-bits='32' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='1' column='1' id='50d9a3fa'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='i' type-id='95e97e5e' visibility='default' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='3' column='1'/>
+      </data-member>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='S' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='5' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='fd01f598' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' const='yes'>
+        <function-decl name='foo' mangled-name='_ZNK1S3fooEv' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='10' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNK1S3fooEv'>
+          <parameter type-id='2ee6aa55' is-artificial='yes'/>
+          <return type-id='95e97e5e'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <pointer-type-def type-id='50d9a3fa' size-in-bits='64' id='fd01f598'/>
+    <qualified-type-def type-id='50d9a3fa' const='yes' id='0fb3b55d'/>
+    <pointer-type-def type-id='0fb3b55d' size-in-bits='64' id='2ee6aa55'/>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/test-read-dwarf.cc b/tests/test-read-dwarf.cc
index ecc70cda..5c653f45 100644
--- a/tests/test-read-dwarf.cc
+++ b/tests/test-read-dwarf.cc
@@ -46,7 +46,11 @@ using abigail::dwarf_reader::read_corpus_from_elf;
 using abigail::dwarf_reader::read_context;
 using abigail::dwarf_reader::read_context_sptr;
 using abigail::dwarf_reader::create_read_context;
+using abigail::xml_writer::COUNTER;
+using abigail::xml_writer::HASH;
 using abigail::xml_writer::create_write_context;
+using abigail::xml_writer::set_type_id_style;
+using abigail::xml_writer::type_id_style_kind;
 using abigail::xml_writer::write_context_sptr;
 using abigail::xml_writer::write_corpus;
 
@@ -56,6 +60,7 @@ struct InOutSpec
 {
   const char* in_elf_path;
   const char* in_suppr_spec_path;
+  type_id_style_kind type_id_style;
   const char* in_abi_path;
   const char* out_abi_path;
 };// end struct InOutSpec
@@ -66,174 +71,266 @@ InOutSpec in_out_specs[] =
   {
     "data/test-read-dwarf/test0",
     "",
+    COUNTER,
     "data/test-read-dwarf/test0.abi",
     "output/test-read-dwarf/test0.abi"
   },
+  {
+    "data/test-read-dwarf/test0",
+    "",
+    HASH,
+    "data/test-read-dwarf/test0.hash.abi",
+    "output/test-read-dwarf/test0.hash.abi"
+  },
   {
     "data/test-read-dwarf/test1",
     "",
+    COUNTER,
     "data/test-read-dwarf/test1.abi",
     "output/test-read-dwarf/test1.abi"
   },
+  {
+    "data/test-read-dwarf/test1",
+    "",
+    HASH,
+    "data/test-read-dwarf/test1.hash.abi",
+    "output/test-read-dwarf/test1.hash.abi"
+  },
   {
     "data/test-read-dwarf/test2.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test2.so.abi",
     "output/test-read-dwarf/test2.so.abi"
   },
+  {
+    "data/test-read-dwarf/test2.so",
+    "",
+    HASH,
+    "data/test-read-dwarf/test2.so.hash.abi",
+    "output/test-read-dwarf/test2.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test3.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test3.so.abi",
     "output/test-read-dwarf/test3.so.abi"
   },
+  {
+    "data/test-read-dwarf/test3.so",
+    "",
+    HASH,
+    "data/test-read-dwarf/test3.so.hash.abi",
+    "output/test-read-dwarf/test3.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test4.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test4.so.abi",
     "output/test-read-dwarf/test4.so.abi"
   },
+  {
+    "data/test-read-dwarf/test4.so",
+    "",
+    HASH,
+    "data/test-read-dwarf/test4.so.hash.abi",
+    "output/test-read-dwarf/test4.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test5.o",
     "",
+    COUNTER,
     "data/test-read-dwarf/test5.o.abi",
     "output/test-read-dwarf/test5.o.abi"
   },
+  {
+    "data/test-read-dwarf/test5.o",
+    "",
+    HASH,
+    "data/test-read-dwarf/test5.o.hash.abi",
+    "output/test-read-dwarf/test5.o.hash.abi"
+  },
   {
     "data/test-read-dwarf/test6.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test6.so.abi",
     "output/test-read-dwarf/test6.so.abi"
   },
+  {
+    "data/test-read-dwarf/test6.so",
+    "",
+    HASH,
+    "data/test-read-dwarf/test6.so.hash.abi",
+    "output/test-read-dwarf/test6.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test7.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test7.so.abi",
     "output/test-read-dwarf/test7.so.abi"
   },
+  {
+    "data/test-read-dwarf/test7.so",
+    "",
+    HASH,
+    "data/test-read-dwarf/test7.so.hash.abi",
+    "output/test-read-dwarf/test7.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test8-qualified-this-pointer.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test8-qualified-this-pointer.so.abi",
     "output/test-read-dwarf/test8-qualified-this-pointer.so.abi"
   },
+  {
+    "data/test-read-dwarf/test8-qualified-this-pointer.so",
+    "",
+    HASH,
+    "data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi",
+    "output/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test9-pr18818-clang.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test9-pr18818-clang.so.abi",
     "output/test-read-dwarf/test9-pr18818-clang.so.abi"
   },
   {
     "data/test-read-dwarf/test10-pr18818-gcc.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test10-pr18818-gcc.so.abi",
     "output/test-read-dwarf/test10-pr18818-gcc.so.abi"
   },
   {
     "data/test-read-dwarf/test11-pr18828.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test11-pr18828.so.abi",
     "output/test-read-dwarf/test11-pr18828.so.abi",
   },
   {
     "data/test-read-dwarf/test12-pr18844.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test12-pr18844.so.abi",
     "output/test-read-dwarf/test12-pr18844.so.abi",
   },
   {
     "data/test-read-dwarf/test13-pr18894.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test13-pr18894.so.abi",
     "output/test-read-dwarf/test13-pr18894.so.abi",
   },
   {
     "data/test-read-dwarf/test14-pr18893.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test14-pr18893.so.abi",
     "output/test-read-dwarf/test14-pr18893.so.abi",
   },
   {
     "data/test-read-dwarf/test15-pr18892.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test15-pr18892.so.abi",
     "output/test-read-dwarf/test15-pr18892.so.abi",
   },
   {
     "data/test-read-dwarf/test16-pr18904.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test16-pr18904.so.abi",
     "output/test-read-dwarf/test16-pr18904.so.abi",
   },
   {
     "data/test-read-dwarf/test17-pr19027.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test17-pr19027.so.abi",
     "output/test-read-dwarf/test17-pr19027.so.abi",
   },
   {
     "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
     "output/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
   },
   {
     "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
     "output/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
   },
   {
     "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
     "output/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
   },
   {
     "data/test-read-dwarf/test21-pr19092.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test21-pr19092.so.abi",
     "output/test-read-dwarf/test21-pr19092.so.abi",
   },
   {
     "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi",
     "output/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi",
   },
   {
     "data/test-read-dwarf/libtest23.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/libtest23.so.abi",
     "output/test-read-dwarf/libtest23.so.abi",
   },
   {
     "data/test-read-dwarf/libtest24-drop-fns.so",
     "data/test-read-dwarf/test24-drop-fns-0.suppr",
+    COUNTER,
     "data/test-read-dwarf/libtest24-drop-fns.so.abi",
     "output/test-read-dwarf/libtest24-drop-fns.so.abi",
   },
   {
     "data/test-read-dwarf/libtest24-drop-fns.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/libtest24-drop-fns-2.so.abi",
     "output/test-read-dwarf/libtest24-drop-fns-2.so.abi",
   },
   {
     "data/test-read-dwarf/PR22015-libboost_iostreams.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/PR22015-libboost_iostreams.so.abi",
     "output/test-read-dwarf/PR22015-libboost_iostreams.so.abi",
   },
   {
     "data/test-read-dwarf/PR22122-libftdc.so",
     "",
+    COUNTER,
     "data/test-read-dwarf/PR22122-libftdc.so.abi",
     "output/test-read-dwarf/PR22122-libftdc.so.abi",
   },
   {
     "data/test-read-dwarf/PR24378-fn-is-not-scope.o",
     "",
+    COUNTER,
     "data/test-read-dwarf/PR24378-fn-is-not-scope.abi",
     "output/test-read-dwarf/PR24378-fn-is-not-scope.abi",
   },
@@ -241,6 +338,7 @@ InOutSpec in_out_specs[] =
   {
     "data/test-read-dwarf/PR25007-sdhci.ko",
     "",
+    COUNTER,
     "data/test-read-dwarf/PR25007-sdhci.ko.abi",
     "output/test-read-dwarf/PR25007-sdhci.ko.abi",
   },
@@ -249,6 +347,7 @@ InOutSpec in_out_specs[] =
   {
     "data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0",
     "",
+    COUNTER,
     "data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
     "output/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
   },
@@ -256,23 +355,26 @@ InOutSpec in_out_specs[] =
   {
     "data/test-read-dwarf/test25-bogus-binary.elf",
     "",
+    COUNTER,
     nullptr,
     nullptr,
   },
   {
     "data/test-read-dwarf/test26-bogus-binary.elf",
     "",
+    COUNTER,
     nullptr,
     nullptr,
   },
   {
     "data/test-read-dwarf/test27-bogus-binary.elf",
     "",
+    COUNTER,
     nullptr,
     nullptr,
   },
   // This should be the last entry.
-  {NULL, NULL, NULL, NULL}
+  {NULL, NULL, COUNTER, NULL, NULL}
 };
 
 using abigail::suppr::suppression_sptr;
@@ -378,8 +480,9 @@ struct test_task : public abigail::workers::task
 	is_ok = false;
 	return;
       }
-    const write_context_sptr write_ctxt
+    write_context_sptr write_ctxt
 	= create_write_context(corp->get_environment(), of);
+    set_type_id_style(*write_ctxt, spec.type_id_style);
     is_ok = write_corpus(*write_ctxt, corp, /*indent=*/0);
     of.close();
 
-- 
2.27.0.290.gba653c62da-goog


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] abg-writer: Add support for stable hash type ids.
  2020-06-12  9:59 ` [PATCH 1/2] abg-writer: Add support for stable hash " Giuliano Procida
@ 2020-06-15 17:18   ` Dodji Seketeli
  2020-06-15 19:29   ` Matthias Maennich
  2020-06-15 21:07   ` [PATCH v2 0/1] Stable " Giuliano Procida
  2 siblings, 0 replies; 8+ messages in thread
From: Dodji Seketeli @ 2020-06-15 17:18 UTC (permalink / raw)
  To: Giuliano Procida; +Cc: libabigail, kernel-team

Hello,

Giuliano Procida <gprocida@google.com> a écrit:

[...]

> diff --git a/include/abg-writer.h b/include/abg-writer.h
> index 8086d828..021a95b7 100644
> --- a/include/abg-writer.h
> +++ b/include/abg-writer.h
> @@ -38,6 +38,12 @@ namespace xml_writer
>  
>  using namespace abigail::ir;
>  
> +enum type_id_style_kind

I think this enum could use some comment that should start with '///',
so that it shows up in the doxygen-generated API doc.

> +{
> +  COUNTER,

I'd rather name this something more self-documented like
COUNTER_BASED_TYPE_ID_STYLE ...

> +  HASH

... and this one something like HASH_BASED_TYPE_ID_STYLE.

> +};
> +

[...]

> +++ b/src/abg-writer.cc
> @@ -27,6 +27,7 @@
>  
>  #include "config.h"
>  #include <assert.h>
> +#include <iomanip>
>  #include <iostream>
>  #include <fstream>
>  #include <sstream>
> @@ -56,6 +57,39 @@ ABG_BEGIN_EXPORT_DECLARATIONS
>  ABG_END_EXPORT_DECLARATIONS
>  // </headers defining libabigail's API>
>  
> +namespace
> +{
> +/// Compute a stable string hash.
> +///
> +/// std::hash has no portability or stability guarantees so is
> +/// unsuitable where reproducibility is a requirement.
> +///
> +/// This is the 32-bit FNV-1a algorithm. The algorithm, reference code
> +/// and constants are all unencumbered. It is fast and has reasonable
> +/// distribution properties.
> +///
> +/// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
> +///
> +/// @param str the string to hash.
> +///
> +/// @return an unsigned 32 bit hash value.
> +uint32_t
> +stable_hash(const std::string& str)

The file include/abg-hash.h and src/abg-hash.cc exist to host
implementations of hashing facilities.  I would put this function in
there.

Also, please rename it to an explicit name like maybe fnv_hash.

> +{
> +  const uint32_t prime = 0x01000193;
> +  const uint32_t offset_basis = 0x811c9dc5;
> +  uint32_t hash = offset_basis;
> +  for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
> +    {
> +      uint8_t byte = *i;
> +      hash = hash ^ byte;
> +      hash = hash * prime;
> +    }
> +  return hash;
> +}
> +
> +} // namespace
> +
>  namespace abigail
>  {
>  using std::cerr;
> @@ -177,7 +211,9 @@ class write_context
>    bool					m_write_parameter_names;
>    bool					m_short_locs;
>    bool					m_write_default_sizes;
> +  type_id_style_kind			m_type_id_style;
>    mutable type_ptr_map			m_type_id_map;
> +  mutable std::unordered_set<uint32_t>	m_used_type_id_hashes;

In our current setting (before c++11), unordered_set is part of the
std::tr1 namespace, stricto sensu.  Thanks to the magic in place, just
using unordered_set rather than std::unordered_set should do the trick.
Otherwise this won't compile on a compiler that doesn't support c++11.

Also, I think you should just conflate the testing patch that follows up
with this one.

All in all, for what it's worth, I like this patch very much!  Thank you
for working on it.

Cheers,

-- 
		Dodji

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] abg-writer: Add support for stable hash type ids.
  2020-06-12  9:59 ` [PATCH 1/2] abg-writer: Add support for stable hash " Giuliano Procida
  2020-06-15 17:18   ` Dodji Seketeli
@ 2020-06-15 19:29   ` Matthias Maennich
  2020-06-15 21:07   ` [PATCH v2 0/1] Stable " Giuliano Procida
  2 siblings, 0 replies; 8+ messages in thread
From: Matthias Maennich @ 2020-06-15 19:29 UTC (permalink / raw)
  To: Giuliano Procida; +Cc: libabigail, dodji, kernel-team

On Fri, Jun 12, 2020 at 10:59:16AM +0100, Android Kernel Team wrote:
>The type ids currently emitted by the XML writer are simply type-id-1,
>type-id-2 etc. Additions or removals of types early in this sequence
>result in cascading changes to many other XML elements.
>
>This commit adds support for stable type ids in the form of hashes of
>libabigail's internal type names. On fairly rare occasions (typically
>involving unnamed types), the names of two distinct types can be the
>same. In any case, if there is a hash collision the XML writer will
>find the next unused id and so preserve uniqueness.
>
>Diffs between XML files produced using --type-id-style hash will be
>much smaller and easier to review.
>
>	* doc/manuals/abidw.rst: Replace stray documentation of
>	--named-type-ids with documention of new --type-id-style
>	option.
>	* include/abg-writer.h (type_id_style_kind): Add new enum.
>	(set_type_id_style): Add new write_context setter.
>	(set_common_options): Set type id style in write context.
>	* src/abg-writer.cc (stable_hash): Add new 32-bit FNV-1a hash
>	function. (write_context): Add m_type_id_style member to
>	record type style to use, defaulting to COUNTER. Add
>	m_used_type_id_hashes to record already used hashes.
>	(write_context::get_type_id_style): Add new getter.
>	(write_context::set_type_id_style): Add new setter.
>	(get_id_for_type): Add support for HASH style.
>	(set_type_id_style): Add new helper function.
>	* tools/abidw.cc (options): Add type_id_style member.
>	(display_usage): Add description of --type-id-style option.
>	(parse_command_line): Parse --type-id-style option.
>
>Signed-off-by: Giuliano Procida <gprocida@google.com>
>---
> doc/manuals/abidw.rst | 15 +++----
> include/abg-writer.h  | 10 +++++
> src/abg-writer.cc     | 95 +++++++++++++++++++++++++++++++++++++++----
> tools/abidw.cc        | 20 ++++++++-
> 4 files changed, 125 insertions(+), 15 deletions(-)
>
>diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst
>index e1fce997..9472cfe8 100644
>--- a/doc/manuals/abidw.rst
>+++ b/doc/manuals/abidw.rst
>@@ -197,13 +197,14 @@ Options
>     1.8 will not set the default size and will interpret types without
>     a size-in-bits attribute as zero sized.
>
>-  * ``--named-type-ids``
>-
>-    Without this option ids used to reference types in the XML file
>-    use simple numbers.  With this option the ids used are derived
>-    from the type name to make it easier to see which type is
>-    referenced and make the XML file more stable in case new types are
>-    added (without this option that might mean all id numbers change).

Note: This (correctly) drops a hunk that was accidentally committed as
part of an earlier change. This feature is not available, but
documented. That is rare :-)

>+  * ``--type-id-style`` ( ``counter`` | ``hash`` )
>+
>+    This option controls how types are idenfied in the generated XML
>+    files.  The default ``counter`` style just numbers (with
>+    ``type-id-`` as prefix) the types in the order they are
>+    encountered.  The ``hash`` style uses a (stable, portable) hash of
>+    the type names that libabigail uses internally and is intended
>+    to make the XML files easier to diff.
>
>   * ``--check-alternate-debug-info-base-name`` <*elf-path*>
>
>diff --git a/include/abg-writer.h b/include/abg-writer.h
>index 8086d828..021a95b7 100644
>--- a/include/abg-writer.h
>+++ b/include/abg-writer.h
>@@ -38,6 +38,12 @@ namespace xml_writer
>
> using namespace abigail::ir;
>
>+enum type_id_style_kind
>+{
>+  COUNTER,

I would rather call it a sequence, but counter is fine for me as well.

>+  HASH
>+};
>+
> class write_context;
>
> /// A convenience typedef for a shared pointer to write_context.
>@@ -74,6 +80,9 @@ set_short_locs(write_context& ctxt, bool flag);
> void
> set_write_parameter_names(write_context& ctxt, bool flag);
>
>+void
>+set_type_id_style(write_context& ctxt, type_id_style_kind style);
>+
> /// A convenience generic function to set common options (usually used
> /// by Libabigail tools) from a generic options carrying-object, into
> /// a given @ref write_context.
>@@ -96,6 +105,7 @@ set_common_options(write_context& ctxt, const OPTS& opts)
>   set_write_parameter_names(ctxt, opts.write_parameter_names);
>   set_short_locs(ctxt, opts.short_locs);
>   set_write_default_sizes(ctxt, opts.default_sizes);
>+  set_type_id_style(ctxt, opts.type_id_style);
> }
>
> void
>diff --git a/src/abg-writer.cc b/src/abg-writer.cc
>index bafa3024..f0dbd096 100644
>--- a/src/abg-writer.cc
>+++ b/src/abg-writer.cc
>@@ -27,6 +27,7 @@
>
> #include "config.h"
> #include <assert.h>
>+#include <iomanip>
> #include <iostream>
> #include <fstream>
> #include <sstream>
>@@ -56,6 +57,39 @@ ABG_BEGIN_EXPORT_DECLARATIONS
> ABG_END_EXPORT_DECLARATIONS
> // </headers defining libabigail's API>
>
>+namespace
>+{
>+/// Compute a stable string hash.
>+///
>+/// std::hash has no portability or stability guarantees so is
>+/// unsuitable where reproducibility is a requirement.
>+///
>+/// This is the 32-bit FNV-1a algorithm. The algorithm, reference code
>+/// and constants are all unencumbered. It is fast and has reasonable
>+/// distribution properties.
>+///
>+/// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
>+///
>+/// @param str the string to hash.
>+///
>+/// @return an unsigned 32 bit hash value.

static

>+uint32_t
>+stable_hash(const std::string& str)
>+{
>+  const uint32_t prime = 0x01000193;
>+  const uint32_t offset_basis = 0x811c9dc5;
>+  uint32_t hash = offset_basis;
>+  for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
>+    {
>+      uint8_t byte = *i;
>+      hash = hash ^ byte;
>+      hash = hash * prime;
>+    }
>+  return hash;
>+}
>+
>+} // namespace
>+
> namespace abigail
> {
> using std::cerr;
>@@ -177,7 +211,9 @@ class write_context
>   bool					m_write_parameter_names;
>   bool					m_short_locs;
>   bool					m_write_default_sizes;
>+  type_id_style_kind			m_type_id_style;
>   mutable type_ptr_map			m_type_id_map;
>+  mutable std::unordered_set<uint32_t>	m_used_type_id_hashes;

Use abg_compat::unordered_set instead.

>   mutable type_ptr_set_type		m_emitted_type_set;
>   type_ptr_set_type			m_emitted_decl_only_set;
>   // A map of types that are referenced by emitted pointers,
>@@ -214,7 +250,8 @@ public:
>       m_write_elf_needed(true),
>       m_write_parameter_names(true),
>       m_short_locs(false),
>-      m_write_default_sizes(true)
>+      m_write_default_sizes(true),
>+      m_type_id_style(COUNTER)
>   {}
>
>   /// Getter of the environment we are operating from.
>@@ -374,6 +411,24 @@ public:
>   set_show_locs(bool f)
>   {m_show_locs = f;}
>
>+  /// Getter of the "type-id-style" option.
>+  ///
>+  /// This option controls the kind of type ids used in XML output.
>+  ///
>+  /// @return the value of the "type-id-style" option.
>+  type_id_style_kind
>+  get_type_id_style() const
>+  {return m_type_id_style;}
>+
>+  /// Setter of the "type-id-style" option.
>+  ///
>+  /// This option controls the kind of type ids used in XML output.
>+  ///
>+  /// @param style the new value of the "type-id-style" option.
>+  void
>+  set_type_id_style(type_id_style_kind style)
>+  {m_type_id_style = style;}
>+
>   /// Getter of the @ref id_manager.
>   ///
>   /// @return the @ref id_manager used by the current instance of @ref
>@@ -421,14 +476,29 @@ public:
>       c = const_cast<type_base*>(t);
>
>     type_ptr_map::const_iterator it = m_type_id_map.find(c);
>-    if (it == m_type_id_map.end())
>+    if (it != m_type_id_map.end())
>+      return it->second;
>+
>+    switch (m_type_id_style)
>       {
>-	interned_string id =
>-	  get_id_manager().get_id_with_prefix("type-id-");
>-	m_type_id_map[c] = id;
>-	return id;
>+      case COUNTER:
>+        {
>+          interned_string id = get_id_manager().get_id_with_prefix("type-id-");
>+          return m_type_id_map[c] = id;
>+        }
>+      case HASH:
>+        {
>+          interned_string pretty = c->get_cached_pretty_representation(true);
>+          size_t hash = stable_hash(*pretty.raw());
>+          while (!m_used_type_id_hashes.insert(hash).second)
>+            ++hash;
>+          std::ostringstream os;
>+          os << std::hex << std::setfill('0') << std::setw(8) << hash;
>+          return m_type_id_map[c] = c->get_environment()->intern(os.str());
>+        }
>       }
>-    return it->second;
>+    ABG_ASSERT_NOT_REACHED;
>+    return interned_string();
>   }
>
>   string
>@@ -2131,6 +2201,17 @@ void
> set_write_default_sizes(write_context& ctxt, bool flag)
> {ctxt.set_write_default_sizes(flag);}
>
>+/// Set the 'type-id-style' property.
>+///
>+/// This property controls the kind of type ids used in XML output.
>+///
>+/// @param ctxt the context to set this property on.
>+///
>+/// @param style the new value of the 'type-id-style' property.
>+void
>+set_type_id_style(write_context& ctxt, type_id_style_kind style)
>+{ctxt.set_type_id_style(style);}
>+
> /// Serialize the canonical types of a given scope.
> ///
> /// @param scope the scope to consider.
>diff --git a/tools/abidw.cc b/tools/abidw.cc
>index 9aec3112..7de31737 100644
>--- a/tools/abidw.cc
>+++ b/tools/abidw.cc
>@@ -70,7 +70,10 @@ using abigail::comparison::corpus_diff_sptr;
> using abigail::comparison::compute_diff;
> using abigail::comparison::diff_context_sptr;
> using abigail::comparison::diff_context;
>+using abigail::xml_writer::COUNTER;
>+using abigail::xml_writer::HASH;
> using abigail::xml_writer::create_write_context;
>+using abigail::xml_writer::type_id_style_kind;
> using abigail::xml_writer::write_context_sptr;
> using abigail::xml_writer::write_corpus;
> using abigail::xml_reader::read_corpus_from_native_xml_file;
>@@ -114,6 +117,7 @@ struct options
>   bool			do_log;
>   bool			drop_private_types;
>   bool			drop_undefined_syms;
>+  type_id_style_kind	type_id_style;
>
>   options()
>     : display_version(),
>@@ -136,7 +140,8 @@ struct options
>       annotate(),
>       do_log(),
>       drop_private_types(false),
>-      drop_undefined_syms(false)
>+      drop_undefined_syms(false),
>+      type_id_style(COUNTER)
>   {}
>
>   ~options()
>@@ -175,6 +180,7 @@ display_usage(const string& prog_name, ostream& out)
>     << "  --no-write-default-sizes  do not emit pointer size when it equals"
>     " the default address size of the translation unit\n"
>     << "  --no-parameter-names  do not show names of function parameters\n"
>+    << "  --type-id-style (counter|hash)  type-id style (counter(default): type-id-number; hash: hexdigits\n"
>     << "  --check-alternate-debug-info <elf-path>  check alternate debug info "
>     "of <elf-path>\n"
>     << "  --check-alternate-debug-info-base-name <elf-path>  check alternate "
>@@ -301,6 +307,18 @@ parse_command_line(int argc, char* argv[], options& opts)
> 	opts.default_sizes = false;
>       else if (!strcmp(argv[i], "--no-parameter-names"))
> 	opts.write_parameter_names = false;
>+      else if (!strcmp(argv[i], "--type-id-style"))
>+        {
>+          ++i;
>+          if (i >= argc)
>+            return false;
>+          if (!strcmp(argv[i], "counter"))
>+            opts.type_id_style = COUNTER;
>+          else if (!strcmp(argv[i], "hash"))
>+            opts.type_id_style = HASH;
>+          else
>+            return false;
>+        }
>       else if (!strcmp(argv[i], "--check-alternate-debug-info")
> 	       || !strcmp(argv[i], "--check-alternate-debug-info-base-name"))
> 	{
>-- 
>2.27.0.290.gba653c62da-goog
>
>-- 
>To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 0/1] Stable type ids
  2020-06-12  9:59 ` [PATCH 1/2] abg-writer: Add support for stable hash " Giuliano Procida
  2020-06-15 17:18   ` Dodji Seketeli
  2020-06-15 19:29   ` Matthias Maennich
@ 2020-06-15 21:07   ` Giuliano Procida
  2020-06-15 21:07     ` [PATCH v2 1/1] abg-writer: Add support for stable hash " Giuliano Procida
  2 siblings, 1 reply; 8+ messages in thread
From: Giuliano Procida @ 2020-06-15 21:07 UTC (permalink / raw)
  To: libabigail; +Cc: dodji, kernel-team, gprocida, mark, maennich

This is a follow-up addressing review comments.

* enum type_id_style_kind now has a doc comment.
* COUNTER is now SEQUENCE (and counter is now sequence).
* The enumerators are now suffixed with _TYPE_ID_STYLE.
* stable_hash is now fnv_hash and lives in abg-hash.{h,cc}.
  (though it has a very different purpose from the other things there)
* std::unordered_set is now unordered_set.
* The two patches are now folded into a single patch.

Regards,
Giuliano.

Giuliano Procida (1):
  abg-writer: Add support for stable hash type ids.

 doc/manuals/abidw.rst                         |  15 +-
 include/abg-hash.h                            |   5 +
 include/abg-writer.h                          |  11 ++
 src/abg-hash.cc                               |  30 ++++
 src/abg-writer.cc                             |  63 ++++++++-
 tests/data/Makefile.am                        |   9 ++
 tests/data/test-read-dwarf/test0.hash.abi     |  70 ++++++++++
 tests/data/test-read-dwarf/test1.hash.abi     | 129 ++++++++++++++++++
 tests/data/test-read-dwarf/test2.so.hash.abi  |  79 +++++++++++
 tests/data/test-read-dwarf/test3.so.hash.abi  |  19 +++
 tests/data/test-read-dwarf/test4.so.hash.abi  |  23 ++++
 tests/data/test-read-dwarf/test5.o.hash.abi   |  13 ++
 tests/data/test-read-dwarf/test6.so.hash.abi  |  42 ++++++
 tests/data/test-read-dwarf/test7.so.hash.abi  |  77 +++++++++++
 .../test8-qualified-this-pointer.so.hash.abi  |  37 +++++
 tests/test-read-dwarf.cc                      | 107 ++++++++++++++-
 tools/abidw.cc                                |  20 ++-
 17 files changed, 732 insertions(+), 17 deletions(-)
 create mode 100644 tests/data/test-read-dwarf/test0.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test1.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test2.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test3.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test4.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test5.o.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test6.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test7.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi

-- 
2.27.0.290.gba653c62da-goog


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/1] abg-writer: Add support for stable hash type ids.
  2020-06-15 21:07   ` [PATCH v2 0/1] Stable " Giuliano Procida
@ 2020-06-15 21:07     ` Giuliano Procida
  2020-06-16  8:21       ` Dodji Seketeli
  0 siblings, 1 reply; 8+ messages in thread
From: Giuliano Procida @ 2020-06-15 21:07 UTC (permalink / raw)
  To: libabigail; +Cc: dodji, kernel-team, gprocida, mark, maennich

The type ids currently emitted by the XML writer are simply type-id-1,
type-id-2 etc. Additions or removals of types early in this sequence
result in cascading changes to many other XML elements.

This commit adds support for stable type ids in the form of hashes of
libabigail's internal type names. On fairly rare occasions (typically
involving unnamed types), the names of two distinct types can be the
same. In any case, if there is a hash collision the XML writer will
find the next unused id and so preserve uniqueness.

Diffs between large XML files produced using --type-id-style hash will
be much smaller and easier to review.

This also commit adds some test cases to verify that the hashing is
actually stable across architectures.

	* doc/manuals/abidw.rst: Replace stray documentation of
	--named-type-ids with documention of new --type-id-style
	option.
	* include/abg-writer.h (type_id_style_kind): Add new enum.
	(set_type_id_style): Add new write_context setter.
	(set_common_options): Set type id style in write context.
	* include/abg-hash.h (fnv_hash): Declare new 32-bit FNV-1a
        hash function in abigail::hashing namespace.
	* src/abg-hash.h (fnv_hash): Define new 32-bit FNV-1a hash
        function in abigail::hashing namespace.
	* src/abg-writer.cc (write_context): Add m_type_id_style
        member to record type style to use, defaulting to
        SEQUENCE_TYPE_ID_STYLE; add m_used_type_id_hashes to record
        already-used hashes.
	(write_context::get_type_id_style): Add new getter.
	(write_context::set_type_id_style): Add new setter.
	(get_id_for_type): Add support for HASH_TYPE_ID_STYLE style.
	(set_type_id_style): Add new helper function.
	* tools/abidw.cc (options): Add type_id_style member.
	(display_usage): Add description of --type-id-style option.
	(parse_command_line): Parse --type-id-style option.
	* tests/data/Makefile.am: Add new hash type id ABI files.
	* tests/test-read-dwarf.cc: (InOutSpec): Add type_id_style
	member.
	(in_out_specs): Set type_id_style to SEQUENCE_TYPE_ID_STYLE in
        existing test specifications. Duplicate first 9 test cases
        with type_id_style set to HASH_TYPE_ID_STYLE.
	* tests/data/test-read-dwarf/test0.hash.abi: New ABI XML file
	with hash type ids.
	* tests/data/test-read-dwarf/test1.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test3.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test4.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test5.o.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test6.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test7.so.hash.abi: Ditto.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Ditto.

Signed-off-by: Giuliano Procida <gprocida@google.com>
---
 doc/manuals/abidw.rst                         |  15 +-
 include/abg-hash.h                            |   5 +
 include/abg-writer.h                          |  11 ++
 src/abg-hash.cc                               |  30 ++++
 src/abg-writer.cc                             |  63 ++++++++-
 tests/data/Makefile.am                        |   9 ++
 tests/data/test-read-dwarf/test0.hash.abi     |  70 ++++++++++
 tests/data/test-read-dwarf/test1.hash.abi     | 129 ++++++++++++++++++
 tests/data/test-read-dwarf/test2.so.hash.abi  |  79 +++++++++++
 tests/data/test-read-dwarf/test3.so.hash.abi  |  19 +++
 tests/data/test-read-dwarf/test4.so.hash.abi  |  23 ++++
 tests/data/test-read-dwarf/test5.o.hash.abi   |  13 ++
 tests/data/test-read-dwarf/test6.so.hash.abi  |  42 ++++++
 tests/data/test-read-dwarf/test7.so.hash.abi  |  77 +++++++++++
 .../test8-qualified-this-pointer.so.hash.abi  |  37 +++++
 tests/test-read-dwarf.cc                      | 107 ++++++++++++++-
 tools/abidw.cc                                |  20 ++-
 17 files changed, 732 insertions(+), 17 deletions(-)
 create mode 100644 tests/data/test-read-dwarf/test0.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test1.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test2.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test3.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test4.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test5.o.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test6.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test7.so.hash.abi
 create mode 100644 tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi

diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst
index e1fce997..5834923b 100644
--- a/doc/manuals/abidw.rst
+++ b/doc/manuals/abidw.rst
@@ -197,13 +197,14 @@ Options
     1.8 will not set the default size and will interpret types without
     a size-in-bits attribute as zero sized.
 
-  * ``--named-type-ids``
-
-    Without this option ids used to reference types in the XML file
-    use simple numbers.  With this option the ids used are derived
-    from the type name to make it easier to see which type is
-    referenced and make the XML file more stable in case new types are
-    added (without this option that might mean all id numbers change).
+  * ``--type-id-style`` ( ``sequence`` | ``hash`` )
+
+    This option controls how types are idenfied in the generated XML
+    files.  The default ``sequence`` style just numbers (with
+    ``type-id-`` as prefix) the types in the order they are
+    encountered.  The ``hash`` style uses a (stable, portable) hash of
+    libabigail's internal type names and is intended to make the XML
+    files easier to diff.
 
   * ``--check-alternate-debug-info-base-name`` <*elf-path*>
 
diff --git a/include/abg-hash.h b/include/abg-hash.h
index 10adedee..ccf50c12 100644
--- a/include/abg-hash.h
+++ b/include/abg-hash.h
@@ -24,6 +24,8 @@
 #define __ABG_HASH_H__
 
 #include <cstddef>
+#include <cstdint>
+#include <string>
 
 namespace abigail
 {
@@ -34,6 +36,9 @@ namespace hashing
   /// This is copied from tree.c in GCC.
   std::size_t
   combine_hashes(std::size_t, std::size_t);
+
+  uint32_t
+  fnv_hash(const std::string& str);
 }//end namespace hashing
 }//end namespace abigail
 
diff --git a/include/abg-writer.h b/include/abg-writer.h
index 8086d828..d44b4838 100644
--- a/include/abg-writer.h
+++ b/include/abg-writer.h
@@ -38,6 +38,13 @@ namespace xml_writer
 
 using namespace abigail::ir;
 
+/// The style of type id the XML writer will output.
+enum type_id_style_kind
+{
+  SEQUENCE_TYPE_ID_STYLE,
+  HASH_TYPE_ID_STYLE
+};
+
 class write_context;
 
 /// A convenience typedef for a shared pointer to write_context.
@@ -74,6 +81,9 @@ set_short_locs(write_context& ctxt, bool flag);
 void
 set_write_parameter_names(write_context& ctxt, bool flag);
 
+void
+set_type_id_style(write_context& ctxt, type_id_style_kind style);
+
 /// A convenience generic function to set common options (usually used
 /// by Libabigail tools) from a generic options carrying-object, into
 /// a given @ref write_context.
@@ -96,6 +106,7 @@ set_common_options(write_context& ctxt, const OPTS& opts)
   set_write_parameter_names(ctxt, opts.write_parameter_names);
   set_short_locs(ctxt, opts.short_locs);
   set_write_default_sizes(ctxt, opts.default_sizes);
+  set_type_id_style(ctxt, opts.type_id_style);
 }
 
 void
diff --git a/src/abg-hash.cc b/src/abg-hash.cc
index 0646ab16..c1cdc57b 100644
--- a/src/abg-hash.cc
+++ b/src/abg-hash.cc
@@ -60,6 +60,36 @@ combine_hashes(size_t val1, size_t val2)
   return val2;
 }
 
+/// Compute a stable string hash.
+///
+/// std::hash has no portability or stability guarantees so is
+/// unsuitable where reproducibility is a requirement such as in XML
+/// output.
+///
+/// This is the 32-bit FNV-1a algorithm. The algorithm, reference code
+/// and constants are all unencumbered. It is fast and has reasonable
+/// distribution properties.
+///
+/// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
+///
+/// @param str the string to hash.
+///
+/// @return an unsigned 32 bit hash value.
+uint32_t
+fnv_hash(const std::string& str)
+{
+  const uint32_t prime = 0x01000193;
+  const uint32_t offset_basis = 0x811c9dc5;
+  uint32_t hash = offset_basis;
+  for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
+    {
+      uint8_t byte = *i;
+      hash = hash ^ byte;
+      hash = hash * prime;
+    }
+  return hash;
+}
+
 }//end namespace hashing
 
 using std::list;
diff --git a/src/abg-writer.cc b/src/abg-writer.cc
index bafa3024..ce0bae2d 100644
--- a/src/abg-writer.cc
+++ b/src/abg-writer.cc
@@ -27,6 +27,7 @@
 
 #include "config.h"
 #include <assert.h>
+#include <iomanip>
 #include <iostream>
 #include <fstream>
 #include <sstream>
@@ -44,6 +45,7 @@ ABG_BEGIN_EXPORT_DECLARATIONS
 #include "abg-config.h"
 #include "abg-corpus.h"
 #include "abg-diff-utils.h"
+#include "abg-hash.h"
 #include "abg-sptr-utils.h"
 
 #if WITH_ZIP_ARCHIVE
@@ -177,7 +179,9 @@ class write_context
   bool					m_write_parameter_names;
   bool					m_short_locs;
   bool					m_write_default_sizes;
+  type_id_style_kind			m_type_id_style;
   mutable type_ptr_map			m_type_id_map;
+  mutable unordered_set<uint32_t>	m_used_type_id_hashes;
   mutable type_ptr_set_type		m_emitted_type_set;
   type_ptr_set_type			m_emitted_decl_only_set;
   // A map of types that are referenced by emitted pointers,
@@ -214,7 +218,8 @@ public:
       m_write_elf_needed(true),
       m_write_parameter_names(true),
       m_short_locs(false),
-      m_write_default_sizes(true)
+      m_write_default_sizes(true),
+      m_type_id_style(SEQUENCE_TYPE_ID_STYLE)
   {}
 
   /// Getter of the environment we are operating from.
@@ -374,6 +379,24 @@ public:
   set_show_locs(bool f)
   {m_show_locs = f;}
 
+  /// Getter of the "type-id-style" option.
+  ///
+  /// This option controls the kind of type ids used in XML output.
+  ///
+  /// @return the value of the "type-id-style" option.
+  type_id_style_kind
+  get_type_id_style() const
+  {return m_type_id_style;}
+
+  /// Setter of the "type-id-style" option.
+  ///
+  /// This option controls the kind of type ids used in XML output.
+  ///
+  /// @param style the new value of the "type-id-style" option.
+  void
+  set_type_id_style(type_id_style_kind style)
+  {m_type_id_style = style;}
+
   /// Getter of the @ref id_manager.
   ///
   /// @return the @ref id_manager used by the current instance of @ref
@@ -421,14 +444,29 @@ public:
       c = const_cast<type_base*>(t);
 
     type_ptr_map::const_iterator it = m_type_id_map.find(c);
-    if (it == m_type_id_map.end())
+    if (it != m_type_id_map.end())
+      return it->second;
+
+    switch (m_type_id_style)
       {
-	interned_string id =
-	  get_id_manager().get_id_with_prefix("type-id-");
-	m_type_id_map[c] = id;
-	return id;
+      case SEQUENCE_TYPE_ID_STYLE:
+        {
+          interned_string id = get_id_manager().get_id_with_prefix("type-id-");
+          return m_type_id_map[c] = id;
+        }
+      case HASH_TYPE_ID_STYLE:
+        {
+          interned_string pretty = c->get_cached_pretty_representation(true);
+          size_t hash = hashing::fnv_hash(*pretty.raw());
+          while (!m_used_type_id_hashes.insert(hash).second)
+            ++hash;
+          std::ostringstream os;
+          os << std::hex << std::setfill('0') << std::setw(8) << hash;
+          return m_type_id_map[c] = c->get_environment()->intern(os.str());
+        }
       }
-    return it->second;
+    ABG_ASSERT_NOT_REACHED;
+    return interned_string();
   }
 
   string
@@ -2131,6 +2169,17 @@ void
 set_write_default_sizes(write_context& ctxt, bool flag)
 {ctxt.set_write_default_sizes(flag);}
 
+/// Set the 'type-id-style' property.
+///
+/// This property controls the kind of type ids used in XML output.
+///
+/// @param ctxt the context to set this property on.
+///
+/// @param style the new value of the 'type-id-style' property.
+void
+set_type_id_style(write_context& ctxt, type_id_style_kind style)
+{ctxt.set_type_id_style(style);}
+
 /// Serialize the canonical types of a given scope.
 ///
 /// @param scope the scope to consider.
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 6592ba32..8ccd50a0 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -395,33 +395,42 @@ test-diff-dwarf/PR25058-liblttng-ctl2.10.so \
 \
 test-read-dwarf/test0			\
 test-read-dwarf/test0.abi			\
+test-read-dwarf/test0.hash.abi		\
 test-read-dwarf/test0.cc			\
 test-read-dwarf/test1			\
 test-read-dwarf/test1.abi			\
+test-read-dwarf/test1.hash.abi		\
 test-read-dwarf/test1.cc			\
 test-read-dwarf/test2.h		\
 test-read-dwarf/test2-0.cc		\
 test-read-dwarf/test2-1.cc		\
 test-read-dwarf/test2.so		\
 test-read-dwarf/test2.so.abi		\
+test-read-dwarf/test2.so.hash.abi	\
 test-read-dwarf/test3.c		\
 test-read-dwarf/test3.so		\
 test-read-dwarf/test3.so.abi		\
+test-read-dwarf/test3.so.hash.abi	\
 test-read-dwarf/test4.c		\
 test-read-dwarf/test4.so		\
 test-read-dwarf/test4.so.abi		\
+test-read-dwarf/test4.so.hash.abi	\
 test-read-dwarf/test5.cc		\
 test-read-dwarf/test5.o		\
 test-read-dwarf/test5.o.abi		\
+test-read-dwarf/test5.o.hash.abi	\
 test-read-dwarf/test6.cc		\
 test-read-dwarf/test6.so		\
 test-read-dwarf/test6.so.abi		\
+test-read-dwarf/test6.so.hash.abi	\
 test-read-dwarf/test7.cc		\
 test-read-dwarf/test7.so		\
 test-read-dwarf/test7.so.abi		\
+test-read-dwarf/test7.so.hash.abi	\
 test-read-dwarf/test8-qualified-this-pointer.cc		\
 test-read-dwarf/test8-qualified-this-pointer.so		\
 test-read-dwarf/test8-qualified-this-pointer.so.abi		\
+test-read-dwarf/test8-qualified-this-pointer.so.hash.abi	\
 test-read-dwarf/test9-pr18818-clang.so  \
 test-read-dwarf/test10-pr18818-gcc.so \
 test-read-dwarf/test9-pr18818-clang.so.abi  \
diff --git a/tests/data/test-read-dwarf/test0.hash.abi b/tests/data/test-read-dwarf/test0.hash.abi
new file mode 100644
index 00000000..3d34a9de
--- /dev/null
+++ b/tests/data/test-read-dwarf/test0.hash.abi
@@ -0,0 +1,70 @@
+<abi-corpus path='data/test-read-dwarf/test0'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_ZN3ns03barEiz' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN3ns03bazERi' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN3ns03fooEPcl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN3ns04bar2ERNS_1EE' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN3ns04baz2ERi' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__libc_csu_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__libc_csu_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <elf-variable-symbols>
+    <elf-symbol name='_IO_stdin_used' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='global' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-variable-symbols>
+  <abi-instr version='1.0' address-size='64' path='test0.cc' comp-dir-path='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='char' size-in-bits='8' id='a84c031d'/>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <type-decl name='long int' size-in-bits='64' id='bd54fe1a'/>
+    <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
+    <type-decl name='unnamed-enum-underlying-type' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='6406df84'/>
+    <type-decl name='void' id='48b5725f'/>
+    <pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
+    <reference-type-def kind='lvalue' type-id='95e97e5e' size-in-bits='64' id='769216e8'/>
+    <reference-type-def kind='lvalue' type-id='383eb5fc' size-in-bits='64' id='b176607d'/>
+    <namespace-decl name='ns0'>
+      <function-decl name='bar' mangled-name='_ZN3ns03barEiz' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns03barEiz'>
+        <parameter type-id='95e97e5e'/>
+        <parameter is-variadic='yes'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <function-decl name='baz' mangled-name='_ZN3ns03bazERi' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns03bazERi'>
+        <parameter type-id='769216e8'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <enum-decl name='E' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='19' column='1' id='383eb5fc'>
+        <underlying-type type-id='6406df84'/>
+        <enumerator name='e0' value='0'/>
+        <enumerator name='e1' value='1'/>
+      </enum-decl>
+      <function-decl name='bar2' mangled-name='_ZN3ns04bar2ERNS_1EE' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns04bar2ERNS_1EE'>
+        <parameter type-id='b176607d'/>
+        <return type-id='48b5725f'/>
+      </function-decl>
+      <typedef-decl name='long_long' type-id='1eb56b1e' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='25' column='1' id='0eabcaca'/>
+      <function-decl name='baz2' mangled-name='_ZN3ns04baz2ERi' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns04baz2ERi'>
+        <parameter type-id='769216e8'/>
+        <return type-id='0eabcaca'/>
+      </function-decl>
+      <function-decl name='foo' mangled-name='_ZN3ns03fooEPcl' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='45' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3ns03fooEPcl'>
+        <parameter type-id='26a90f95'/>
+        <parameter type-id='bd54fe1a'/>
+        <return type-id='bd54fe1a'/>
+      </function-decl>
+    </namespace-decl>
+    <function-decl name='main' mangled-name='main' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='49' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='main'>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+    <var-decl name='global' type-id='95e97e5e' mangled-name='global' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test0.cc' line='3' column='1' elf-symbol-id='global'/>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test1.hash.abi b/tests/data/test-read-dwarf/test1.hash.abi
new file mode 100644
index 00000000..0bd86868
--- /dev/null
+++ b/tests/data/test-read-dwarf/test1.hash.abi
@@ -0,0 +1,129 @@
+<abi-corpus path='data/test-read-dwarf/test1'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_Z3fooR2s0' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2b0C1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2b0C2Ev' type='func-type' binding='weak-binding' visibility='default-visibility' alias='_ZN2b0C1Ev' is-defined='yes'/>
+    <elf-symbol name='_ZN2b1C1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' alias='_ZN2b1C2Ev' is-defined='yes'/>
+    <elf-symbol name='_ZN2b1C2Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2s07mem_funEv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2s0C1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN2s0D1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__libc_csu_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__libc_csu_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <elf-variable-symbols>
+    <elf-symbol name='_IO_stdin_used' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTI2b0' size='16' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTI2b1' size='16' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTI2s0' size='56' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTS2b0' size='4' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTS2b1' size='4' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTS2s0' size='4' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTT2s0' size='8' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTV2s0' size='32' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3' size='88' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZTVN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3' size='88' type='object-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-variable-symbols>
+  <abi-instr version='1.0' address-size='64' path='test1.cc' comp-dir-path='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='char' size-in-bits='8' id='a84c031d'/>
+    <type-decl name='double' size-in-bits='64' id='a0eb0f08'/>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
+    <type-decl name='unsigned char' size-in-bits='8' id='002ac4a6'/>
+    <type-decl name='void' id='48b5725f'/>
+    <class-decl name='b0' size-in-bits='128' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='1' column='1' id='96c6f7f7'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='m0' type-id='1eb56b1e' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='3' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='64'>
+        <var-decl name='m1' type-id='a84c031d' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='4' column='1'/>
+      </data-member>
+    </class-decl>
+    <class-decl name='b1' size-in-bits='128' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='7' column='1' id='95c6f664'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='m0' type-id='a0eb0f08' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='9' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='64'>
+        <var-decl name='m1' type-id='a84c031d' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='10' column='1'/>
+      </data-member>
+    </class-decl>
+    <class-decl name='s0' size-in-bits='384' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='13' column='1' id='10ec88de'>
+      <base-class access='public' layout-offset-in-bits='192' is-virtual='yes' type-id='96c6f7f7'/>
+      <base-class access='public' layout-offset-in-bits='256' is-virtual='yes' type-id='95c6f664'/>
+
+        <member-type access='public'>
+          <typedef-decl name='integer' type-id='95e97e5e' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='15' column='1' id='61814d27'/>
+        </member-type>
+
+        <member-type access='public'>
+          <typedef-decl name='byte' type-id='002ac4a6' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='16' column='1' id='92bf8355'/>
+        </member-type>
+      <data-member access='public' layout-offset-in-bits='64'>
+        <var-decl name='m0' type-id='61814d27' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='18' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='96'>
+        <var-decl name='m1' type-id='92bf8355' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='19' column='1'/>
+      </data-member>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='s0' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='21' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <parameter type-id='95e97e5e' is-artificial='yes'/>
+          <parameter type-id='63e171df' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' destructor='yes'>
+        <function-decl name='~s0' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='27' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <parameter type-id='95e97e5e' is-artificial='yes'/>
+          <parameter type-id='63e171df' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public'>
+        <function-decl name='mem_fun' mangled-name='_ZN2s07mem_funEv' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN2s07mem_funEv'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <return type-id='61814d27'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='s0' mangled-name='_ZN2s0C1Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN2s0C1Ev'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <parameter type-id='95e97e5e' is-artificial='yes'/>
+          <parameter type-id='63e171df' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' destructor='yes'>
+        <function-decl name='~s0' mangled-name='_ZN2s0D1Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN2s0D1Ev'>
+          <parameter type-id='a1a34114' is-artificial='yes'/>
+          <parameter type-id='95e97e5e' is-artificial='yes'/>
+          <parameter type-id='63e171df' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <qualified-type-def type-id='95a32e30' id='95a32e31'/>
+    <reference-type-def kind='lvalue' type-id='10ec88de' size-in-bits='64' id='95a32e30'/>
+    <pointer-type-def type-id='10ec88de' size-in-bits='64' id='a1a34114'/>
+    <pointer-type-def type-id='48b5725f' size-in-bits='64' id='eaa32e2f'/>
+    <pointer-type-def type-id='eaa32e2f' size-in-bits='64' id='63e171df'/>
+    <function-decl name='foo' mangled-name='_Z3fooR2s0' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3fooR2s0'>
+      <parameter type-id='95a32e31' name='s' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='42' column='1'/>
+      <return type-id='48b5725f'/>
+    </function-decl>
+    <function-decl name='main' mangled-name='main' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test1.cc' line='48' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='main'>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test2.so.hash.abi b/tests/data/test-read-dwarf/test2.so.hash.abi
new file mode 100644
index 00000000..bb814f73
--- /dev/null
+++ b/tests/data/test-read-dwarf/test2.so.hash.abi
@@ -0,0 +1,79 @@
+<abi-corpus path='data/test-read-dwarf/test2.so'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_ZN10first_typeC1Ev' type='func-type' binding='global-binding' visibility='default-visibility' alias='_ZN10first_typeC2Ev' is-defined='yes'/>
+    <elf-symbol name='_ZN10first_typeC2Ev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN11second_typeC1Ev' type='func-type' binding='global-binding' visibility='default-visibility' alias='_ZN11second_typeC2Ev' is-defined='yes'/>
+    <elf-symbol name='_ZN11second_typeC2Ev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN1a16build_first_typeEv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN1a17build_second_typeEv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test2-0.cc' comp-dir-path='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <typedef-decl name='character' type-id='002ac4a6' id='8ec86933'/>
+    <typedef-decl name='integer' type-id='95e97e5e' id='c2cab9c6'/>
+    <type-decl name='unsigned char' size-in-bits='8' id='002ac4a6'/>
+    <type-decl name='void' id='48b5725f'/>
+    <class-decl name='first_type' size-in-bits='64' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='4' column='1' id='55265432'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='member0' type-id='c2cab9c6' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='6' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='32'>
+        <var-decl name='member1' type-id='8ec86933' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='7' column='1'/>
+      </data-member>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='first_type' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='82c95d70' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='first_type' mangled-name='_ZN10first_typeC2Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN10first_typeC1Ev'>
+          <parameter type-id='82c95d70' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <pointer-type-def type-id='55265432' size-in-bits='64' id='82c95d70'/>
+    <namespace-decl name='a'>
+      <function-decl name='build_first_type' mangled-name='_ZN1a16build_first_typeEv' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2-0.cc' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN1a16build_first_typeEv'>
+        <return type-id='82c95d70'/>
+      </function-decl>
+    </namespace-decl>
+  </abi-instr>
+  <abi-instr version='1.0' address-size='64' path='test2-1.cc' comp-dir-path='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <class-decl name='second_type' size-in-bits='64' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='12' column='1' id='cf111fae'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='member0' type-id='c2cab9c6' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='14' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='32'>
+        <var-decl name='member1' type-id='8ec86933' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='15' column='1'/>
+      </data-member>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='second_type' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='fc0abc74' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='second_type' mangled-name='_ZN11second_typeC2Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN11second_typeC1Ev'>
+          <parameter type-id='fc0abc74' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <pointer-type-def type-id='cf111fae' size-in-bits='64' id='fc0abc74'/>
+    <namespace-decl name='a'>
+      <function-decl name='build_second_type' mangled-name='_ZN1a17build_second_typeEv' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2-1.cc' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN1a17build_second_typeEv'>
+        <return type-id='fc0abc74'/>
+      </function-decl>
+    </namespace-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test3.so.hash.abi b/tests/data/test-read-dwarf/test3.so.hash.abi
new file mode 100644
index 00000000..e01f3959
--- /dev/null
+++ b/tests/data/test-read-dwarf/test3.so.hash.abi
@@ -0,0 +1,19 @@
+<abi-corpus path='data/test-read-dwarf/test3.so' soname='test3.so.1'>
+  <elf-needed>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='__foo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='__foo__' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='foo' type='func-type' binding='weak-binding' visibility='default-visibility' alias='foo__,__foo__,__foo' is-defined='yes'/>
+    <elf-symbol name='foo__' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test3.c' comp-dir-path='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf' language='LANG_C89'>
+    <type-decl name='void' id='48b5725f'/>
+    <function-decl name='__foo' mangled-name='foo' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test3.c' line='8' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='foo'>
+      <return type-id='48b5725f'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test4.so.hash.abi b/tests/data/test-read-dwarf/test4.so.hash.abi
new file mode 100644
index 00000000..446df1da
--- /dev/null
+++ b/tests/data/test-read-dwarf/test4.so.hash.abi
@@ -0,0 +1,23 @@
+<abi-corpus path='data/test-read-dwarf/test4.so'>
+  <elf-needed>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='cpy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test4.c' comp-dir-path='/home/mark/src/tests' language='LANG_C89'>
+    <type-decl name='char' size-in-bits='8' id='a84c031d'/>
+    <type-decl name='unsigned int' size-in-bits='32' id='f0981eeb'/>
+    <pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
+    <qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/>
+    <qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/>
+    <pointer-type-def type-id='9b45d938' size-in-bits='64' id='80f4b756'/>
+    <qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
+    <function-decl name='cpy' mangled-name='cpy' filepath='/home/mark/src/tests/test4.c' line='2' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cpy'>
+      <parameter type-id='266fe297' name='s1' filepath='/home/mark/src/tests/test4.c' line='2' column='1'/>
+      <parameter type-id='9d26089a' name='s2' filepath='/home/mark/src/tests/test4.c' line='2' column='1'/>
+      <parameter type-id='f0981eeb' name='n' filepath='/home/mark/src/tests/test4.c' line='2' column='1'/>
+      <return type-id='26a90f95'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test5.o.hash.abi b/tests/data/test-read-dwarf/test5.o.hash.abi
new file mode 100644
index 00000000..9ed9932a
--- /dev/null
+++ b/tests/data/test-read-dwarf/test5.o.hash.abi
@@ -0,0 +1,13 @@
+<abi-corpus path='data/test-read-dwarf/test5.o'>
+  <elf-function-symbols>
+    <elf-symbol name='_Z3barPv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test.cc' comp-dir-path='/home/dodji/libabigailtests' language='LANG_C_plus_plus'>
+    <type-decl name='void' id='48b5725f'/>
+    <pointer-type-def type-id='48b5725f' size-in-bits='64' id='eaa32e2f'/>
+    <function-decl name='bar' mangled-name='_Z3barPv' filepath='/home/dodji/libabigailtests/test.cc' line='2' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3barPv'>
+      <parameter type-id='eaa32e2f'/>
+      <return type-id='48b5725f'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test6.so.hash.abi b/tests/data/test-read-dwarf/test6.so.hash.abi
new file mode 100644
index 00000000..7867a28f
--- /dev/null
+++ b/tests/data/test-read-dwarf/test6.so.hash.abi
@@ -0,0 +1,42 @@
+<abi-corpus path='data/test-read-dwarf/test6.so'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_Z3barv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_Z4blehv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZN1B3fooEv' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <elf-variable-symbols>
+    <elf-symbol name='_ZN1CIiE3barE' size='4' type='object-type' binding='gnu-unique-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_ZZN1B3fooEvE1a' size='4' type='object-type' binding='gnu-unique-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-variable-symbols>
+  <abi-instr version='1.0' address-size='64' path='test6.cc' comp-dir-path='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <class-decl name='B' size-in-bits='8' is-struct='yes' visibility='default' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='9' column='1' id='41d98c5d'>
+      <member-function access='public'>
+        <function-decl name='foo' mangled-name='_ZN1B3fooEv' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN1B3fooEv'>
+          <parameter type-id='06dd347d' is-artificial='yes'/>
+          <return type-id='95e97e5e'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <class-decl name='C&lt;int&gt;' size-in-bits='8' is-struct='yes' visibility='default' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='26' column='1' id='923eef9f'>
+      <data-member access='public' static='yes'>
+        <var-decl name='bar' type-id='95e97e5e' mangled-name='_ZN1CIiE3barE' visibility='default' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='31' column='1' elf-symbol-id='_ZN1CIiE3barE'/>
+      </data-member>
+    </class-decl>
+    <pointer-type-def type-id='41d98c5d' size-in-bits='64' id='06dd347d'/>
+    <function-decl name='bar' mangled-name='_Z3barv' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3barv'>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+    <function-decl name='bleh' mangled-name='_Z4blehv' filepath='/home/skumari/Tasks/source_repo/dodji/libabigail/tests/data/test-read-dwarf/test6.cc' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z4blehv'>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test7.so.hash.abi b/tests/data/test-read-dwarf/test7.so.hash.abi
new file mode 100644
index 00000000..a04025f6
--- /dev/null
+++ b/tests/data/test-read-dwarf/test7.so.hash.abi
@@ -0,0 +1,77 @@
+<abi-corpus path='data/test-read-dwarf/test7.so'>
+  <elf-function-symbols>
+    <elf-symbol name='_Z3fooR1S' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test7.cc' comp-dir-path='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+
+
+
+
+
+
+
+    <type-decl name='char' size-in-bits='8' id='a84c031d'/>
+    <array-type-def dimensions='1' type-id='26a90f95' size-in-bits='448' id='0626c76e'>
+      <subrange length='7' type-id='4c87fef4' id='16fc326e'/>
+
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='8' id='89feb1ec'>
+      <subrange length='1' type-id='4c87fef4' id='52f813b4'/>
+
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='infinite' id='e84913bd'>
+      <subrange length='infinite' type-id='4c87fef4' id='031f2035'/>
+
+    </array-type-def>
+    <type-decl name='double' size-in-bits='64' id='a0eb0f08'/>
+    <array-type-def dimensions='2' type-id='a0eb0f08' size-in-bits='960' id='9ba86d8c'>
+      <subrange length='5' type-id='4c87fef4' id='53010e10'/>
+
+      <subrange length='3' type-id='4c87fef4' id='56f209d2'/>
+
+    </array-type-def>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <array-type-def dimensions='1' type-id='7292109c' size-in-bits='256' id='5abcdf1a'>
+      <subrange length='4' type-id='4c87fef4' id='16fe7105'/>
+
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='07535890' size-in-bits='640' id='bea34bd7'>
+      <subrange length='10' type-id='4c87fef4' id='487da03a'/>
+
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='95e97e5e' size-in-bits='160' id='e41e1db9'>
+      <subrange length='5' type-id='4c87fef4' id='53010e10'/>
+
+    </array-type-def>
+    <type-decl name='sizetype' size-in-bits='64' id='4c87fef4'/>
+    <class-decl name='S' size-in-bits='2304' is-struct='yes' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='1' column='1' id='50d9a3fa'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='a' type-id='e41e1db9' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='3' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='192'>
+        <var-decl name='b' type-id='0626c76e' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='4' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='640'>
+        <var-decl name='c' type-id='9ba86d8c' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='5' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='1600'>
+        <var-decl name='d' type-id='bea34bd7' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='6' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='2240'>
+        <var-decl name='e' type-id='89feb1ec' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='7' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='2248'>
+        <var-decl name='f' type-id='e84913bd' visibility='default' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='8' column='1'/>
+      </data-member>
+    </class-decl>
+    <qualified-type-def type-id='f901ef4c' id='f901ef4d'/>
+    <reference-type-def kind='lvalue' type-id='50d9a3fa' size-in-bits='64' id='f901ef4c'/>
+    <pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
+    <pointer-type-def type-id='95e97e5e' size-in-bits='64' id='7292109c'/>
+    <pointer-type-def type-id='5abcdf1a' size-in-bits='64' id='07535890'/>
+    <function-decl name='foo' mangled-name='_Z3fooR1S' filepath='/home/ooprala/rh/u/libabigail/tests/data/test-read-dwarf/test7.cc' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3fooR1S'>
+      <parameter type-id='f901ef4d'/>
+      <return type-id='95e97e5e'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi b/tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi
new file mode 100644
index 00000000..7197425d
--- /dev/null
+++ b/tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi
@@ -0,0 +1,37 @@
+<abi-corpus path='data/test-read-dwarf/test8-qualified-this-pointer.so'>
+  <elf-needed>
+    <dependency name='libstdc++.so.6'/>
+    <dependency name='libm.so.6'/>
+    <dependency name='libgcc_s.so.1'/>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_ZNK1S3fooEv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test8-qualified-this-pointer.cc' comp-dir-path='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf' language='LANG_C_plus_plus'>
+    <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
+    <type-decl name='void' id='48b5725f'/>
+    <class-decl name='S' size-in-bits='32' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='1' column='1' id='50d9a3fa'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='i' type-id='95e97e5e' visibility='default' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='3' column='1'/>
+      </data-member>
+      <member-function access='public' constructor='yes'>
+        <function-decl name='S' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='5' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <parameter type-id='fd01f598' is-artificial='yes'/>
+          <return type-id='48b5725f'/>
+        </function-decl>
+      </member-function>
+      <member-function access='public' const='yes'>
+        <function-decl name='foo' mangled-name='_ZNK1S3fooEv' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='10' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNK1S3fooEv'>
+          <parameter type-id='2ee6aa55' is-artificial='yes'/>
+          <return type-id='95e97e5e'/>
+        </function-decl>
+      </member-function>
+    </class-decl>
+    <pointer-type-def type-id='50d9a3fa' size-in-bits='64' id='fd01f598'/>
+    <qualified-type-def type-id='50d9a3fa' const='yes' id='0fb3b55d'/>
+    <pointer-type-def type-id='0fb3b55d' size-in-bits='64' id='2ee6aa55'/>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/test-read-dwarf.cc b/tests/test-read-dwarf.cc
index 7c99d218..5ddb8e4e 100644
--- a/tests/test-read-dwarf.cc
+++ b/tests/test-read-dwarf.cc
@@ -46,7 +46,11 @@ using abigail::dwarf_reader::read_corpus_from_elf;
 using abigail::dwarf_reader::read_context;
 using abigail::dwarf_reader::read_context_sptr;
 using abigail::dwarf_reader::create_read_context;
+using abigail::xml_writer::SEQUENCE_TYPE_ID_STYLE;
+using abigail::xml_writer::HASH_TYPE_ID_STYLE;
 using abigail::xml_writer::create_write_context;
+using abigail::xml_writer::set_type_id_style;
+using abigail::xml_writer::type_id_style_kind;
 using abigail::xml_writer::write_context_sptr;
 using abigail::xml_writer::write_corpus;
 
@@ -56,6 +60,7 @@ struct InOutSpec
 {
   const char* in_elf_path;
   const char* in_suppr_spec_path;
+  type_id_style_kind type_id_style;
   const char* in_abi_path;
   const char* out_abi_path;
 };// end struct InOutSpec
@@ -66,174 +71,266 @@ InOutSpec in_out_specs[] =
   {
     "data/test-read-dwarf/test0",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test0.abi",
     "output/test-read-dwarf/test0.abi"
   },
+  {
+    "data/test-read-dwarf/test0",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test0.hash.abi",
+    "output/test-read-dwarf/test0.hash.abi"
+  },
   {
     "data/test-read-dwarf/test1",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test1.abi",
     "output/test-read-dwarf/test1.abi"
   },
+  {
+    "data/test-read-dwarf/test1",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test1.hash.abi",
+    "output/test-read-dwarf/test1.hash.abi"
+  },
   {
     "data/test-read-dwarf/test2.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test2.so.abi",
     "output/test-read-dwarf/test2.so.abi"
   },
+  {
+    "data/test-read-dwarf/test2.so",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test2.so.hash.abi",
+    "output/test-read-dwarf/test2.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test3.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test3.so.abi",
     "output/test-read-dwarf/test3.so.abi"
   },
+  {
+    "data/test-read-dwarf/test3.so",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test3.so.hash.abi",
+    "output/test-read-dwarf/test3.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test4.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test4.so.abi",
     "output/test-read-dwarf/test4.so.abi"
   },
+  {
+    "data/test-read-dwarf/test4.so",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test4.so.hash.abi",
+    "output/test-read-dwarf/test4.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test5.o",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test5.o.abi",
     "output/test-read-dwarf/test5.o.abi"
   },
+  {
+    "data/test-read-dwarf/test5.o",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test5.o.hash.abi",
+    "output/test-read-dwarf/test5.o.hash.abi"
+  },
   {
     "data/test-read-dwarf/test6.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test6.so.abi",
     "output/test-read-dwarf/test6.so.abi"
   },
+  {
+    "data/test-read-dwarf/test6.so",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test6.so.hash.abi",
+    "output/test-read-dwarf/test6.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test7.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test7.so.abi",
     "output/test-read-dwarf/test7.so.abi"
   },
+  {
+    "data/test-read-dwarf/test7.so",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test7.so.hash.abi",
+    "output/test-read-dwarf/test7.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test8-qualified-this-pointer.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test8-qualified-this-pointer.so.abi",
     "output/test-read-dwarf/test8-qualified-this-pointer.so.abi"
   },
+  {
+    "data/test-read-dwarf/test8-qualified-this-pointer.so",
+    "",
+    HASH_TYPE_ID_STYLE,
+    "data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi",
+    "output/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi"
+  },
   {
     "data/test-read-dwarf/test9-pr18818-clang.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test9-pr18818-clang.so.abi",
     "output/test-read-dwarf/test9-pr18818-clang.so.abi"
   },
   {
     "data/test-read-dwarf/test10-pr18818-gcc.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test10-pr18818-gcc.so.abi",
     "output/test-read-dwarf/test10-pr18818-gcc.so.abi"
   },
   {
     "data/test-read-dwarf/test11-pr18828.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test11-pr18828.so.abi",
     "output/test-read-dwarf/test11-pr18828.so.abi",
   },
   {
     "data/test-read-dwarf/test12-pr18844.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test12-pr18844.so.abi",
     "output/test-read-dwarf/test12-pr18844.so.abi",
   },
   {
     "data/test-read-dwarf/test13-pr18894.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test13-pr18894.so.abi",
     "output/test-read-dwarf/test13-pr18894.so.abi",
   },
   {
     "data/test-read-dwarf/test14-pr18893.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test14-pr18893.so.abi",
     "output/test-read-dwarf/test14-pr18893.so.abi",
   },
   {
     "data/test-read-dwarf/test15-pr18892.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test15-pr18892.so.abi",
     "output/test-read-dwarf/test15-pr18892.so.abi",
   },
   {
     "data/test-read-dwarf/test16-pr18904.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test16-pr18904.so.abi",
     "output/test-read-dwarf/test16-pr18904.so.abi",
   },
   {
     "data/test-read-dwarf/test17-pr19027.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test17-pr19027.so.abi",
     "output/test-read-dwarf/test17-pr19027.so.abi",
   },
   {
     "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
     "output/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
   },
   {
     "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
     "output/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
   },
   {
     "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
     "output/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
   },
   {
     "data/test-read-dwarf/test21-pr19092.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test21-pr19092.so.abi",
     "output/test-read-dwarf/test21-pr19092.so.abi",
   },
   {
     "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi",
     "output/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi",
   },
   {
     "data/test-read-dwarf/libtest23.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/libtest23.so.abi",
     "output/test-read-dwarf/libtest23.so.abi",
   },
   {
     "data/test-read-dwarf/libtest24-drop-fns.so",
     "data/test-read-dwarf/test24-drop-fns-0.suppr",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/libtest24-drop-fns.so.abi",
     "output/test-read-dwarf/libtest24-drop-fns.so.abi",
   },
   {
     "data/test-read-dwarf/libtest24-drop-fns.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/libtest24-drop-fns-2.so.abi",
     "output/test-read-dwarf/libtest24-drop-fns-2.so.abi",
   },
   {
     "data/test-read-dwarf/PR22015-libboost_iostreams.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/PR22015-libboost_iostreams.so.abi",
     "output/test-read-dwarf/PR22015-libboost_iostreams.so.abi",
   },
   {
     "data/test-read-dwarf/PR22122-libftdc.so",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/PR22122-libftdc.so.abi",
     "output/test-read-dwarf/PR22122-libftdc.so.abi",
   },
   {
     "data/test-read-dwarf/PR24378-fn-is-not-scope.o",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/PR24378-fn-is-not-scope.abi",
     "output/test-read-dwarf/PR24378-fn-is-not-scope.abi",
   },
@@ -241,6 +338,7 @@ InOutSpec in_out_specs[] =
   {
     "data/test-read-dwarf/PR25007-sdhci.ko",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/PR25007-sdhci.ko.abi",
     "output/test-read-dwarf/PR25007-sdhci.ko.abi",
   },
@@ -249,6 +347,7 @@ InOutSpec in_out_specs[] =
   {
     "data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
     "output/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
   },
@@ -256,23 +355,26 @@ InOutSpec in_out_specs[] =
   {
     "data/test-read-dwarf/test25-bogus-binary.elf",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "",
     "",
   },
   {
     "data/test-read-dwarf/test26-bogus-binary.elf",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "",
     "",
   },
   {
     "data/test-read-dwarf/test27-bogus-binary.elf",
     "",
+    SEQUENCE_TYPE_ID_STYLE,
     "",
     "",
   },
   // This should be the last entry.
-  {NULL, NULL, NULL, NULL}
+  {NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL}
 };
 
 using abigail::suppr::suppression_sptr;
@@ -377,8 +479,9 @@ struct test_task : public abigail::workers::task
 	is_ok = false;
 	return;
       }
-    const write_context_sptr write_ctxt
+    write_context_sptr write_ctxt
 	= create_write_context(corp->get_environment(), of);
+    set_type_id_style(*write_ctxt, spec.type_id_style);
     is_ok = write_corpus(*write_ctxt, corp, /*indent=*/0);
     of.close();
 
diff --git a/tools/abidw.cc b/tools/abidw.cc
index 1de48f49..2cd848df 100644
--- a/tools/abidw.cc
+++ b/tools/abidw.cc
@@ -70,7 +70,10 @@ using abigail::comparison::corpus_diff_sptr;
 using abigail::comparison::compute_diff;
 using abigail::comparison::diff_context_sptr;
 using abigail::comparison::diff_context;
+using abigail::xml_writer::SEQUENCE_TYPE_ID_STYLE;
+using abigail::xml_writer::HASH_TYPE_ID_STYLE;
 using abigail::xml_writer::create_write_context;
+using abigail::xml_writer::type_id_style_kind;
 using abigail::xml_writer::write_context_sptr;
 using abigail::xml_writer::write_corpus;
 using abigail::xml_reader::read_corpus_from_native_xml_file;
@@ -114,6 +117,7 @@ struct options
   bool			do_log;
   bool			drop_private_types;
   bool			drop_undefined_syms;
+  type_id_style_kind	type_id_style;
 
   options()
     : display_version(),
@@ -136,7 +140,8 @@ struct options
       annotate(),
       do_log(),
       drop_private_types(false),
-      drop_undefined_syms(false)
+      drop_undefined_syms(false),
+      type_id_style(SEQUENCE_TYPE_ID_STYLE)
   {}
 
   ~options()
@@ -175,6 +180,7 @@ display_usage(const string& prog_name, ostream& out)
     << "  --no-write-default-sizes  do not emit pointer size when it equals"
     " the default address size of the translation unit\n"
     << "  --no-parameter-names  do not show names of function parameters\n"
+    << "  --type-id-style (sequence|hash)  type-id style (sequence(default): type-id-number; hash: hexdigits\n"
     << "  --check-alternate-debug-info <elf-path>  check alternate debug info "
     "of <elf-path>\n"
     << "  --check-alternate-debug-info-base-name <elf-path>  check alternate "
@@ -301,6 +307,18 @@ parse_command_line(int argc, char* argv[], options& opts)
 	opts.default_sizes = false;
       else if (!strcmp(argv[i], "--no-parameter-names"))
 	opts.write_parameter_names = false;
+      else if (!strcmp(argv[i], "--type-id-style"))
+        {
+          ++i;
+          if (i >= argc)
+            return false;
+          if (!strcmp(argv[i], "sequence"))
+            opts.type_id_style = SEQUENCE_TYPE_ID_STYLE;
+          else if (!strcmp(argv[i], "hash"))
+            opts.type_id_style = HASH_TYPE_ID_STYLE;
+          else
+            return false;
+        }
       else if (!strcmp(argv[i], "--check-alternate-debug-info")
 	       || !strcmp(argv[i], "--check-alternate-debug-info-base-name"))
 	{
-- 
2.27.0.290.gba653c62da-goog


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/1] abg-writer: Add support for stable hash type ids.
  2020-06-15 21:07     ` [PATCH v2 1/1] abg-writer: Add support for stable hash " Giuliano Procida
@ 2020-06-16  8:21       ` Dodji Seketeli
  0 siblings, 0 replies; 8+ messages in thread
From: Dodji Seketeli @ 2020-06-16  8:21 UTC (permalink / raw)
  To: Giuliano Procida; +Cc: libabigail, kernel-team, mark, maennich

Giuliano Procida <gprocida@google.com> a écrit:

[...]

> +++ b/include/abg-hash.h
> @@ -24,6 +24,8 @@
>  #define __ABG_HASH_H__
>  
>  #include <cstddef>
> +#include <cstdint>

This is a c++11 only header.  I have replaced it with #include
<stdint.h> otherwise it won't compile on a pre c++11 compiler.

[...]

>
> 	* doc/manuals/abidw.rst: Replace stray documentation of
> 	--named-type-ids with documention of new --type-id-style
> 	option.
> 	* include/abg-writer.h (type_id_style_kind): Add new enum.
> 	(set_type_id_style): Add new write_context setter.
> 	(set_common_options): Set type id style in write context.
> 	* include/abg-hash.h (fnv_hash): Declare new 32-bit FNV-1a
>         hash function in abigail::hashing namespace.
> 	* src/abg-hash.h (fnv_hash): Define new 32-bit FNV-1a hash
>         function in abigail::hashing namespace.
> 	* src/abg-writer.cc (write_context): Add m_type_id_style
>         member to record type style to use, defaulting to
>         SEQUENCE_TYPE_ID_STYLE; add m_used_type_id_hashes to record
>         already-used hashes.
> 	(write_context::get_type_id_style): Add new getter.
> 	(write_context::set_type_id_style): Add new setter.
> 	(get_id_for_type): Add support for HASH_TYPE_ID_STYLE style.
> 	(set_type_id_style): Add new helper function.
> 	* tools/abidw.cc (options): Add type_id_style member.
> 	(display_usage): Add description of --type-id-style option.
> 	(parse_command_line): Parse --type-id-style option.
> 	* tests/data/Makefile.am: Add new hash type id ABI files.
> 	* tests/test-read-dwarf.cc: (InOutSpec): Add type_id_style
> 	member.
> 	(in_out_specs): Set type_id_style to SEQUENCE_TYPE_ID_STYLE in
>         existing test specifications. Duplicate first 9 test cases
>         with type_id_style set to HASH_TYPE_ID_STYLE.
> 	* tests/data/test-read-dwarf/test0.hash.abi: New ABI XML file
> 	with hash type ids.
> 	* tests/data/test-read-dwarf/test1.hash.abi: Ditto.
> 	* tests/data/test-read-dwarf/test2.so.hash.abi: Ditto.
> 	* tests/data/test-read-dwarf/test3.so.hash.abi: Ditto.
> 	* tests/data/test-read-dwarf/test4.so.hash.abi: Ditto.
> 	* tests/data/test-read-dwarf/test5.o.hash.abi: Ditto.
> 	* tests/data/test-read-dwarf/test6.so.hash.abi: Ditto.
> 	* tests/data/test-read-dwarf/test7.so.hash.abi: Ditto.
> 	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
> 	Ditto.
>
> Signed-off-by: Giuliano Procida <gprocida@google.com>

Applied to master, thanks!

Cheers,

-- 
		Dodji

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-06-16  8:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-12  9:59 [PATCH 0/2] Stable type ids Giuliano Procida
2020-06-12  9:59 ` [PATCH 1/2] abg-writer: Add support for stable hash " Giuliano Procida
2020-06-15 17:18   ` Dodji Seketeli
2020-06-15 19:29   ` Matthias Maennich
2020-06-15 21:07   ` [PATCH v2 0/1] Stable " Giuliano Procida
2020-06-15 21:07     ` [PATCH v2 1/1] abg-writer: Add support for stable hash " Giuliano Procida
2020-06-16  8:21       ` Dodji Seketeli
2020-06-12  9:59 ` [PATCH 2/2] Add tests for abidw --type-id-style hash Giuliano Procida

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).