Files
roytam1 38409ecc56 import change from rmottola/Arctic-Fox:
- Bug 1144802 part 1. Add a JSOP_GIMPLICITTHIS which acts like JSOP_IMPLICITTHIS when the script hasPollutedGlobalScope and JSOP_UNDEFINED otherwise. (7b0f4bf1f)
- Bug 1144802 part 2. Add JIT and interpreter fast paths for JSOP_GIMPLICITTHIS when the script doesn't have a polluted scope. (7ed943ea9)
- Bug 1144802 part 3. Output JSOP_GIMPLICITTHIS whenever we have a JSOP_GETNAME in call context and don't know for a fact that we need an implicit this. (5b77362cc)
- Bug 1144802 part 4. Stop returning true from ByteCodeEmitter::needsImplicitThis based on the compileAndGo flag. (3961fb79d)
- Bug 1144802 part 5. Flag eval scripts as having a polluted scopechain when inside a with scope. (59c83ceb0)
- Bug 1144802 part 6. Remove the scopechain walk in BytecodeEmitter::needsImplicitThis, since consumers should now set hasPollutedGlobalScope as needed. (9df2cdacd)
- Bug 1144802 part 7. Remove the scopechain walk in the FunctionBox constructor, since consumers should now set hasPollutedGlobalScope as needed. (4c271aff8)
- Bug 1144802 part 8. Drop the scopechain member from GlobalSharedContext, since it's not needed anymore. (dc58199c2)
- Bug 1336791 - Allow readelf to print types without parentheses. (Fix FreeBSD) (cef15d006)
- pointer style (95722a23a)
- Bug 974418 - Fix a TSan race involving the double-elements flag on template objects. (e5eb524b6)
- pointer style fix and cleanup (2c44d9120)
- Bug 1143802 - Forward jit level information to profiler frontend. (3eefdde2b)
- pointer style (8c639a731)
- Bug 1143860 - Add column number to PCToLineNumber. (7cdb37ad9)
- Bug 1143860 - Deduplicate tracked optimizations when streaming the profile. (2c13cb5fe)
- Bug 1145440 - Ship constant names for tracked strategy and outcomes in the profile JSON instead of slightly longer form strings. (3b8cfa5b5)
- Bug 1142669 part 6 - Don't inline scripts that are known to inline a lot of code. (73bcdf96d)
2019-05-14 07:01:35 +08:00

145 lines
5.1 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
'''Given a library, dependentlibs.py prints the list of libraries it depends
upon that are in the same directory, followed by the library itself.
'''
from optparse import OptionParser
import os
import re
import fnmatch
import subprocess
import sys
from mozpack.executables import (
get_type,
ELF,
MACHO,
)
from buildconfig import substs
TOOLCHAIN_PREFIX = ''
def dependentlibs_dumpbin(lib):
'''Returns the list of dependencies declared in the given DLL'''
try:
proc = subprocess.Popen(['dumpbin', '-dependents', lib], stdout = subprocess.PIPE)
except OSError:
# dumpbin is missing, probably mingw compilation. Try using objdump.
return dependentlibs_mingw_objdump(lib)
deps = []
for line in proc.stdout:
# Each line containing an imported library name starts with 4 spaces
match = re.match(' (\S+)', line)
if match:
deps.append(match.group(1))
elif len(deps):
# There may be several groups of library names, but only the
# first one is interesting. The second one is for delayload-ed
# libraries.
break
proc.wait()
return deps
def dependentlibs_mingw_objdump(lib):
proc = subprocess.Popen(['objdump', '-x', lib], stdout = subprocess.PIPE)
deps = []
for line in proc.stdout:
match = re.match('\tDLL Name: (\S+)', line)
if match:
deps.append(match.group(1))
proc.wait()
return deps
def dependentlibs_readelf(lib):
'''Returns the list of dependencies declared in the given ELF .so'''
proc = subprocess.Popen([TOOLCHAIN_PREFIX + 'readelf', '-d', lib], stdout = subprocess.PIPE)
deps = []
for line in proc.stdout:
# Each line has the following format:
# tag (TYPE) value
# or with BSD readelf:
# tag TYPE value
# Looking for NEEDED type entries
tmp = line.split(' ', 3)
if len(tmp) > 3 and 'NEEDED' in tmp[2]:
# NEEDED lines look like:
# 0x00000001 (NEEDED) Shared library: [libname]
# or with BSD readelf:
# 0x00000001 NEEDED Shared library: [libname]
match = re.search('\[(.*)\]', tmp[3])
if match:
deps.append(match.group(1))
proc.wait()
return deps
def dependentlibs_otool(lib):
'''Returns the list of dependencies declared in the given MACH-O dylib'''
proc = subprocess.Popen([substs['OTOOL'], '-l', lib], stdout = subprocess.PIPE)
deps= []
cmd = None
for line in proc.stdout:
# otool -l output contains many different things. The interesting data
# is under "Load command n" sections, with the content:
# cmd LC_LOAD_DYLIB
# cmdsize 56
# name libname (offset 24)
tmp = line.split()
if len(tmp) < 2:
continue
if tmp[0] == 'cmd':
cmd = tmp[1]
elif cmd == 'LC_LOAD_DYLIB' and tmp[0] == 'name':
deps.append(re.sub('^@executable_path/','',tmp[1]))
proc.wait()
return deps
def dependentlibs(lib, libpaths, func):
'''For a given library, returns the list of recursive dependencies that can
be found in the given list of paths, followed by the library itself.'''
assert(libpaths)
assert(isinstance(libpaths, list))
deps = []
for dep in func(lib):
if dep in deps or os.path.isabs(dep):
continue
for dir in libpaths:
deppath = os.path.join(dir, dep)
if os.path.exists(deppath):
deps.extend([d for d in dependentlibs(deppath, libpaths, func) if not d in deps])
# Black list the ICU data DLL because preloading it at startup
# leads to startup performance problems because of its excessive
# size (around 10MB).
if not dep.startswith("icu"):
deps.append(dep)
break
return deps
def main():
parser = OptionParser()
parser.add_option("-L", dest="libpaths", action="append", metavar="PATH", help="Add the given path to the library search path")
parser.add_option("-p", dest="toolchain_prefix", metavar="PREFIX", help="Use the given prefix to readelf")
(options, args) = parser.parse_args()
if options.toolchain_prefix:
global TOOLCHAIN_PREFIX
TOOLCHAIN_PREFIX = options.toolchain_prefix
lib = args[0]
binary_type = get_type(lib)
if binary_type == ELF:
func = dependentlibs_readelf
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)]
print '\n'.join(dependentlibs(lib, options.libpaths, func) + [lib])
if __name__ == '__main__':
main()