Bug 852950 - Use signature sniffing for Elf and Mach-O binaries for dependentlibs.py. r=ted

This commit is contained in:
Mike Hommey 2013-03-20 20:11:16 +01:00
parent 4eac70e2f5
commit 45116cdee1
2 changed files with 49 additions and 29 deletions

View File

@ -20,9 +20,42 @@ MACHO_SIGNATURES = [
FAT_SIGNATURE = 0xcafebabe # mach-o FAT binary
EXECUTABLE_SIGNATURES = [
0x7f454c46, # Elf
] + MACHO_SIGNATURES
ELF_SIGNATURE = 0x7f454c46 # Elf binary
UNKNOWN = 0
MACHO = 1
ELF = 2
def get_type(path):
'''
Check the signature of the give file and returns what kind of executable
matches.
'''
with open(path, 'rb') as f:
signature = f.read(4)
if len(signature) < 4:
return UNKNOWN
signature = struct.unpack('>L', signature)[0]
if signature == ELF_SIGNATURE:
return ELF
if signature in MACHO_SIGNATURES:
return MACHO
if signature != FAT_SIGNATURE:
return UNKNOWN
# We have to sanity check the second four bytes, because Java class
# files use the same magic number as Mach-O fat binaries.
# This logic is adapted from file(1), which says that Mach-O uses
# these bytes to count the number of architectures within, while
# Java uses it for a version number. Conveniently, there are only
# 18 labelled Mach-O architectures, and Java's first released
# class format used the version 43.0.
num = f.read(4)
if len(num) < 4:
return UNKNOWN
num = struct.unpack('>L', num)[0]
if num < 20:
return MACHO
return UNKNOWN
def is_executable(path):
@ -45,27 +78,7 @@ def is_executable(path):
return path.lower().endswith((substs['DLL_SUFFIX'],
substs['BIN_SUFFIX']))
with open(path, 'rb') as f:
signature = f.read(4)
if len(signature) < 4:
return False
signature = struct.unpack('>L', signature)[0]
if signature in EXECUTABLE_SIGNATURES:
return True
if signature != FAT_SIGNATURE:
return False
# We have to sanity check the second four bytes, because Java class
# files use the same magic number as Mach-O fat binaries.
# This logic is adapted from file(1), which says that Mach-O uses
# these bytes to count the number of architectures within, while
# Java uses it for a version number. Conveniently, there are only
# 18 labelled Mach-O architectures, and Java's first released
# class format used the version 43.0.
num = f.read(4)
if len(num) < 4:
return False
num = struct.unpack('>L', num)[0]
return num < 20
return get_type(path) != UNKNOWN
def may_strip(path):

View File

@ -12,6 +12,11 @@ import re
import fnmatch
import subprocess
import sys
from mozpack.executables import (
get_type,
ELF,
MACHO,
)
TOOLCHAIN_PREFIX = ''
@ -112,13 +117,15 @@ def main():
global TOOLCHAIN_PREFIX
TOOLCHAIN_PREFIX = options.toolchain_prefix
lib = args[0]
ext = os.path.splitext(lib)[1]
if ext == '.dll':
func = dependentlibs_dumpbin
elif ext == '.so' or fnmatch.fnmatch(lib, '*.so.*'):
binary_type = get_type(lib)
if binary_type == ELF:
func = dependentlibs_readelf
elif ext == '.dylib':
elif binary_type == MACHO:
func = dependentlibs_otool
else:
ext = os.path.splitext(lib)[1]
assert(ext == '.dll')
func = dependentlibs_dumpbin
if not options.libpaths:
options.libpaths = [os.path.dirname(lib)]