summaryrefslogtreecommitdiff
path: root/abi/abitool.py
diff options
context:
space:
mode:
Diffstat (limited to 'abi/abitool.py')
-rw-r--r--abi/abitool.py71
1 files changed, 71 insertions, 0 deletions
diff --git a/abi/abitool.py b/abi/abitool.py
new file mode 100644
index 0000000..9491c3f
--- /dev/null
+++ b/abi/abitool.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import subprocess
+import logging
+
+log = logging.getLogger(__name__)
+
+class AbiTool(object):
+ """ Base class for different kinds of abi analysis tools"""
+ def dump_kernel_abi(self, linux_tree, dump_path):
+ raise NotImplementedError()
+
+ def diff_abi(self, old_dump, new_dump, diff_report):
+ raise NotImplementedError()
+
+ def name(self):
+ raise NotImplementedError()
+
+class Libabigail(AbiTool):
+ """" Concrete AbiTool implementation for libabigail """
+ def dump_kernel_abi(self, linux_tree, dump_path):
+ dump_abi_cmd = ['abidw',
+ '--linux-tree',
+ linux_tree,
+ '--out-file',
+ dump_path]
+ subprocess.check_call(dump_abi_cmd)
+
+ def diff_abi(self, old_dump, new_dump, diff_report):
+ log.info('libabigail diffing: {} and {} at {}'.format(old_dump,
+ new_dump,
+ diff_report))
+ diff_abi_cmd = ['abidiff',
+ '--impacted-interfaces',
+ '--leaf-changes-only',
+ '--dump-diff-tree',
+ old_dump,
+ new_dump]
+
+ with open(diff_report, 'w') as out:
+ try:
+ subprocess.check_call(diff_abi_cmd, stdout=out, stderr=out)
+ except subprocess.CalledProcessError as e:
+ if e.returncode in (1, 2): # abigail error, user error
+ raise
+ return True # actual abi change
+
+ return False # no abi change
+
+def get_abi_tool(abi_tool):
+ if abi_tool == 'libabigail':
+ log.info('using libabigail for abi analysis')
+ return Libabigail()
+
+ raise ValueError("not a valid abi_tool: %s" % abi_tool)
+