Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 '''Given a library, dependentlibs.py prints the list of libraries it depends
6 upon that are in the same directory, followed by the library itself.
7 '''
9 from optparse import OptionParser
10 import os
11 import re
12 import fnmatch
13 import subprocess
14 import sys
15 from mozpack.executables import (
16 get_type,
17 ELF,
18 MACHO,
19 )
21 TOOLCHAIN_PREFIX = ''
23 def dependentlibs_dumpbin(lib):
24 '''Returns the list of dependencies declared in the given DLL'''
25 try:
26 proc = subprocess.Popen(['dumpbin', '-dependents', lib], stdout = subprocess.PIPE)
27 except OSError:
28 # dumpbin is missing, probably mingw compilation. Try using objdump.
29 return dependentlibs_mingw_objdump(lib)
30 deps = []
31 for line in proc.stdout:
32 # Each line containing an imported library name starts with 4 spaces
33 match = re.match(' (\S+)', line)
34 if match:
35 deps.append(match.group(1))
36 elif len(deps):
37 # There may be several groups of library names, but only the
38 # first one is interesting. The second one is for delayload-ed
39 # libraries.
40 break
41 proc.wait()
42 return deps
44 def dependentlibs_mingw_objdump(lib):
45 proc = subprocess.Popen(['objdump', '-x', lib], stdout = subprocess.PIPE)
46 deps = []
47 for line in proc.stdout:
48 match = re.match('\tDLL Name: (\S+)', line)
49 if match:
50 deps.append(match.group(1))
51 proc.wait()
52 return deps
54 def dependentlibs_readelf(lib):
55 '''Returns the list of dependencies declared in the given ELF .so'''
56 proc = subprocess.Popen([TOOLCHAIN_PREFIX + 'readelf', '-d', lib], stdout = subprocess.PIPE)
57 deps = []
58 for line in proc.stdout:
59 # Each line has the following format:
60 # tag (TYPE) value
61 # Looking for NEEDED type entries
62 tmp = line.split(' ', 3)
63 if len(tmp) > 3 and tmp[2] == '(NEEDED)':
64 # NEEDED lines look like:
65 # 0x00000001 (NEEDED) Shared library: [libname]
66 match = re.search('\[(.*)\]', tmp[3])
67 if match:
68 deps.append(match.group(1))
69 proc.wait()
70 return deps
72 def dependentlibs_otool(lib):
73 '''Returns the list of dependencies declared in the given MACH-O dylib'''
74 proc = subprocess.Popen(["../../../../../x-tools/x86_64-apple-darwin10/bin/" + TOOLCHAIN_PREFIX + 'otool', '-l', lib], stdout = subprocess.PIPE)
75 deps= []
76 cmd = None
77 for line in proc.stdout:
78 # otool -l output contains many different things. The interesting data
79 # is under "Load command n" sections, with the content:
80 # cmd LC_LOAD_DYLIB
81 # cmdsize 56
82 # name libname (offset 24)
83 tmp = line.split()
84 if len(tmp) < 2:
85 continue
86 if tmp[0] == 'cmd':
87 cmd = tmp[1]
88 elif cmd == 'LC_LOAD_DYLIB' and tmp[0] == 'name':
89 deps.append(re.sub('^@executable_path/','',tmp[1]))
90 proc.wait()
91 return deps
93 def dependentlibs(lib, libpaths, func):
94 '''For a given library, returns the list of recursive dependencies that can
95 be found in the given list of paths, followed by the library itself.'''
96 assert(libpaths)
97 assert(isinstance(libpaths, list))
98 deps = []
99 for dep in func(lib):
100 if dep in deps or os.path.isabs(dep):
101 continue
102 for dir in libpaths:
103 deppath = os.path.join(dir, dep)
104 if os.path.exists(deppath):
105 deps.extend([d for d in dependentlibs(deppath, libpaths, func) if not d in deps])
106 # Black list the ICU data DLL because preloading it at startup
107 # leads to startup performance problems because of its excessive
108 # size (around 10MB).
109 if not dep.startswith("icu"):
110 deps.append(dep)
111 break
113 return deps
115 def main():
116 parser = OptionParser()
117 parser.add_option("-L", dest="libpaths", action="append", metavar="PATH", help="Add the given path to the library search path")
118 parser.add_option("-p", dest="toolchain_prefix", metavar="PREFIX", help="Use the given prefix to readelf")
119 (options, args) = parser.parse_args()
120 if options.toolchain_prefix:
121 global TOOLCHAIN_PREFIX
122 TOOLCHAIN_PREFIX = options.toolchain_prefix
123 lib = args[0]
124 binary_type = get_type(lib)
125 if binary_type == ELF:
126 func = dependentlibs_readelf
127 elif binary_type == MACHO:
128 func = dependentlibs_otool
129 else:
130 ext = os.path.splitext(lib)[1]
131 assert(ext == '.dll')
132 func = dependentlibs_dumpbin
133 if not options.libpaths:
134 options.libpaths = [os.path.dirname(lib)]
136 print '\n'.join(dependentlibs(lib, options.libpaths, func) + [lib])
138 if __name__ == '__main__':
139 main()