[applied] Suppress patch file that was wrongly added to the repository

Message ID 87wmo28voc.fsf@redhat.com
State New
Headers
Series [applied] Suppress patch file that was wrongly added to the repository |

Commit Message

Dodji Seketeli May 9, 2024, 10:30 p.m. UTC
  Hello,

I have wrongly added a patch to the source repository.  Oops.  Remove it.

	* patches/0001-WIP-Emit-read-undefined-interfaces-to-from-ABIXML.patch:
	Remove from the repository.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Applied to master branch.
---
 ...-undefined-interfaces-to-from-ABIXML.patch | 1051 -----------------
 1 file changed, 1051 deletions(-)
 delete mode 100644 patches/0001-WIP-Emit-read-undefined-interfaces-to-from-ABIXML.patch
  

Patch

diff --git a/patches/0001-WIP-Emit-read-undefined-interfaces-to-from-ABIXML.patch b/patches/0001-WIP-Emit-read-undefined-interfaces-to-from-ABIXML.patch
deleted file mode 100644
index 218820e1..00000000
--- a/patches/0001-WIP-Emit-read-undefined-interfaces-to-from-ABIXML.patch
+++ /dev/null
@@ -1,1051 +0,0 @@ 
-From cab35084da3550474f5349cfc2e65d36a7f3f91b Mon Sep 17 00:00:00 2001
-From: Dodji Seketeli <dodji@redhat.com>
-Date: Wed, 6 Mar 2024 13:47:14 +0100
-Subject: [PATCH] WIP: Emit & read undefined interfaces to & from ABIXML
-
-This work-in-progress patch teaches the ABIXML writer to emit
-information about undefined interfaces.  It also teaches the ABIXML
-reader to read information about undefined interfaces.
-
-It introduces two new ABIXML elements:
-'undefined-elf-function-symbols' and 'undefined-elf-variable-symbols'
-to represent undefined function and variable symbols.
-
-Then, in the 'abi-instr' element functions and variables that
-reference undefined elf symbols now have an 'elf-symbol-id' attribute
-referencing the undefined symbol listed in the new
-'undefined-elf-variable-symbols' or 'undefined-elf-function-symbols'
-element.
-
-This work-in-progress branch comes on top of the users/dodji/abidb
-branch and should be merged into it at some point.
-
-TODO: add some tests.
-
-	* include/abg-writer.h (set_write_undefined_symbols): Declare new
-	function.
-	(set_common_options): Use the new set_write_undefined_symbols in
-	this function template.
-	* src/abg-corpus.cc (corpus::lookup_{function,variable}_symbol):
-	Lookup the symbol also among undefined symbols, not just among
-	defined symbols.
-	* src/abg-dwarf-reader.cc (reader::{get_die_language, die_is_in_c,
-	die_is_in_cplus_plus, die_is_in_c_or_cplusplus}): Move these
-	member functions into ...
-	(get_die_language, die_is_in_c, die_is_in_cplus_plus)
-	(die_is_in_c_or_cplusplus): ... these static non-member functions.
-	(fn_die_equal_by_linkage_name): Adjust and remove the now useless
-	reader parameter.
-	(compare_dies, get_scope_die, function_is_suppressed)
-	(variable_is_suppressed): Adjust.
-	(build_translation_unit_and_add_to_ir): When we are asked to load
-	undefined symbol, make sure to also analyze top-level class types
-	and if we are in C++, also analyze top-level unions and structs as
-	these might also have some undefined interfaces.
-	* src/abg-reader.cc (build_elf_symbol_db): Let's not construct and
-	return the symbol DB anymore.  Rather, let's let the caller
-	construct it, so we can just update it with the input gathered.
-	(read_symbol_db_from_input): Support getting undefined function
-	and variable symbols from the new undefined-elf-function-symbols
-	and undefined-elf-variable-symbols elements.  Note that undefined
-	and defined function symbols go into the same symbol DB whereas
-	undefined and defined variable symbols go into another symbol DB.
-	Now, we suppose that the variable & symbol DBs are allocated by
-	the caller.  We pass it down to build_elf_symbol_db that populates
-	it.  Maybe we should rename build_elf_symbol_db into
-	populate_elf_symbol_db.
-	(reader::read_corpus): Allocate the function
-	and variable symbol DB and let read_symbol_db_from_input populate
-	it.  Sort functions and variables after reading the whole ABIXML.
-	* src/abg-writer.cc (write_context::write_context): Define new
-	data member.
-	(write_context::write_context): Initialize it.
-	(write_context::{get,set}::write_undefined_symbols): Define
-	accessors.
-	(set_write_undefined_symbols): Define a new function.
-	(write_context::decl_is_emitted): Add a new overload.
-	(write_elf_symbol_reference): Add a writer context and a corpus
-	parameter.  If the symbol is not in the corpus or if the symbol is
-	undefined and we were not asked to emit undefined symbols then do
-	not emit any reference to it.
-	(write_translation_unit): Emit the undefined functions and
-	variables that belong to the current translation unit, along with
-	their reference to the undefined ELF symbol they are associated
-	to.
-	(write_var_decl, write_function_decl): Let
-	write_elf_symbol_reference decide whether it should emit the
-	reference to ELF symbol or not, as it now know how to make that
-	decision.
-	(write_corpus): Write the undefined function & variable ELF symbol
-	data bases.  These in the new 'undefined-elf-function-symbols' and
-	'undefined-elf-variable-symbols' elements.
-	* tools/abidw.cc (options::load_undefined_interfaces): Define new
-	data member.
-	(options:options): Initialize it.
-	(display_usage): Add a help string for the
-	--no-load-undefined-interfaces option.
-	(parse_command_line): Parse the --no-load-undefined-interfaces
-	option.
-	(set_generic_options): Set the
-	fe_iface::option_type::load_undefined_interfaces option.
-	* doc/manuals/abidw.rst: Document the new
-	--no-load-undefined-interfaces of abidw.
-
-Signed-off-by: Dodji Seketeli <dodji@redhat.com>
----
- doc/manuals/abidw.rst    |  10 +++
- include/abg-writer.h     |   4 +
- src/abg-corpus.cc        |  38 +++++---
- src/abg-dwarf-reader.cc  | 189 +++++++++++++++++++++------------------
- src/abg-reader.cc        |  81 +++++++++++------
- src/abg-writer.cc        | 152 +++++++++++++++++++++++++++++--
- tests/test-annotate.cc   |   2 +-
- tests/test-read-dwarf.cc |   2 +-
- tools/abidw.cc           |   7 ++
- 9 files changed, 350 insertions(+), 135 deletions(-)
-
-diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst
-index 1e308e66..6c399675 100644
---- a/doc/manuals/abidw.rst
-+++ b/doc/manuals/abidw.rst
-@@ -329,6 +329,16 @@ Options
-     makes ``abidw`` load *all* the types defined in the binaries, even
-     those that are not reachable from public declarations.
- 
-+    * ``--no-load-undefined-interfaces``
-+
-+    By default, ``libabigail`` (and thus ``abidw``) loads information
-+    about undefined function and variable symbols as well as functions
-+    and variables that are associated with those undefined symbols.
-+    Those are called undefined interfaces.  This option however makes
-+    makes ``abidw`` avoid loading information about undefined
-+    interfaces.  The resulting XML file thus doesn't contain
-+    information about those undefined interfaces.
-+
-   *  ``--abidiff``
- 
-     Load the ABI of the ELF binary given in argument, save it in
-diff --git a/include/abg-writer.h b/include/abg-writer.h
-index 540487e0..45508544 100644
---- a/include/abg-writer.h
-+++ b/include/abg-writer.h
-@@ -57,6 +57,9 @@ set_write_comp_dir(write_context& ctxt, bool flag);
- void
- set_write_elf_needed(write_context& ctxt, bool flag);
- 
-+void
-+set_write_undefined_symbols(write_context& ctxt, bool flag);
-+
- void
- set_write_default_sizes(write_context& ctxt, bool flag);
- 
-@@ -88,6 +91,7 @@ set_common_options(write_context& ctxt, const OPTS& opts)
-   set_write_corpus_path(ctxt, opts.write_corpus_path);
-   set_write_comp_dir(ctxt, opts.write_comp_dir);
-   set_write_elf_needed(ctxt, opts.write_elf_needed);
-+  set_write_undefined_symbols(ctxt, opts.load_undefined_interfaces);
-   set_write_parameter_names(ctxt, opts.write_parameter_names);
-   set_short_locs(ctxt, opts.short_locs);
-   set_write_default_sizes(ctxt, opts.default_sizes);
-diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc
-index e99b23fe..76c6bbb1 100644
---- a/src/abg-corpus.cc
-+++ b/src/abg-corpus.cc
-@@ -1208,13 +1208,16 @@ corpus::get_undefined_var_symbol_map() const
- const elf_symbol_sptr
- corpus::lookup_function_symbol(const string& n) const
- {
--  if (get_fun_symbol_map().empty())
-+  if (get_fun_symbol_map().empty() && get_undefined_fun_symbol_map().empty())
-     return elf_symbol_sptr();
- 
--  string_elf_symbols_map_type::const_iterator it =
--    get_fun_symbol_map().find(n);
-+  string_elf_symbols_map_type::const_iterator it = get_fun_symbol_map().find(n);
-   if ( it == get_fun_symbol_map().end())
--    return elf_symbol_sptr();
-+    {
-+      it = get_undefined_fun_symbol_map().find(n);
-+      if (it == get_undefined_fun_symbol_map().end())
-+	return elf_symbol_sptr();
-+    }
-   return it->second[0];
- }
- 
-@@ -1275,13 +1278,17 @@ const elf_symbol_sptr
- corpus::lookup_function_symbol(const string& symbol_name,
- 			       const elf_symbol::version& version) const
- {
--  if (get_fun_symbol_map().empty())
-+  if (get_fun_symbol_map().empty() && get_undefined_fun_symbol_map().empty())
-     return elf_symbol_sptr();
- 
-   string_elf_symbols_map_type::const_iterator it =
-     get_fun_symbol_map().find(symbol_name);
-   if ( it == get_fun_symbol_map().end())
--    return elf_symbol_sptr();
-+    {
-+      it = get_undefined_fun_symbol_map().find(symbol_name);
-+      if (it == get_undefined_fun_symbol_map().end())
-+	return elf_symbol_sptr();
-+    }
- 
-   return find_symbol_by_version(version, it->second);
- }
-@@ -1304,13 +1311,16 @@ corpus::lookup_function_symbol(const elf_symbol& symbol) const
- const elf_symbol_sptr
- corpus::lookup_variable_symbol(const string& n) const
- {
--  if (get_var_symbol_map().empty())
-+  if (get_var_symbol_map().empty() && get_undefined_var_symbol_map().empty())
-     return elf_symbol_sptr();
- 
--  string_elf_symbols_map_type::const_iterator it =
--    get_var_symbol_map().find(n);
-+  string_elf_symbols_map_type::const_iterator it = get_var_symbol_map().find(n);
-   if ( it == get_var_symbol_map().end())
--    return elf_symbol_sptr();
-+    {
-+      it = get_undefined_var_symbol_map().find(n);
-+      if (it == get_undefined_var_symbol_map().end())
-+	return elf_symbol_sptr();
-+    }
-   return it->second[0];
- }
- 
-@@ -1326,13 +1336,17 @@ const elf_symbol_sptr
- corpus::lookup_variable_symbol(const string& symbol_name,
- 			       const elf_symbol::version& version) const
- {
--  if (get_var_symbol_map().empty())
-+  if (get_var_symbol_map().empty() && get_undefined_var_symbol_map().empty())
-     return elf_symbol_sptr();
- 
-   string_elf_symbols_map_type::const_iterator it =
-     get_var_symbol_map().find(symbol_name);
-   if ( it == get_var_symbol_map().end())
--    return elf_symbol_sptr();
-+    {
-+      it = get_undefined_var_symbol_map().find(symbol_name);
-+      if (it == get_undefined_var_symbol_map().end())
-+	return elf_symbol_sptr();
-+    }
- 
-   return find_symbol_by_version(version, it->second);
- }
-diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
-index d0aa8c29..89c7be3b 100644
---- a/src/abg-dwarf-reader.cc
-+++ b/src/abg-dwarf-reader.cc
-@@ -379,6 +379,18 @@ get_scope_die(const reader&	rdr,
- 	      size_t			where_offset,
- 	      Dwarf_Die&		scope_die);
- 
-+static bool
-+get_die_language(const Dwarf_Die *die, translation_unit::language &lang) ;
-+
-+static bool
-+die_is_in_c(const Dwarf_Die *die);
-+
-+static bool
-+die_is_in_cplus_plus(const Dwarf_Die *die);
-+
-+static bool
-+die_is_in_c_or_cplusplus(const Dwarf_Die *die);
-+
- static bool
- die_is_anonymous(const Dwarf_Die* die);
- 
-@@ -654,6 +666,75 @@ compare_dies_during_canonicalization(reader& rdr,
- static bool
- get_member_child_die(const Dwarf_Die *die, Dwarf_Die *child);
- 
-+/// Get the language used to generate a given DIE.
-+///
-+/// @param die the DIE to consider.
-+///
-+/// @param lang the resulting language.
-+///
-+/// @return true iff the language of the DIE was found.
-+static bool
-+get_die_language(const Dwarf_Die *die, translation_unit::language &lang) 
-+{
-+  Dwarf_Die cu_die;
-+  ABG_ASSERT(dwarf_diecu(const_cast<Dwarf_Die*>(die), &cu_die, 0, 0));
-+
-+  uint64_t l = 0;
-+  if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
-+    return false;
-+
-+  lang = dwarf_language_to_tu_language(l);
-+  return true;
-+}
-+
-+/// Test if a given DIE originates from a program written in the C
-+/// language.
-+///
-+/// @param die the DIE to consider.
-+///
-+/// @return true iff @p die originates from a program in the C
-+/// language.
-+static bool
-+die_is_in_c(const Dwarf_Die *die)
-+{
-+  translation_unit::language l = translation_unit::LANG_UNKNOWN;
-+  if (!get_die_language(die, l))
-+    return false;
-+  return is_c_language(l);
-+}
-+
-+/// Test if a given DIE originates from a program written in the C++
-+/// language.
-+///
-+/// @param die the DIE to consider.
-+///
-+/// @return true iff @p die originates from a program in the C++
-+/// language.
-+static bool
-+die_is_in_cplus_plus(const Dwarf_Die *die)
-+{
-+  translation_unit::language l = translation_unit::LANG_UNKNOWN;
-+  if (!get_die_language(die, l))
-+    return false;
-+  return is_cplus_plus_language(l);
-+}
-+
-+/// Test if a given DIE originates from a program written either in
-+/// C or C++.
-+///
-+/// @param die the DIE to consider.
-+///
-+/// @return true iff @p die originates from a program written either in
-+/// C or C++.
-+static bool
-+die_is_in_c_or_cplusplus(const Dwarf_Die *die)
-+{
-+  translation_unit::language l = translation_unit::LANG_UNKNOWN;
-+  if (!get_die_language(die, l))
-+    return false;
-+  return (is_cplus_plus_language(l) || is_c_language(l));
-+}
-+
- /// Compare a symbol name against another name, possibly demangling
- /// the symbol_name before performing the comparison.
- ///
-@@ -3320,75 +3401,6 @@ public:
-     return i->second;
-   }
- 
--  /// Get the language used to generate a given DIE.
--  ///
--  /// @param die the DIE to consider.
--  ///
--  /// @param lang the resulting language.
--  ///
--  /// @return true iff the language of the DIE was found.
--  bool
--  get_die_language(const Dwarf_Die *die, translation_unit::language &lang) const
--  {
--    Dwarf_Die cu_die;
--    ABG_ASSERT(dwarf_diecu(const_cast<Dwarf_Die*>(die), &cu_die, 0, 0));
--
--    uint64_t l = 0;
--    if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
--      return false;
--
--    lang = dwarf_language_to_tu_language(l);
--    return true;
--  }
--
--  /// Test if a given DIE originates from a program written in the C
--  /// language.
--  ///
--  /// @param die the DIE to consider.
--  ///
--  /// @return true iff @p die originates from a program in the C
--  /// language.
--  bool
--  die_is_in_c(const Dwarf_Die *die) const
--  {
--    translation_unit::language l = translation_unit::LANG_UNKNOWN;
--    if (!get_die_language(die, l))
--      return false;
--    return is_c_language(l);
--  }
--
--  /// Test if a given DIE originates from a program written in the C++
--  /// language.
--  ///
--  /// @param die the DIE to consider.
--  ///
--  /// @return true iff @p die originates from a program in the C++
--  /// language.
--  bool
--  die_is_in_cplus_plus(const Dwarf_Die *die) const
--  {
--    translation_unit::language l = translation_unit::LANG_UNKNOWN;
--    if (!get_die_language(die, l))
--      return false;
--    return is_cplus_plus_language(l);
--  }
--
--  /// Test if a given DIE originates from a program written either in
--  /// C or C++.
--  ///
--  /// @param die the DIE to consider.
--  ///
--  /// @return true iff @p die originates from a program written either in
--  /// C or C++.
--  bool
--  die_is_in_c_or_cplusplus(const Dwarf_Die *die) const
--  {
--    translation_unit::language l = translation_unit::LANG_UNKNOWN;
--    if (!get_die_language(die, l))
--      return false;
--    return (is_cplus_plus_language(l) || is_c_language(l));
--  }
--
-   /// Check if we can assume the One Definition Rule[1] to be relevant
-   /// for the current translation unit.
-   ///
-@@ -9818,7 +9830,7 @@ die_function_signature(const reader& rdr,
- 
-   translation_unit::language lang;
-   bool has_lang = false;
--  if ((has_lang = rdr.get_die_language(fn_die, lang)))
-+  if ((has_lang = get_die_language(fn_die, lang)))
-     {
-       // In a binary originating from the C language, it's OK to use
-       // the linkage name of the function as a key for the map which
-@@ -10324,8 +10336,6 @@ compare_as_decl_and_type_dies(const reader &rdr,
- /// in C++ for instance, that doesn't imply that the two functions are
- /// equal.
- ///
--/// @param rdr the @ref reader to consider.
--///
- /// @param l the first function DIE to consider.
- ///
- /// @param r the second function DIE to consider.
-@@ -10333,8 +10343,7 @@ compare_as_decl_and_type_dies(const reader &rdr,
- /// @return true iff the function represented by @p l have the same
- /// linkage name as the function represented by @p r.
- static bool
--fn_die_equal_by_linkage_name(const reader &rdr,
--			     const Dwarf_Die *l,
-+fn_die_equal_by_linkage_name(const Dwarf_Die *l,
- 			     const Dwarf_Die *r)
- {
-   if (!!l != !!r)
-@@ -10352,8 +10361,8 @@ fn_die_equal_by_linkage_name(const reader &rdr,
-   string llinkage_name = die_linkage_name(l),
-     rlinkage_name = die_linkage_name(r);
- 
--  if (rdr.die_is_in_c_or_cplusplus(l)
--      && rdr.die_is_in_c_or_cplusplus(r))
-+  if (die_is_in_c_or_cplusplus(l)
-+      && die_is_in_c_or_cplusplus(r))
-     {
-       if (!llinkage_name.empty() && !rlinkage_name.empty())
- 	return llinkage_name == rlinkage_name;
-@@ -11277,19 +11286,18 @@ compare_dies(const reader& rdr,
- 	rdr.compare_count_++;
- 
- 	if (l_tag == DW_TAG_subprogram
--	    && !fn_die_equal_by_linkage_name(rdr, l, r))
-+	    && !fn_die_equal_by_linkage_name(l, r))
- 	  {
- 	    SET_RESULT_TO_FALSE(result, l, r);
- 	    break;
- 	  }
- 	else if (l_tag == DW_TAG_subprogram
--		 && rdr.die_is_in_c(l) && rdr.die_is_in_c(r)
--		 /*&& fn_die_equal_by_linkage_name(rdr, l, r)*/)
-+		 && die_is_in_c(l) && die_is_in_c(r))
- 	  {
- 	    result = COMPARISON_RESULT_EQUAL;
- 	    break;
- 	  }
--	else if (!rdr.die_is_in_c(l) && !rdr.die_is_in_c(r))
-+	else if (!die_is_in_c(l) && !die_is_in_c(r))
- 	  {
- 	    // In C, we cannot have two different functions with the
- 	    // same linkage name in a given binary.  But here we are
-@@ -11914,7 +11922,7 @@ get_scope_die(const reader&	rdr,
-     memcpy(&origin_die_mem, dye, sizeof(origin_die_mem));
- 
-   translation_unit::language die_lang = translation_unit::LANG_UNKNOWN;
--  rdr.get_die_language(die, die_lang);
-+  get_die_language(die, die_lang);
-   if (is_c_language(die_lang)
-       || rdr.die_parent_map(rdr.get_die_source(die)).empty())
-     {
-@@ -11974,7 +11982,7 @@ get_scope_for_die(reader&	rdr,
-   const die_source source_of_die = rdr.get_die_source(die);
- 
-   translation_unit::language die_lang = translation_unit::LANG_UNKNOWN;
--  rdr.get_die_language(die, die_lang);
-+  get_die_language(die, die_lang);
-   if (is_c_language(die_lang)
-       || rdr.die_parent_map(source_of_die).empty())
-     {
-@@ -12342,10 +12350,17 @@ build_translation_unit_and_add_to_ir(reader&	rdr,
-     return result;
- 
-   result->set_is_constructed(false);
--
-+  int tag = dwarf_tag(&child);
-   do
-     if (rdr.load_undefined_interfaces()
--	&& rdr.is_decl_die_with_undefined_symbol(&child))
-+	&& (rdr.is_decl_die_with_undefined_symbol(&child)
-+	    || tag == DW_TAG_class_type // Top-level classes might
-+					// have undefined interfaces
-+					// that need to be
-+					// represented, so let's
-+					// analyze them as well.
-+	    || ((tag == DW_TAG_union_type || tag == DW_TAG_structure_type)
-+		&& die_is_in_cplus_plus(&child))))
-       {
- 	// Analyze undefined functions & variables for the purpose of
- 	// analyzing compatibility matters.
-@@ -15013,7 +15028,7 @@ function_is_suppressed(const reader& rdr,
- 
-   string fname = die_string_attribute(function_die, DW_AT_name);
-   string flinkage_name = die_linkage_name(function_die);
--  if (flinkage_name.empty() && rdr.die_is_in_c(function_die))
-+  if (flinkage_name.empty() && die_is_in_c(function_die))
-     flinkage_name = fname;
-   string qualified_name = build_qualified_name(scope, fname);
- 
-@@ -15190,7 +15205,7 @@ variable_is_suppressed(const reader&		rdr,
- 
-   string name = die_string_attribute(variable_die, DW_AT_name);
-   string linkage_name = die_linkage_name(variable_die);
--  if (linkage_name.empty() && rdr.die_is_in_c(variable_die))
-+  if (linkage_name.empty() && die_is_in_c(variable_die))
-     linkage_name = name;
-   string qualified_name = build_qualified_name(scope, name);
- 
-@@ -16049,7 +16064,7 @@ build_ir_node_from_die(reader&	rdr,
- 	bool var_is_cloned = false;
- 
- 	if (tag == DW_TAG_member)
--	  ABG_ASSERT(!rdr.die_is_in_c(die));
-+	  ABG_ASSERT(!die_is_in_c(die));
- 
- 	if (die_die_attribute(die, DW_AT_specification, spec_die, false)
- 	    || (var_is_cloned = die_die_attribute(die, DW_AT_abstract_origin,
-diff --git a/src/abg-reader.cc b/src/abg-reader.cc
-index b525a137..a91cfaf4 100644
---- a/src/abg-reader.cc
-+++ b/src/abg-reader.cc
-@@ -1270,7 +1270,8 @@ public:
-     if (!needed.empty())
-       corp.set_needed(needed);
- 
--    string_elf_symbols_map_sptr fn_sym_db, var_sym_db;
-+    string_elf_symbols_map_sptr fn_sym_db(new string_elf_symbols_map_type),
-+      var_sym_db(new string_elf_symbols_map_type);
- 
-     // Read the symbol databases.
-     read_symbol_db_from_input(*this, fn_sym_db, var_sym_db);
-@@ -1338,6 +1339,9 @@ public:
- 	set_corpus_node(node);
-       }
- 
-+    corpus()->sort_functions();
-+    corpus()->sort_variables();
-+
-     status = STATUS_OK;
-     return corpus();
-   }
-@@ -1389,8 +1393,9 @@ build_elf_symbol(reader&, const xmlNodePtr, bool);
- static elf_symbol_sptr
- build_elf_symbol_from_reference(reader&, const xmlNodePtr);
- 
--static string_elf_symbols_map_sptr
--build_elf_symbol_db(reader&, const xmlNodePtr, bool);
-+static bool
-+build_elf_symbol_db(reader&, const xmlNodePtr, bool,
-+		    string_elf_symbols_map_sptr&);
- 
- static function_decl::parameter_sptr
- build_function_parameter (reader&, const xmlNodePtr);
-@@ -1898,9 +1903,9 @@ read_translation_unit_from_input(fe_iface& iface)
- ///
- /// @return true upon successful parsing, false otherwise.
- static bool
--read_symbol_db_from_input(reader&		 rdr,
--			  string_elf_symbols_map_sptr& fn_symdb,
--			  string_elf_symbols_map_sptr& var_symdb)
-+read_symbol_db_from_input(reader&			rdr,
-+			  string_elf_symbols_map_sptr&	fn_symdb,
-+			  string_elf_symbols_map_sptr&	var_symdb)
- {
-   xml::reader_sptr reader = rdr.get_libxml_reader();
-   if (!reader)
-@@ -1917,13 +1922,20 @@ read_symbol_db_from_input(reader&		 rdr,
- 	if (status != 1)
- 	  return false;
- 
--	bool has_fn_syms = false, has_var_syms = false;
-+	bool has_fn_syms = false, has_undefined_fn_syms = false,
-+	  has_var_syms = false, has_undefined_var_syms = false;
- 	if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
- 			 BAD_CAST("elf-function-symbols")))
- 	  has_fn_syms = true;
- 	else if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
- 			      BAD_CAST("elf-variable-symbols")))
- 	  has_var_syms = true;
-+	else if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
-+			      BAD_CAST("undefined-elf-function-symbols")))
-+	  has_undefined_fn_syms = true;
-+	else if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
-+			      BAD_CAST("undefined-elf-variable-symbols")))
-+	  has_undefined_var_syms = true;
- 	else
- 	  break;
- 
-@@ -1932,20 +1944,30 @@ read_symbol_db_from_input(reader&		 rdr,
- 	  return false;
- 
- 	if (has_fn_syms)
--	  fn_symdb = build_elf_symbol_db(rdr, node, true);
-+	  build_elf_symbol_db(rdr, node, /*function_sym=*/true, fn_symdb);
-+	else if (has_undefined_fn_syms)
-+	  build_elf_symbol_db(rdr, node, /*function_sym=*/true, fn_symdb);
- 	else if (has_var_syms)
--	  var_symdb = build_elf_symbol_db(rdr, node, false);
-+	  build_elf_symbol_db(rdr, node, /*function_sym=*/false, var_symdb);
-+	else if (has_undefined_var_syms)
-+	  build_elf_symbol_db(rdr, node, /*function_sym=*/false, var_symdb);
- 
- 	xmlTextReaderNext(reader.get());
-       }
-   else
-     for (xmlNodePtr n = rdr.get_corpus_node(); n; n = xmlNextElementSibling(n))
-       {
--	bool has_fn_syms = false, has_var_syms = false;
-+	bool has_fn_syms = false, has_undefined_fn_syms = false,
-+	  has_var_syms = false, has_undefined_var_syms = false;
- 	if (xmlStrEqual(n->name, BAD_CAST("elf-function-symbols")))
- 	  has_fn_syms = true;
-+	else if (xmlStrEqual(n->name, BAD_CAST("undefined-elf-function-symbols")))
-+	  has_undefined_fn_syms = true;
- 	else if (xmlStrEqual(n->name, BAD_CAST("elf-variable-symbols")))
- 	  has_var_syms = true;
-+	else if (xmlStrEqual(n->name,
-+			     BAD_CAST("undefined-elf-variable-symbols")))
-+	  has_undefined_var_syms = true;
- 	else
- 	  {
- 	    rdr.set_corpus_node(n);
-@@ -1953,9 +1975,13 @@ read_symbol_db_from_input(reader&		 rdr,
- 	  }
- 
- 	if (has_fn_syms)
--	  fn_symdb = build_elf_symbol_db(rdr, n, true);
-+	  build_elf_symbol_db(rdr, n, /*function_sym=*/true, fn_symdb);
-+	else if (has_undefined_fn_syms)
-+	  build_elf_symbol_db(rdr, n, /*function_sym=*/true, fn_symdb);
- 	else if (has_var_syms)
--	  var_symdb = build_elf_symbol_db(rdr, n, false);
-+	  build_elf_symbol_db(rdr, n, /*function_sym=*/false, var_symdb);
-+	else if (has_undefined_var_syms)
-+	  build_elf_symbol_db(rdr, n, /*function_sym=*/false, var_symdb);
- 	else
- 	  break;
-       }
-@@ -3300,24 +3326,30 @@ build_elf_symbol_from_reference(reader& rdr, const xmlNodePtr node)
- /// @param function_syms true if we should look for a function symbols
- /// data base, false if we should look for a variable symbols data
- /// base.
--static string_elf_symbols_map_sptr
--build_elf_symbol_db(reader& rdr,
--		    const xmlNodePtr node,
--		    bool function_syms)
-+///
-+/// @param map a pointer to the map to fill with the symbol database.
-+///
-+/// @return true if some elf symbols were found.
-+static bool
-+build_elf_symbol_db(reader&				rdr,
-+		    const xmlNodePtr			node,
-+		    bool				function_syms,
-+		    string_elf_symbols_map_sptr&	map)
- {
--  string_elf_symbols_map_sptr map, nil;
-   string_elf_symbol_sptr_map_type id_sym_map;
- 
-   if (!node)
--    return nil;
-+    return false;
- 
-   if (function_syms
--      && !xmlStrEqual(node->name, BAD_CAST("elf-function-symbols")))
--    return nil;
-+      && !xmlStrEqual(node->name, BAD_CAST("elf-function-symbols"))
-+      && !xmlStrEqual(node->name, BAD_CAST("undefined-elf-function-symbols")))
-+    return false;
- 
-   if (!function_syms
--      && !xmlStrEqual(node->name, BAD_CAST("elf-variable-symbols")))
--    return nil;
-+      && !xmlStrEqual(node->name, BAD_CAST("elf-variable-symbols"))
-+      && !xmlStrEqual(node->name, BAD_CAST("undefined-elf-variable-symbols")))
-+    return false;
- 
-   rdr.set_corpus_node(node);
- 
-@@ -3336,9 +3368,8 @@ build_elf_symbol_db(reader& rdr,
-       }
- 
-   if (id_sym_map.empty())
--    return nil;
-+    return false;
- 
--  map.reset(new string_elf_symbols_map_type);
-   string_elf_symbols_map_type::iterator it;
-   for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
-        i != id_sym_map.end();
-@@ -3374,7 +3405,7 @@ build_elf_symbol_db(reader& rdr,
- 	}
-     }
- 
--  return map;
-+  return true;
- }
- 
- /// Build a function parameter from a 'parameter' xml element node.
-diff --git a/src/abg-writer.cc b/src/abg-writer.cc
-index 408623ab..dafe706c 100644
---- a/src/abg-writer.cc
-+++ b/src/abg-writer.cc
-@@ -214,6 +214,7 @@ class write_context
-   bool					m_write_corpus_path;
-   bool					m_write_comp_dir;
-   bool					m_write_elf_needed;
-+  bool					m_write_undefined_symbols;
-   bool					m_write_parameter_names;
-   bool					m_short_locs;
-   bool					m_write_default_sizes;
-@@ -252,6 +253,7 @@ public:
-       m_write_corpus_path(true),
-       m_write_comp_dir(true),
-       m_write_elf_needed(true),
-+      m_write_undefined_symbols(true),
-       m_write_parameter_names(true),
-       m_short_locs(false),
-       m_write_default_sizes(true),
-@@ -325,6 +327,20 @@ public:
-   set_write_elf_needed(bool f)
-   {m_write_elf_needed = f;}
- 
-+  /// Getter of the "undefined-symbols" option.
-+  ///
-+  /// @return true iff undefined symbols shall be emitted.
-+  bool
-+  get_write_undefined_symbols() const
-+  {return m_write_undefined_symbols;}
-+
-+  /// Setter of the "undefined-symbols" option.
-+  ///
-+  /// @param f true iff undefined symbols shall be emitted.
-+  void
-+  set_write_undefined_symbols(bool f)
-+  {m_write_undefined_symbols = f;}
-+
-   /// Getter of the default-sizes option.
-   ///
-   /// @return true iff default size-in-bits needs to be emitted
-@@ -793,6 +809,20 @@ public:
-   type_is_emitted(const type_base_sptr& t) const
-   {return type_is_emitted(t.get());}
- 
-+  /// Test if a given decl has been written out to the XML output.
-+  ///
-+  /// @param the decl to consider.
-+  ///
-+  /// @return true if the decl has already been emitted, false
-+  /// otherwise.
-+  bool
-+  decl_is_emitted(const decl_base& decl) const
-+  {
-+    string repr = decl.get_pretty_representation(true);
-+    interned_string irepr = decl.get_environment().intern(repr);
-+    return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
-+  }
-+
-   /// Test if a given decl has been written out to the XML output.
-   ///
-   /// @param the decl to consider.
-@@ -901,8 +931,14 @@ static void write_voffset(function_decl_sptr, ostream&);
- static void write_elf_symbol_type(elf_symbol::type, ostream&);
- static void write_elf_symbol_binding(elf_symbol::binding, ostream&);
- static bool write_elf_symbol_aliases(const elf_symbol&, ostream&);
--static bool write_elf_symbol_reference(const elf_symbol&, ostream&);
--static bool write_elf_symbol_reference(const elf_symbol_sptr, ostream&);
-+static bool write_elf_symbol_reference(write_context&,
-+				       const elf_symbol&,
-+				       const corpus& abi,
-+				       ostream&);
-+static bool write_elf_symbol_reference(write_context&,
-+				       const elf_symbol_sptr,
-+				       const corpus& abi,
-+				       ostream&);
- static void write_is_declaration_only(const decl_base_sptr&, ostream&);
- static void write_is_struct(const class_decl_sptr&, ostream&);
- static void write_is_anonymous(const decl_base_sptr&, ostream&);
-@@ -1766,14 +1802,36 @@ write_elf_symbol_aliases(const elf_symbol& sym, ostream& out)
- /// Write an XML attribute for the reference to a symbol for the
- /// current decl.
- ///
-+///
-+/// @param ctxt the current write context to consider.
-+///
- /// @param sym the symbol to consider.
- ///
-+/// @param abi the ABI corpus the symbol @p sym is supposed to belong
-+/// to.  If the symbol doesn't belong to that corpus, then the
-+/// reference is not be emitted.
-+///
- /// @param o the output stream to write the attribute to.
- ///
- /// @return true upon successful completion.
- static bool
--write_elf_symbol_reference(const elf_symbol& sym, ostream& o)
-+write_elf_symbol_reference(write_context& ctxt,
-+			   const elf_symbol& sym,
-+			   const corpus& abi,
-+			   ostream& o)
- {
-+  elf_symbol_sptr s = abi.lookup_function_symbol(sym);
-+  if (!s)
-+    s = abi.lookup_variable_symbol(sym);
-+
-+  if (// If that symbol wasn't found in the current corpus ...
-+      !s
-+      // ... or we were NOT asked to represent undefined symbols and
-+      // yet that symbol is undefined ...
-+      || (!ctxt.get_write_undefined_symbols() && !s->is_defined()))
-+    // Then do not emit this symbol reference.
-+    return false;
-+
-   const elf_symbol* main = sym.get_main_symbol().get();
-   const elf_symbol* alias = &sym;
-   bool found = !alias->is_suppressed();
-@@ -1804,18 +1862,27 @@ write_elf_symbol_reference(const elf_symbol& sym, ostream& o)
- /// Write an XML attribute for the reference to a symbol for the
- /// current decl.
- ///
-+/// @param ctxt the write context to consider.
-+/// 
- /// @param sym the symbol to consider.
- ///
-+/// @param abi the ABI corpus the symbol @p sym is supposed to belong
-+/// to.  If the symbol doesn't belong to that corpus, then the
-+/// reference is not be emitted.
-+///
- /// @param o the output stream to write the attribute to.
- ///
- /// @return true upon successful completion.
- static bool
--write_elf_symbol_reference(const elf_symbol_sptr sym, ostream& o)
-+write_elf_symbol_reference(write_context& ctxt,
-+			   const elf_symbol_sptr sym,
-+			   const corpus& abi,
-+			   ostream& o)
- {
-   if (!sym)
-     return false;
- 
--  return write_elf_symbol_reference(*sym, o);
-+  return write_elf_symbol_reference(ctxt, *sym, abi, o);
- }
- 
- /// Serialize the attributes "constructor", "destructor" or "static"
-@@ -2255,6 +2322,18 @@ void
- set_write_elf_needed(write_context& ctxt, bool flag)
- {ctxt.set_write_elf_needed(flag);}
- 
-+/// Set the 'undefined-symbols' flag.
-+///
-+/// When this flag is set then the XML writer will emit corpus
-+/// information about the undefined function and variable symbols.
-+///
-+/// @param ctxt the context to set this flag on to.
-+///
-+/// @param flag the new value of the 'undefined-symbols' flag.
-+void
-+set_write_undefined_symbols(write_context& ctxt, bool flag)
-+{ctxt.set_write_undefined_symbols(flag);}
-+
- /// Set the 'default-sizes' flag.
- ///
- /// When this flag is set then the XML writer will emit default
-@@ -2549,6 +2628,32 @@ write_translation_unit(write_context&		ctxt,
- 	}
-     }
- 
-+  // Write the undefined functions that belong to this translation
-+  // unit
-+  if (const abigail::ir::corpus* abi = tu.get_corpus())
-+    for (auto undefined_function : abi->get_sorted_undefined_functions())
-+      {
-+	function_decl_sptr f(const_cast<function_decl*>(undefined_function),
-+			     noop_deleter());
-+	if (f->get_translation_unit() != &tu || ctxt.decl_is_emitted(f))
-+	  continue;
-+
-+	write_decl(f, ctxt, indent + c.get_xml_element_indent());
-+      }
-+
-+  // Write the undefined variables that belong to this translation
-+  // unit
-+  if (const abigail::ir::corpus* abi = tu.get_corpus())
-+    for (auto undefined_var : abi->get_sorted_undefined_variables())
-+      {
-+	var_decl_sptr v(const_cast<var_decl*>(undefined_var),
-+			noop_deleter());
-+	if (v->get_translation_unit() != &tu || ctxt.decl_is_emitted(v))
-+	  continue;
-+
-+	write_decl(v, ctxt, indent + c.get_xml_element_indent());
-+      }
-+
-   write_referenced_types(ctxt, tu, indent, is_last);
- 
-   // Now handle all function types that were not only referenced by
-@@ -3468,8 +3573,8 @@ write_var_decl(const var_decl_sptr& decl, write_context& ctxt,
-   write_location(decl, ctxt);
- 
-   if (elf_symbol_sptr sym = decl->get_symbol())
--    if (sym->is_defined())
--      write_elf_symbol_reference(decl->get_symbol(), o);
-+    if (corpus* abi = decl->get_corpus())
-+      write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
- 
-   o << "/>\n";
- 
-@@ -3526,8 +3631,8 @@ write_function_decl(const function_decl_sptr& decl, write_context& ctxt,
- 			    : decl->get_translation_unit()->get_address_size()),
- 			   0);
-   if (elf_symbol_sptr sym = decl->get_symbol())
--    if (sym->is_defined())
--      write_elf_symbol_reference(decl->get_symbol(), o);
-+    if (corpus* abi = decl->get_corpus())
-+      write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
- 
-   o << ">\n";
- 
-@@ -4734,6 +4839,35 @@ write_corpus(write_context&	ctxt,
-       out << "</elf-variable-symbols>\n";
-     }
- 
-+  // Write the undefined function symbols database.
-+  if (ctxt.get_write_undefined_symbols()
-+      && !corpus->get_sorted_undefined_fun_symbols().empty())
-+    {
-+      do_indent_to_level(ctxt, indent, 1);
-+      out << "<undefined-elf-function-symbols>\n";
-+
-+      write_elf_symbols_table(corpus->get_sorted_undefined_fun_symbols(), ctxt,
-+			      get_indent_to_level(ctxt, indent, 2));
-+
-+      do_indent_to_level(ctxt, indent, 1);
-+      out << "</undefined-elf-function-symbols>\n";
-+    }
-+
-+
-+  // Write the undefined variable symbols database.
-+    if (ctxt.get_write_undefined_symbols()
-+	&& !corpus->get_sorted_undefined_var_symbols().empty())
-+    {
-+      do_indent_to_level(ctxt, indent, 1);
-+      out << "<undefined-elf-variable-symbols>\n";
-+
-+      write_elf_symbols_table(corpus->get_sorted_undefined_var_symbols(), ctxt,
-+			      get_indent_to_level(ctxt, indent, 2));
-+
-+      do_indent_to_level(ctxt, indent, 1);
-+      out << "</undefined-elf-variable-symbols>\n";
-+    }
-+
-   // Now write the translation units.
-   unsigned nb_tus = corpus->get_translation_units().size(), n = 0;
-   for (translation_units::const_iterator i =
-diff --git a/tests/test-annotate.cc b/tests/test-annotate.cc
-index cb9c8af6..8ddd93fb 100644
---- a/tests/test-annotate.cc
-+++ b/tests/test-annotate.cc
-@@ -158,7 +158,7 @@ main()
-   string abidw;
- 
-   abidw = string(get_build_dir()) + "/tools/abidw "
--    "--annotate --no-corpus-path --no-architecture";
-+    "--annotate --no-corpus-path --no-architecture --no-load-undefined-interfaces";
-   for (InOutSpec* s = in_out_specs; s->in_elf_path; ++s)
-     {
-       bool is_ok = true;
-diff --git a/tests/test-read-dwarf.cc b/tests/test-read-dwarf.cc
-index 8570d774..a391c0f1 100644
---- a/tests/test-read-dwarf.cc
-+++ b/tests/test-read-dwarf.cc
-@@ -651,7 +651,7 @@ test_task_dwarf::perform()
-   if (spec.type_id_style == HASH_TYPE_ID_STYLE)
-     type_id_style = "hash";
- 
--  string cmd = abidw + " --no-architecture "
-+  string cmd = abidw + " --no-architecture --no-load-undefined-interfaces"
-     + " --type-id-style " + type_id_style
-     + " --no-corpus-path "
-     + drop_private_types + " " + in_elf_path
-diff --git a/tools/abidw.cc b/tools/abidw.cc
-index c8a44dda..7ea12908 100644
---- a/tools/abidw.cc
-+++ b/tools/abidw.cc
-@@ -109,6 +109,7 @@ struct options
-   bool			short_locs;
-   bool			default_sizes;
-   bool			load_all_types;
-+  bool			load_undefined_interfaces;
-   bool			linux_kernel_mode;
-   bool			corpus_group_for_linux;
-   bool			show_stats;
-@@ -155,6 +156,7 @@ struct options
-       short_locs(false),
-       default_sizes(true),
-       load_all_types(),
-+      load_undefined_interfaces(true),
-       linux_kernel_mode(true),
-       corpus_group_for_linux(false),
-       show_stats(),
-@@ -233,6 +235,8 @@ display_usage(const string& prog_name, ostream& out)
-     "debug info of <elf-path>, and show its base name\n"
-     << "  --load-all-types  read all types including those not reachable from "
-     "exported declarations\n"
-+    << "  --no-load-undefined-interfaces  do not consider undefined "
-+    "interfaces from the binary"
-     << "  --no-linux-kernel-mode  don't consider the input binary as "
-        "a Linux Kernel binary\n"
-     << "  --kmi-whitelist|-w  path to a linux kernel "
-@@ -445,6 +449,8 @@ parse_command_line(int argc, char* argv[], options& opts)
- 	}
-       else if (!strcmp(argv[i], "--load-all-types"))
- 	opts.load_all_types = true;
-+      else if (!strcmp(argv[i], "--no-load-undefined-interfaces"))
-+	opts.load_undefined_interfaces = false;
-       else if (!strcmp(argv[i], "--drop-private-types"))
- 	opts.drop_private_types = true;
-       else if (!strcmp(argv[i], "--drop-undefined-syms"))
-@@ -614,6 +620,7 @@ set_generic_options(abigail::elf_based_reader& rdr, options& opts)
-     opts.leverage_dwarf_factorization;
-   rdr.options().assume_odr_for_cplusplus =
-     opts.assume_odr_for_cplusplus;
-+  rdr.options().load_undefined_interfaces = opts.load_undefined_interfaces;
- }
- 
- /// Load an ABI @ref corpus (the internal representation of the ABI of
--- 
-2.39.3
-