README.md
1
2# Bloaty McBloatface: a size profiler for binaries
3
4[![Build Status](https://travis-ci.org/google/bloaty.svg?branch=master)](https://travis-ci.org/google/bloaty)
5
6Ever wondered what's making your binary big? Bloaty
7McBloatface will show you a size profile of the binary so
8you can understand what's taking up space inside.
9
10Bloaty works on binaries, shared objects, object files, and
11static libraries (`.a` files). The following file formats
12are supported:
13
14* ELF
15* Mach-O
16* WebAssembly (experimental)
17
18These formats are NOT supported, but I am very interested
19in adding support for them (I may implement these myself but
20would also be happy to get contributions!)
21
22* PE/COFF (not supported)
23* Android APK (not supported, might be tricky due to compression)
24
25This is not an official Google product.
26
27## Building Bloaty
28
29Building Bloaty requires CMake and ``protoc``, the protobuf compiler. On Ubuntu, install them with:
30
31```
32$ sudo apt install cmake protobuf-compiler
33```
34
35Bloaty bundles ``libprotobuf``, ``re2``, ``capstone``, and ``pkg-config`` as Git submodules, but it will prefer the system's versions of those dependencies if available. All other dependencies are included as Git submodules. To build, run:
36
37```
38$ cmake .
39$ make -j6
40```
41
42To run tests (Git only, these are not included in the release tarball), type:
43
44```
45$ make test
46```
47
48All the normal CMake features are available, like out-of-source builds:
49
50```
51$ mkdir build
52$ cd build
53$ cmake ..
54$ make -j6
55```
56
57## Running Bloaty
58
59Run it directly on a binary target. For example, run it on itself.
60
61```
62$ ./bloaty bloaty
63```
64
65On Linux you'll see output something like:
66
67```cmdoutput
68$ ./bloaty bloaty
69 FILE SIZE VM SIZE
70 -------------- --------------
71 32.3% 6.84Mi 0.0% 0 .debug_info
72 19.6% 4.15Mi 0.0% 0 .debug_loc
73 11.3% 2.39Mi 39.5% 2.39Mi .rodata
74 9.4% 1.98Mi 0.0% 0 .debug_str
75 6.8% 1.43Mi 0.0% 0 .debug_ranges
76 5.9% 1.24Mi 20.5% 1.24Mi .text
77 5.8% 1.24Mi 0.0% 0 .debug_line
78 0.0% 0 16.6% 1.00Mi .bss
79 2.0% 440Ki 7.1% 440Ki .data
80 1.6% 352Ki 5.7% 352Ki .rela.dyn
81 1.5% 329Ki 5.3% 329Ki .data.rel.ro
82 1.0% 208Ki 0.0% 0 .strtab
83 0.6% 138Ki 0.0% 0 .debug_abbrev
84 0.6% 122Ki 0.0% 0 .symtab
85 0.6% 120Ki 1.9% 120Ki .eh_frame
86 0.5% 100Ki 1.6% 100Ki .dynstr
87 0.2% 43.6Ki 0.7% 43.5Ki .dynsym
88 0.2% 35.2Ki 0.4% 27.9Ki [24 Others]
89 0.1% 20.3Ki 0.3% 20.2Ki .eh_frame_hdr
90 0.1% 19.8Ki 0.3% 19.8Ki .gcc_except_table
91 0.1% 13.3Ki 0.0% 0 .debug_aranges
92 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
93```
94
95The "VM SIZE" column tells you how much space the binary
96will take when it is loaded into memory. The "FILE SIZE"
97column tells you about how much space the binary is taking
98on disk. These two can be very different from each other:
99
100- Some data lives in the file but isn't loaded into memory,
101 like debug information.
102- Some data is mapped into memory but doesn't exist in the
103 file. This mainly applies to the `.bss` section
104 (zero-initialized data).
105
106The default breakdown in Bloaty is by sections, but many
107other ways of slicing the binary are supported such as
108symbols and segments. If you compiled with debug info, you
109can even break down by compile units and inlines!
110
111```cmdoutput
112$ ./bloaty bloaty -d compileunits
113 FILE SIZE VM SIZE
114 -------------- --------------
115 34.5% 7.30Mi 34.5% 2.08Mi [124 Others]
116 10.5% 2.22Mi 6.7% 413Ki ../third_party/capstone/arch/ARM/ARMDisassembler.c
117 1.7% 366Ki 17.4% 1.05Mi ../third_party/capstone/arch/M68K/M68KDisassembler.c
118 4.5% 979Ki 13.9% 863Ki ../third_party/capstone/arch/X86/X86Mapping.c
119 4.4% 957Ki 1.3% 79.0Ki ../third_party/capstone/arch/SystemZ/SystemZDisassembler.c
120 4.1% 898Ki 1.5% 91.2Ki ../third_party/capstone/arch/AArch64/AArch64Disassembler.c
121 3.9% 853Ki 0.7% 42.0Ki ../third_party/re2/re2/re2.cc
122 3.7% 802Ki 2.0% 126Ki ../src/bloaty.cc
123 3.6% 772Ki 0.6% 38.6Ki ../third_party/re2/re2/dfa.cc
124 3.3% 705Ki 0.6% 39.8Ki ../third_party/re2/re2/regexp.cc
125 3.1% 662Ki 1.1% 67.8Ki ../third_party/capstone/arch/Mips/MipsDisassembler.c
126 2.7% 577Ki 0.4% 23.4Ki ../third_party/re2/re2/prog.cc
127 2.5% 549Ki 7.0% 432Ki ../third_party/capstone/arch/X86/X86DisassemblerDecoder.c
128 2.5% 544Ki 1.5% 92.6Ki ../third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp
129 2.5% 537Ki 0.6% 35.3Ki ../third_party/re2/re2/parse.cc
130 2.4% 524Ki 2.8% 172Ki ../third_party/capstone/arch/AArch64/AArch64InstPrinter.c
131 2.3% 503Ki 0.4% 26.4Ki ../third_party/re2/re2/compile.cc
132 2.1% 460Ki 0.6% 35.8Ki ../third_party/capstone/arch/PowerPC/PPCDisassembler.c
133 2.0% 427Ki 1.7% 108Ki ../third_party/capstone/arch/X86/X86ATTInstPrinter.c
134 1.9% 409Ki 4.5% 278Ki ../third_party/capstone/arch/SystemZ/SystemZMapping.c
135 1.8% 400Ki 0.2% 15.0Ki ../third_party/re2/re2/nfa.cc
136 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
137```
138
139
140Run Bloaty with `--help` to see a list of available options:
141
142```cmdoutput
143$ ./bloaty --help
144Bloaty McBloatface: a size profiler for binaries.
145
146USAGE: bloaty [OPTION]... FILE... [-- BASE_FILE...]
147
148Options:
149
150 --csv Output in CSV format instead of human-readable.
151 --tsv Output in TSV format instead of human-readable.
152 -c FILE Load configuration from <file>.
153 -d SOURCE,SOURCE Comma-separated list of sources to scan.
154 --debug-file=FILE Use this file for debug symbols and/or symbol table.
155 -C MODE How to demangle symbols. Possible values are:
156 --demangle=MODE --demangle=none no demangling, print raw symbols
157 --demangle=short demangle, but omit arg/return types
158 --demangle=full print full demangled type
159 The default is --demangle=short.
160 --disassemble=FUNCTION
161 Disassemble this function (EXPERIMENTAL)
162 --domain=DOMAIN Which domains to show. Possible values are:
163 --domain=vm
164 --domain=file
165 --domain=both (the default)
166 -n NUM How many rows to show per level before collapsing
167 other keys into '[Other]'. Set to '0' for unlimited.
168 Defaults to 20.
169 -s SORTBY Whether to sort by VM or File size. Possible values
170 are:
171 -s vm
172 -s file
173 -s both (the default: sorts by max(vm, file)).
174 -w Wide output; don't truncate long labels.
175 --help Display this message and exit.
176 --list-sources Show a list of available sources and exit.
177 --source-filter=PATTERN
178 Only show keys with names matching this pattern.
179
180Options for debugging Bloaty:
181
182 --debug-vmaddr=ADDR
183 --debug-fileoff=OFF
184 Print extended debugging information for the given
185 VM address and/or file offset.
186 -v Verbose output. Dumps warnings encountered during
187 processing and full VM/file maps at the end.
188 Add more v's (-vv, -vvv) for even more.
189
190```
191
192# Size Diffs
193
194You can use Bloaty to see how the size of a binary changed.
195On the command-line, pass `--` followed by the files you
196want to use as the diff base.
197
198For example, here is a size diff between a couple different versions
199of Bloaty, showing how it grew when I added some features.
200
201```
202$ ./bloaty bloaty -- oldbloaty
203 VM SIZE FILE SIZE
204 -------------- --------------
205 [ = ] 0 .debug_loc +688Ki +9.9%
206 +19% +349Ki .text +349Ki +19%
207 [ = ] 0 .debug_ranges +180Ki +11%
208 [ = ] 0 .debug_info +120Ki +0.9%
209 +23% +73.5Ki .rela.dyn +73.5Ki +23%
210 +3.5% +57.1Ki .rodata +57.1Ki +3.5%
211 +28e3% +53.9Ki .data +53.9Ki +28e3%
212 [ = ] 0 .debug_line +40.2Ki +4.8%
213 +2.3% +5.35Ki .eh_frame +5.35Ki +2.3%
214 -6.0% -5 [Unmapped] +2.65Ki +215%
215 +0.5% +1.70Ki .dynstr +1.70Ki +0.5%
216 [ = ] 0 .symtab +1.59Ki +0.9%
217 [ = ] 0 .debug_abbrev +1.29Ki +0.5%
218 [ = ] 0 .strtab +1.26Ki +0.3%
219 +16% +992 .bss 0 [ = ]
220 +0.2% +642 [13 Others] +849 +0.2%
221 +0.6% +792 .dynsym +792 +0.6%
222 +16% +696 .rela.plt +696 +16%
223 +16% +464 .plt +464 +16%
224 +0.8% +312 .eh_frame_hdr +312 +0.8%
225 [ = ] 0 .debug_str -19.6Ki -0.4%
226 +11% +544Ki TOTAL +1.52Mi +4.6%
227```
228
229Each line shows the how much each part changed compared to
230its previous size. Most sections grew, but one section at
231the bottom (`.debug_str`) shrank. The "TOTAL" line shows
232how much the size changed overall.
233
234# Hierarchical Profiles
235
236Bloaty supports breaking the binary down in lots of
237different ways. You can combine multiple data sources into
238a single hierarchical profile. For example, we can use the
239`segments` and `sections` data sources in a single report:
240
241```cmdoutput
242$ ./bloaty -d segments,sections bloaty
243 FILE SIZE VM SIZE
244 -------------- --------------
245 76.1% 16.1Mi 0.0% 0 [Unmapped]
246 42.4% 6.84Mi NAN% 0 .debug_info
247 25.7% 4.15Mi NAN% 0 .debug_loc
248 12.3% 1.98Mi NAN% 0 .debug_str
249 8.9% 1.43Mi NAN% 0 .debug_ranges
250 7.7% 1.24Mi NAN% 0 .debug_line
251 1.3% 208Ki NAN% 0 .strtab
252 0.8% 138Ki NAN% 0 .debug_abbrev
253 0.7% 121Ki NAN% 0 .symtab
254 0.1% 13.2Ki NAN% 0 .debug_aranges
255 0.0% 5.65Ki NAN% 0 [Unmapped]
256 0.0% 383 NAN% 0 .shstrtab
257 0.0% 28 NAN% 0 .comment
258 12.0% 2.54Mi 42.1% 2.54Mi LOAD #4 [R]
259 93.8% 2.39Mi 93.8% 2.39Mi .rodata
260 4.6% 120Ki 4.6% 120Ki .eh_frame
261 0.8% 20.2Ki 0.8% 20.2Ki .eh_frame_hdr
262 0.8% 19.8Ki 0.8% 19.8Ki .gcc_except_table
263 0.0% 4 0.0% 4 [LOAD #4 [R]]
264 3.6% 772Ki 29.0% 1.76Mi LOAD #5 [RW]
265 0.0% 0 57.1% 1.00Mi .bss
266 57.0% 440Ki 24.4% 440Ki .data
267 42.7% 329Ki 18.3% 329Ki .data.rel.ro
268 0.2% 1.63Ki 0.1% 1.63Ki .got.plt
269 0.1% 560 0.0% 560 .dynamic
270 0.0% 200 0.0% 200 .got
271 0.0% 96 0.0% 96 .init_array
272 0.0% 24 0.0% 24 [LOAD #5 [RW]]
273 0.0% 8 0.0% 8 .fini_array
274 5.9% 1.24Mi 20.5% 1.24Mi LOAD #3 [RX]
275 99.7% 1.24Mi 99.7% 1.24Mi .text
276 0.3% 3.23Ki 0.3% 3.23Ki .plt
277 0.0% 96 0.0% 96 .plt.got
278 0.0% 23 0.0% 23 .init
279 0.0% 12 0.0% 12 [LOAD #3 [RX]]
280 0.0% 9 0.0% 9 .fini
281 2.4% 517Ki 8.4% 517Ki LOAD #2 [R]
282 68.0% 352Ki 68.0% 352Ki .rela.dyn
283 19.3% 100Ki 19.3% 100Ki .dynstr
284 8.4% 43.5Ki 8.4% 43.5Ki .dynsym
285 2.4% 12.4Ki 2.4% 12.4Ki .gnu.hash
286 0.9% 4.83Ki 0.9% 4.83Ki .rela.plt
287 0.7% 3.62Ki 0.7% 3.62Ki .gnu.version
288 0.1% 691 0.1% 691 [LOAD #2 [R]]
289 0.1% 368 0.1% 368 .gnu.version_r
290 0.0% 36 0.0% 36 .note.gnu.build-id
291 0.0% 32 0.0% 32 .note.ABI-tag
292 0.0% 28 0.0% 28 .interp
293 0.0% 2.44Ki 0.0% 0 [ELF Headers]
294 46.2% 1.12Ki NAN% 0 [18 Others]
295 5.1% 128 NAN% 0 [ELF Headers]
296 2.6% 64 NAN% 0 .comment
297 2.6% 64 NAN% 0 .data
298 2.6% 64 NAN% 0 .data.rel.ro
299 2.6% 64 NAN% 0 .debug_abbrev
300 2.6% 64 NAN% 0 .debug_aranges
301 2.6% 64 NAN% 0 .debug_info
302 2.6% 64 NAN% 0 .debug_line
303 2.6% 64 NAN% 0 .debug_loc
304 2.6% 64 NAN% 0 .debug_ranges
305 2.6% 64 NAN% 0 .debug_str
306 2.6% 64 NAN% 0 .dynamic
307 2.6% 64 NAN% 0 .dynstr
308 2.6% 64 NAN% 0 .dynsym
309 2.6% 64 NAN% 0 .eh_frame
310 2.6% 64 NAN% 0 .eh_frame_hdr
311 2.6% 64 NAN% 0 .fini
312 2.6% 64 NAN% 0 .fini_array
313 2.6% 64 NAN% 0 .gcc_except_table
314 2.6% 64 NAN% 0 .gnu.hash
315 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
316```
317
318Bloaty displays a maximum of 20 lines for each level; other
319values are grouped into an `[Other]` bin. Use `-n <num>`
320to override this setting. If you pass `-n 0`, all data
321will be output without collapsing anything into `[Other]`.
322
323# Debugging Stripped Binaries
324
325Bloaty supports reading debuginfo/symbols from separate
326binaries. This lets you profile a stripped binary, even for
327data sources like "compileunits" or "symbols" that require
328this extra information.
329
330Bloaty uses build IDs to verify that the binary and the
331debug file match. Otherwise the results would be nonsense
332(this kind of mismatch might sound unlikely but it's a very
333easy mistake to make, and one that I made several times even
334as Bloaty's author!).
335
336If your binary has a build ID, then using separate debug
337files is as simple as:
338
339```
340$ cp bloaty bloaty.stripped
341$ strip bloaty.stripped
342$ ./bloaty -d symbols --debug-file=bloaty bloaty.stripped
343```
344
345Some format-specific notes follow.
346
347## ELF
348
349For ELF, make sure you are compiling with build IDs enabled.
350With gcc this happens automatically, but [Clang decided not
351to make this the default, since it makes the link
352slower](http://releases.llvm.org/3.9.0/tools/clang/docs/ReleaseNotes.html#major-new-features).
353For Clang add `-Wl,--build-id` to your link line. (If you
354want a slightly faster link and don't care about
355reproducibility, you can use `-Wl,--build-id=uuid` instead).
356
357Bloaty does not currently support the GNU debuglink or
358looking up debug files by build ID, [which are the methods
359GDB uses to find debug
360files](https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html).
361If there are use cases where Bloaty's `--debug-file` option
362won't work, we can reconsider implementing these.
363
364## Mach-O
365
366Mach-O files always have build IDs (as far as I can tell),
367so no special configuration is needed to make sure you get
368them.
369
370Mach-O puts debug information in separate files which you
371can create with `dsymutil`:
372
373```
374$ dsymutil bloaty
375$ strip bloaty (optional)
376$ ./bloaty -d symbols --debug-file=bloaty.dSYM/Contents/Resources/DWARF/bloaty bloaty
377```
378
379# Configuration Files
380
381Any options that you can specify on the command-line, you
382can put into a configuration file instead. Then use can use
383`-c FILE` to load those options from the config file. Also,
384a few features are only available with configuration files
385and cannot be specify on the command-line.
386
387The configuration file is a in Protocol Buffers text format.
388The schema is the `Options` message in
389[src/bloaty.proto](src/bloaty.proto).
390
391The two most useful cases for configuration files are:
392
3931. You have too many input files to put on the command-line.
394 At Google we sometimes run Bloaty over thousands of input
395 files. This can cause the overall command-line to exceed
396 OS limits. With a config file, we can avoid this:
397
398 ```
399 filename: "path/to/long_filename_a.o"
400 filename: "path/to/long_filename_b.o"
401 filename: "path/to/long_filename_c.o"
402 # ...repeat for thousands of files.
403 ```
4042. For custom data sources, it can be very useful to put
405 them in a config file, for greater reusability. For
406 example, see the custom data sources defined in
407 [custom_sources.bloaty](custom_sources.bloaty).
408 Also read more about custom data sources below.
409
410# Data Sources
411
412Bloaty has many data sources built in. These all provide
413different ways of looking at the binary. You can also
414create your own data sources by applying regexes to the
415built-in data sources (see "Custom Data Sources" below).
416
417While Bloaty works on binaries, shared objects, object
418files, and static libraries (`.a` files), some of the data
419sources don't work on object files. This applies especially
420to data sources that read debug info.
421
422## Segments
423
424Segments are what the run-time loader uses to determine what
425parts of the binary need to be loaded/mapped into memory.
426There are usually just a few segments: one for each set of
427`mmap()` permissions required:
428
429```cmdoutput
430$ ./bloaty -d segments bloaty
431 FILE SIZE VM SIZE
432 -------------- --------------
433 76.1% 16.1Mi 0.0% 0 [Unmapped]
434 12.0% 2.54Mi 42.1% 2.54Mi LOAD #4 [R]
435 3.6% 772Ki 29.0% 1.76Mi LOAD #5 [RW]
436 5.9% 1.24Mi 20.5% 1.24Mi LOAD #3 [RX]
437 2.4% 517Ki 8.4% 517Ki LOAD #2 [R]
438 0.0% 2.44Ki 0.0% 0 [ELF Headers]
439 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
440```
441
442Here we see one segment mapped `[RX]` (read/execute) and
443one segment mapped `[RW]` (read/write). A large part of
444the binary is not loaded into memory, which we see as
445`[Unmapped]`.
446
447Object files and static libraries don't have segments.
448However we fake it by grouping sections by their flags.
449This gives us a break-down sort of like real segments.
450
451```cmdoutput
452$ ./bloaty -d segments CMakeFiles/libbloaty.dir/src/bloaty.cc.o
453 FILE SIZE VM SIZE
454 -------------- --------------
455 90.8% 1.27Mi 0.0% 0 Section []
456 5.7% 81.6Ki 76.7% 81.6Ki Section [AX]
457 1.7% 24.0Ki 22.6% 24.0Ki Section [A]
458 1.7% 24.0Ki 0.0% 0 [ELF Headers]
459 0.1% 991 0.0% 0 [Unmapped]
460 0.0% 656 0.7% 725 Section [AW]
461 100.0% 1.40Mi 100.0% 106Ki TOTAL
462```
463
464## Sections
465
466Sections give us a bit more granular look into the binary.
467If we want to find the symbol table, the unwind information,
468or the debug information, each kind of information lives in
469its own section. Bloaty's default output is sections.
470
471```cmdoutput
472$ ./bloaty -d sections bloaty
473 FILE SIZE VM SIZE
474 -------------- --------------
475 32.3% 6.84Mi 0.0% 0 .debug_info
476 19.6% 4.15Mi 0.0% 0 .debug_loc
477 11.3% 2.39Mi 39.5% 2.39Mi .rodata
478 9.4% 1.98Mi 0.0% 0 .debug_str
479 6.8% 1.43Mi 0.0% 0 .debug_ranges
480 5.9% 1.24Mi 20.5% 1.24Mi .text
481 5.8% 1.24Mi 0.0% 0 .debug_line
482 0.0% 0 16.6% 1.00Mi .bss
483 2.0% 440Ki 7.1% 440Ki .data
484 1.6% 352Ki 5.7% 352Ki .rela.dyn
485 1.5% 329Ki 5.3% 329Ki .data.rel.ro
486 1.0% 208Ki 0.0% 0 .strtab
487 0.6% 138Ki 0.0% 0 .debug_abbrev
488 0.6% 122Ki 0.0% 0 .symtab
489 0.6% 120Ki 1.9% 120Ki .eh_frame
490 0.5% 100Ki 1.6% 100Ki .dynstr
491 0.2% 43.6Ki 0.7% 43.5Ki .dynsym
492 0.2% 35.2Ki 0.4% 27.9Ki [24 Others]
493 0.1% 20.3Ki 0.3% 20.2Ki .eh_frame_hdr
494 0.1% 19.8Ki 0.3% 19.8Ki .gcc_except_table
495 0.1% 13.3Ki 0.0% 0 .debug_aranges
496 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
497```
498
499## Symbols
500
501Symbols come from the symbol table, and represent individual
502functions or variables.
503
504```cmdoutput
505$ ./bloaty -d symbols bloaty
506 FILE SIZE VM SIZE
507 -------------- --------------
508 32.3% 6.84Mi 0.0% 0 [section .debug_info]
509 19.6% 4.15Mi 0.0% 0 [section .debug_loc]
510 12.3% 2.60Mi 37.3% 2.26Mi [3789 Others]
511 9.4% 1.98Mi 0.0% 0 [section .debug_str]
512 6.8% 1.43Mi 0.0% 0 [section .debug_ranges]
513 6.8% 1.43Mi 23.6% 1.43Mi insns
514 5.8% 1.24Mi 0.0% 0 [section .debug_line]
515 0.0% 44 16.5% 1024Ki g_instruction_table
516 1.3% 279Ki 4.5% 279Ki insn_name_maps
517 1.0% 218Ki 3.5% 218Ki ARMInsts
518 0.8% 175Ki 2.8% 175Ki insn_ops
519 0.6% 140Ki 2.3% 140Ki x86DisassemblerTwoByteOpcodes
520 0.6% 138Ki 0.0% 0 [section .debug_abbrev]
521 0.6% 119Ki 1.9% 119Ki AArch64_printInst
522 0.5% 101Ki 1.6% 101Ki Sparc_printInst
523 0.4% 81.0Ki 1.3% 81.0Ki PPC_printInst
524 0.3% 74.0Ki 1.2% 74.0Ki x86DisassemblerThreeByte38Opcodes
525 0.3% 61.1Ki 1.0% 60.9Ki DecoderTable32
526 0.2% 54.0Ki 0.9% 54.0Ki x86DisassemblerThreeByte3AOpcodes
527 0.2% 50.1Ki 0.8% 49.8Ki reg_name_maps
528 0.2% 42.6Ki 0.7% 42.5Ki SystemZ_getInstruction
529 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
530```
531
532You can control how symbols are demangled with the `-C MODE`
533or `--demangle=MODE` flag. You can also specify the
534demangling mode explicitly in the `-d` switch. We have
535three different demangling modes:
536
537* `-C none` or `-d rawsymbols`: no, demangling.
538* `-C short` or `-d shortsymbols`: short demangling: return
539 types, template parameters, and function parameter types
540 are omitted. For example:
541 `bloaty::dwarf::FormReader<>::GetFunctionForForm<>()`.
542 This is the default.
543* `-C full` or `-d fullsymbols`: full demangling.
544
545One very handy thing about `-C short` (the default) is that
546it groups all template instantiations together, regardless
547of their parameters. You can use this to determine how much
548code size you are paying by doing multiple instantiations of
549templates. Try `bloaty -d shortsymbols,fullsymbols`.
550
551## Input Files
552
553When you pass multiple files to Bloaty, the `inputfiles`
554source will let you break it down by input file:
555
556```cmdoutput
557$ ./bloaty -d inputfiles CMakeFiles/libbloaty.dir/src/*.o
558 FILE SIZE VM SIZE
559 -------------- --------------
560 37.4% 1.40Mi 33.6% 106Ki CMakeFiles/libbloaty.dir/src/bloaty.cc.o
561 18.4% 702Ki 14.2% 45.0Ki CMakeFiles/libbloaty.dir/src/dwarf.cc.o
562 10.4% 395Ki 13.3% 42.1Ki CMakeFiles/libbloaty.dir/src/bloaty.pb.cc.o
563 9.8% 374Ki 12.7% 40.2Ki CMakeFiles/libbloaty.dir/src/elf.cc.o
564 7.8% 298Ki 8.5% 26.8Ki CMakeFiles/libbloaty.dir/src/macho.cc.o
565 5.9% 226Ki 4.8% 15.1Ki CMakeFiles/libbloaty.dir/src/webassembly.cc.o
566 3.8% 146Ki 4.0% 12.5Ki CMakeFiles/libbloaty.dir/src/range_map.cc.o
567 3.7% 142Ki 6.4% 20.4Ki CMakeFiles/libbloaty.dir/src/demangle.cc.o
568 2.7% 103Ki 2.4% 7.66Ki CMakeFiles/libbloaty.dir/src/disassemble.cc.o
569 100.0% 3.73Mi 100.0% 316Ki TOTAL
570```
571
572## Archive Members
573
574When you are running Bloaty on a `.a` file, the `armembers`
575source will let you break it down by `.o` file inside the
576archive.
577
578```cmdoutput
579$ ./bloaty -d armembers liblibbloaty.a
580 FILE SIZE VM SIZE
581 -------------- --------------
582 25.5% 1.40Mi 21.4% 106Ki bloaty.cc.o
583 20.1% 1.10Mi 19.1% 95.0Ki cxa_demangle.cpp.o
584 12.5% 702Ki 9.1% 45.0Ki dwarf.cc.o
585 7.1% 395Ki 8.5% 42.1Ki bloaty.pb.cc.o
586 6.7% 374Ki 8.1% 40.2Ki elf.cc.o
587 5.3% 298Ki 5.4% 26.8Ki macho.cc.o
588 4.0% 226Ki 3.0% 15.1Ki webassembly.cc.o
589 2.6% 146Ki 2.5% 12.5Ki range_map.cc.o
590 2.5% 142Ki 4.1% 20.4Ki demangle.cc.o
591 2.2% 122Ki 3.0% 14.8Ki escaping.cc.o
592 2.0% 114Ki 3.5% 17.4Ki charconv_bigint.cc.o
593 1.9% 103Ki 1.5% 7.66Ki disassemble.cc.o
594 1.5% 81.4Ki 2.2% 10.8Ki [8 Others]
595 1.2% 65.1Ki 0.0% 0 [AR Symbol Table]
596 1.1% 60.4Ki 2.3% 11.4Ki numbers.cc.o
597 1.0% 56.5Ki 2.8% 13.8Ki charconv.cc.o
598 0.9% 47.9Ki 1.3% 6.22Ki str_cat.cc.o
599 0.6% 34.4Ki 0.8% 3.91Ki throw_delegate.cc.o
600 0.5% 28.0Ki 0.5% 2.36Ki ascii.cc.o
601 0.5% 26.3Ki 0.7% 3.26Ki string_view.cc.o
602 0.4% 25.1Ki 0.3% 1.50Ki str_split.cc.o
603 100.0% 5.48Mi 100.0% 496Ki TOTAL
604```
605
606You are free to use this data source even for non-`.a`
607files, but it won't be very useful since it will always just
608resolve to the input file (the `.a` file).
609
610## Compile Units
611
612Using debug information, we can tell what compile unit (and
613corresponding source file) each bit of the binary came from.
614
615```cmdoutput
616$ ./bloaty -d compileunits bloaty
617 FILE SIZE VM SIZE
618 -------------- --------------
619 34.5% 7.30Mi 34.5% 2.08Mi [124 Others]
620 10.5% 2.22Mi 6.7% 413Ki ../third_party/capstone/arch/ARM/ARMDisassembler.c
621 1.7% 366Ki 17.4% 1.05Mi ../third_party/capstone/arch/M68K/M68KDisassembler.c
622 4.5% 979Ki 13.9% 863Ki ../third_party/capstone/arch/X86/X86Mapping.c
623 4.4% 957Ki 1.3% 79.0Ki ../third_party/capstone/arch/SystemZ/SystemZDisassembler.c
624 4.1% 898Ki 1.5% 91.2Ki ../third_party/capstone/arch/AArch64/AArch64Disassembler.c
625 3.9% 853Ki 0.7% 42.0Ki ../third_party/re2/re2/re2.cc
626 3.7% 802Ki 2.0% 126Ki ../src/bloaty.cc
627 3.6% 772Ki 0.6% 38.6Ki ../third_party/re2/re2/dfa.cc
628 3.3% 705Ki 0.6% 39.8Ki ../third_party/re2/re2/regexp.cc
629 3.1% 662Ki 1.1% 67.8Ki ../third_party/capstone/arch/Mips/MipsDisassembler.c
630 2.7% 577Ki 0.4% 23.4Ki ../third_party/re2/re2/prog.cc
631 2.5% 549Ki 7.0% 432Ki ../third_party/capstone/arch/X86/X86DisassemblerDecoder.c
632 2.5% 544Ki 1.5% 92.6Ki ../third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp
633 2.5% 537Ki 0.6% 35.3Ki ../third_party/re2/re2/parse.cc
634 2.4% 524Ki 2.8% 172Ki ../third_party/capstone/arch/AArch64/AArch64InstPrinter.c
635 2.3% 503Ki 0.4% 26.4Ki ../third_party/re2/re2/compile.cc
636 2.1% 460Ki 0.6% 35.8Ki ../third_party/capstone/arch/PowerPC/PPCDisassembler.c
637 2.0% 427Ki 1.7% 108Ki ../third_party/capstone/arch/X86/X86ATTInstPrinter.c
638 1.9% 409Ki 4.5% 278Ki ../third_party/capstone/arch/SystemZ/SystemZMapping.c
639 1.8% 400Ki 0.2% 15.0Ki ../third_party/re2/re2/nfa.cc
640 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
641```
642
643## Inlines
644
645The DWARF debugging information also contains "line info"
646information that understands inlining. So within a
647function, it will know which instructions came from an
648inlined function from a header file. This is the
649information the debugger uses to point at a specific source
650line as you're tracing through a program.
651
652```cmdoutput
653$ ./bloaty -d inlines bloaty
654 FILE SIZE VM SIZE
655 -------------- --------------
656 32.3% 6.84Mi 0.0% 0 [section .debug_info]
657 19.6% 4.15Mi 0.0% 0 [section .debug_loc]
658 11.3% 2.39Mi 39.5% 2.39Mi [section .rodata]
659 9.4% 1.98Mi 0.0% 0 [section .debug_str]
660 6.8% 1.43Mi 0.0% 0 [section .debug_ranges]
661 5.9% 1.25Mi 20.3% 1.23Mi [35364 Others]
662 5.8% 1.24Mi 0.0% 0 [section .debug_line]
663 0.0% 0 16.6% 1.00Mi [section .bss]
664 2.0% 440Ki 7.1% 440Ki [section .data]
665 1.6% 352Ki 5.7% 352Ki [section .rela.dyn]
666 1.5% 329Ki 5.3% 329Ki [section .data.rel.ro]
667 1.0% 208Ki 0.0% 0 [section .strtab]
668 0.6% 138Ki 0.0% 0 [section .debug_abbrev]
669 0.6% 122Ki 0.0% 0 [section .symtab]
670 0.6% 120Ki 1.9% 120Ki [section .eh_frame]
671 0.5% 100Ki 1.6% 100Ki [section .dynstr]
672 0.2% 43.6Ki 0.7% 43.5Ki [section .dynsym]
673 0.1% 20.3Ki 0.3% 20.2Ki [section .eh_frame_hdr]
674 0.1% 20.1Ki 0.3% 20.1Ki ../third_party/capstone/arch/ARM/ARMDisassembler.c:115
675 0.1% 19.8Ki 0.3% 19.8Ki [section .gcc_except_table]
676 0.1% 16.0Ki 0.3% 16.0Ki /usr/include/c++/8/bits/basic_string.h:220
677 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
678```
679
680# Custom Data Sources
681
682Sometimes you want to munge the labels from an existing data
683source. For example, when we use "compileunits" on Bloaty
684itself, we see files from all our dependencies mixed
685together:
686
687```cmdoutput
688$ ./bloaty -d compileunits bloaty
689 FILE SIZE VM SIZE
690 -------------- --------------
691 34.5% 7.30Mi 34.5% 2.08Mi [124 Others]
692 10.5% 2.22Mi 6.7% 413Ki ../third_party/capstone/arch/ARM/ARMDisassembler.c
693 1.7% 366Ki 17.4% 1.05Mi ../third_party/capstone/arch/M68K/M68KDisassembler.c
694 4.5% 979Ki 13.9% 863Ki ../third_party/capstone/arch/X86/X86Mapping.c
695 4.4% 957Ki 1.3% 79.0Ki ../third_party/capstone/arch/SystemZ/SystemZDisassembler.c
696 4.1% 898Ki 1.5% 91.2Ki ../third_party/capstone/arch/AArch64/AArch64Disassembler.c
697 3.9% 853Ki 0.7% 42.0Ki ../third_party/re2/re2/re2.cc
698 3.7% 802Ki 2.0% 126Ki ../src/bloaty.cc
699 3.6% 772Ki 0.6% 38.6Ki ../third_party/re2/re2/dfa.cc
700 3.3% 705Ki 0.6% 39.8Ki ../third_party/re2/re2/regexp.cc
701 3.1% 662Ki 1.1% 67.8Ki ../third_party/capstone/arch/Mips/MipsDisassembler.c
702 2.7% 577Ki 0.4% 23.4Ki ../third_party/re2/re2/prog.cc
703 2.5% 549Ki 7.0% 432Ki ../third_party/capstone/arch/X86/X86DisassemblerDecoder.c
704 2.5% 544Ki 1.5% 92.6Ki ../third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp
705 2.5% 537Ki 0.6% 35.3Ki ../third_party/re2/re2/parse.cc
706 2.4% 524Ki 2.8% 172Ki ../third_party/capstone/arch/AArch64/AArch64InstPrinter.c
707 2.3% 503Ki 0.4% 26.4Ki ../third_party/re2/re2/compile.cc
708 2.1% 460Ki 0.6% 35.8Ki ../third_party/capstone/arch/PowerPC/PPCDisassembler.c
709 2.0% 427Ki 1.7% 108Ki ../third_party/capstone/arch/X86/X86ATTInstPrinter.c
710 1.9% 409Ki 4.5% 278Ki ../third_party/capstone/arch/SystemZ/SystemZMapping.c
711 1.8% 400Ki 0.2% 15.0Ki ../third_party/re2/re2/nfa.cc
712 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
713```
714
715If we want to bucket all of these by which library they came
716from, we can write a custom data source. It specifies the
717base data source and a set of regexes to apply to it. The
718regexes are tried in order, and the first matching regex
719will cause the entire label to be rewritten to the
720replacement text. Regexes follow [RE2
721syntax](https://github.com/google/re2/wiki/Syntax) and the
722replacement can refer to capture groups.
723
724```cmdoutput
725$ cat bloaty_package.bloaty
726custom_data_source: {
727 name: "bloaty_package"
728 base_data_source: "compileunits"
729
730 rewrite: {
731 pattern: "^(\\.\\./)?src"
732 replacement: "src"
733 }
734 rewrite: {
735 pattern: "^(\\.\\./)?(third_party/\\w+)"
736 replacement: "\\2"
737 }
738}
739```
740
741Then use the data source like so:
742
743```cmdoutput
744$ ./bloaty -c bloaty_package.bloaty -d bloaty_package bloaty
745 FILE SIZE VM SIZE
746 -------------- --------------
747 58.4% 12.4Mi 84.0% 5.08Mi third_party/capstone
748 25.7% 5.44Mi 4.8% 295Ki third_party/re2
749 9.8% 2.07Mi 6.3% 390Ki src
750 2.5% 544Ki 1.5% 92.6Ki third_party/demumble
751 1.3% 281Ki 0.0% 0 [section .debug_loc]
752 1.3% 279Ki 1.6% 100Ki third_party/abseil
753 0.3% 57.9Ki 0.0% 0 [section .debug_str]
754 0.2% 36.5Ki 0.6% 36.5Ki [section .rodata]
755 0.1% 19.8Ki 0.3% 19.8Ki [section .gcc_except_table]
756 0.1% 19.5Ki 0.0% 0 [section .strtab]
757 0.1% 15.1Ki 0.0% 0 [section .symtab]
758 0.1% 14.7Ki 0.2% 11.4Ki [28 Others]
759 0.1% 13.2Ki 0.0% 0 [section .debug_aranges]
760 0.1% 12.4Ki 0.2% 12.4Ki [section .gnu.hash]
761 0.0% 9.50Ki 0.2% 9.50Ki [section .dynstr]
762 0.0% 6.54Ki 0.1% 6.54Ki [section .data]
763 0.0% 5.98Ki 0.1% 5.98Ki [section .dynsym]
764 0.0% 5.92Ki 0.0% 0 [section .debug_ranges]
765 0.0% 5.65Ki 0.0% 0 [Unmapped]
766 0.0% 4.25Ki 0.1% 4.25Ki [section .text]
767 0.0% 4.06Ki 0.1% 4.06Ki [section .eh_frame]
768 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
769```
770
771We can get an even richer report by combining the
772`bloaty_package` source with the original `compileunits`
773source:
774
775```cmdoutput
776$ ./bloaty -c config.bloaty -d bloaty_package,compileunits bloaty
777 FILE SIZE VM SIZE
778 -------------- --------------
779 58.4% 12.4Mi 84.0% 5.08Mi third_party/capstone
780 17.9% 2.22Mi 8.0% 413Ki ../third_party/capstone/arch/ARM/ARMDisassembler.c
781 13.6% 1.68Mi 7.1% 369Ki [38 Others]
782 2.9% 366Ki 20.7% 1.05Mi ../third_party/capstone/arch/M68K/M68KDisassembler.c
783 7.7% 979Ki 16.6% 863Ki ../third_party/capstone/arch/X86/X86Mapping.c
784 7.6% 957Ki 1.5% 79.0Ki ../third_party/capstone/arch/SystemZ/SystemZDisassembler.c
785 7.1% 898Ki 1.8% 91.2Ki ../third_party/capstone/arch/AArch64/AArch64Disassembler.c
786 5.2% 662Ki 1.3% 67.8Ki ../third_party/capstone/arch/Mips/MipsDisassembler.c
787 4.3% 549Ki 8.3% 432Ki ../third_party/capstone/arch/X86/X86DisassemblerDecoder.c
788 4.1% 524Ki 3.3% 172Ki ../third_party/capstone/arch/AArch64/AArch64InstPrinter.c
789 3.6% 460Ki 0.7% 35.8Ki ../third_party/capstone/arch/PowerPC/PPCDisassembler.c
790 3.4% 427Ki 2.1% 108Ki ../third_party/capstone/arch/X86/X86ATTInstPrinter.c
791 3.2% 409Ki 5.4% 278Ki ../third_party/capstone/arch/SystemZ/SystemZMapping.c
792 3.0% 376Ki 1.9% 101Ki ../third_party/capstone/arch/ARM/ARMInstPrinter.c
793 2.6% 335Ki 2.1% 111Ki ../third_party/capstone/arch/PowerPC/PPCInstPrinter.c
794 2.6% 325Ki 2.2% 111Ki ../third_party/capstone/arch/Sparc/SparcInstPrinter.c
795 2.2% 284Ki 4.6% 237Ki ../third_party/capstone/arch/AArch64/AArch64Mapping.c
796 2.1% 262Ki 4.1% 213Ki ../third_party/capstone/arch/ARM/ARMMapping.c
797 2.0% 259Ki 1.9% 100Ki ../third_party/capstone/arch/X86/X86IntelInstPrinter.c
798 1.6% 202Ki 3.1% 160Ki ../third_party/capstone/arch/PowerPC/PPCMapping.c
799 1.6% 201Ki 2.9% 152Ki ../third_party/capstone/arch/Mips/MipsMapping.c
800 1.4% 181Ki 0.5% 28.2Ki ../third_party/capstone/arch/X86/X86Disassembler.c
801 25.7% 5.44Mi 4.8% 295Ki third_party/re2
802 15.3% 853Ki 14.2% 42.0Ki ../third_party/re2/re2/re2.cc
803 13.9% 772Ki 13.1% 38.6Ki ../third_party/re2/re2/dfa.cc
804 12.7% 705Ki 13.5% 39.8Ki ../third_party/re2/re2/regexp.cc
805 10.4% 577Ki 7.9% 23.4Ki ../third_party/re2/re2/prog.cc
806 9.6% 537Ki 12.0% 35.3Ki ../third_party/re2/re2/parse.cc
807 9.0% 503Ki 8.9% 26.4Ki ../third_party/re2/re2/compile.cc
808 7.2% 400Ki 5.1% 15.0Ki ../third_party/re2/re2/nfa.cc
809 6.8% 376Ki 7.4% 21.8Ki ../third_party/re2/re2/simplify.cc
810 4.4% 243Ki 2.2% 6.40Ki ../third_party/re2/re2/onepass.cc
811 4.0% 221Ki 1.8% 5.38Ki ../third_party/re2/re2/bitstate.cc
812 3.8% 213Ki 2.4% 7.20Ki ../third_party/re2/re2/tostring.cc
813 1.0% 55.5Ki 6.3% 18.5Ki ../third_party/re2/re2/unicode_groups.cc
814 0.9% 49.2Ki 0.8% 2.22Ki ../third_party/re2/re2/stringpiece.cc
815 0.8% 41.9Ki 0.6% 1.73Ki ../third_party/re2/util/strutil.cc
816 0.1% 7.53Ki 2.3% 6.71Ki ../third_party/re2/re2/unicode_casefold.cc
817 0.1% 5.68Ki 0.4% 1.17Ki ../third_party/re2/util/rune.cc
818 0.1% 4.92Ki 1.1% 3.38Ki ../third_party/re2/re2/perl_groups.cc
819 9.8% 2.07Mi 6.3% 390Ki src
820 37.9% 802Ki 32.4% 126Ki ../src/bloaty.cc
821 18.5% 392Ki 14.2% 55.4Ki ../src/dwarf.cc
822 9.1% 191Ki 14.3% 55.7Ki src/bloaty.pb.cc
823 7.8% 166Ki 10.5% 40.9Ki ../src/elf.cc
824 7.7% 163Ki 1.9% 7.30Ki ../src/main.cc
825 5.6% 118Ki 7.6% 29.8Ki ../src/macho.cc
826 4.6% 97.6Ki 4.4% 17.1Ki ../src/webassembly.cc
827 3.9% 82.9Ki 9.4% 36.6Ki ../src/demangle.cc
828 2.9% 62.1Ki 3.5% 13.7Ki ../src/range_map.cc
829 1.9% 40.9Ki 1.9% 7.32Ki ../src/disassemble.cc
830 2.5% 544Ki 1.5% 92.6Ki third_party/demumble
831 100.0% 544Ki 100.0% 92.6Ki ../third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp
832 1.3% 281Ki 0.0% 0 [section .debug_loc]
833 1.3% 279Ki 1.6% 100Ki third_party/abseil
834 20.1% 56.2Ki 21.2% 21.4Ki ../third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc
835 19.9% 55.6Ki 15.8% 15.9Ki ../third_party/abseil-cpp/absl/strings/escaping.cc
836 11.4% 31.9Ki 14.2% 14.3Ki ../third_party/abseil-cpp/absl/strings/charconv.cc
837 10.3% 28.8Ki 12.5% 12.6Ki ../third_party/abseil-cpp/absl/strings/numbers.cc
838 7.6% 21.2Ki 8.3% 8.38Ki ../third_party/abseil-cpp/absl/base/internal/throw_delegate.cc
839 7.4% 20.8Ki 6.9% 6.98Ki ../third_party/abseil-cpp/absl/strings/str_cat.cc
840 4.8% 13.4Ki 4.1% 4.10Ki ../third_party/abseil-cpp/absl/strings/string_view.cc
841 3.9% 10.9Ki 1.9% 1.94Ki ../third_party/abseil-cpp/absl/strings/ascii.cc
842 3.2% 8.99Ki 3.3% 3.29Ki ../third_party/abseil-cpp/absl/strings/substitute.cc
843 3.2% 8.89Ki 3.2% 3.24Ki ../third_party/abseil-cpp/absl/base/internal/raw_logging.cc
844 3.2% 8.81Ki 4.5% 4.51Ki ../third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc
845 2.6% 7.38Ki 1.8% 1.81Ki ../third_party/abseil-cpp/absl/strings/str_split.cc
846 1.3% 3.49Ki 1.6% 1.57Ki ../third_party/abseil-cpp/absl/strings/internal/memutil.cc
847 0.7% 2.09Ki 0.6% 635 ../third_party/abseil-cpp/absl/strings/match.cc
848 0.2% 670 0.2% 230 ../third_party/abseil-cpp/absl/strings/internal/utf8.cc
849 0.3% 57.9Ki 0.0% 0 [section .debug_str]
850 0.2% 36.5Ki 0.6% 36.5Ki [section .rodata]
851 0.1% 19.8Ki 0.3% 19.8Ki [section .gcc_except_table]
852 0.1% 19.5Ki 0.0% 0 [section .strtab]
853 0.1% 15.1Ki 0.0% 0 [section .symtab]
854 0.1% 14.7Ki 0.2% 11.4Ki [28 Others]
855 0.1% 13.2Ki 0.0% 0 [section .debug_aranges]
856 0.1% 12.4Ki 0.2% 12.4Ki [section .gnu.hash]
857 0.0% 9.50Ki 0.2% 9.50Ki [section .dynstr]
858 0.0% 6.54Ki 0.1% 6.54Ki [section .data]
859 0.0% 5.98Ki 0.1% 5.98Ki [section .dynsym]
860 0.0% 5.92Ki 0.0% 0 [section .debug_ranges]
861 0.0% 5.65Ki 0.0% 0 [Unmapped]
862 0.0% 4.25Ki 0.1% 4.25Ki [section .text]
863 0.0% 4.06Ki 0.1% 4.06Ki [section .eh_frame]
864 100.0% 21.2Mi 100.0% 6.05Mi TOTAL
865```
866
867# Source filter
868
869Sometimes, you are only interested in parts of the binary
870instead of the whole package. This is common in embedded
871programming, where ELF files are used only as a container
872format, and only a few sections are actually loaded onto
873the device.
874
875For this, Bloaty provides a `--source-filter` option which
876allows filtering out irrelevant data. It takes a regex
877which is applied to each of the symbol names in a data
878source. Only symbols which match the regex are displayed
879in the output. This is especially powerful when combined
880with custom data sources, as the rewriting occurs before
881the filtering.
882
883In the case of hierarchical data source profiles, the regex
884is applied to all symbol names in the hierarchy. If any
885name matches, all of its parents will be displayed as well.
886
887For example, given the above scenario, maybe we are only
888interested in how large the first-party Bloaty code is.
889This can be displayed using a source filter on the `src`
890directory.
891
892```cmdoutput
893$ ./bloaty -c config.bloaty -d bloaty_package,compileunits --source-filter src bloaty
894 FILE SIZE VM SIZE
895 -------------- --------------
896 100.0% 2.07Mi 100.0% 390Ki src
897 37.9% 802Ki 32.4% 126Ki ../src/bloaty.cc
898 18.5% 392Ki 14.2% 55.4Ki ../src/dwarf.cc
899 9.1% 191Ki 14.3% 55.7Ki src/bloaty.pb.cc
900 7.8% 166Ki 10.5% 40.9Ki ../src/elf.cc
901 7.7% 163Ki 1.9% 7.30Ki ../src/main.cc
902 5.6% 118Ki 7.6% 29.8Ki ../src/macho.cc
903 4.6% 97.6Ki 4.4% 17.1Ki ../src/webassembly.cc
904 3.9% 82.9Ki 9.4% 36.6Ki ../src/demangle.cc
905 2.9% 62.1Ki 3.5% 13.7Ki ../src/range_map.cc
906 1.9% 40.9Ki 1.9% 7.32Ki ../src/disassemble.cc
907 100.0% 2.07Mi 100.0% 390Ki TOTAL
908Filtering enabled (source_filter); omitted file = 19.1Mi, vm = 5.67Mi of entries
909```
910
911# Future Work
912
913Here are some tentative plans for future features.
914
915## Understanding Symbol References
916
917If we can analyze references between symbols, this would
918enable a lot of features:
919
920- Detect garbage symbols (ie. how much would the binary
921 shrink if we compiled with `-ffunction-sections
922 -fdata-sections -Wl,-gc-sections`).
923- Understand why a particular symbol can't be
924 garbage-collected (like `ld -why_live` on OS X).
925- Visualize the dependency tree of symbols (probably as a
926 dominator tree) so users can see the weight of their
927 binary in this way.
928