-
Notifications
You must be signed in to change notification settings - Fork 152
/
groupmask.py
91 lines (73 loc) · 2.56 KB
/
groupmask.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
import sys, os, re
from prjxray.util import OpenSafeFile, parse_db_lines, write_db_lines
def index_masks(fn_in, groups_in):
"""Return a dictionary with the bits active in each group for the specified list of groups"""
# Only analyze the given groups
groups = {}
for group in groups_in:
groups[group] = set()
# Index bits
for line, (tag, bits, mode) in parse_db_lines(fn_in):
assert not mode, "Unresolved tag: %s" % (line, )
prefix = tag[0:tag.rfind(".")]
group = groups.get(prefix, None)
# Drop groups we aren't interested in
if group is None:
continue
for bit in bits:
bit = bit.replace("!", "")
group.add(bit)
# Verify we were able to find all groups
for groupk, groupv in groups.items():
assert len(groupv), "Bad group %s" % groupk
return groups
def apply_masks(fn_in, groups):
"""Add 0 entries ("!") to .db entries based on groups definition"""
new_db = {}
for line, (tag, bits, mode) in parse_db_lines(fn_in):
assert not mode, "Unresolved tag: %s" % (line, )
prefix = tag[0:tag.rfind(".")]
group = groups.get(prefix, None)
if group:
bits = set(bits)
for bit in group:
if bit not in bits:
bits.add("!" + bit)
bits = frozenset(bits)
new_db[tag] = bits
return new_db
def load_groups(fn):
ret = []
with OpenSafeFile(fn, "r") as f:
for l in f:
ret.append(l.strip())
return ret
def run(fn_in, fn_out, groups_fn, verbose=False):
groups_in = load_groups(groups_fn)
groups = index_masks(fn_in, groups_in)
new_db = apply_masks(fn_in, groups)
write_db_lines(fn_out, new_db)
def main():
import argparse
parser = argparse.ArgumentParser(description='Create multi-bit entries')
parser.add_argument('--verbose', action='store_true', help='')
parser.add_argument(
'--groups-fn',
default="groups.grp",
help='File containing one group per line to parse')
parser.add_argument('fn_in', help='')
parser.add_argument('fn_out', help='')
args = parser.parse_args()
run(args.fn_in, args.fn_out, args.groups_fn, verbose=args.verbose)
if __name__ == '__main__':
main()