diff --git a/benchmarks/linker_relocation/regen/common_types.py b/benchmarks/linker_relocation/regen/common_types.py
new file mode 100644
index 0000000..94168b0
--- /dev/null
+++ b/benchmarks/linker_relocation/regen/common_types.py
@@ -0,0 +1,187 @@
+# Copyright (C) 2019 The Android Open Source Project
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+from enum import Enum
+from typing import Any, Dict, Iterator, List, Optional, Set, Tuple
+
+
+class SymKind(Enum):
+    Func = 1
+    Var = 2
+
+    def to_json(self) -> str:
+        return {SymKind.Func: 'func', SymKind.Var: 'var'}[self]
+
+    @staticmethod
+    def from_json(obj: str) -> 'SymKind':
+        return {'func': SymKind.Func, 'var': SymKind.Var}[obj]
+
+
+class SymBind(Enum):
+    Global = 1
+    Weak = 2
+
+    def to_json(self) -> str:
+        return {SymBind.Global: 'global', SymBind.Weak: 'weak'}[self]
+
+    @staticmethod
+    def from_json(obj: str) -> 'SymBind':
+        return {'global': SymBind.Global, 'weak': SymBind.Weak}[obj]
+
+
+class DynSymbol:
+    def __init__(self, name: str, kind: SymKind, bind: SymBind, defined: bool,
+                 ver_type: Optional[str], ver_name: Optional[str]):
+        assert ver_type in {None, '@', '@@'}
+        self.name: str = name
+        self.kind: SymKind = kind
+        self.bind: SymBind = bind
+        self.defined: bool = defined
+        self.ver_type: Optional[str] = ver_type
+        self.ver_name: Optional[str] = ver_name
+
+    def to_json(self) -> Dict[str, Any]:
+        result: Dict[str, Any] = {}
+        result['name'] = self.name
+        result['kind'] = self.kind.to_json()
+        result['bind'] = self.bind.to_json()
+        result['defined'] = self.defined
+        result['ver_type'] = self.ver_type
+        result['ver_name'] = self.ver_name
+        return result
+
+    @staticmethod
+    def from_json(obj: Dict[str, Any]) -> 'DynSymbol':
+        return DynSymbol(obj['name'],
+                         SymKind.from_json(obj['kind']),
+                         SymBind.from_json(obj['bind']),
+                         obj['defined'],
+                         obj['ver_type'],
+                         obj['ver_name'])
+
+
+DynSymbols = Dict[int, DynSymbol]
+
+
+class SymbolRef:
+    def __init__(self, name: str, is_weak: bool, ver: Optional[str]):
+        self.name: str = name
+        self.is_weak: bool = is_weak
+        self.ver: Optional[str] = ver
+
+    def to_json(self) -> Dict[str, Any]:
+        result: Dict[str, Any] = {}
+        result['name'] = self.name
+        result['is_weak'] = self.is_weak
+        if self.ver is not None:
+            result['ver'] = self.ver
+        return result
+
+    @staticmethod
+    def from_json(obj: Dict[str, Any]) -> 'SymbolRef':
+        return SymbolRef(obj['name'], obj['is_weak'], obj.get('ver'))
+
+
+class Relocations:
+    def __init__(self):
+        self.jump_slots: List[SymbolRef] = []
+        self.got: List[SymbolRef] = []
+        self.symbolic: List[Tuple[int, SymbolRef]] = []
+        self.relative: List[int] = []
+
+    def to_json(self) -> Dict[str, Any]:
+        result: Dict[str, Any] = {}
+        result['jump_slots'] = [sym.to_json() for sym in self.jump_slots]
+        result['got'] = [sym.to_json() for sym in self.got]
+        result['symbolic'] = [(off, sym.to_json()) for (off, sym) in self.symbolic]
+        result['relative'] = self.relative
+        return result
+
+    @staticmethod
+    def from_json(obj: Dict[str, Any]) -> 'Relocations':
+        result = Relocations()
+        result.jump_slots = [SymbolRef.from_json(sym) for sym in obj['jump_slots']]
+        result.got = [SymbolRef.from_json(sym) for sym in obj['got']]
+        result.symbolic = [(off, SymbolRef.from_json(sym)) for (off, sym) in obj['symbolic']]
+        result.relative = obj['relative']
+        return result
+
+
+class LoadedLibrary:
+    def __init__(self):
+        self.soname: str = None
+        self.syms: DynSymbols = None
+        self.rels: Relocations = None
+        self.needed: List[LoadedLibrary] = []
+
+    def to_json(self) -> Dict[str, Any]:
+        result: Dict[str, Any] = {}
+        result['soname'] = self.soname
+        result['syms'] = {name: sym.to_json() for name, sym in self.syms.items()}
+        result['rels'] = self.rels.to_json()
+        result['needed'] = [lib.soname for lib in self.needed]
+        return result
+
+    @staticmethod
+    def from_json(obj: Dict[str, Any]) -> Tuple['LoadedLibrary', List[str]]:
+        result = LoadedLibrary()
+        result.soname = obj['soname']
+        result.syms = {name: DynSymbol.from_json(sym) for name, sym in obj['syms'].items()}
+        result.rels = Relocations.from_json(obj['rels'])
+        return result, obj['needed']
+
+
+def elf_tree_to_json(tree: LoadedLibrary) -> Dict[str, Any]:
+    libraries: Dict[str, LoadedLibrary] = {}
+    result: Dict[str, Any] = {}
+    result['root'] = tree.soname
+    result['libs'] = []
+    for lib in bfs_walk(tree):
+        result['libs'].append(lib.to_json())
+    return result
+
+
+def json_to_elf_tree(obj: Dict[str, Any]) -> LoadedLibrary:
+    libraries: Dict[str, LoadedLibrary] = {}
+    all_needed: List[Tuple[LoadedLibrary, List[str]]] = []
+    for lib_obj in obj['libs']:
+        lib, needed = LoadedLibrary.from_json(lib_obj)
+        libraries[lib.soname] = lib
+        all_needed.append((lib, needed))
+    for lib, needed in all_needed:
+        lib.needed = [libraries[x] for x in needed]
+    return libraries[obj['root']]
+
+
+def bfs_walk(tree: LoadedLibrary) -> Iterator[LoadedLibrary]:
+    work_list = [tree]
+    seen: Set[LoadedLibrary] = set()
+    while len(work_list) > 0:
+        lib = work_list.pop(0)
+        if lib in seen: continue
+        seen.add(lib)
+        yield lib
+        work_list.extend(lib.needed)
diff --git a/benchmarks/linker_relocation/regen/dump_relocs.py b/benchmarks/linker_relocation/regen/dump_relocs.py
new file mode 100755
index 0000000..165da05
--- /dev/null
+++ b/benchmarks/linker_relocation/regen/dump_relocs.py
@@ -0,0 +1,247 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2019 The Android Open Source Project
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+# Scan an ELF file and its tree of DT_NEEDED ELF files, and dump out a JSON file listing:
+#  - each ELF file
+#  - its DT_NEEDED entries
+#  - its defined symbols
+#  - its relocations
+
+import argparse
+import json
+import os
+import re
+import shlex
+import shutil
+import subprocess
+import sys
+import tempfile
+import textwrap
+import typing
+from enum import Enum
+from typing import Any, Set, List, Dict, Optional
+from subprocess import PIPE, DEVNULL
+from pathlib import Path
+
+from common_types import LoadedLibrary, SymBind, SymKind, DynSymbol, DynSymbols, Relocations, \
+    SymbolRef, bfs_walk, elf_tree_to_json
+
+
+g_readelf_cache: Dict[str, str] = {}
+g_path_to_soname_cache: Dict[Path, str] = {}
+
+def do_readelf_query(arguments: List[str]) -> List[str]:
+    cmdline = ['llvm-readelf'] + arguments
+    key = repr(cmdline)
+    if key in g_readelf_cache: return g_readelf_cache[key].splitlines()
+    out = subprocess.run(cmdline, check=True, stdout=PIPE).stdout.decode()
+    g_readelf_cache[key] = out
+    return out.splitlines()
+
+
+def get_elf_soname(path: Path) -> str:
+    if path in g_path_to_soname_cache: return g_path_to_soname_cache[path]
+    out = do_readelf_query(['-d', str(path)])
+    for line in out:
+        m = re.search(r'\(SONAME\)\s+Library soname: \[(.+)\]$', line)
+        if not m: continue
+        result = m.group(1)
+        break
+    else:
+        result = os.path.basename(path)
+    g_path_to_soname_cache[path] = result
+    return result
+
+
+def get_elf_needed(path: Path) -> List[str]:
+    result = []
+    out = do_readelf_query(['-d', str(path)])
+    for line in out:
+        m = re.search(r'\(NEEDED\)\s+Shared library: \[(.+)\]$', line)
+        if not m: continue
+        result.append(m.group(1))
+    return result
+
+
+kSymbolMatcher = re.compile(r'''
+    \s+ (\d+) : \s*                 # number
+    [0-9a-f]+ \s+                   # value
+    [0-9a-f]+ \s+                   # size
+    (FUNC|IFUNC|OBJECT|NOTYPE) \s+  # type
+    (GLOBAL|WEAK) \s+               # bind
+    \w+ \s+                         # vis
+    (\d+|UND) \s+                   # ndx
+    ([\.\w]+)                       # name
+    (?:(@@?)(\w+))?                 # version
+    $
+''', re.VERBOSE)
+
+
+def get_dyn_symbols(path: Path) -> DynSymbols:
+    kind_lookup = {
+        'FUNC': SymKind.Func,
+        'IFUNC': SymKind.Func,
+        'OBJECT': SymKind.Var,
+        'NOTYPE': SymKind.Func,
+    }
+    bind_lookup = { 'GLOBAL': SymBind.Global, 'WEAK': SymBind.Weak }
+
+    result = {}
+    out = do_readelf_query(['--dyn-syms', str(path)])
+    for line in out:
+        m = kSymbolMatcher.match(line)
+        if not m:
+            # gLinux currently has a version of llvm-readelf whose output is very different from
+            # the current versions of llvm-readelf (or GNU readelf).
+            if 'Symbol table of .gnu.hash for image:' in line:
+                sys.exit(f'error: obsolete version of llvm-readelf')
+            continue
+
+        num, kind, bind, ndx, name, ver_type, ver_name = m.groups()
+
+        if name == '__cfi_check':
+            # The linker gives an error like:
+            #    CANNOT LINK EXECUTABLE "/data/local/tmp/out-linker-bench/b_libandroid_servers": unaligned __cfi_check in the library "(null)"
+            # I am probably breaking some kind of CFI invariant, so strip these out for now.
+            continue
+
+        result[int(num)] = DynSymbol(name, kind_lookup[kind], bind_lookup[bind], ndx != 'UND',
+                                     ver_type, ver_name)
+
+    return result
+
+
+kRelocationMatcher = re.compile(r'''
+    ([0-9a-f]+) \s+     # offset
+    ([0-9a-f]+) \s+     # info
+    (\w+)               # type
+    (?:
+        \s+ [0-9a-f]+ \s+       # symbol value
+        ([\.\w]+)               # symbol name
+        (?: @@? ([\.\w]+) )?    # version
+    )?
+    \b
+''', re.VERBOSE)
+
+
+def scan_relocations(path: Path, syms: DynSymbols) -> Relocations:
+    result: Relocations = Relocations()
+    out = do_readelf_query(['-r', str(path)])
+    for line in out:
+        m = kRelocationMatcher.match(line)
+        if not m: continue
+
+        offset_str, info_str, reloc_name, sym_name, ver = m.groups()
+
+        if len(offset_str) == 8:
+            offset = int(offset_str, 16) // 4
+            sym_idx = int(info_str, 16) >> 8
+        elif len(offset_str) == 16:
+            offset = int(offset_str, 16) // 8
+            sym_idx = int(info_str, 16) >> 32
+        else:
+            sys.exit(f'error: invalid offset length: {repr(offset_str)}')
+
+        # TODO: R_ARM_IRELATIVE doesn't work, so skip it.
+        if reloc_name == 'R_ARM_IRELATIVE': continue
+
+        if reloc_name in ['R_ARM_RELATIVE', 'R_AARCH64_RELATIVE']:
+            assert sym_name is None
+            result.relative.append(offset)
+        else:
+            if sym_name is None:
+                sys.exit(f'error: missing symbol for reloc {m.groups()} in {path}')
+
+            is_weak = syms[sym_idx].bind == SymBind.Weak
+            symbol = SymbolRef(sym_name, is_weak, ver)
+
+            if reloc_name in ['R_ARM_JUMP_SLOT', 'R_AARCH64_JUMP_SLOT']:
+                result.jump_slots.append(symbol)
+            elif reloc_name in ['R_ARM_GLOB_DAT', 'R_AARCH64_GLOB_DAT']:
+                result.got.append(symbol)
+            elif reloc_name in ['R_ARM_ABS32', 'R_AARCH64_ABS64']:
+                result.symbolic.append((offset, symbol))
+            else:
+                sys.exit(f'error: unrecognized reloc {m.groups()} in {path}')
+
+    return result
+
+
+def load_elf_tree(search_path: List[Path], path: Path) -> LoadedLibrary:
+
+    libraries: Dict[str, LoadedLibrary] = {}
+
+    def find_library(needed: str) -> Optional[LoadedLibrary]:
+        nonlocal libraries
+
+        if needed in libraries: return libraries[needed]
+
+        for candidate_dir in search_path:
+            candidate_path = candidate_dir / needed
+            if candidate_path.exists():
+                return load(candidate_path)
+
+        sys.exit(f'error: missing DT_NEEDED lib {needed}!')
+
+    def load(path: Path) -> LoadedLibrary:
+        nonlocal libraries
+
+        lib = LoadedLibrary()
+        lib.soname = get_elf_soname(path)
+        if lib.soname in libraries: sys.exit(f'soname already loaded: {lib.soname}')
+        libraries[lib.soname] = lib
+
+        lib.syms = get_dyn_symbols(path)
+        lib.rels = scan_relocations(path, lib.syms)
+
+        for needed in get_elf_needed(path):
+            needed_lib = find_library(needed)
+            if needed_lib is not None:
+                lib.needed.append(needed_lib)
+
+        return lib
+
+    return load(path)
+
+
+def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument('input', type=str)
+    parser.add_argument('output', type=str)
+    parser.add_argument('-L', dest='search_path', metavar='PATH', action='append', type=str, default=[])
+
+    args = parser.parse_args()
+    search_path = [Path(p) for p in args.search_path]
+
+    with open(Path(args.output), 'w') as f:
+        root = load_elf_tree(search_path, Path(args.input))
+        json.dump(elf_tree_to_json(root), f, sort_keys=True, indent=2)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/benchmarks/linker_relocation/regen/gen_bench.py b/benchmarks/linker_relocation/regen/gen_bench.py
new file mode 100755
index 0000000..61156ce
--- /dev/null
+++ b/benchmarks/linker_relocation/regen/gen_bench.py
@@ -0,0 +1,404 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2019 The Android Open Source Project
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+# Generate a benchmark using a JSON dump of ELF file symbols and relocations.
+
+import argparse
+import codecs
+import json
+import math
+import os
+import re
+import shlex
+import shutil
+import subprocess
+import sys
+import tempfile
+import textwrap
+import typing
+from enum import Enum
+from typing import Dict, List, Optional, Set
+from subprocess import PIPE, DEVNULL
+from pathlib import Path
+
+from common_types import LoadedLibrary, SymbolRef, SymKind, bfs_walk, json_to_elf_tree
+
+
+g_obfuscate = True
+g_benchmark_name = 'linker_reloc_bench'
+
+
+kBionicSonames: Set[str] = set([
+    'libc.so',
+    'libdl.so',
+    'libdl_android.so',
+    'libm.so',
+    'ld-android.so',
+])
+
+# Skip these symbols so the benchmark runs on multiple C libraries (glibc, Bionic, musl).
+kBionicSymbolBlacklist: Set[str] = set([
+    '__FD_ISSET_chk',
+    '__FD_SET_chk',
+    '__assert',
+    '__assert2',
+    '__b64_ntop',
+    '__cmsg_nxthdr',
+    '__cxa_thread_atexit_impl',
+    '__errno',
+    '__gnu_basename',
+    '__gnu_strerror_r',
+    '__memcpy_chk',
+    '__memmove_chk',
+    '__memset_chk',
+    '__open_2',
+    '__openat_2',
+    '__pread64_chk',
+    '__pread_chk',
+    '__read_chk',
+    '__readlink_chk',
+    '__register_atfork',
+    '__sF',
+    '__strcat_chk',
+    '__strchr_chk',
+    '__strcpy_chk',
+    '__strlcat_chk',
+    '__strlcpy_chk',
+    '__strlen_chk',
+    '__strncat_chk',
+    '__strncpy_chk',
+    '__strncpy_chk2',
+    '__strrchr_chk',
+    '__system_property_area_serial',
+    '__system_property_find',
+    '__system_property_foreach',
+    '__system_property_get',
+    '__system_property_read',
+    '__system_property_serial',
+    '__system_property_set',
+    '__umask_chk',
+    '__vsnprintf_chk',
+    '__vsprintf_chk',
+    'android_dlopen_ext',
+    'android_set_abort_message',
+    'arc4random_buf',
+    'dl_unwind_find_exidx',
+    'fts_close',
+    'fts_open',
+    'fts_read',
+    'fts_set',
+    'getprogname',
+    'gettid',
+    'isnanf',
+    'mallinfo',
+    'malloc_info',
+    'pthread_gettid_np',
+    'res_mkquery',
+    'strlcpy',
+    'strtoll_l',
+    'strtoull_l',
+    'tgkill',
+])
+
+
+Definitions = Dict[str, LoadedLibrary]
+
+def build_symbol_index(lib: LoadedLibrary) -> Definitions:
+    defs: Dict[str, LoadedLibrary] = {}
+    for lib in bfs_walk(lib):
+        for sym in lib.syms.values():
+            if not sym.defined: continue
+            defs.setdefault(sym.name, lib)
+    return defs
+
+
+def sanity_check_rels(root: LoadedLibrary, defs: Definitions) -> None:
+    # Find every symbol for every relocation in the load group.
+    has_missing = False
+    for lib in bfs_walk(root):
+        rels = lib.rels
+        for sym in rels.got + rels.jump_slots + [sym for off, sym in rels.symbolic]:
+            if sym.name not in defs:
+                if sym.is_weak:
+                    pass # print('info: weak undefined', lib.soname, r)
+                else:
+                    print(f'error: {lib.soname}: unresolved relocation to {sym.name}')
+                    has_missing = True
+    if has_missing: sys.exit('error: had unresolved relocations')
+
+
+# Obscure names to avoid polluting Android code search.
+def rot13(text: str) -> str:
+    if g_obfuscate:
+        result = codecs.getencoder("rot-13")(text)[0]
+        assert isinstance(result, str)
+        return result
+    else:
+        return text
+
+
+def make_asm_file(lib: LoadedLibrary, is_main: bool, out_filename: Path, map_out_filename: Path,
+                  defs: Definitions) -> bool:
+
+    def trans_sym(name: str, ver: Optional[str]) -> Optional[str]:
+        nonlocal defs
+        d = defs.get(name)
+        if d is not None and d.soname in kBionicSonames:
+            if name in kBionicSymbolBlacklist: return None
+            # Discard relocations to newer Bionic symbols, because there aren't many of them, and
+            # they would limit where the benchmark can run.
+            if ver == 'LIBC': return name
+            return None
+        return 'b_' + rot13(name)
+
+    versions: Dict[Optional[str], List[str]] = {}
+
+    with open(out_filename, 'w') as out:
+        out.write(f'// AUTO-GENERATED BY {os.path.basename(__file__)} -- do not edit manually\n')
+        out.write(f'#include "{g_benchmark_name}_asm.h"\n')
+        out.write('.data\n')
+        out.write('.p2align 4\n')
+
+        if is_main:
+            out.write('.text\n' 'MAIN\n')
+
+        for d in lib.syms.values():
+            if not d.defined: continue
+            sym = trans_sym(d.name, None)
+            if sym is None: continue
+            if d.kind == SymKind.Func:
+                out.write('.text\n'
+                          f'.globl {sym}\n'
+                          f'.type {sym},%function\n'
+                          f'{sym}:\n'
+                          'nop\n')
+            else: # SymKind.Var
+                out.write('.data\n'
+                          f'.globl {sym}\n'
+                          f'.type {sym},%object\n'
+                          f'{sym}:\n'
+                          f'.space __SIZEOF_POINTER__\n')
+            versions.setdefault(d.ver_name, []).append(sym)
+
+        out.write('.text\n')
+        for r in lib.rels.jump_slots:
+            sym = trans_sym(r.name, r.ver)
+            if sym is None: continue
+            if r.is_weak: out.write(f'.weak {sym}\n')
+            out.write(f'CALL({sym})\n')
+        out.write('.text\n')
+        for r in lib.rels.got:
+            sym = trans_sym(r.name, r.ver)
+            if sym is None: continue
+            if r.is_weak: out.write(f'.weak {sym}\n')
+            out.write(f'GOT_RELOC({sym})\n')
+
+        out.write('.data\n')
+        out.write('local_label:\n')
+
+        image = []
+        for off in lib.rels.relative:
+            image.append((off, f'DATA_WORD(local_label)\n'))
+        for off, r in lib.rels.symbolic:
+            sym = trans_sym(r.name, r.ver)
+            if sym is None: continue
+            text = f'DATA_WORD({sym})\n'
+            if r.is_weak: text += f'.weak {sym}\n'
+            image.append((off, text))
+        image.sort()
+
+        cur_off = 0
+        for off, text in image:
+            if cur_off < off:
+                out.write(f'.space (__SIZEOF_POINTER__ * {off - cur_off})\n')
+                cur_off = off
+            out.write(text)
+            cur_off += 1
+
+    has_map_file = False
+    if len(versions) > 0 and list(versions.keys()) != [None]:
+        has_map_file = True
+        with open(map_out_filename, 'w') as out:
+            if None in versions:
+                print(f'error: {out_filename} has both unversioned and versioned symbols')
+                print(versions.keys())
+                sys.exit(1)
+            for ver in sorted(versions.keys()):
+                assert ver is not None
+                out.write(f'{rot13(ver)} {{\n')
+                if len(versions[ver]) > 0:
+                    out.write('  global:\n')
+                    out.write(''.join(f'    {x};\n' for x in versions[ver]))
+                out.write(f'}};\n')
+
+    return has_map_file
+
+
+class LibNames:
+    def __init__(self, root: LoadedLibrary):
+        self._root = root
+        self._names: Dict[LoadedLibrary, str] = {}
+        all_libs = [x for x in bfs_walk(root) if x is not root and x.soname not in kBionicSonames]
+        num_digits = math.ceil(math.log10(len(all_libs) + 1))
+        if g_obfuscate:
+            self._names = {x : f'{i:0{num_digits}}' for i, x in enumerate(all_libs)}
+        else:
+            self._names = {x : re.sub(r'\.so$', '', x.soname) for x in all_libs}
+
+    def name(self, lib: LoadedLibrary) -> str:
+        if lib is self._root:
+            return f'{g_benchmark_name}_main'
+        else:
+            return f'lib{g_benchmark_name}_{self._names[lib]}'
+
+
+# Generate a ninja file directly that builds the benchmark using a C compiler driver and ninja.
+# Using a driver directly can be faster than building with Soong, and it allows testing
+# configurations that Soong can't target, like musl.
+def make_ninja_benchmark(root: LoadedLibrary, defs: Definitions, cc: str, out: Path) -> None:
+
+    lib_names = LibNames(root)
+
+    def lib_dso_name(lib: LoadedLibrary) -> str:
+        return lib_names.name(lib) + '.so'
+
+    ninja = open(out / 'build.ninja', 'w')
+    include_path = os.path.relpath(os.path.dirname(__file__) + '/../include', out)
+    common_flags = f"-Wl,-rpath-link,. -lm -I{include_path}"
+    ninja.write(textwrap.dedent(f'''\
+        rule exe
+            command = {cc} -fpie -pie $in -o $out {common_flags} $extra_args
+        rule dso
+            command = {cc} -fpic -shared $in -o $out -Wl,-soname,$out {common_flags} $extra_args
+    '''))
+
+    for lib in bfs_walk(root):
+        if lib.soname in kBionicSonames: continue
+
+        lib_base_name = lib_names.name(lib)
+        asm_name = lib_base_name + '.S'
+        map_name = lib_base_name + '.map'
+        asm_path = out / asm_name
+        map_path = out / map_name
+
+        has_map_file = make_asm_file(lib, lib is root, asm_path, map_path, defs)
+        needed = ' '.join([lib_dso_name(x) for x in lib.needed if x.soname not in kBionicSonames])
+
+        if lib is root:
+            ninja.write(f'build {lib_base_name}: exe {asm_name} {needed}\n')
+        else:
+            ninja.write(f'build {lib_dso_name(lib)}: dso {asm_name} {needed}\n')
+        if has_map_file:
+            ninja.write(f'    extra_args = -Wl,--version-script={map_name}\n')
+
+    ninja.close()
+
+    subprocess.run(['ninja', '-C', str(out), lib_names.name(root)], check=True)
+
+
+def make_soong_benchmark(root: LoadedLibrary, defs: Definitions, out: Path) -> None:
+
+    lib_names = LibNames(root)
+
+    bp = open(out / 'Android.bp', 'w')
+    bp.write(f'// AUTO-GENERATED BY {os.path.basename(__file__)} -- do not edit\n')
+
+    bp.write(f'cc_defaults {{\n')
+    bp.write(f'    name: "{g_benchmark_name}_all_libs",\n')
+    bp.write(f'    runtime_libs: [\n')
+    for lib in bfs_walk(root):
+        if lib.soname in kBionicSonames: continue
+        if lib is root: continue
+        bp.write(f'        "{lib_names.name(lib)}",\n')
+    bp.write(f'    ],\n')
+    bp.write(f'}}\n')
+
+    for lib in bfs_walk(root):
+        if lib.soname in kBionicSonames: continue
+
+        lib_base_name = lib_names.name(lib)
+        asm_name = lib_base_name + '.S'
+        map_name = lib_base_name + '.map'
+        asm_path = out / asm_name
+        map_path = out / map_name
+
+        has_map_file = make_asm_file(lib, lib is root, asm_path, map_path, defs)
+
+        if lib is root:
+            bp.write(f'cc_binary {{\n')
+            bp.write(f'    defaults: ["{g_benchmark_name}_binary"],\n')
+        else:
+            bp.write(f'cc_test_library {{\n')
+            bp.write(f'    defaults: ["{g_benchmark_name}_library"],\n')
+        bp.write(f'    name: "{lib_base_name}",\n')
+        bp.write(f'    srcs: ["{asm_name}"],\n')
+        bp.write(f'    shared_libs: [\n')
+        for need in lib.needed:
+            if need.soname in kBionicSonames: continue
+            bp.write(f'        "{lib_names.name(need)}",\n')
+        bp.write(f'    ],\n')
+        if has_map_file:
+            bp.write(f'    version_script: "{map_name}",\n')
+        bp.write('}\n')
+
+    bp.close()
+
+
+def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument('input', type=str)
+    parser.add_argument('out_dir', type=str)
+    parser.add_argument('--ninja', action='store_true',
+                        help='Generate a benchmark using a compiler and ninja rather than Soong')
+    parser.add_argument('--cc',
+                        help='For --ninja, a target-specific C clang driver and flags (e.g. "'
+                             '$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang'
+                             ' -fuse-ld=lld")')
+
+    args = parser.parse_args()
+
+    if args.ninja:
+        if args.cc is None: sys.exit('error: --cc required with --ninja')
+
+    out = Path(args.out_dir)
+    with open(Path(args.input)) as f:
+        root = json_to_elf_tree(json.load(f))
+    defs = build_symbol_index(root)
+    sanity_check_rels(root, defs)
+
+    if out.exists(): shutil.rmtree(out)
+    os.makedirs(str(out))
+
+    if args.ninja:
+        make_ninja_benchmark(root, defs, args.cc, out)
+    else:
+        make_soong_benchmark(root, defs, out)
+
+
+if __name__ == '__main__':
+    main()
