mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 08:15:31 +00:00
Backed out 4 changesets (bug 1654182
) for Spidermonkey failure and Android build bustage. CLOSED TREE
Backed out changeset 8ecbb1da91cf (bug1654182
) Backed out changeset 205329cc5f30 (bug1654182
) Backed out changeset 13ab8f6d24bf (bug1654182
) Backed out changeset 6100f0d3c0ad (bug1654182
)
This commit is contained in:
parent
990d081d9f
commit
3f7ad38666
@ -17,6 +17,7 @@ from mozbuild.util import memoize
|
|||||||
from mozpack.executables import (
|
from mozpack.executables import (
|
||||||
get_type,
|
get_type,
|
||||||
ELF,
|
ELF,
|
||||||
|
MACHO,
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -76,33 +77,74 @@ def at_least_one(iter):
|
|||||||
raise Empty()
|
raise Empty()
|
||||||
|
|
||||||
|
|
||||||
# Iterates the symbol table on ELF binaries.
|
# Iterates the symbol table on ELF and MACHO, and the export table on
|
||||||
def iter_elf_symbols(target, binary, all=False):
|
# COFF/PE.
|
||||||
|
def iter_symbols(binary):
|
||||||
ty = get_type(binary)
|
ty = get_type(binary)
|
||||||
# Static libraries are ar archives. Assume they are ELF.
|
# XXX: Static libraries on ELF, MACHO and COFF/PE systems are all
|
||||||
|
# ar archives. So technically speaking, the following is wrong
|
||||||
|
# but is enough for now. llvm-objdump -t can actually be used on all
|
||||||
|
# platforms for static libraries, but its format is different for
|
||||||
|
# Windows .obj files, so the following won't work for them, but
|
||||||
|
# it currently doesn't matter.
|
||||||
if ty == UNKNOWN and open(binary, 'rb').read(8) == b'!<arch>\n':
|
if ty == UNKNOWN and open(binary, 'rb').read(8) == b'!<arch>\n':
|
||||||
ty = ELF
|
ty = ELF
|
||||||
assert ty == ELF
|
if ty in (ELF, MACHO):
|
||||||
for line in get_output(target['readelf'], '--syms' if all else '--dyn-syms', binary):
|
for line in get_output(buildconfig.substs['LLVM_OBJDUMP'], '-t',
|
||||||
data = line.split()
|
binary):
|
||||||
if not (len(data) >= 8 and data[0].endswith(':') and data[0][:-1].isdigit()):
|
m = ADDR_RE.match(line)
|
||||||
continue
|
if not m:
|
||||||
n, addr, size, type, bind, vis, index, name = data[:8]
|
continue
|
||||||
|
addr = int(m.group(0), 16)
|
||||||
|
# The second "column" is 7 one-character items that can be
|
||||||
|
# whitespaces. We don't have use for their value, so just skip
|
||||||
|
# those.
|
||||||
|
rest = line[m.end() + 9:].split()
|
||||||
|
# The number of remaining colums will vary between ELF and MACHO.
|
||||||
|
# On ELF, we have:
|
||||||
|
# Section Size .hidden? Name
|
||||||
|
# On Macho, the size is skipped.
|
||||||
|
# In every case, the symbol name is last.
|
||||||
|
name = rest[-1]
|
||||||
|
if '@' in name:
|
||||||
|
name, ver = name.rsplit('@', 1)
|
||||||
|
while name.endswith('@'):
|
||||||
|
name = name[:-1]
|
||||||
|
else:
|
||||||
|
ver = None
|
||||||
|
yield {
|
||||||
|
'addr': addr,
|
||||||
|
'size': int(rest[1], 16) if ty == ELF else 0,
|
||||||
|
'name': name,
|
||||||
|
'version': ver or None,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
export_table = False
|
||||||
|
for line in get_output(buildconfig.substs['LLVM_OBJDUMP'], '-p',
|
||||||
|
binary):
|
||||||
|
if line.strip() == 'Export Table:':
|
||||||
|
export_table = True
|
||||||
|
continue
|
||||||
|
elif not export_table:
|
||||||
|
continue
|
||||||
|
|
||||||
if '@' in name:
|
cols = line.split()
|
||||||
name, ver = name.rsplit('@', 1)
|
# The data we're interested in comes in 3 columns, and the first
|
||||||
while name.endswith('@'):
|
# column is a number.
|
||||||
name = name[:-1]
|
if len(cols) != 3 or not cols[0].isdigit():
|
||||||
else:
|
continue
|
||||||
ver = None
|
_, rva, name = cols
|
||||||
yield {
|
# - The MSVC mangling has some type info following `@@`
|
||||||
'addr': int(addr, 16),
|
# - Any namespacing that can happen on the symbol appears as a
|
||||||
# readelf output may contain decimal values or hexadecimal
|
# suffix, after a `@`.
|
||||||
# values prefixed with 0x for the size. Let python autodetect.
|
# - Mangled symbols are prefixed with `?`.
|
||||||
'size': int(size, 0),
|
name = name.split('@@')[0].split('@')[0].lstrip('?')
|
||||||
'name': name,
|
yield {
|
||||||
'version': ver,
|
'addr': int(rva, 16),
|
||||||
}
|
'size': 0,
|
||||||
|
'name': name,
|
||||||
|
'version': None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def iter_readelf_dynamic(target, binary):
|
def iter_readelf_dynamic(target, binary):
|
||||||
@ -112,19 +154,13 @@ def iter_readelf_dynamic(target, binary):
|
|||||||
yield data[1].rstrip(')').lstrip('('), data[2]
|
yield data[1].rstrip(')').lstrip('('), data[2]
|
||||||
|
|
||||||
|
|
||||||
def check_binary_compat(target, binary):
|
def check_dep_versions(target, binary, lib, prefix, max_version):
|
||||||
if get_type(binary) != ELF:
|
if get_type(binary) != ELF:
|
||||||
raise Skip()
|
raise Skip()
|
||||||
checks = (
|
unwanted = []
|
||||||
('libstdc++', 'GLIBCXX_', STDCXX_MAX_VERSION),
|
prefix = prefix + '_'
|
||||||
('libstdc++', 'CXXABI_', CXXABI_MAX_VERSION),
|
|
||||||
('libgcc', 'GCC_', LIBGCC_MAX_VERSION),
|
|
||||||
('libc', 'GLIBC_', GLIBC_MAX_VERSION),
|
|
||||||
)
|
|
||||||
|
|
||||||
unwanted = {}
|
|
||||||
try:
|
try:
|
||||||
for sym in at_least_one(iter_elf_symbols(target, binary)):
|
for sym in at_least_one(iter_symbols(binary)):
|
||||||
# Only check versions on undefined symbols
|
# Only check versions on undefined symbols
|
||||||
if sym['addr'] != 0:
|
if sym['addr'] != 0:
|
||||||
continue
|
continue
|
||||||
@ -133,22 +169,33 @@ def check_binary_compat(target, binary):
|
|||||||
if not sym['version']:
|
if not sym['version']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for _, prefix, max_version in checks:
|
if sym['version'].startswith(prefix):
|
||||||
if sym['version'].startswith(prefix):
|
version = Version(sym['version'][len(prefix):])
|
||||||
version = Version(sym['version'][len(prefix):])
|
if version > max_version:
|
||||||
if version > max_version:
|
unwanted.append(sym)
|
||||||
unwanted.setdefault(prefix, []).append(sym)
|
|
||||||
except Empty:
|
except Empty:
|
||||||
raise RuntimeError('Could not parse llvm-objdump output?')
|
raise RuntimeError('Could not parse llvm-objdump output?')
|
||||||
if unwanted:
|
if unwanted:
|
||||||
error = []
|
raise RuntimeError('\n'.join([
|
||||||
for lib, prefix, _ in checks:
|
'We do not want these {} symbol versions to be used:'.format(lib)
|
||||||
if prefix in unwanted:
|
] + [
|
||||||
error.append(
|
' {} ({})'.format(s['name'], s['version']) for s in unwanted
|
||||||
'We do not want these {} symbol versions to be used:'.format(lib))
|
]))
|
||||||
error.extend(
|
|
||||||
' {} ({})'.format(s['name'], s['version']) for s in unwanted[prefix])
|
|
||||||
raise RuntimeError('\n'.join(error))
|
def check_stdcxx(target, binary):
|
||||||
|
check_dep_versions(
|
||||||
|
target, binary, 'libstdc++', 'GLIBCXX', STDCXX_MAX_VERSION)
|
||||||
|
check_dep_versions(
|
||||||
|
target, binary, 'libstdc++', 'CXXABI', CXXABI_MAX_VERSION)
|
||||||
|
|
||||||
|
|
||||||
|
def check_libgcc(target, binary):
|
||||||
|
check_dep_versions(target, binary, 'libgcc', 'GCC', LIBGCC_MAX_VERSION)
|
||||||
|
|
||||||
|
|
||||||
|
def check_glibc(target, binary):
|
||||||
|
check_dep_versions(target, binary, 'libc', 'GLIBC', GLIBC_MAX_VERSION)
|
||||||
|
|
||||||
|
|
||||||
def check_textrel(target, binary):
|
def check_textrel(target, binary):
|
||||||
@ -213,7 +260,7 @@ def check_mozglue_order(target, binary):
|
|||||||
raise RuntimeError('Could not parse readelf output?')
|
raise RuntimeError('Could not parse readelf output?')
|
||||||
|
|
||||||
|
|
||||||
def check_networking(target, binary):
|
def check_networking(binary):
|
||||||
retcode = 0
|
retcode = 0
|
||||||
networking_functions = set([
|
networking_functions = set([
|
||||||
# socketpair is not concerning; it is restricted to AF_UNIX
|
# socketpair is not concerning; it is restricted to AF_UNIX
|
||||||
@ -230,7 +277,7 @@ def check_networking(target, binary):
|
|||||||
bad_occurences_names = set()
|
bad_occurences_names = set()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for sym in at_least_one(iter_elf_symbols(target, binary, all=True)):
|
for sym in at_least_one(iter_symbols(binary)):
|
||||||
if sym['addr'] == 0 and sym['name'] in networking_functions:
|
if sym['addr'] == 0 and sym['name'] in networking_functions:
|
||||||
bad_occurences_names.add(sym['name'])
|
bad_occurences_names.add(sym['name'])
|
||||||
except Empty:
|
except Empty:
|
||||||
@ -256,7 +303,9 @@ def checks(target, binary):
|
|||||||
target = HOST
|
target = HOST
|
||||||
checks = []
|
checks = []
|
||||||
if target['MOZ_LIBSTDCXX_VERSION']:
|
if target['MOZ_LIBSTDCXX_VERSION']:
|
||||||
checks.append(check_binary_compat)
|
checks.append(check_stdcxx)
|
||||||
|
checks.append(check_libgcc)
|
||||||
|
checks.append(check_glibc)
|
||||||
|
|
||||||
# Disabled for local builds because of readelf performance: See bug 1472496
|
# Disabled for local builds because of readelf performance: See bug 1472496
|
||||||
if not buildconfig.substs.get('DEVELOPER_OPTIONS'):
|
if not buildconfig.substs.get('DEVELOPER_OPTIONS'):
|
||||||
@ -309,7 +358,7 @@ def main(args):
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
if options.networking:
|
if options.networking:
|
||||||
return check_networking(TARGET, options.binary)
|
return check_networking(options.binary)
|
||||||
elif options.host:
|
elif options.host:
|
||||||
return checks(HOST, options.binary)
|
return checks(HOST, options.binary)
|
||||||
elif options.target:
|
elif options.target:
|
||||||
|
Loading…
Reference in New Issue
Block a user