[diffoscope] 01/01: Add support for reading the symbol table to ArFile
Ximin Luo
infinity0 at debian.org
Sat Aug 13 16:29:14 CEST 2016
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository diffoscope.
commit cc3a2ba785e1853282c48bb7468e96ac62103c2f
Author: Ximin Luo <infinity0 at debian.org>
Date: Sat Aug 13 16:27:27 2016 +0200
Add support for reading the symbol table to ArFile
---
diffoscope/__init__.py | 4 ++++
diffoscope/comparators/ar.py | 31 +++++++++++++++++++------------
tests/comparators/test_rlib.py | 31 ++++++++++++++++++++-----------
tests/data/rlib_armap_expected_diff | 12 ++++++++++++
4 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/diffoscope/__init__.py b/diffoscope/__init__.py
index a72323f..b993682 100644
--- a/diffoscope/__init__.py
+++ b/diffoscope/__init__.py
@@ -131,6 +131,10 @@ class RequiredToolNotFound(Exception):
'arch': 'gettext',
'FreeBSD': 'gettext-tools',
},
+ 'nm': {
+ 'debian': 'binutils-multiarch',
+ 'arch': 'binutils',
+ },
'objdump': {
'debian': 'binutils-multiarch',
'arch': 'binutils',
diff --git a/diffoscope/comparators/ar.py b/diffoscope/comparators/ar.py
index d66f7e4..cc54aec 100644
--- a/diffoscope/comparators/ar.py
+++ b/diffoscope/comparators/ar.py
@@ -18,13 +18,15 @@
# You should have received a copy of the GNU General Public License
# along with diffoscope. If not, see <http://www.gnu.org/licenses/>.
-import os.path
import re
+from diffoscope import tool_required
from diffoscope.difference import Difference
from diffoscope.comparators.binary import File
from diffoscope.comparators.libarchive import LibarchiveContainer, list_libarchive
+from diffoscope.comparators.utils import Command
from diffoscope import logger
+
# TODO: this would also be useful for Go archives. Currently those are handled
# by StaticLibFile, but then readelf complains with "Error: Not an ELF file".
# ArFile gives slightly more reasonable output, e.g. a readable plain diff of
@@ -34,16 +36,20 @@ class ArContainer(LibarchiveContainer):
def get_members(self):
members = LibarchiveContainer.get_members(self)
cls = members.__class__
- # for some reason libarchive outputs ["/", "//"] as member names for
- # some archives. for now, let's just filter these out, otherwise they
- # cause exceptions later. eventually, we should investigate this in
- # more detail and handle it properly.
- filtered_out = cls([p for p in members.items() if not os.path.basename(p[0])])
+ known_ignores = {
+ "/" : "this is the symbol table, already accounted for in other output",
+ "//" : "this is the table for GNU long names, already accounted for in the archive filelist",
+ }
+ filtered_out = cls([p for p in members.items() if p[0] in known_ignores])
if filtered_out:
- logger.debug("ignored directory ar members %s in %s, don't yet know how to handle these",
- list(filtered_out.keys()), self.source.path)
- return cls([p for p in members.items() if os.path.basename(p[0])])
+ for k, v in filtered_out.items():
+ logger.debug("ignored ar member '%s' because %s", k, known_ignores[k])
+ return cls([p for p in members.items() if p[0] not in known_ignores])
+class ArSymbolTableDumper(Command):
+ @tool_required('nm')
+ def cmdline(self):
+ return ['nm', '-s', self.path]
class ArFile(File):
CONTAINER_CLASS = ArContainer
@@ -54,6 +60,7 @@ class ArFile(File):
return ArFile.RE_FILE_TYPE.search(file.magic_file_type)
def compare_details(self, other, source=None):
- return [Difference.from_text_readers(list_libarchive(self.path),
- list_libarchive(other.path),
- self.path, other.path, source="file list")]
+ return [Difference.from_command(ArSymbolTableDumper, self.path, other.path),
+ Difference.from_text_readers(list_libarchive(self.path),
+ list_libarchive(other.path),
+ self.path, other.path, source="file list")]
diff --git a/tests/comparators/test_rlib.py b/tests/comparators/test_rlib.py
index 3bc89c0..5e93a20 100644
--- a/tests/comparators/test_rlib.py
+++ b/tests/comparators/test_rlib.py
@@ -52,22 +52,31 @@ def test_no_differences(rlib1):
def differences(rlib1, rlib2):
return rlib1.compare(rlib2).details
-def test_item0_elf(differences):
- assert differences[0].source1 == 'alloc_system-d16b8f0e.0.o'
- assert differences[0].source2 == 'alloc_system-d16b8f0e.0.o'
+def test_num_items(differences):
+ assert len(differences) == 4
+
+def test_item0_armap(differences):
+ assert differences[0].source1 == 'nm -s {}'
+ assert differences[0].source2 == 'nm -s {}'
+ expected_diff = open(os.path.join(os.path.dirname(__file__), '../data/rlib_armap_expected_diff')).read()
+ assert differences[0].unified_diff == expected_diff
+
+def test_item1_elf(differences):
+ assert differences[1].source1 == 'alloc_system-d16b8f0e.0.o'
+ assert differences[1].source2 == 'alloc_system-d16b8f0e.0.o'
expected_diff = open(os.path.join(os.path.dirname(__file__), '../data/rlib_elf_expected_diff')).read()
- assert differences[0].details[0].unified_diff == expected_diff
+ assert differences[1].details[0].unified_diff == expected_diff
-def test_item1_rust_metadata_bin(differences):
- assert differences[1].source1 == 'rust.metadata.bin'
- assert differences[1].source2 == 'rust.metadata.bin'
+def test_item2_rust_metadata_bin(differences):
+ assert differences[2].source1 == 'rust.metadata.bin'
+ assert differences[2].source2 == 'rust.metadata.bin'
@pytest.mark.skipif(tool_missing('llvm-dis'), reason='missing llvm-dis')
-def test_item2_deflate_llvm_bitcode(differences):
- assert differences[2].source1 == 'alloc_system-d16b8f0e.0.bytecode.deflate'
- assert differences[2].source2 == 'alloc_system-d16b8f0e.0.bytecode.deflate'
+def test_item3_deflate_llvm_bitcode(differences):
+ assert differences[3].source1 == 'alloc_system-d16b8f0e.0.bytecode.deflate'
+ assert differences[3].source2 == 'alloc_system-d16b8f0e.0.bytecode.deflate'
expected_diff = open(os.path.join(os.path.dirname(__file__), '../data/rlib_llvm_dis_expected_diff')).read()
- actual_diff = differences[2].details[0].details[1].unified_diff
+ actual_diff = differences[3].details[0].details[1].unified_diff
assert diff_ignore_line_numbers(actual_diff) == diff_ignore_line_numbers(expected_diff)
def test_compare_non_existing(monkeypatch, rlib1):
diff --git a/tests/data/rlib_armap_expected_diff b/tests/data/rlib_armap_expected_diff
new file mode 100644
index 0000000..1c44838
--- /dev/null
+++ b/tests/data/rlib_armap_expected_diff
@@ -0,0 +1,12 @@
+@@ -1,10 +1,10 @@
+
+ Archive index:
+-__rust_allocate in alloc_system-d16b8f0e.0.o
++__rust_all0cate in alloc_system-d16b8f0e.0.o
+ __rust_deallocate in alloc_system-d16b8f0e.0.o
+ __rust_reallocate in alloc_system-d16b8f0e.0.o
+ __rust_reallocate_inplace in alloc_system-d16b8f0e.0.o
+ __rust_usable_size in alloc_system-d16b8f0e.0.o
+
+ alloc_system-d16b8f0e.0.o:
+ 0000000000000000 T __rust_allocate
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git
More information about the diffoscope
mailing list