[5/6] BTF: add btfinfo and btfdiff tools

Message ID 20210611153319.778996-6-gprocida@google.com
State New
Headers
Series BTF ABI |

Commit Message

Giuliano Procida June 11, 2021, 3:33 p.m. UTC
  This commit adds BTF command line tools. They are fairly thin wrappers
around the core BTF functionality.

The files are almost a straight copy of the originals.

Changes:

- Files renamed and #includes updated.

	* tools/Makefile.am: Compile BTF tools, conditional on C++17
	and <linux/btf.h>.
	* tools/btfdiff.cc: New utility that compares BTF information.
	* tools/btfinfo.cc: New utility that dumps BTF information.

Co-authored-by: Maria Teguiani <teguiani@google.com>
Signed-off-by: Giuliano Procida <gprocida@google.com>
---
 tools/Makefile.am | 14 ++++++++++
 tools/btfdiff.cc  | 67 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/btfinfo.cc  | 19 ++++++++++++++
 3 files changed, 100 insertions(+)
 create mode 100644 tools/btfdiff.cc
 create mode 100644 tools/btfinfo.cc
  

Patch

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 648a71b5..bd310c18 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -9,6 +9,12 @@  else
   noinst_SCRIPTS = fedabipkgdiff
 endif
 
+if ENABLE_CXX17
+if HAVE_BTF
+  bin_PROGRAMS += btfinfo btfdiff
+endif
+endif
+
 noinst_PROGRAMS = abisym abinilint
 
 abidiff_SOURCES = abidiff.cc
@@ -45,6 +51,14 @@  kmidiffdir = $(bindir)
 kmidiff_LDADD = $(abs_top_builddir)/src/libabigail.la
 kmidiff_LDFLAGS = -pthread
 
+btfinfo_SOURCES = btfinfo.cc
+btfinfodir = $(bindir)
+btfinfo_LDADD = ../src/libabigail.la
+
+btfdiff_SOURCES = btfdiff.cc
+btfdiffdir = $(bindir)
+btfdiff_LDADD = ../src/libabigail.la
+
 AM_CXXFLAGS = \
 $(VISIBILITY_FLAGS) -I$(abs_top_srcdir)/include \
 -I$(abs_top_srcdir)/tools -fPIC
diff --git a/tools/btfdiff.cc b/tools/btfdiff.cc
new file mode 100644
index 00000000..58c40e42
--- /dev/null
+++ b/tools/btfdiff.cc
@@ -0,0 +1,67 @@ 
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+// -*- mode: C++ -*-
+//
+// Copyright (C) 2020-2021 Google, Inc.
+//
+// Author: Maria Teguiani
+// Author: Giuliano Procida
+
+#include <getopt.h>
+#include <string.h>
+
+#include <iomanip>
+#include <iostream>
+
+#include "abg-btf.h"
+
+const int kAbiChange = 4;
+
+int main(int argc, char* argv[]) {
+  bool use_elf_symbols = true;
+  static option opts[]{
+      {"symbols", required_argument, nullptr, 's'},
+      {nullptr, 0, nullptr, 0},
+  };
+  auto usage = [&]() {
+    std::cerr << "usage: " << argv[0] << " [-s|--symbols type] file1 file2\n"
+	      << "  where type is elf (the default) or btf\n";
+    return 1;
+  };
+  auto bad_arg = [&](int ix) {
+    std::cerr << argv[0] << ": option '--" << opts[ix].name
+	      << "' unrecognized argument '" << optarg << "'\n";
+    return usage();
+  };
+  while (true) {
+    int ix;
+    int c = getopt_long(argc, argv, "s:", opts, &ix);
+    if (c == -1)
+      break;
+    switch (c) {
+      case 's':
+        if (!strcmp(optarg, "btf"))
+          use_elf_symbols = false;
+        else if (!strcmp(optarg, "elf"))
+          use_elf_symbols = true;
+        else
+          return bad_arg(ix);
+        break;
+      default:
+        return usage();
+    }
+  }
+  if (optind + 2 != argc)
+    return usage();
+
+  const auto structs1 = abigail::btf::ReadFile(argv[optind++]);
+  const auto structs2 = abigail::btf::ReadFile(argv[optind++]);
+  const auto& map1 = structs1.GetSymbols(use_elf_symbols);
+  const auto& map2 = structs2.GetSymbols(use_elf_symbols);
+  abigail::btf::Outcomes outcomes;
+  auto result = abigail::btf::Type::CompareSymbols(map1, map2, outcomes);
+  abigail::btf::NameCache names;
+  abigail::btf::Seen seen;
+  abigail::btf::Print(result.details_, outcomes, seen, names, std::cout);
+
+  return result.equals_ ? 0 : kAbiChange;
+}
diff --git a/tools/btfinfo.cc b/tools/btfinfo.cc
new file mode 100644
index 00000000..dbda7945
--- /dev/null
+++ b/tools/btfinfo.cc
@@ -0,0 +1,19 @@ 
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+// -*- mode: C++ -*-
+//
+// Copyright (C) 2020 Google, Inc.
+//
+// Author: Maria Teguiani
+
+#include "abg-btf.h"
+
+int main(int argc, const char *argv[]) {
+  if (argc != 2) {
+    std::cerr << "Please specify the path to a BTF file.";
+    return 1;
+  }
+
+  (void) abigail::btf::ReadFile(argv[1], /* verbose = */ true);
+
+  return 0;
+}