• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright 2019 The ChromiumOS Authors
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Script to do post-process on orderfile generated by C3.
8
9The goal of this script is to take in an orderfile generated by C3, and do
10the following post process:
11
121. Take in the result of nm command on Chrome binary to find out all the
13Builtin functions and put them after the input symbols.
14
152. Put special markers "chrome_begin_ordered_code" and "chrome_end_ordered_code"
16in begin and end of the file.
17
18The results of the file is intended to be uploaded and consumed when linking
19Chrome in ChromeOS.
20"""
21
22
23import argparse
24import os
25import sys
26
27
28def _parse_nm_output(stream):
29    for line in (line.rstrip() for line in stream):
30        if not line:
31            continue
32
33        pieces = line.split()
34        if len(pieces) != 3:
35            continue
36
37        _, ty, symbol = pieces
38        if ty not in "tT":
39            continue
40
41        # We'll sometimes see synthesized symbols that start with $. There isn't
42        # much we can do about or with them, regrettably.
43        if symbol.startswith("$"):
44            continue
45
46        yield symbol
47
48
49def _remove_duplicates(iterable):
50    seen = set()
51    for item in iterable:
52        if item in seen:
53            continue
54        seen.add(item)
55        yield item
56
57
58def run(c3_ordered_stream, chrome_nm_stream, output_stream):
59    head_marker = "chrome_begin_ordered_code"
60    tail_marker = "chrome_end_ordered_code"
61
62    c3_ordered_syms = [x.strip() for x in c3_ordered_stream.readlines()]
63    all_chrome_syms = set(_parse_nm_output(chrome_nm_stream))
64    # Sort by name, so it's predictable. Otherwise, these should all land in the
65    # same hugepage anyway, so order doesn't matter as much.
66    builtin_syms = sorted(
67        s for s in all_chrome_syms if s.startswith("Builtins_")
68    )
69    output = _remove_duplicates(
70        [head_marker] + c3_ordered_syms + builtin_syms + [tail_marker]
71    )
72    output_stream.write("\n".join(output))
73
74
75def main(argv):
76    parser = argparse.ArgumentParser()
77    parser.add_argument("--chrome_nm", required=True, dest="chrome_nm")
78    parser.add_argument("--input", required=True, dest="input_file")
79    parser.add_argument("--output", required=True, dest="output_file")
80
81    options = parser.parse_args(argv)
82
83    if not os.path.exists(options.input_file):
84        sys.exit("Input orderfile doesn't exist.")
85
86    with open(options.input_file) as in_stream, open(
87        options.chrome_nm
88    ) as chrome_nm_stream, open(options.output_file, "w") as out_stream:
89        run(in_stream, chrome_nm_stream, out_stream)
90
91
92if __name__ == "__main__":
93    sys.exit(main(sys.argv[1:]))
94