Backed out 4 changesets (bug 1654182) for Spidermonkey failure and Android build bustage. CLOSED TREE

Backed out changeset 8ecbb1da91cf (bug 1654182)
Backed out changeset 205329cc5f30 (bug 1654182)
Backed out changeset 13ab8f6d24bf (bug 1654182)
Backed out changeset 6100f0d3c0ad (bug 1654182)
This commit is contained in:
Dorel Luca 2020-07-22 03:04:57 +03:00
parent 990d081d9f
commit 3f7ad38666

View File

@ -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: