diff --git a/doc/manuals/abidiff.rst b/doc/manuals/abidiff.rst
index 6aac73b..74c3ebf 100644
--- a/doc/manuals/abidiff.rst
+++ b/doc/manuals/abidiff.rst
@@ -101,8 +101,18 @@ Options
   * ``--headers-dir1 | --hd1`` <headers-directory-path-1>
 
     Specifies where to find the public headers of the first shared
-    library that the tool has to consider.  The tool will thus filter
-    out ABI changes on types that are not defined in public headers.
+    library (or binary in general) that the tool has to consider.  The
+    tool will thus filter out ABI changes on types that are not
+    defined in public headers.
+
+    Note that several public header directories can be specified for
+    the first shared library.  In that case the ``--headers-dir1``
+    option should be present several times on the command line, like
+    in the following example: ::
+
+      $ abidiff --headers-dir1 /some/path       \
+                --headers-dir1 /some/other/path \
+		binary-version-1 binary-version-2
 
   * ``--header-file1 | --hf1`` <header-file-path-1>
 
@@ -116,6 +126,15 @@ Options
     library that the tool has to consider.  The tool will thus filter
     out ABI changes on types that are not defined in public headers.
 
+    Note that several public header directories can be specified for
+    the second shared library.  In that case the ``--headers-dir2``
+    option should be present several times like in the following
+    example: ::
+
+      $ abidiff --headers-dir2 /some/path       \
+                --headers-dir2 /some/other/path \
+		binary-version-1 binary-version-2
+
   * ``--header-file2 | --hf2`` <header-file-path-2>
 
     Specifies where to find one public header of the second shared
diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst
index d0720a0..a67e5fa 100644
--- a/doc/manuals/abidw.rst
+++ b/doc/manuals/abidw.rst
@@ -128,9 +128,18 @@ Options
 
   * ``--headers-dir | --hd`` <headers-directory-path-1>
 
-    Specifies where to find the public headers of the first shared
-    library that the tool has to consider.  The tool will thus filter
-    out types that are not defined in public headers.
+    Specifies where to find the public headers of the binary that the
+    tool has to consider.  The tool will thus filter out types that
+    are not defined in public headers.
+
+    Note that several public header directories can be specified for
+    the binary to consider.  In that case the ``--header-dir`` option
+    should be present several times on the command line, like in the
+    following example: ::
+
+      $ abidw --header-dir /some/path       \
+              --header-dir /some/other/path \
+              binary > binary.abi
 
   * ``--header-file | --hf`` <header-file-path>
 
diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h
index c47e3f4..12651fc 100644
--- a/include/abg-tools-utils.h
+++ b/include/abg-tools-utils.h
@@ -91,6 +91,10 @@ suppr::type_suppression_sptr
 gen_suppr_spec_from_headers(const string& hdrs_root_dir,
 			    const vector<string>& hdr_files);
 
+suppr::type_suppression_sptr
+gen_suppr_spec_from_headers(const vector<string>& headers_root_dirs,
+			    const vector<string>& header_files);
+
 suppr::suppressions_type
 gen_suppr_spec_from_kernel_abi_whitelists
    (const vector<string>& abi_whitelist_paths);
diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc
index f1dc736..bc3d587 100644
--- a/src/abg-tools-utils.cc
+++ b/src/abg-tools-utils.cc
@@ -1842,12 +1842,44 @@ handle_fts_entry(const FTSENT *entry,
     }
 }
 
+/// Populate a type_supression from header files found in a given
+/// directory tree.
+///
+/// The suppression suppresses types defined in source files that are
+/// *NOT* found in the directory tree.
+///
+/// This is a subroutine for gen_suppr_spect_from_headers.
+///
+/// @param headers_root_dir the directory tree to consider for header
+/// files.
+///
+/// @param result the type_supression to populate from the content of
+/// @p headers_root_dir.
+static void
+gen_suppr_spec_from_headers_root_dir(const string& headers_root_dir,
+				     type_suppression_sptr &result)
+{
+  if (!headers_root_dir.empty())
+    {
+      char* paths[] = {const_cast<char*>(headers_root_dir.c_str()), 0};
+
+      if (FTS *file_hierarchy = fts_open(paths, FTS_LOGICAL|FTS_NOCHDIR, NULL))
+	{
+	  FTSENT *entry;
+	  while ((entry = fts_read(file_hierarchy)))
+	    handle_fts_entry(entry, result);
+	  fts_close(file_hierarchy);
+	}
+    }
+}
+
 /// Generate a type suppression specification that suppresses ABI
 /// changes for types defined in source files that are neither in a
-/// given header root dir, not in a set of header files.
+/// given set of header root directories nor in a set of header
+/// files.
 ///
-/// @param headers_root_dir ABI changes in types defined in files
-/// *NOT* found in this directory tree are going be suppressed.
+/// @param headers_root_dirs ABI changes in types defined in files
+/// *NOT* found in these directory trees are going be suppressed.
 ///
 /// @param header_files a set of additional header files that define
 /// types that are to be kept (not supressed) by the returned type
@@ -1856,29 +1888,15 @@ handle_fts_entry(const FTSENT *entry,
 /// @return the resulting type suppression generated, if any file was
 /// found in the directory tree @p headers_root_dir.
 type_suppression_sptr
-gen_suppr_spec_from_headers(const string& headers_root_dir,
+gen_suppr_spec_from_headers(const vector<string>& headers_root_dirs,
 			    const vector<string>& header_files)
 {
   type_suppression_sptr result;
 
-  if (headers_root_dir.empty() && header_files.empty())
-    // We were given no headers root dir and no header files
-    // so the resulting suppression specification shall be empty.
-    return result;
-
-  if (!headers_root_dir.empty())
-    {
-      char* paths[] = {const_cast<char*>(headers_root_dir.c_str()), 0};
-
-      FTS *file_hierarchy = fts_open(paths, FTS_LOGICAL|FTS_NOCHDIR, NULL);
-      if (!file_hierarchy)
-	return result;
-
-      FTSENT *entry;
-      while ((entry = fts_read(file_hierarchy)))
-	handle_fts_entry(entry, result);
-      fts_close(file_hierarchy);
-    }
+  for (vector<string>::const_iterator root_dir = headers_root_dirs.begin();
+       root_dir != headers_root_dirs.end();
+       ++root_dir)
+    gen_suppr_spec_from_headers_root_dir(*root_dir, result);
 
   for (vector<string>::const_iterator file = header_files.begin();
        file != header_files.end();
@@ -1889,6 +1907,32 @@ gen_suppr_spec_from_headers(const string& headers_root_dir,
 }
 
 /// Generate a type suppression specification that suppresses ABI
+/// changes for types defined in source files that are neither in a
+/// given header root dir, not in a set of header files.
+///
+/// @param headers_root_dir ABI changes in types defined in files
+/// *NOT* found in this directory tree are going be suppressed.
+///
+/// @param header_files a set of additional header files that define
+/// types that are to be kept (not supressed) by the returned type
+/// suppression.
+///
+/// @return the resulting type suppression generated, if any file was
+/// found in the directory tree @p headers_root_dir.
+type_suppression_sptr
+gen_suppr_spec_from_headers(const string& headers_root_dir,
+			    const vector<string>& header_files)
+{
+  type_suppression_sptr result;
+  vector<string> root_dirs;
+
+  if (!headers_root_dir.empty())
+    root_dirs.push_back(headers_root_dir);
+
+  return gen_suppr_spec_from_headers(root_dirs, header_files);
+}
+
+/// Generate a type suppression specification that suppresses ABI
 /// changes for types defined in source files that are not in a given
 /// header root dir.
 ///
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 7334db2..8712b0c 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -174,6 +174,16 @@ test-abidiff-exit/test-net-change-report0.txt \
 test-abidiff-exit/test-net-change-report1.txt \
 test-abidiff-exit/test-net-change-report2.txt \
 test-abidiff-exit/test-net-change-report3.txt \
+test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h \
+test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h \
+test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h \
+test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt  \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o \
 \
 test-diff-dwarf/test0-v0.cc		\
 test-diff-dwarf/test0-v0.o			\
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h b/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h
new file mode 100644
index 0000000..49f956f
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h
@@ -0,0 +1,26 @@
+typedef struct opaque_struct * opaque_struct_pointer_type;
+
+typedef struct public_struct_type *public_struct_pointer_type;
+typedef struct public_struct_type2 *public_struct_pointer_type2;
+
+typedef void (*FuncPointerType0) (public_struct_pointer_type,
+				  public_struct_pointer_type);
+
+typedef void (*FuncPointerType1) (public_struct_pointer_type, int);
+
+typedef struct public_struct_type2
+{
+  FuncPointerType0 m0;
+  FuncPointerType1 m1;
+} public_struct_type2;
+
+typedef struct public_struct_type
+{
+  opaque_struct_pointer_type m0;
+  public_struct_type2 *m1;
+} public_struct_type;
+
+void foo(public_struct_pointer_type p1);
+
+void bar(second_public_struct_pointer_type p1,
+	 second_opaque_struct_pointer_type p2);
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h b/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h
new file mode 100644
index 0000000..49f956f
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h
@@ -0,0 +1,26 @@
+typedef struct opaque_struct * opaque_struct_pointer_type;
+
+typedef struct public_struct_type *public_struct_pointer_type;
+typedef struct public_struct_type2 *public_struct_pointer_type2;
+
+typedef void (*FuncPointerType0) (public_struct_pointer_type,
+				  public_struct_pointer_type);
+
+typedef void (*FuncPointerType1) (public_struct_pointer_type, int);
+
+typedef struct public_struct_type2
+{
+  FuncPointerType0 m0;
+  FuncPointerType1 m1;
+} public_struct_type2;
+
+typedef struct public_struct_type
+{
+  opaque_struct_pointer_type m0;
+  public_struct_type2 *m1;
+} public_struct_type;
+
+void foo(public_struct_pointer_type p1);
+
+void bar(second_public_struct_pointer_type p1,
+	 second_opaque_struct_pointer_type p2);
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h b/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h
new file mode 100644
index 0000000..1fe1b37
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h
@@ -0,0 +1,8 @@
+typedef struct second_opaque_struct *second_opaque_struct_pointer_type;
+
+typedef struct second_public_struct * second_public_struct_pointer_type;
+
+struct second_public_struct
+{
+  int m1;
+};
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h b/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h
new file mode 100644
index 0000000..cd7802d
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h
@@ -0,0 +1,9 @@
+typedef struct second_opaque_struct *second_opaque_struct_pointer_type;
+
+typedef struct second_public_struct * second_public_struct_pointer_type;
+
+struct second_public_struct
+{
+  int m1;
+  char m2;
+};
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt
new file mode 100644
index 0000000..41fc64d
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (2 filtered out), 0 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt
new file mode 100644
index 0000000..75d5a61
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt
@@ -0,0 +1,13 @@
+Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+1 function with some indirect sub-type change:
+
+  [C] 'function void bar(second_public_struct_pointer_type, second_opaque_struct_pointer_type)' at test-headers-dir-v1.c:33:1 has some indirect sub-type changes:
+    parameter 1 of type 'typedef second_public_struct_pointer_type' has sub-type changes:
+      underlying type 'second_public_struct*' changed:
+        in pointed to type 'struct second_public_struct' at header-b-v1.h:5:1:
+          type size changed from 32 to 64 (in bits)
+          1 data member insertion:
+            'char second_public_struct::m2', at offset 32 (in bits) at header-b-v1.h:8:1
+
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c
new file mode 100644
index 0000000..0784f53
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c
@@ -0,0 +1,33 @@
+/*
+ * Compile this test with:
+ *   gcc -c -g test-headers-dir-v0.c
+ *
+ *   This test exhibits changes that are redundant in a weird way.
+ *   The redundant path through the diff graph involves typedefs,
+ *   function types and function parameter diff nodes.
+ *
+ */
+#include "headers-b/header-b-v0.h"
+#include "headers-a/header-a-v0.h"
+
+struct opaque_struct
+{
+  int m0;
+  int m1;
+  struct public_struct_type *m2;
+};
+
+struct second_opaque_struct
+{
+  int m0;
+};
+
+void foo(public_struct_pointer_type p __attribute__((unused)))
+{
+}
+
+void
+bar(second_public_struct_pointer_type p1 __attribute__((unused)),
+    second_opaque_struct_pointer_type p2 __attribute__((unused)))
+{
+}
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o
new file mode 100644
index 0000000000000000000000000000000000000000..477198bc15a428381a62586991281d6a87c269dc
GIT binary patch
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c
new file mode 100644
index 0000000..a600757
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c
@@ -0,0 +1,36 @@
+/*
+ * Compile this test with:
+ *   gcc -c -g test-headers-dir-v1.c
+ *
+ *   This test exhibits changes that are redundant in a weird way.
+ *   The redundant path through the diff graph involves typedefs,
+ *   function types and function parameter diff nodes.
+ *
+ */
+
+#include "headers-b/header-b-v1.h"
+#include "headers-a/header-a-v1.h"
+
+struct opaque_struct
+{
+  int m0;
+  int m1;
+  struct public_struct_type *m2;
+  char m3;
+};
+
+struct second_opaque_struct
+{
+  int m0;
+  char m1;
+};
+
+void foo(public_struct_pointer_type p __attribute__((unused)))
+{
+}
+
+void
+bar(second_public_struct_pointer_type p1 __attribute__((unused)),
+    second_opaque_struct_pointer_type p2 __attribute__((unused)))
+{
+}
diff --git a/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o b/tests/data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o
new file mode 100644
index 0000000000000000000000000000000000000000..a7978e2e78677acdde0a47d75735ce8359661483
GIT binary patch
diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc
index 936d1d6..6ebe2a0 100644
--- a/tests/test-abidiff-exit.cc
+++ b/tests/test-abidiff-exit.cc
@@ -34,6 +34,7 @@
 #include <sys/wait.h>
 #include <cstring>
 #include <string>
+#include <vector>
 #include <fstream>
 #include <iostream>
 #include <cstdlib>
@@ -47,6 +48,8 @@ struct InOutSpec
   const char*	in_elfv0_path;
   const char*	in_elfv1_path;
   const char*	in_suppr_path;
+  const char*   in_elfv0_headers_dirs;
+  const char*   in_elfv1_headers_dirs;
   const char*	abidiff_options;
   abidiff_status status;
   const char*	in_report_path;
@@ -59,6 +62,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test1-voffset-change-v0.o",
     "data/test-abidiff-exit/test1-voffset-change-v1.o",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -69,6 +74,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test1-voffset-change-v0.o",
     "data/test-abidiff-exit/test1-voffset-change-v1.o",
     "data/test-abidiff-exit/test1-voffset-change.abignore",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test1-voffset-change-report1.txt",
@@ -78,6 +85,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test2-filtered-removed-fns-v0.o",
     "data/test-abidiff-exit/test2-filtered-removed-fns-v1.o",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -88,6 +97,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test2-filtered-removed-fns-v0.o",
     "data/test-abidiff-exit/test2-filtered-removed-fns-v1.o",
     "data/test-abidiff-exit/test2-filtered-removed-fns.abignore",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test2-filtered-removed-fns-report1.txt",
@@ -98,6 +109,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-loc-v1.bi",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-loc-with-locs-report.txt",
     "output/test-abidiff-exit/test-loc-with-locs-report.txt"
@@ -106,6 +119,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-loc-v0.bi",
     "data/test-abidiff-exit/test-loc-v1.bi",
     "",
+    "",
+    "",
     "--no-show-locs",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-loc-without-locs-report.txt",
@@ -115,6 +130,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-no-stray-comma-v0.o",
     "data/test-abidiff-exit/test-no-stray-comma-v1.o",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-no-stray-comma-report.txt",
@@ -124,6 +141,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-leaf-stats-v0.o",
     "data/test-abidiff-exit/test-leaf-stats-v1.o",
     "",
+    "",
+    "",
     "--no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-leaf-stats-report.txt",
@@ -133,6 +152,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-leaf-more-v0.o",
     "data/test-abidiff-exit/test-leaf-more-v1.o",
     "",
+    "",
+    "",
     "--no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -143,6 +164,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-leaf-fun-type-v0.o",
     "data/test-abidiff-exit/test-leaf-fun-type-v1.o",
     "",
+    "",
+    "",
     "--no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-leaf-fun-type-report.txt",
@@ -152,6 +175,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-leaf-redundant-v0.o",
     "data/test-abidiff-exit/test-leaf-redundant-v1.o",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-leaf-redundant-report.txt",
@@ -161,6 +186,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-leaf-peeling-v0.o",
     "data/test-abidiff-exit/test-leaf-peeling-v1.o",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-leaf-peeling-report.txt",
@@ -170,6 +197,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-leaf-cxx-members-v0.o",
     "data/test-abidiff-exit/test-leaf-cxx-members-v1.o",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -181,6 +210,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-member-size-v1.o",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-member-size-report0.txt",
     "output/test-abidiff-exit/test-member-size-report0.txt"
@@ -189,6 +220,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-member-size-v0.o",
     "data/test-abidiff-exit/test-member-size-v1.o",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-member-size-report1.txt",
@@ -198,6 +231,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-decl-struct-v0.o",
     "data/test-abidiff-exit/test-decl-struct-v1.o",
     "",
+    "",
+    "",
     "--harmless",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-decl-struct-report.txt",
@@ -208,6 +243,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-fun-param-v1.abi",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-fun-param-report.txt",
     "output/test-abidiff-exit/test-fun-param-report.txt"
@@ -216,6 +253,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-decl-enum-v0.o",
     "data/test-abidiff-exit/test-decl-enum-v1.o",
     "",
+    "",
+    "",
     "--harmless",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE,
     "data/test-abidiff-exit/test-decl-enum-report.txt",
@@ -226,6 +265,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-decl-enum-v1.o",
     "",
     "",
+    "",
+    "",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-decl-enum-report-2.txt",
     "output/test-abidiff-exit/test-decl-enum-report-2.txt"
@@ -234,6 +275,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-decl-enum-v0.o",
     "data/test-abidiff-exit/test-decl-enum-v1.o",
     "",
+    "",
+    "",
     "--leaf-changes-only",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-decl-enum-report-3.txt",
@@ -243,6 +286,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-net-change-v0.o",
     "data/test-abidiff-exit/test-net-change-v1.o",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -253,6 +298,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-net-change-v0.o",
     "data/test-abidiff-exit/test-net-change-v1.o",
     "data/test-abidiff-exit/test-net-change.abignore",
+    "",
+    "",
     "--no-default-suppression --no-show-locs",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-net-change-report1.txt",
@@ -262,6 +309,8 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-net-change-v0.o",
     "data/test-abidiff-exit/test-net-change-v1.o",
     "",
+    "",
+    "",
     "--no-default-suppression --no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_ABI_CHANGE
     | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -272,44 +321,90 @@ InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-net-change-v0.o",
     "data/test-abidiff-exit/test-net-change-v1.o",
     "data/test-abidiff-exit/test-net-change.abignore",
+    "",
+    "",
     "--no-default-suppression --no-show-locs --leaf-changes-only",
     abigail::tools_utils::ABIDIFF_OK,
     "data/test-abidiff-exit/test-net-change-report3.txt",
     "output/test-abidiff-exit/test-net-change-report3.txt"
   },
-  {0, 0, 0 ,0,  abigail::tools_utils::ABIDIFF_OK, 0, 0}
+  {
+    "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o",
+    "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o",
+    "",
+    "data/test-abidiff-exit/test-headers-dirs/headers-a",
+    "data/test-abidiff-exit/test-headers-dirs/headers-a",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_OK,
+    "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt",
+    "output/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt"
+  },
+  {
+    "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o",
+    "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o",
+    "",
+    "data/test-abidiff-exit/test-headers-dirs/headers-a, "
+    "data/test-abidiff-exit/test-headers-dirs/headers-b",
+    "data/test-abidiff-exit/test-headers-dirs/headers-a, "
+    "data/test-abidiff-exit/test-headers-dirs/headers-b",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt",
+    "output/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt"
+  },
+  {0, 0, 0 ,0, 0, 0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
 };
 
+/// Prefix the strings in a vector of string.
+///
+/// @param strings the strings to prefix.
+///
+/// @param prefix the prefix to use.
+static void
+do_prefix_strings(std::vector<std::string> &strings,
+		  const std::string& prefix)
+{
+  for (std::vector<std::string>::size_type i = 0; i < strings.size(); ++i)
+    strings[i] = prefix + strings[i];
+}
+
 int
 main()
 {
   using std::string;
+  using std::vector;
   using std::cerr;
   using abigail::tests::get_src_dir;
   using abigail::tests::get_build_dir;
   using abigail::tools_utils::ensure_parent_dir_created;
+  using abigail::tools_utils::split_string;
   using abigail::tools_utils::abidiff_status;
 
   bool is_ok = true;
   string in_elfv0_path, in_elfv1_path,
     in_suppression_path, abidiff_options, abidiff, cmd,
     ref_diff_report_path, out_diff_report_path;
+  vector<string> in_elfv0_headers_dirs, in_elfv1_headers_dirs;
+  string source_dir_prefix = string(get_src_dir()) + "/tests/";
+  string build_dir_prefix = string(get_build_dir()) + "/tests/";
 
     for (InOutSpec* s = in_out_specs; s->in_elfv0_path; ++s)
       {
-	in_elfv0_path = string(get_src_dir()) + "/tests/" + s->in_elfv0_path;
-	in_elfv1_path = string(get_src_dir()) + "/tests/" + s->in_elfv1_path;
+	in_elfv0_path = source_dir_prefix + s->in_elfv0_path;
+	in_elfv1_path = source_dir_prefix + s->in_elfv1_path;
+	split_string(s->in_elfv0_headers_dirs, ",", in_elfv0_headers_dirs);
+	split_string(s->in_elfv1_headers_dirs, ",", in_elfv1_headers_dirs);
+	do_prefix_strings(in_elfv0_headers_dirs, source_dir_prefix);
+	do_prefix_strings(in_elfv1_headers_dirs, source_dir_prefix);
+
 	if (s->in_suppr_path && strcmp(s->in_suppr_path, ""))
-	  in_suppression_path =
-	    string(get_src_dir()) + "/tests/" + s->in_suppr_path;
+	  in_suppression_path = source_dir_prefix + s->in_suppr_path;
 	else
 	  in_suppression_path.clear();
 
 	abidiff_options = s->abidiff_options;
-	ref_diff_report_path =
-	  string(get_src_dir()) + "/tests/" + s->in_report_path;
-	out_diff_report_path =
-	  string(get_build_dir()) + "/tests/" + s->out_report_path;
+	ref_diff_report_path = source_dir_prefix + s->in_report_path;
+	out_diff_report_path = build_dir_prefix + s->out_report_path;
 
 	if (!ensure_parent_dir_created(out_diff_report_path))
 	  {
@@ -323,6 +418,18 @@ main()
 	if (!abidiff_options.empty())
 	  abidiff += " " + abidiff_options;
 
+	if (!in_elfv0_headers_dirs.empty())
+	  for (vector<string>::const_iterator s = in_elfv0_headers_dirs.begin();
+	       s != in_elfv0_headers_dirs.end();
+	       ++s)
+	    abidiff += " --headers-dir1 " + *s;
+
+	if (!in_elfv1_headers_dirs.empty())
+	  for (vector<string>::const_iterator s = in_elfv1_headers_dirs.begin();
+	       s != in_elfv1_headers_dirs.end();
+	       ++s)
+	    abidiff += " --headers-dir2 " + *s;
+
 	if (!in_suppression_path.empty())
 	  abidiff += " --suppressions " + in_suppression_path;
 
diff --git a/tools/abidiff.cc b/tools/abidiff.cc
index 162d5eb..6ac81ee 100644
--- a/tools/abidiff.cc
+++ b/tools/abidiff.cc
@@ -78,9 +78,9 @@ struct options
   vector<string>	drop_var_regex_patterns;
   vector<string>	keep_fn_regex_patterns;
   vector<string>	keep_var_regex_patterns;
-  string		headers_dir1;
+  vector<string>	headers_dirs1;
   vector<string>        header_files1;
-  string		headers_dir2;
+  vector<string>	headers_dirs2;
   vector<string>        header_files2;
   bool			drop_private_types;
   bool			linux_kernel_mode;
@@ -318,7 +318,9 @@ parse_command_line(int argc, char* argv[], options& opts)
 	      opts.wrong_option = argv[i];
 	      return true;
 	    }
-	  opts.headers_dir1 = argv[j];
+	  // The user can specify several header files directories for
+	  // the first binary.
+	  opts.headers_dirs1.push_back(argv[j]);
 	  ++i;
 	}
       else if (!strcmp(argv[i], "--header-file1")
@@ -344,7 +346,9 @@ parse_command_line(int argc, char* argv[], options& opts)
 	      opts.wrong_option = argv[i];
 	      return true;
 	    }
-	  opts.headers_dir2 = argv[j];
+	  // The user can specify several header files directories for
+	  // the first binary.
+	  opts.headers_dirs2.push_back(argv[j]);
 	  ++i;
 	}
       else if (!strcmp(argv[i], "--header-file2")
@@ -720,22 +724,22 @@ set_diff_context_from_opts(diff_context_sptr ctxt,
       load_default_user_suppressions(supprs);
     }
 
-  if (!opts.headers_dir1.empty() || !opts.header_files1.empty())
+  if (!opts.headers_dirs1.empty() || !opts.header_files1.empty())
     {
       // Generate suppression specification to avoid showing ABI
       // changes on types that are not defined in public headers.
       suppression_sptr suppr =
-	gen_suppr_spec_from_headers(opts.headers_dir1, opts.header_files1);
+	gen_suppr_spec_from_headers(opts.headers_dirs1, opts.header_files1);
       if (suppr)
 	ctxt->add_suppression(suppr);
     }
 
-  if (!opts.headers_dir2.empty() || !opts.header_files2.empty())
+  if (!opts.headers_dirs2.empty() || !opts.header_files2.empty())
     {
       // Generate suppression specification to avoid showing ABI
       // changes on types that are not defined in public headers.
       suppression_sptr suppr =
-	gen_suppr_spec_from_headers(opts.headers_dir2, opts.header_files2);
+	gen_suppr_spec_from_headers(opts.headers_dirs2, opts.header_files2);
       if (suppr)
 	ctxt->add_suppression(suppr);
     }
@@ -770,7 +774,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts)
     read_suppressions(*i, supprs);
 
   if (read_context_get_path(read_ctxt) == opts.file1
-      && (!opts.headers_dir1.empty() || !opts.header_files1.empty()))
+      && (!opts.headers_dirs1.empty() || !opts.header_files1.empty()))
     {
       // Generate suppression specification to avoid showing ABI
       // changes on types that are not defined in public headers for
@@ -780,7 +784,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts)
       // corpus loading, they are going to be dropped from the
       // internal representation altogether.
       suppression_sptr suppr =
-	gen_suppr_spec_from_headers(opts.headers_dir1, opts.header_files1);
+	gen_suppr_spec_from_headers(opts.headers_dirs1, opts.header_files1);
       if (suppr)
 	{
 	  if (opts.drop_private_types)
@@ -790,7 +794,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts)
     }
 
   if (read_context_get_path(read_ctxt) == opts.file2
-      && (!opts.headers_dir2.empty() || !opts.header_files2.empty()))
+      && (!opts.headers_dirs2.empty() || !opts.header_files2.empty()))
     {
       // Generate suppression specification to avoid showing ABI
       // changes on types that are not defined in public headers for
@@ -800,7 +804,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts)
       // corpus loading, they are going to be dropped from the
       // internal representation altogether.
       suppression_sptr suppr =
-	gen_suppr_spec_from_headers(opts.headers_dir2, opts.header_files2);
+	gen_suppr_spec_from_headers(opts.headers_dirs2, opts.header_files2);
       if (suppr)
 	{
 	  if (opts.drop_private_types)
diff --git a/tools/abidw.cc b/tools/abidw.cc
index 27a9e48..756a29e 100644
--- a/tools/abidw.cc
+++ b/tools/abidw.cc
@@ -90,7 +90,7 @@ struct options
   string		out_file_path;
   vector<char*>	di_root_paths;
   vector<char**>	prepared_di_root_paths;
-  string		headers_dir;
+  vector<string>	headers_dirs;
   vector<string>	header_files;
   string		vmlinux;
   vector<string>	suppression_paths;
@@ -239,7 +239,7 @@ parse_command_line(int argc, char* argv[], options& opts)
 	  int j = i + 1;
 	  if (j >= argc)
 	    return false;
-	  opts.headers_dir = argv[j];
+	  opts.headers_dirs.push_back(argv[j]);
 	  ++i;
 	}
       else if (!strcmp(argv[i], "--header-file")
@@ -445,7 +445,7 @@ set_suppressions(read_context& read_ctxt, options& opts)
     read_suppressions(*i, supprs);
 
   suppression_sptr suppr =
-    abigail::tools_utils::gen_suppr_spec_from_headers(opts.headers_dir,
+    abigail::tools_utils::gen_suppr_spec_from_headers(opts.headers_dirs,
 						      opts.header_files);
   if (suppr)
     {
