Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /tools /unused-symbols-report.py
blob: b1bd99c8e65a77164b114de206ea773a4f2e5383 [file] [log] [blame] [edit]
#!/usr/bin/env python
# Copyright 2011 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Prints a report of symbols stripped by the linker due to being unused.
To use, build with these linker flags:
-Wl,--gc-sections
-Wl,--print-gc-sections
the first one is the default in Release; search build/common.gypi for it
and to see where to add the other.
Then build, saving the output into a file:
make chrome 2>&1 | tee buildlog
and run this script on it:
./tools/unused-symbols-report.py buildlog > report.html
"""
from __future__import print_function
import cgi
import optparse
import os
import re
import subprocess
import sys
cppfilt_proc=None
defDemangle(sym):
"""Demangle a C++ symbol by passing it through c++filt."""
global cppfilt_proc
if cppfilt_procisNone:
cppfilt_proc= subprocess.Popen(['c++filt'], stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
print(sym, file=cppfilt_proc.stdin)
return cppfilt_proc.stdout.readline().strip()
defUnyuck(sym):
"""Attempt to prettify a C++ symbol by some basic heuristics."""
sym= sym.replace('std::basic_string<char, std::char_traits<char>, '
'std::allocator<char> >','std::string')
sym= sym.replace('std::basic_string<wchar_t, std::char_traits<wchar_t>, '
'std::allocator<wchar_t> >','std::wstring')
sym= sym.replace(
'std::basic_string<char16_t, std::char_traits<char16_t>, '
'std::allocator<char16_t> >','std::u16string')
sym= re.sub(r', std::allocator<\S+\s+>','', sym)
return sym
defParse(input, skip_paths=None, only_paths=None):
"""Parse the --print-gc-sections build output.
Args:
input: iterable over the lines of the build output
Yields:
(target name, path to .o file, demangled symbol)
"""
symbol_re= re.compile(r"'\.text\.(\S+)' in file '(\S+)'$")
path_re= re.compile(r"^out/[^/]+/[^/]+/([^/]+)/(.*)$")
for linein input:
match= symbol_re.search(line)
ifnot match:
continue
symbol, path= match.groups()
symbol=Unyuck(Demangle(symbol))
path= os.path.normpath(path)
if skip_pathsand skip_pathsin path:
continue
if only_pathsand only_pathsnotin path:
continue
match= path_re.match(path)
ifnot match:
print("Skipping weird path", path, file=sys.stderr)
continue
target, path= match.groups()
yield target, path, symbol
# HTML header for our output page.
TEMPLATE_HEADER="""<!DOCTYPE html>
<head>
<style>
body {
font-family: sans-serif;
font-size: 0.8em;
}
h1, h2 {
font-weight: normal;
margin: 0.5em 0;
}
h2 {
margin-top: 1em;
}
tr:hover {
background: #eee;
}
.permalink {
padding-left: 1ex;
font-size: 80%;
text-decoration: none;
color: #ccc;
}
.symbol {
font-family: WebKitWorkAround, monospace;
margin-left: 4ex;
text-indent: -4ex;
padding: 0.5ex 1ex;
}
.file {
padding: 0.5ex 1ex;
padding-left: 2ex;
font-family: WebKitWorkAround, monospace;
font-size: 90%;
color: #777;
}
</style>
</head>
<body>
<h1>chrome symbols deleted at link time</h1>
"""
defOutput(iter):
"""Print HTML given an iterable of (target, path, symbol) tuples."""
targets={}
for target, path, symbolin iter:
entries= targets.setdefault(target,[])
entries.append((symbol, path))
print(TEMPLATE_HEADER)
print("<p>jump to target:")
print("<select onchange='document.location.hash = this.value'>")
for targetin sorted(targets.keys()):
print("<option>%s</option>"% target)
print("</select></p>")
for targetin sorted(targets.keys()):
print("<h2>%s"% target)
print("<a class=permalink href='#%s' name='%s'>#</a>"%(target, target))
print("</h2>")
print("<table width=100% cellspacing=0>")
for symbol, pathin sorted(targets[target]):
htmlsymbol= cgi.escape(symbol).replace('::','::<wbr>')
print("<tr><td><div class=symbol>%s</div></td>"% htmlsymbol)
print("<td valign=top><div class=file>%s</div></td></tr>"% path)
print("</table>")
def main():
parser= optparse.OptionParser(usage='%prog [options] buildoutput\n\n'+
__doc__)
parser.add_option("--skip-paths", metavar="STR", default="third_party",
help="skip paths matching STR [default=%default]")
parser.add_option("--only-paths", metavar="STR",
help="only include paths matching STR [default=%default]")
opts, args= parser.parse_args()
if len(args)<1:
parser.print_help()
sys.exit(1)
iter=Parse(open(args[0]),
skip_paths=opts.skip_paths,
only_paths=opts.only_paths)
Output(iter)
if __name__=='__main__':
main()

[8]ページ先頭

©2009-2025 Movatter.jp