diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc
index 8feaf5b2..0337898b 100644
--- a/src/abg-ctf-reader.cc
+++ b/src/abg-ctf-reader.cc
@@ -84,6 +84,52 @@ public:
 
   corpus_sptr			cur_corpus_;
   corpus_group_sptr		cur_corpus_group_;
+  corpus::exported_decls_builder* exported_decls_builder_;
+
+  /// Setter of the exported decls builder object.
+  ///
+  /// Note that this @ref read_context is not responsible for the live
+  /// time of the exported_decls_builder object.  The corpus is.
+  ///
+  /// @param b the new builder.
+  void
+  exported_decls_builder(corpus::exported_decls_builder* b)
+  {exported_decls_builder_ = b;}
+
+  /// Getter of the exported decls builder object.
+  ///
+  /// @return the exported decls builder.
+  corpus::exported_decls_builder*
+  exported_decls_builder()
+  {return exported_decls_builder_;}
+
+  /// If a given function decl is suitable for the set of exported
+  /// functions of the current corpus, this function adds it to that
+  /// set.
+  ///
+  /// @param fn the function to consider for inclusion into the set of
+  /// exported functions of the current corpus.
+  void
+  maybe_add_fn_to_exported_decls(function_decl* fn)
+  {
+    if (fn)
+      if (corpus::exported_decls_builder* b = exported_decls_builder())
+	b->maybe_add_fn_to_exported_fns(fn);
+  }
+
+  /// If a given variable decl is suitable for the set of exported
+  /// variables of the current corpus, this variable adds it to that
+  /// set.
+  ///
+  /// @param fn the variable to consider for inclusion into the set of
+  /// exported variables of the current corpus.
+  void
+  maybe_add_var_to_exported_decls(var_decl* var)
+  {
+    if (var)
+      if (corpus::exported_decls_builder* b = exported_decls_builder())
+	b->maybe_add_var_to_exported_vars(var);
+  }
 
   /// Getter of the current corpus group being constructed.
   ///
@@ -211,6 +257,7 @@ public:
     ctfa = NULL;
     symtab.reset();
     cur_corpus_group_.reset();
+    exported_decls_builder_ = 0;
   }
 
   ~read_context()
@@ -362,6 +409,26 @@ process_ctf_base_type(read_context *ctxt,
   return result;
 }
 
+/// Build the IR node for a variadic parameter type.
+///
+/// @param ctxt the read context to use.
+///
+/// @return the variadic parameter type.
+static decl_base_sptr
+build_ir_node_for_variadic_parameter_type(read_context &ctxt,
+                                          translation_unit_sptr tunit)
+{
+
+  ir::environment* env = ctxt.ir_env;
+  ABG_ASSERT(env);
+  type_base_sptr t = env->get_variadic_parameter_type();
+  decl_base_sptr type_declaration = get_type_declaration(t);
+  if (!has_scope(type_declaration))
+    add_decl_to_scope(type_declaration, tunit->get_global_scope());
+  canonicalize(t);
+  return type_declaration;
+}
+
 /// Build and return a function type libabigail IR.
 ///
 /// @param ctxt the read context.
@@ -412,11 +479,24 @@ process_ctf_function_type(read_context *ctxt,
       function_decl::parameter_sptr parm
         (new function_decl::parameter(arg_type, "",
                                       location(),
-                                      vararg_p && (i == argc - 1),
+                                      false,
                                       false /* is_artificial */));
       function_parms.push_back(parm);
     }
 
+  if (vararg_p)
+    {
+      type_base_sptr arg_type =
+       is_type(build_ir_node_for_variadic_parameter_type(*ctxt, tunit));
+
+      function_decl::parameter_sptr parm
+       (new function_decl::parameter(arg_type, "",
+                                     location(),
+                                     true,
+                                     false /* is_artificial */));
+      function_parms.push_back(parm);
+    }
+
   result = dynamic_pointer_cast<function_type>(ctxt->lookup_type(ctf_dictionary,
                                                                  ctf_type));
   if (result)
@@ -1105,22 +1185,22 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
   for (const auto& symbol : symtab_reader::filtered_symtab(*symtab, filter))
     {
       std::string sym_name = symbol->get_name();
-      ctf_id_t ctf_var_type;
+      ctf_id_t ctf_sym_type;
 
       if (corp->get_origin() == corpus::LINUX_KERNEL_BINARY_ORIGIN
           || ctxt->is_elf_exec)
-        ctf_var_type= ctf_lookup_variable (ctf_dict, sym_name.c_str());
+        ctf_sym_type= ctf_lookup_variable (ctf_dict, sym_name.c_str());
       else
-        ctf_var_type = ctf_lookup_by_symbol_name(ctf_dict, sym_name.c_str());
+        ctf_sym_type = ctf_lookup_by_symbol_name(ctf_dict, sym_name.c_str());
 
-      if (ctf_var_type == (ctf_id_t) -1)
+      if (ctf_sym_type == (ctf_id_t) -1)
         continue;
 
-      if (ctf_type_kind (ctf_dict, ctf_var_type) != CTF_K_FUNCTION)
+      if (ctf_type_kind (ctf_dict, ctf_sym_type) != CTF_K_FUNCTION)
         {
           const char *var_name = sym_name.c_str();
           type_base_sptr var_type = lookup_type(ctxt, corp, ir_translation_unit,
-                                                ctf_dict, ctf_var_type);
+                                                ctf_dict, ctf_sym_type);
           if (!var_type)
             /* Ignore variable if its type can't be sorted out.  */
             continue;
@@ -1134,11 +1214,13 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
           var_declaration->set_symbol(symbol);
           add_decl_to_scope(var_declaration,
                             ir_translation_unit->get_global_scope());
+          var_declaration->set_is_in_public_symbol_table(true);
+          ctxt->maybe_add_var_to_exported_decls(var_declaration.get());
         }
       else
         {
           const char *func_name = sym_name.c_str();
-          ctf_id_t ctf_sym = ctf_var_type;
+          ctf_id_t ctf_sym = ctf_sym_type;
           type_base_sptr func_type = lookup_type(ctxt, corp, ir_translation_unit,
                                                  ctf_dict, ctf_sym);
           if (!func_type)
@@ -1154,6 +1236,8 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
           func_declaration->set_symbol(symbol);
           add_decl_to_scope(func_declaration,
                             ir_translation_unit->get_global_scope());
+	  func_declaration->set_is_in_public_symbol_table(true);
+          ctxt->maybe_add_fn_to_exported_decls(func_declaration.get());
         }
     }
 
@@ -1331,6 +1415,10 @@ read_corpus(read_context *ctxt, elf_reader::status &status)
       return corp;
     }
 
+  // Set the set of exported declaration that are defined.
+  ctxt->exported_decls_builder
+   (ctxt->cur_corpus_->get_exported_decls_builder().get());
+
   int errp;
   if (corp->get_origin() == corpus::CTF_ORIGIN)
     /* Build the ctfa from the contents of the relevant ELF sections,
diff --git a/tests/data/test-read-ctf/test-PR26568-1.o.abi b/tests/data/test-read-ctf/test-PR26568-1.o.abi
index cfb8a50c..832dc1bd 100644
--- a/tests/data/test-read-ctf/test-PR26568-1.o.abi
+++ b/tests/data/test-read-ctf/test-PR26568-1.o.abi
@@ -7,43 +7,25 @@
       <data-member access='public' layout-offset-in-bits='0'>
         <var-decl name='' type-id='type-id-2' visibility='default'/>
       </data-member>
-      <data-member access='public' layout-offset-in-bits='0'>
-        <var-decl name='' type-id='type-id-3' visibility='default'/>
-      </data-member>
-      <data-member access='public' layout-offset-in-bits='0'>
-        <var-decl name='x' type-id='type-id-4' visibility='default'/>
-      </data-member>
-      <data-member access='public' layout-offset-in-bits='0'>
-        <var-decl name='' type-id='type-id-5' visibility='default'/>
-      </data-member>
-      <data-member access='public' layout-offset-in-bits='0'>
-        <var-decl name='y' type-id='type-id-6' visibility='default'/>
-      </data-member>
     </class-decl>
-    <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-5'>
+    <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'>
       <data-member access='public' layout-offset-in-bits='0'>
-        <var-decl name='y' type-id='type-id-6' visibility='default'/>
+        <var-decl name='y' type-id='type-id-4' visibility='default'/>
       </data-member>
     </class-decl>
-    <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'>
+    <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-5'>
       <data-member access='public' layout-offset-in-bits='0'>
-        <var-decl name='x' type-id='type-id-4' visibility='default'/>
+        <var-decl name='x' type-id='type-id-6' visibility='default'/>
       </data-member>
     </class-decl>
-    <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/>
-    <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/>
+    <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-6'/>
+    <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
     <union-decl name='' size-in-bits='64' is-anonymous='yes' visibility='default' id='type-id-2'>
-      <data-member access='public'>
-        <var-decl name='' type-id='type-id-3' visibility='default'/>
-      </data-member>
-      <data-member access='public'>
-        <var-decl name='x' type-id='type-id-4' visibility='default'/>
-      </data-member>
       <data-member access='public'>
         <var-decl name='' type-id='type-id-5' visibility='default'/>
       </data-member>
       <data-member access='public'>
-        <var-decl name='y' type-id='type-id-6' visibility='default'/>
+        <var-decl name='' type-id='type-id-3' visibility='default'/>
       </data-member>
     </union-decl>
     <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/>
diff --git a/tests/data/test-read-ctf/test-PR26568-2.o.abi b/tests/data/test-read-ctf/test-PR26568-2.o.abi
index 1163f085..70e0772f 100644
--- a/tests/data/test-read-ctf/test-PR26568-2.o.abi
+++ b/tests/data/test-read-ctf/test-PR26568-2.o.abi
@@ -19,15 +19,9 @@
       <data-member access='public'>
         <var-decl name='' type-id='type-id-3' visibility='default'/>
       </data-member>
-      <data-member access='public'>
-        <var-decl name='x' type-id='type-id-4' visibility='default'/>
-      </data-member>
       <data-member access='public'>
         <var-decl name='' type-id='type-id-1' visibility='default'/>
       </data-member>
-      <data-member access='public'>
-        <var-decl name='y' type-id='type-id-2' visibility='default'/>
-      </data-member>
     </union-decl>
     <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/>
     <function-decl name='fun' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='fun'>
diff --git a/tests/data/test-read-ctf/test-anonymous-fields.o.abi b/tests/data/test-read-ctf/test-anonymous-fields.o.abi
index 0419c29c..2134a86d 100644
--- a/tests/data/test-read-ctf/test-anonymous-fields.o.abi
+++ b/tests/data/test-read-ctf/test-anonymous-fields.o.abi
@@ -3,14 +3,14 @@
     <elf-symbol name='t' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
   </elf-variable-symbols>
   <abi-instr address-size='64' language='LANG_C'>
-    <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-1'>
+    <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-1'>
       <data-member access='public' layout-offset-in-bits='0'>
-        <var-decl name='vaddr' type-id='type-id-2' visibility='default'/>
+        <var-decl name='dup_xol_work' type-id='type-id-2' visibility='default'/>
       </data-member>
     </class-decl>
-    <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'>
+    <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'>
       <data-member access='public' layout-offset-in-bits='0'>
-        <var-decl name='dup_xol_work' type-id='type-id-4' visibility='default'/>
+        <var-decl name='vaddr' type-id='type-id-4' visibility='default'/>
       </data-member>
     </class-decl>
     <class-decl name='uprobe_task' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-5'>
@@ -18,16 +18,16 @@
         <var-decl name='' type-id='type-id-6' visibility='default'/>
       </data-member>
     </class-decl>
-    <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/>
+    <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-2'/>
     <union-decl name='' size-in-bits='64' is-anonymous='yes' visibility='default' id='type-id-6'>
       <data-member access='public'>
-        <var-decl name='' type-id='type-id-1' visibility='default'/>
+        <var-decl name='' type-id='type-id-3' visibility='default'/>
       </data-member>
       <data-member access='public'>
-        <var-decl name='' type-id='type-id-3' visibility='default'/>
+        <var-decl name='' type-id='type-id-1' visibility='default'/>
       </data-member>
     </union-decl>
-    <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
-    <var-decl name='t' type-id='type-id-5' mangled-name='t' visibility='default'/>
+    <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
+    <var-decl name='t' type-id='type-id-5' mangled-name='t' visibility='default' elf-symbol-id='t'/>
   </abi-instr>
 </abi-corpus>
diff --git a/tests/data/test-read-ctf/test5.o.abi b/tests/data/test-read-ctf/test5.o.abi
index f7bcdeb1..1dafd13e 100644
--- a/tests/data/test-read-ctf/test5.o.abi
+++ b/tests/data/test-read-ctf/test5.o.abi
@@ -32,6 +32,7 @@
       <return type-id='type-id-7'/>
     </function-decl>
     <function-decl name='bar' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='bar'>
+      <parameter type-id='type-id-9'/>
       <parameter is-variadic='yes'/>
       <return type-id='type-id-12'/>
     </function-decl>
diff --git a/tests/data/test-read-ctf/test7.o.abi b/tests/data/test-read-ctf/test7.o.abi
index a13af174..ca572400 100644
--- a/tests/data/test-read-ctf/test7.o.abi
+++ b/tests/data/test-read-ctf/test7.o.abi
@@ -26,6 +26,7 @@
       <return type-id='type-id-10'/>
     </function-decl>
     <function-type size-in-bits='64' alignment-in-bits='8' id='type-id-9'>
+      <parameter is-variadic='yes'/>
       <return type-id='type-id-10'/>
     </function-type>
     <type-decl name='void' id='type-id-10'/>
diff --git a/tests/test-read-common.cc b/tests/test-read-common.cc
index 9681ac27..b441945c 100644
--- a/tests/test-read-common.cc
+++ b/tests/test-read-common.cc
@@ -95,6 +95,8 @@ test_task::run_abidw(const string& extargs)
 {
   string abidw = string(get_build_dir()) + "/tools/abidw";
   string drop_private_types;
+  set_in_abi_path();
+
   if (!in_public_headers_path.empty())
     drop_private_types += "--headers-dir " + in_public_headers_path +
       " --drop-private-types";
@@ -103,7 +105,7 @@ test_task::run_abidw(const string& extargs)
   if (system(cmd.c_str()))
     {
       error_message = string("ABIs differ:\n")
-        + in_elf_path
+        + in_abi_path
         + "\nand:\n"
         + out_abi_path
         + "\n";
