[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