blob: cb9d2c7fc3e1f30ea0c536e6b01014057e02cd40 [file] [log] [blame]
Sharjeel Khancc173632023-08-08 21:04:41 +00001#!/usr/bin/env python3
2#
3# Copyright (C) 2023 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17# Sample Usage:
18# $ python3 create_orderfile.py --profile-file ../orderfiles/test/example.prof --mapping-file ../orderfiles/test/example-mapping.txt
19#
20# Try '-h' for a full list of command line arguments.
21
22import argparse
23import orderfile_utils
24
25def parse_args():
26 """Parses and returns command line arguments."""
27 parser = argparse.ArgumentParser(prog="create_orderfile",
28 description="Create orderfile from profile file and mapping file")
29
30 parser.add_argument(
31 "--profile-file",
32 required=True,
33 help="Parsed profile file that represents the order of the symbol execution")
34
35 parser.add_argument(
36 "--mapping-file",
37 required=True,
38 help="Mapped file that provides the mapping between MD5 hash and symbol name")
39
40 parser.add_argument(
41 "--output",
42 default="default.orderfile",
43 help="Provide the output file name for the order file. Default Name: default.orderfile")
44
45 parser.add_argument(
46 "--denylist",
47 default="",
48 help=f"Exclude symbols based on a symbol-per-line file with @ or comma separarted values within a quotation."
49 f"For example, you can say @file.txt or 'main,bar,foo'")
50
51 parser.add_argument(
52 "--last-symbol",
53 help=f"Create an order file until the passed last symbol and ignore the symbols after it."
54 f"Useful if you want an order file only for startup so you should pass the last startup symbol."
55 f"Last-symbol has priority over leftover so we will output until the last symbol and ignore the leftover flag.")
56
57 parser.add_argument(
58 "--leftover",
59 action='store_true',
60 default=False,
61 help="Add the symbols seen in mapping file but not in profile file at the end")
62
63 return parser.parse_args()
64
65def main():
66 args = parse_args()
67
68 symbols = []
69 mapping = {}
70 seen = set()
71 denylist = orderfile_utils.parse_set(args.denylist)
72
73 # Load the MD5 hash mappings of the symbols.
74 with open(args.mapping_file, "r") as f:
75 for line in f:
76 line = line.strip().split()
77 mapping[line[1]] = line[2]
78
79 # Parse the profile file
80 with open(args.profile_file, "r") as f:
81 for line in f:
82 line = line.strip().split()
83
84 # Every line should have 2 MD5 hashes in reverse order (little Endian)
85 # so we need to reverse them to get the actual md5 hashes
86 if len(line) >= 8:
87 md5_1_b_list = line[1:9]
88 md5_2_b_list = line[9:17]
89
90 md5_1_b_list.reverse()
91 md5_2_b_list.reverse()
92
93 md5_1 = "".join(md5_1_b_list)
94 md5_2 = "".join(md5_2_b_list)
95
96 if(md5_1 in mapping):
97 symbol_1 = mapping[md5_1]
98 seen.add(symbol_1)
99
100 if symbol_1 not in denylist:
101 symbols.append(symbol_1)
102
103 if(md5_2 in mapping):
104 symbol_2 = mapping[md5_2]
105 seen.add(symbol_2)
106
107 if symbol_2 not in denylist:
108 symbols.append(symbol_2)
109
110 # Functions in the mapping but not seen in the partial order.
111 # If you want to add them, you can use the leftover flag.
112 # Note: You can only use the leftover flag if the last-symbol flag was not passed
113 if args.leftover and args.last_symbol != None:
114 for md5 in mapping:
115 if mapping[md5] not in seen:
116 symbols.append(mapping[md5])
117
118 # Write it to output file
119 with open(args.output, "w") as f:
120 for symbol in symbols:
121 f.write(symbol+"\n")
122
123 # If we are at the last-symbol, we do not write the rest of the symbols
124 if symbol == args.last_symbol:
125 break
126
127if __name__ == '__main__':
128 main()