blob: 5f52aa6feb92f3f5f24c31197000cc3f5c17bf5d [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Script to do post-process on orderfile generated by C3.
The goal of this script is to take in an orderfile generated by C3, and do
the following post process:
1. Take in the result of nm command on Chrome binary to find out all the
Builtin functions and put them after the input symbols.
2. Put special markers "chrome_begin_ordered_code" and "chrome_end_ordered_code"
in begin and end of the file.
The results of the file is intended to be uploaded and consumed when linking
Chrome in ChromeOS.
"""
import argparse
import os
import sys
def _parse_nm_output(stream):
for line in (line.rstrip() for line in stream):
if not line:
continue
pieces = line.split()
if len(pieces) != 3:
continue
_, ty, symbol = pieces
if ty not in "tT":
continue
# We'll sometimes see synthesized symbols that start with $. There isn't
# much we can do about or with them, regrettably.
if symbol.startswith("$"):
continue
yield symbol
def _remove_duplicates(iterable):
seen = set()
for item in iterable:
if item in seen:
continue
seen.add(item)
yield item
def run(c3_ordered_stream, chrome_nm_stream, output_stream):
head_marker = "chrome_begin_ordered_code"
tail_marker = "chrome_end_ordered_code"
c3_ordered_syms = [x.strip() for x in c3_ordered_stream.readlines()]
all_chrome_syms = set(_parse_nm_output(chrome_nm_stream))
# Sort by name, so it's predictable. Otherwise, these should all land in the
# same hugepage anyway, so order doesn't matter as much.
builtin_syms = sorted(
s for s in all_chrome_syms if s.startswith("Builtins_")
)
output = _remove_duplicates(
[head_marker] + c3_ordered_syms + builtin_syms + [tail_marker]
)
output_stream.write("\n".join(output))
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument("--chrome_nm", required=True, dest="chrome_nm")
parser.add_argument("--input", required=True, dest="input_file")
parser.add_argument("--output", required=True, dest="output_file")
options = parser.parse_args(argv)
if not os.path.exists(options.input_file):
sys.exit("Input orderfile doesn't exist.")
with open(options.input_file) as in_stream, open(
options.chrome_nm
) as chrome_nm_stream, open(options.output_file, "w") as out_stream:
run(in_stream, chrome_nm_stream, out_stream)
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))