[diffoscope] 02/05: Add support for reading Rust LLVM object files

Ximin Luo infinity0 at debian.org
Sat Aug 13 03:05:03 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 28dbe48e742b2ce78fae1714030f7bf7e51d5953
Author: Ximin Luo <infinity0 at debian.org>
Date:   Sat Aug 13 01:20:02 2016 +0200

    Add support for reading Rust LLVM object files
---
 diffoscope/comparators/__init__.py          |  2 ++
 diffoscope/comparators/{gzip.py => rust.py} | 36 +++++++++++++++++++----------
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/diffoscope/comparators/__init__.py b/diffoscope/comparators/__init__.py
index faa0c16..53e3423 100644
--- a/diffoscope/comparators/__init__.py
+++ b/diffoscope/comparators/__init__.py
@@ -66,6 +66,7 @@ from diffoscope.comparators.pdf import PdfFile
 from diffoscope.comparators.png import PngFile
 from diffoscope.comparators.ppu import PpuFile
 from diffoscope.comparators.ps import PsFile
+from diffoscope.comparators.rust import RustObjectFile
 try:
     from diffoscope.comparators.rpm import RpmFile
 except ImportError as ex:
@@ -153,6 +154,7 @@ FILE_CLASSES = (
     TtfFile,
     MoFile,
     IpkFile,
+    RustObjectFile,
     GzipFile,
     HiFile,
     IccFile,
diff --git a/diffoscope/comparators/gzip.py b/diffoscope/comparators/rust.py
similarity index 57%
copy from diffoscope/comparators/gzip.py
copy to diffoscope/comparators/rust.py
index 5ec244e..7a92728 100644
--- a/diffoscope/comparators/gzip.py
+++ b/diffoscope/comparators/rust.py
@@ -3,6 +3,7 @@
 # diffoscope: in-depth comparison of files, archives, and directories
 #
 # Copyright © 2014-2015 Jérémy Bobbio <lunar at debian.org>
+# Copyright © 2016 Ximin Luo <infinity0 at debian.org>
 #
 # diffoscope is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -21,12 +22,18 @@ from collections import OrderedDict
 import re
 import subprocess
 import os.path
+import zlib
 from diffoscope import logger, tool_required
 from diffoscope.comparators.utils import Archive, get_compressed_content_name
 from diffoscope.difference import Difference
 
 
-class GzipContainer(Archive):
+RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET = 15
+RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET = 23
+ZLIB_DEFAULT_COMPRESSION = b'\x78\x9C'
+
+
+class RustObjectContainer(Archive):
     def open_archive(self):
         return self
 
@@ -34,29 +41,34 @@ class GzipContainer(Archive):
         pass
 
     def get_members(self):
-        return OrderedDict({'gzip-content': self.get_member(self.get_member_names()[0])})
+        return OrderedDict({'deflate-content': self.get_member(self.get_member_names()[0])})
 
     def get_member_names(self):
-        return [get_compressed_content_name(self.source.path, '.gz')]
+        return [get_compressed_content_name(self.source.path, '.deflate')]
 
     @tool_required('gzip')
     def extract(self, member_name, dest_dir):
         dest_path = os.path.join(dest_dir, member_name)
-        logger.debug('gzip extracting to %s', dest_path)
-        with open(dest_path, 'wb') as fp:
-            subprocess.check_call(
-                ["gzip", "--decompress", "--stdout", self.source.path],
-                shell=False, stdout=fp, stderr=None)
+        logger.debug('rust-object extracting to %s', dest_path)
+        # See librustc_trans/back/link.rs for details of this format
+        with open(dest_path, 'wb') as fpw, open(self.source.path, 'rb') as fpr:
+            raw_deflate = fpr.read()[RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET:]
+            # decompressobj() ignores the (non-existent) checksum; a zlib.decompress() would error
+            raw_inflate = zlib.decompressobj().decompress(ZLIB_DEFAULT_COMPRESSION + raw_deflate)
+            fpw.write(raw_inflate)
         return dest_path
 
 
-class GzipFile(object):
-    CONTAINER_CLASS = GzipContainer
-    RE_FILE_TYPE = re.compile(r'^gzip compressed data\b')
+class RustObjectFile(object):
+    CONTAINER_CLASS = RustObjectContainer
 
     @staticmethod
     def recognizes(file):
-        return GzipFile.RE_FILE_TYPE.match(file.magic_file_type)
+        if not file.name.endswith(".deflate"):
+            return False
+        # See librustc_trans/back/link.rs for details of this format
+        with open(file.path, "rb") as fp:
+            return fp.read(RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET) == b'RUST_OBJECT\x01\x00\x00\x00'
 
     def compare_details(self, other, source=None):
         return [Difference.from_text(self.magic_file_type, other.magic_file_type, self, other, source='metadata')]

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list