xref: /llvm-project/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst (revision 5e7662efec36b0117cfdf85c0182e026e0019c4e)
1llvm-debuginfo-analyzer - Print a logical representation of low-level debug information.
2========================================================================================
3
4.. program:: llvm-debuginfo-analyzer
5
6.. contents::
7   :local:
8
9SYNOPSIS
10--------
11:program:`llvm-debuginfo-analyzer` [*options*] [*filename ...*]
12
13DESCRIPTION
14-----------
15:program:`llvm-debuginfo-analyzer` parses debug and text sections in
16binary object files and prints their contents in a logical view, which
17is a human readable representation that closely matches the structure
18of the original user source code. Supported object file formats include
19ELF, Mach-O, WebAssembly, PDB and COFF.
20
21The **logical view** abstracts the complexity associated with the
22different low-level representations of the debugging information that
23is embedded in the object file. :program:`llvm-debuginfo-analyzer`
24produces a canonical view of the debug information regardless of how it
25is formatted. The same logical view will be seen regardless of object
26file format, assuming the debug information correctly represents the
27same original source code.
28
29The logical view includes the following **logical elements**: *type*,
30*scope*, *symbol* and *line*, which are the basic software elements used
31in the C/C++ programming language. Each logical element has a set of
32**attributes**, such as *types*, *classes*, *functions*, *variables*,
33*parameters*, etc. The :option:`--attribute` can be used to specify which
34attributes to include when printing a logical element. A logical element
35may have a **kind** that describes specific types of elements. For
36instance, a *scope* could have a kind value of *function*, *class*,
37*namespace*.
38
39:program:`llvm-debuginfo-analyzer` defaults to print a pre-defined
40layout of logical elements and attributes. The command line options can
41be used to control the printed elements (:option:`--print`), using a
42specific layout (:option:`--report`), matching a given pattern
43(:option:`--select`, :option:`--select-offsets`). Also, the output can
44be limited to specified logical elements using (:option:`--select-lines`,
45:option:`--select-scopes`, :option:`--select-symbols`,
46:option:`--select-types`).
47
48:program:`llvm-debuginfo-analyzer` can also compare a set of logical
49views (:option:`--compare`), to find differences and identify possible
50debug information syntax issues (:option:`--warning`) in any object file.
51
52OPTIONS
53-------
54:program:`llvm-debuginfo-analyzer` options are separated into several
55categories, each tailored to a different purpose:
56
57  * :ref:`general_` - Standard LLVM options to display help, version, etc.
58  * :ref:`attributes_` - Describe how to include different details when
59    printing an element.
60  * :ref:`print_` - Specify which elements will be included when printing
61    the view.
62  * :ref:`output_` - Describe the supported formats when printing the view.
63  * :ref:`report_` - Describe the format layouts for view printing.
64  * :ref:`select_` - Allows to use specific criteria or conditions to
65    select which elements to print.
66  * :ref:`compare_` - Compare logical views and print missing and/or
67    added elements.
68  * :ref:`warning_` - Print the warnings detected during the creation
69    of the view.
70  * :ref:`internal_` - Internal analysis of the logical view.
71
72.. _general_:
73
74GENERAL
75~~~~~~~
76This section describes the standard help options, used to display the
77usage, version, response files, etc.
78
79.. option:: -h, --help
80
81 Show help and usage for this command. (--help-hidden for more).
82
83.. option:: --help-list
84
85 Show help and usage for this command without grouping the options
86 into categories (--help-list-hidden for more).
87
88.. option:: --help-hidden
89
90 Display all available options.
91
92.. option:: --print-all-options
93
94 Print all option values after command line parsing.
95
96.. option:: --print-options
97
98 Print non-default options after command line parsing
99
100.. option:: --version
101
102 Display the version of the tool.
103
104.. option:: @<FILE>
105
106 Read command-line options from `<FILE>`.
107
108If no input file is specified, :program:`llvm-debuginfo-analyzer`
109defaults to read `a.out` and return an error when no input file is found.
110
111If `-` is used as the input file, :program:`llvm-debuginfo-analyzer`
112reads the input from its standard input stream.
113
114.. _attributes_:
115
116ATTRIBUTES
117~~~~~~~~~~
118The following options enable attributes given for the printed elements.
119The attributes are divided in categories based on the type of data being
120added, such as: internal offsets in the binary file, location descriptors,
121register names, user source filenames, additional element transformations,
122toolchain name, binary file format, etc.
123
124.. option:: --attribute=<value[,value,...]>
125
126 With **value** being one of the options in the following lists.
127
128 .. code-block:: text
129
130   =all: Include all the below attributes.
131   =extended: Add low-level attributes.
132   =standard: Add standard high-level attributes.
133
134 The following attributes describe the most common information for a
135 logical element. They help to identify the lexical scope level; the
136 element visibility across modules (global, local); the toolchain name
137 that produced the binary file.
138
139 .. code-block:: text
140
141   =global: Element referenced across Compile Units.
142   =format: Object file format name.
143   =level: Lexical scope level (File=0, Compile Unit=1).
144   =local: Element referenced only in the Compile Unit.
145   =producer: Toolchain identification name.
146
147 The following attributes describe files and directory names from the
148 user source code, where the elements are declared or defined; functions
149 with public visibility across modules. These options allow to map the
150 elements to their user code location, for cross references purposes.
151
152 .. code-block:: text
153
154   =directories: Directories referenced in the debug information.
155   =filename: Filename where the element is defined.
156   =files: Files referenced in the debug information.
157   =pathname: Pathname where the object is defined.
158   =publics: Function names that are public.
159
160 The following attributes describe additional logical element source
161 transformations, in order to display built-in types (int, bool, etc.);
162 parameters and arguments used during template instantiation; parent
163 name hierarchy; array dimensions information; compiler generated
164 elements and the underlying types associated with the types aliases.
165
166 .. code-block:: text
167
168   =argument: Template parameters replaced by its arguments.
169   =base: Base types (int, bool, etc.).
170   =generated: Compiler generated elements.
171   =encoded: Template arguments encoded in the template name.
172   =qualified: The element type include parents in its name.
173   =reference: Element declaration and definition references.
174   =subrange: Subrange encoding information for arrays.
175   =typename: Template parameters.
176   =underlying: Underlying type for type definitions.
177
178 The following attributes describe the debug location information for
179 a symbol or scope. It includes the symbol percentage coverage and any
180 gaps within the location layout; ranges determining the code sections
181 attached to a function. When descriptors are used, the target processor
182 registers are displayed.
183
184 .. code-block:: text
185
186   =coverage: Symbol location coverage.
187   =gaps: Missing debug location (gaps).
188   =location: Symbol debug location.
189   =range: Debug location ranges.
190   =register: Processor register names.
191
192 The following attributes are associated with low level details, such
193 as: offsets in the binary file; discriminators added to the lines of
194 inlined functions in order to distinguish specific instances; debug
195 lines state machine registers; elements discarded by the compiler
196 (inlining) or by the linker optimizations (dead-stripping); system
197 compile units generated by the MS toolchain in PDBs.
198
199 .. code-block:: text
200
201   =discarded: Discarded elements by the linker.
202   =discriminator: Discriminators for inlined function instances.
203   =inserted: Generated inlined abstract references.
204   =linkage: Object file linkage name.
205   =offset: Debug information offset.
206   =qualifier: Line qualifiers (Newstatement, BasicBlock, etc).
207   =zero: Zero line numbers.
208
209 The following attribute described specific information for the **PE/COFF**
210 file format. It includes MS runtime types.
211
212 .. code-block:: text
213
214   =system: Display PDB's MS system elements.
215
216 The above attributes are grouped into *standard* and *extended*
217 categories that can be enabled.
218
219 The *standard* group, contains those attributes that add sufficient
220 information to describe a logical element and that can cover the
221 normal situations while dealing with debug information.
222
223 .. code-block:: text
224
225   =base
226   =coverage
227   =directories
228   =discriminator
229   =filename
230   =files
231   =format
232   =level
233   =producer
234   =publics
235   =range
236   =reference
237   =zero
238
239 The *extended* group, contains those attributes that require a more
240 extended knowledge about debug information. They are intended when a
241 lower level of detail is required.
242
243 .. code-block:: text
244
245   =argument
246   =discarded
247   =encoded
248   =gaps
249   =generated
250   =global
251   =inserted
252   =linkage
253   =local
254   =location
255   =offset
256   =operation
257   =pathname
258   =qualified
259   =qualifier
260   =register
261   =subrange
262   =system
263   =typename
264
265.. _print_:
266
267PRINT
268~~~~~
269The following options describe the elements to print. The layout used
270is determined by the :option:`--report`. In the tree layout, all the
271elements have their enclosing lexical scopes printed, even when not
272explicitly specified.
273
274.. option:: --print=<value[,value,...]>
275
276 With **value** being one of the options in the following lists.
277
278 .. code-block:: text
279
280   =all: Include all the below attributes.
281
282 The following options print the requested elements; in the case of any
283 given select conditions (:option:`--select`), only those elements that
284 match them, will be printed. The **elements** value is a convenient
285 way to specify instructions, lines, scopes, symbols and types all at
286 once.
287
288 .. code-block:: text
289
290   =elements: Instructions, lines, scopes, symbols and types.
291   =instructions: Assembler instructions for code sections.
292   =lines: Source lines referenced in the debug information.
293   =scopes: Lexical blocks (function, class, namespace, etc).
294   =symbols: Symbols (variable, member, parameter, etc).
295   =types: Types (pointer, reference, type alias, etc).
296
297 The following options print information, collected during the creation
298 of the elements, such as: scope contributions to the debug information;
299 summary of elements created, printed or matched (:option:`--select`);
300 warnings produced during the view creation.
301
302 .. code-block:: text
303
304   =sizes: Debug Information scopes contributions.
305   =summary: Summary of elements allocated, selected or printed.
306   =warnings: Warnings detected.
307
308 Note: The **--print=sizes** option is ELF specific.
309
310.. _output_:
311
312OUTPUT
313~~~~~~
314The following options describe how to control the output generated when
315printing the logical elements.
316
317.. option:: --output-file=<path>
318
319 Redirect the output to a file specified by <path>, where - is the
320 standard output stream.
321
322:program:`llvm-debuginfo-analyzer` has the concept of **split view**.
323When redirecting the output from a complex binary format, it is
324**divided** into individual files, each one containing the logical view
325output for a single compilation unit.
326
327.. option:: --output-folder=<name>
328
329 The folder to write a file per compilation unit when **--output=split**
330 is specified.
331
332.. option:: --output-level=<level>
333
334 Only print elements up to the given **lexical level** value. The input
335 file is at lexical level zero and a compilation unit is at lexical level
336 one.
337
338.. option:: --output=<value[,value,...]>
339
340 With **value** being one of the options in the following lists.
341
342 .. code-block:: text
343
344   =all: Include all the below outputs.
345
346 .. code-block:: text
347
348   =json: Use JSON as the output format (Not implemented).
349   =split: Split the output by Compile Units.
350   =text: Use a free form text output.
351
352.. option:: --output-sort=<key>
353
354 Primary key when ordering the elements in the output (default: line).
355 Sorting by logical element kind, requires be familiarity with the
356 element kind selection options (:option:`--select-lines`,
357 :option:`--select-scopes`, :option:`--select-symbols`,
358 :option:`--select-types`), as those options describe the different
359 logical element kinds.
360
361 .. code-block:: text
362
363   =kind: Sort by element kind.
364   =line: Sort by element line number.
365   =name: Sort by element name.
366   =offset: Sort by element offset.
367
368.. _report_:
369
370REPORT
371~~~~~~
372Depending on the task being executed (print, compare, select), several
373layouts are supported to display the elements in a more suitable way,
374to make the output easier to understand.
375
376.. option:: --report=<value[,value,...]>
377
378 With **value** being one of the options in the following list.
379
380 .. code-block:: text
381
382   =all: Include all the below reports.
383
384 .. code-block:: text
385
386   =children: Elements and children are displayed in a tree format.
387   =list: Elements are displayed in a tabular format.
388   =parents: Elements and parents are displayed in a tree format.
389   =view: Elements, parents and children are displayed in a tree format.
390
391The **list** layout presents the logical elements in a tabular form
392without any parent-child relationship. This may be the preferred way to
393display elements that match specific conditions when comparing logical
394views, making it easier to find differences.
395
396The **children**, **parents** and **view** layout displays the elements
397in a tree format, with the scopes representing their nodes, and types,
398symbols, lines and other scopes representing the children. The layout
399shows the lexical scoping relationship between elements, with the binary
400file being the tree root (level 0) and each compilation unit being a
401child (level 1).
402
403The **children** layout includes the elements that match any given
404criteria (:option:`--select`) or (:option:`--compare`) and its children.
405
406The **parents** layout includes the elements that match any given
407criteria (:option:`--select`) or (:option:`--compare`) and its parents.
408
409The combined **view** layout includes the elements that match any given
410criteria (:option:`--select`) or (:option:`--compare`), its parents
411and children.
412
413**Notes**:
414
4151. When a selection criteria (:option:`--select`) is specified with no
416   report option, the **list** layout is selected.
4172. The comparison mode always uses the **view** layout.
418
419.. _select_:
420
421SELECTION
422~~~~~~~~~
423When printing an element, different data can be included and it varies
424(:option:`--attribute`) from data directly associated with the binary
425file (offset) to high level details such as coverage, lexical scope
426level, location. As the printed output can reach a considerable size,
427several selection options, enable printing of specific elements.
428
429The pattern matching can ignore the case (:option:`--select-nocase`)
430and be extended to use regular expressions (:option:`--select-regex`).
431
432ELEMENTS
433^^^^^^^^
434The following options allow printing of elements that match the given
435<pattern>, offset <value> or an element <condition>.
436
437.. option:: --select=<pattern>
438
439 Print all elements whose name or line number matches the given <pattern>.
440
441.. option:: --select-offsets=<value[,value,...]>
442
443 Print all elements whose offset matches the given values. See
444 :option:`--attribute` option.
445
446.. option:: --select-elements=<condition[,condition,...]>
447
448 Print all elements that satisfy the given <condition>. With **condition**
449 being one of the options in the following list.
450
451 .. code-block:: text
452
453   =discarded: Discarded elements by the linker.
454   =global: Element referenced across Compile Units.
455   =optimized: Optimized inlined abstract references.
456
457.. option:: --select-nocase
458
459 Pattern matching is case-insensitive when using :option:`--select`.
460
461.. option:: --select-regex
462
463 Treat any <pattern> strings as regular expressions when selecting with
464 :option:`--select` option. If :option:`--select-nocase` is specified,
465 the regular expression becomes case-insensitive.
466
467If the <pattern> criteria is too general, a more selective option can
468be specified to target a particular category of elements:
469lines (:option:`--select-lines`), scopes (:option:`--select-scopes`),
470symbols (:option:`--select-symbols`) and types (:option:`--select-types`).
471
472These options require knowledge of the debug information format (DWARF,
473CodeView), as the given **kind** describes a very specific type
474of element.
475
476LINES
477^^^^^
478The following options allow printing of lines that match the given <kind>.
479The given criteria describes the debug line state machine registers.
480
481.. option:: --select-lines=<kind[,kind,...]>
482
483 With **kind** being one of the options in the following list.
484
485 .. code-block:: text
486
487   =AlwaysStepInto: marks an always step into.
488   =BasicBlock: Marks a new basic block.
489   =Discriminator: Line that has a discriminator.
490   =EndSequence: Marks the end in the sequence of lines.
491   =EpilogueBegin: Marks the start of a function epilogue.
492   =LineDebug: Lines that correspond to debug lines.
493   =LineAssembler: Lines that correspond to disassembly text.
494   =NeverStepInto: marks a never step into.
495   =NewStatement: Marks a new statement.
496   =PrologueEnd: Marks the end of a function prologue.
497
498SCOPES
499^^^^^^
500The following options allow printing of scopes that match the given <kind>.
501
502.. option:: --select-scopes=<kind[,kind,...]>
503
504 With **kind** being one of the options in the following list.
505
506 .. code-block:: text
507
508    =Aggregate: A class, structure or union.
509    =Array: An array.
510    =Block: A generic block (lexical block or exception block).
511    =CallSite: A call site.
512    =CatchBlock: An exception block.
513    =Class: A class.
514    =CompileUnit: A compile unit.
515    =EntryPoint: A subroutine entry point.
516    =Enumeration: An enumeration.
517    =Function: A function.
518    =FunctionType: A function pointer.
519    =InlinedFunction: An inlined function.
520    =Label: A label.
521    =LexicalBlock: A lexical block.
522    =Namespace: A namespace.
523    =Root: The element representing the main scope.
524    =Structure: A structure.
525    =Subprogram: A subprogram.
526    =Template: A template definition.
527    =TemplateAlias: A template alias.
528    =TemplatePack: A template pack.
529    =TryBlock: An exception try block.
530    =Union: A union.
531
532SYMBOLS
533^^^^^^^
534The following options allow printing of symbols that match the given <kind>.
535
536.. option:: --select-symbols=<kind[,kind,...]>
537
538 With **kind** being one of the options in the following list.
539
540 .. code-block:: text
541
542    =CallSiteParameter: A call site parameter.
543    =Constant: A constant symbol.
544    =Inheritance: A base class.
545    =Member: A member class.
546    =Parameter: A parameter to function.
547    =Unspecified: Unspecified parameters to function.
548    =Variable: A variable.
549
550TYPES
551^^^^^
552The following options allow printing of types that match the given <kind>.
553
554.. option:: --select-types=<kind[,kind,...]>
555
556 With **kind** being one of the options in the following list.
557
558 .. code-block:: text
559
560    =Base: Base type (integer, boolean, etc).
561    =Const: Constant specifier.
562    =Enumerator: Enumerator.
563    =Import: Import declaration.
564    =ImportDeclaration: Import declaration.
565    =ImportModule: Import module.
566    =Pointer: Pointer type.
567    =PointerMember: Pointer to member function.
568    =Reference: Reference type.
569    =Restrict: Restrict specifier.
570    =RvalueReference: R-value reference.
571    =Subrange: Array subrange.
572    =TemplateParam: Template parameter.
573    =TemplateTemplateParam: Template template parameter.
574    =TemplateTypeParam: Template type parameter.
575    =TemplateValueParam: Template value parameter.
576    =Typedef: Type definition.
577    =Unspecified: Unspecified type.
578    =Volatile: Volatile specifier.
579
580.. _compare_:
581
582COMPARE
583~~~~~~~
584When dealing with debug information, there are situations when the
585printing of the elements is not the correct approach. That is the case,
586when we are interested in the effects caused by different versions of
587the same toolchain, or the impact of specific compiler optimizations.
588
589For those cases, we are looking to see which elements have been added
590or removed. Due to the complicated debug information format, it is very
591difficult to use a regular diff tool to find those elements; even
592impossible when dealing with different debug formats.
593
594:program:`llvm-debuginfo-analyzer` supports a logical element comparison,
595allowing to find semantic differences between logical views, produced by
596different toolchain versions or even debug information formats.
597
598When comparing logical views created from different debug formats, its
599accuracy depends on how close the debug information represents the
600user code. For instance, a logical view created from a binary file with
601DWARF debug information may include more detailed data than a logical
602view created from a binary file with CodeView debug information.
603
604The following options describe the elements to compare.
605
606.. option:: --compare=<value[,value,...]>
607
608 With **value** being one of the options in the following list.
609
610 .. code-block:: text
611
612    =all: Include all the below elements.
613
614 .. code-block:: text
615
616    =lines: Include lines.
617    =scopes: Include scopes.
618    =symbols: Include symbols.
619    =types: Include types.
620
621:program:`llvm-debuginfo-analyzer` takes the first binary file on the
622command line as the **reference** and the second one as the **target**.
623To get a more descriptive report, the comparison is done twice. The
624reference and target views are swapped, in order to produce those
625**missing** elements from the target view and those **added** elements
626to the reference view.
627
628See :option:`--report` options on how to describe the comparison
629reports.
630
631.. _warning_:
632
633WARNING
634~~~~~~~
635When reading the input object files, :program:`llvm-debuginfo-analyzer`
636can detect issues in the raw debug information. These may not be
637considered fatal to the purpose of printing a logical view but they can
638give an indication about the quality and potentially expose issues with
639the generated debug information.
640
641The following options describe the warnings to be recorded for later
642printing, if they are requested by :option:`--print`.
643
644.. option:: --warning=<value[,value,...]>
645
646 With **value** being one of the options in the following list.
647
648 .. code-block:: text
649
650    =all: Include all the below warnings.
651
652 The following options collect additional information during the creation
653 of the logical view, to include invalid coverage values and locations
654 for symbols; invalid code ranges; lines that are zero.
655
656 .. code-block:: text
657
658    =coverages: Invalid symbol coverages values.
659    =lines: Debug lines that are zero.
660    =locations: Invalid symbol locations.
661    =ranges: Invalid code ranges.
662
663.. _internal_:
664
665INTERNAL
666~~~~~~~~
667 For a better understanding of the logical view, access to more detailed
668 internal information could be needed. Such data would help to identify
669 debug information processed or incorrect logical element management.
670 Typically these kind of options are available only in *debug* builds.
671
672 :program:`llvm-debuginfo-analyzer` supports these advanced options in
673 both *release* and *debug* builds, with the exception of the unique ID
674 that is generated only in *debug* builds.
675
676.. option:: --internal=<value[,value,...]>
677
678 With **value** being one of the options in the following list.
679
680 .. code-block:: text
681
682    =all: Include all the below options.
683
684 The following options allow to check the integrity of the logical view;
685 collect the debug tags that are processed or not implemented; ignore the
686 logical element line number, to facilitate the logical view comparison
687 when using external comparison tools; print the command line options
688 used to invoke :program:`llvm-debuginfo-analyzer`.
689
690 .. code-block:: text
691
692    =id: Print unique element ID.
693    =cmdline: Print command line.
694    =integrity: Check elements integrity.
695    =none: Ignore element line number.
696    =tag: Debug information tags.
697
698 **Note:** For ELF format, the collected tags represent the debug tags
699 that are not processed. For PE/COFF format, they represent the tags
700 that are processed.
701
702EXAMPLES
703--------
704This section includes some real binary files to show how to use
705:program:`llvm-debuginfo-analyzer` to print a logical view and to
706diagnose possible debug information issues.
707
708TEST CASE 1 - GENERAL OPTIONS
709~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
710The below example is used to show different output generated by
711:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
712ELF target with Clang (-O0 -g):
713
714.. code-block:: c++
715
716  1  using INTPTR = const int *;
717  2  int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {
718  3    if (ParamBool) {
719  4      typedef int INTEGER;
720  5      const INTEGER CONSTANT = 7;
721  6      return CONSTANT;
722  7    }
723  8    return ParamUnsigned;
724  9  }
725
726PRINTING MODE
727^^^^^^^^^^^^^
728In this mode :program:`llvm-debuginfo-analyzer` prints the *logical view*
729or portions of it, based on criteria patterns (including regular
730expressions) to select the kind of *logical elements* to be included in
731the output.
732
733BASIC DETAILS
734"""""""""""""
735The following command prints basic details for all the logical elements
736sorted by the debug information internal offset; it includes its lexical
737level and debug info format.
738
739.. code-block:: none
740
741  llvm-debuginfo-analyzer --attribute=level,format
742                          --output-sort=offset
743                          --print=scopes,symbols,types,lines,instructions
744                          test-dwarf-clang.o
745
746or
747
748.. code-block:: none
749
750  llvm-debuginfo-analyzer --attribute=level,format
751                          --output-sort=offset
752                          --print=elements
753                          test-dwarf-clang.o
754
755Each row represents an element that is present within the debug
756information. The first column represents the scope level, followed by
757the associated line number (if any), and finally the description of
758the element.
759
760.. code-block:: none
761
762  Logical View:
763  [000]           {File} 'test-dwarf-clang.o' -> elf64-x86-64
764
765  [001]             {CompileUnit} 'test.cpp'
766  [002]     2         {Function} extern not_inlined 'foo' -> 'int'
767  [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
768  [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
769  [003]     2           {Parameter} 'ParamBool' -> 'bool'
770  [003]                 {Block}
771  [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
772  [004]     5             {Line}
773  [004]                   {Code} 'movl	$0x7, -0x1c(%rbp)'
774  [004]     6             {Line}
775  [004]                   {Code} 'movl	$0x7, -0x4(%rbp)'
776  [004]                   {Code} 'jmp	0x6'
777  [004]     8             {Line}
778  [004]                   {Code} 'movl	-0x14(%rbp), %eax'
779  [003]     4           {TypeAlias} 'INTEGER' -> 'int'
780  [003]     2           {Line}
781  [003]                 {Code} 'pushq	%rbp'
782  [003]                 {Code} 'movq	%rsp, %rbp'
783  [003]                 {Code} 'movb	%dl, %al'
784  [003]                 {Code} 'movq	%rdi, -0x10(%rbp)'
785  [003]                 {Code} 'movl	%esi, -0x14(%rbp)'
786  [003]                 {Code} 'andb	$0x1, %al'
787  [003]                 {Code} 'movb	%al, -0x15(%rbp)'
788  [003]     3           {Line}
789  [003]                 {Code} 'testb	$0x1, -0x15(%rbp)'
790  [003]                 {Code} 'je	0x13'
791  [003]     8           {Line}
792  [003]                 {Code} 'movl	%eax, -0x4(%rbp)'
793  [003]     9           {Line}
794  [003]                 {Code} 'movl	-0x4(%rbp), %eax'
795  [003]                 {Code} 'popq	%rbp'
796  [003]                 {Code} 'retq'
797  [003]     9           {Line}
798  [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
799
800On closer inspection, we can see what could be a potential debug issue:
801
802.. code-block:: none
803
804  [003]                 {Block}
805  [003]     4           {TypeAlias} 'INTEGER' -> 'int'
806
807The **'INTEGER'** definition is at level **[003]**, the same lexical
808scope as the anonymous **{Block}** ('true' branch for the 'if' statement)
809whereas in the original source code the typedef statement is clearly
810inside that block, so the **'INTEGER'** definition should also be at
811level **[004]** inside the block.
812
813SELECT LOGICAL ELEMENTS
814"""""""""""""""""""""""
815The following prints all *instructions*, *symbols* and *types* that
816contain **'inte'** or **'movl'** in their names or types, using a tab
817layout and given the number of matches.
818
819.. code-block:: none
820
821  llvm-debuginfo-analyzer --attribute=level
822                          --select-nocase --select-regex
823                          --select=INTe --select=movl
824                          --report=list
825                          --print=symbols,types,instructions,summary
826                          test-dwarf-clang.o
827
828  Logical View:
829  [000]           {File} 'test-dwarf-clang.o'
830
831  [001]           {CompileUnit} 'test.cpp'
832  [003]           {Code} 'movl	$0x7, -0x1c(%rbp)'
833  [003]           {Code} 'movl	$0x7, -0x4(%rbp)'
834  [003]           {Code} 'movl	%eax, -0x4(%rbp)'
835  [003]           {Code} 'movl	%esi, -0x14(%rbp)'
836  [003]           {Code} 'movl	-0x14(%rbp), %eax'
837  [003]           {Code} 'movl	-0x4(%rbp), %eax'
838  [003]     4     {TypeAlias} 'INTEGER' -> 'int'
839  [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
840
841  -----------------------------
842  Element      Total      Found
843  -----------------------------
844  Scopes           3          0
845  Symbols          4          1
846  Types            2          1
847  Lines           17          6
848  -----------------------------
849  Total           26          8
850
851COMPARISON MODE
852^^^^^^^^^^^^^^^
853In this mode :program:`llvm-debuginfo-analyzer` compares logical views
854to produce a report with the logical elements that are missing or added.
855This a very powerful aid in finding semantic differences in the debug
856information produced by different toolchain versions or even completely
857different toolchains altogether (For example a compiler producing DWARF
858can be directly compared against a completely different compiler that
859produces CodeView).
860
861Given the previous example we found the above debug information issue
862(related to the previous invalid scope location for the **'typedef int
863INTEGER'**) by comparing against another compiler.
864
865Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern
866with the printing mode to obtain the following logical view output.
867
868.. code-block:: none
869
870  llvm-debuginfo-analyzer --attribute=level
871                          --select-regex --select-nocase --select=INTe
872                          --report=list
873                          --print=symbols,types
874                          test-dwarf-clang.o test-dwarf-gcc.o
875
876  Logical View:
877  [000]           {File} 'test-dwarf-clang.o'
878
879  [001]           {CompileUnit} 'test.cpp'
880  [003]     4     {TypeAlias} 'INTEGER' -> 'int'
881  [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
882
883  Logical View:
884  [000]           {File} 'test-dwarf-gcc.o'
885
886  [001]           {CompileUnit} 'test.cpp'
887  [004]     4     {TypeAlias} 'INTEGER' -> 'int'
888  [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
889
890The output shows that both objects contain the same elements. But the
891**'typedef INTEGER'** is located at different scope level. The GCC
892generated object, shows **'4'**, which is the correct value.
893
894Note that there is no requirement that GCC must produce identical or
895similar DWARF to Clang to allow the comparison. We're only comparing
896the semantics. The same case when comparing CodeView debug information
897generated by MSVC and Clang.
898
899There are 2 comparison methods: logical view and logical elements.
900
901LOGICAL VIEW
902""""""""""""
903It compares the logical view as a whole unit; for a match, each compared
904logical element must have the same parents and children.
905
906Using the :program:`llvm-debuginfo-analyzer` comparison functionality,
907that issue can be seen in a more global context, that can include the
908logical view.
909
910The output shows in view form the **missing (-), added (+)** elements,
911giving more context by swapping the reference and target object files.
912
913.. code-block:: none
914
915  llvm-debuginfo-analyzer --attribute=level
916                          --compare=types
917                          --report=view
918                          --print=symbols,types
919                          test-dwarf-clang.o test-dwarf-gcc.o
920
921  Reference: 'test-dwarf-clang.o'
922  Target:    'test-dwarf-gcc.o'
923
924  Logical View:
925   [000]           {File} 'test-dwarf-clang.o'
926
927   [001]             {CompileUnit} 'test.cpp'
928   [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
929   [002]     2         {Function} extern not_inlined 'foo' -> 'int'
930   [003]                 {Block}
931   [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
932  +[004]     4             {TypeAlias} 'INTEGER' -> 'int'
933   [003]     2           {Parameter} 'ParamBool' -> 'bool'
934   [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
935   [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
936  -[003]     4           {TypeAlias} 'INTEGER' -> 'int'
937
938The output shows the merging view path (reference and target) with the
939missing and added elements.
940
941LOGICAL ELEMENTS
942""""""""""""""""
943It compares individual logical elements without considering if their
944parents are the same. For both comparison methods, the equal criteria
945includes the name, source code location, type, lexical scope level.
946
947.. code-block:: none
948
949  llvm-debuginfo-analyzer --attribute=level
950                          --compare=types
951                          --report=list
952                          --print=symbols,types,summary
953                          test-dwarf-clang.o test-dwarf-gcc.o
954
955  Reference: 'test-dwarf-clang.o'
956  Target:    'test-dwarf-gcc.o'
957
958  (1) Missing Types:
959  -[003]     4     {TypeAlias} 'INTEGER' -> 'int'
960
961  (1) Added Types:
962  +[004]     4     {TypeAlias} 'INTEGER' -> 'int'
963
964  ----------------------------------------
965  Element   Expected    Missing      Added
966  ----------------------------------------
967  Scopes           4          0          0
968  Symbols          0          0          0
969  Types            2          1          1
970  Lines            0          0          0
971  ----------------------------------------
972  Total            6          1          1
973
974Changing the *Reference* and *Target* order:
975
976.. code-block:: none
977
978  llvm-debuginfo-analyzer --attribute=level
979                          --compare=types
980                          --report=list
981                          --print=symbols,types,summary
982                          test-dwarf-gcc.o test-dwarf-clang.o
983
984  Reference: 'test-dwarf-gcc.o'
985  Target:    'test-dwarf-clang.o'
986
987  (1) Missing Types:
988  -[004]     4     {TypeAlias} 'INTEGER' -> 'int'
989
990  (1) Added Types:
991  +[003]     4     {TypeAlias} 'INTEGER' -> 'int'
992
993  ----------------------------------------
994  Element   Expected    Missing      Added
995  ----------------------------------------
996  Scopes           4          0          0
997  Symbols          0          0          0
998  Types            2          1          1
999  Lines            0          0          0
1000  ----------------------------------------
1001  Total            6          1          1
1002
1003As the *Reference* and *Target* are switched, the *Added Types* from
1004the first case now are listed as *Missing Types*.
1005
1006TEST CASE 2 - ASSEMBLER INSTRUCTIONS
1007~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1008The below example is used to show different output generated by
1009:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
1010Codeview and ELF targets with recent versions of Clang, GCC and MSVC
1011(-O0 -g) for Windows and Linux.
1012
1013.. code-block:: c++
1014
1015   1  extern int printf(const char * format, ... );
1016   2
1017   3  int main()
1018   4  {
1019   5    printf("Hello, World\n");
1020   6    return 0;
1021   7  }
1022
1023These are the logical views that :program:`llvm-debuginfo-analyzer`
1024generates for 3 different compilers (MSVC, Clang and GCC), emitting
1025different debug information formats (CodeView, DWARF) on Windows and
1026Linux.
1027
1028.. code-block:: none
1029
1030  llvm-debuginfo-analyzer --attribute=level,format,producer
1031                          --print=lines,instructions
1032                          hello-world-codeview-clang.o
1033                          hello-world-codeview-msvc.o
1034                          hello-world-dwarf-clang.o
1035                          hello-world-dwarf-gcc.o
1036
1037CodeView - Clang (Windows)
1038^^^^^^^^^^^^^^^^^^^^^^^^^^
1039
1040.. code-block:: none
1041
1042  Logical View:
1043  [000]           {File} 'hello-world-codeview-clang.o' -> COFF-x86-64
1044
1045  [001]             {CompileUnit} 'hello-world.cpp'
1046  [002]               {Producer} 'clang version 14.0.0'
1047  [002]               {Function} extern not_inlined 'main' -> 'int'
1048  [003]     4           {Line}
1049  [003]                 {Code} 'subq	$0x28, %rsp'
1050  [003]                 {Code} 'movl	$0x0, 0x24(%rsp)'
1051  [003]     5           {Line}
1052  [003]                 {Code} 'leaq	(%rip), %rcx'
1053  [003]                 {Code} 'callq	0x0'
1054  [003]     6           {Line}
1055  [003]                 {Code} 'xorl	%eax, %eax'
1056  [003]                 {Code} 'addq	$0x28, %rsp'
1057  [003]                 {Code} 'retq'
1058
1059CodeView - MSVC (Windows)
1060^^^^^^^^^^^^^^^^^^^^^^^^^
1061
1062.. code-block:: none
1063
1064  Logical View:
1065  [000]           {File} 'hello-world-codeview-msvc.o' -> COFF-i386
1066
1067  [001]             {CompileUnit} 'hello-world.cpp'
1068  [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
1069  [002]               {Function} extern not_inlined 'main' -> 'int'
1070  [003]     4           {Line}
1071  [003]                 {Code} 'pushl	%ebp'
1072  [003]                 {Code} 'movl	%esp, %ebp'
1073  [003]     5           {Line}
1074  [003]                 {Code} 'pushl	$0x0'
1075  [003]                 {Code} 'calll	0x0'
1076  [003]                 {Code} 'addl	$0x4, %esp'
1077  [003]     6           {Line}
1078  [003]                 {Code} 'xorl	%eax, %eax'
1079  [003]     7           {Line}
1080  [003]                 {Code} 'popl	%ebp'
1081  [003]                 {Code} 'retl'
1082
1083DWARF - Clang (Linux)
1084^^^^^^^^^^^^^^^^^^^^^
1085
1086.. code-block:: none
1087
1088  Logical View:
1089  [000]           {File} 'hello-world-dwarf-clang.o' -> elf64-x86-64
1090
1091  [001]             {CompileUnit} 'hello-world.cpp'
1092  [002]               {Producer} 'clang version 14.0.0'
1093  [002]     3         {Function} extern not_inlined 'main' -> 'int'
1094  [003]     4           {Line}
1095  [003]                 {Code} 'pushq	%rbp'
1096  [003]                 {Code} 'movq	%rsp, %rbp'
1097  [003]                 {Code} 'subq	$0x10, %rsp'
1098  [003]                 {Code} 'movl	$0x0, -0x4(%rbp)'
1099  [003]     5           {Line}
1100  [003]                 {Code} 'movabsq	$0x0, %rdi'
1101  [003]                 {Code} 'movb	$0x0, %al'
1102  [003]                 {Code} 'callq	0x0'
1103  [003]     6           {Line}
1104  [003]                 {Code} 'xorl	%eax, %eax'
1105  [003]                 {Code} 'addq	$0x10, %rsp'
1106  [003]                 {Code} 'popq	%rbp'
1107  [003]                 {Code} 'retq'
1108  [003]     6           {Line}
1109
1110DWARF - GCC (Linux)
1111^^^^^^^^^^^^^^^^^^^
1112
1113.. code-block:: none
1114
1115  Logical View:
1116  [000]           {File} 'hello-world-dwarf-gcc.o' -> elf64-x86-64
1117
1118  [001]             {CompileUnit} 'hello-world.cpp'
1119  [002]               {Producer} 'GNU C++14 9.3.0'
1120  [002]     3         {Function} extern not_inlined 'main' -> 'int'
1121  [003]     4           {Line}
1122  [003]                 {Code} 'endbr64'
1123  [003]                 {Code} 'pushq	%rbp'
1124  [003]                 {Code} 'movq	%rsp, %rbp'
1125  [003]     5           {Line}
1126  [003]                 {Code} 'leaq	(%rip), %rdi'
1127  [003]                 {Code} 'movl	$0x0, %eax'
1128  [003]                 {Code} 'callq	0x0'
1129  [003]     6           {Line}
1130  [003]                 {Code} 'movl	$0x0, %eax'
1131  [003]     7           {Line}
1132  [003]                 {Code} 'popq	%rbp'
1133  [003]                 {Code} 'retq'
1134  [003]     7           {Line}
1135
1136The logical views shows the intermixed lines and assembler instructions,
1137allowing to compare the code generated by the different toolchains.
1138
1139TEST CASE 3 - INCORRECT LEXICAL SCOPE FOR TYPEDEF
1140~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1141The below example is used to show different output generated by
1142:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
1143Codeview and ELF targets with recent versions of Clang, GCC and MSVC
1144(-O0 -g).
1145
1146.. code-block:: c++
1147
1148   1  int bar(float Input) { return (int)Input; }
1149   2
1150   3  unsigned foo(char Param) {
1151   4    typedef int INT;                // ** Definition for INT **
1152   5    INT Value = Param;
1153   6    {
1154   7      typedef float FLOAT;          // ** Definition for FLOAT **
1155   8      {
1156   9        FLOAT Added = Value + Param;
1157  10        Value = bar(Added);
1158  11      }
1159  12    }
1160  13    return Value + Param;
1161  14  }
1162
1163The above test is used to illustrate a scope issue found in the Clang
1164compiler:
1165`PR44884 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=44884>`_ /
1166`PR44229 (GitHub LLVM) <https://github.com/llvm/llvm-project/issues/44229>`_
1167
1168The lines 4 and 7 contains 2 typedefs, defined at different lexical
1169scopes.
1170
1171.. code-block:: c++
1172
1173  4    typedef int INT;
1174  7      typedef float FLOAT;
1175
1176These are the logical views that :program:`llvm-debuginfo-analyzer`
1177generates for 3 different compilers (MSVC, Clang and GCC), emitting
1178different debug information formats (CodeView, DWARF) on different
1179platforms.
1180
1181.. code-block:: none
1182
1183  llvm-debuginfo-analyzer --attribute=level,format,producer
1184                          --print=symbols,types,lines
1185                          --output-sort=kind
1186                          pr-44884-codeview-clang.o
1187                          pr-44884-codeview-msvc.o
1188                          pr-44884-dwarf-clang.o
1189                          pr-44884-dwarf-gcc.o
1190
1191CodeView - Clang (Windows)
1192^^^^^^^^^^^^^^^^^^^^^^^^^^
1193
1194.. code-block:: none
1195
1196  Logical View:
1197  [000]           {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64
1198
1199  [001]             {CompileUnit} 'pr-44884.cpp'
1200  [002]               {Producer} 'clang version 14.0.0'
1201  [002]               {Function} extern not_inlined 'bar' -> 'int'
1202  [003]                 {Parameter} 'Input' -> 'float'
1203  [003]     1           {Line}
1204  [002]               {Function} extern not_inlined 'foo' -> 'unsigned'
1205  [003]                 {Block}
1206  [004]                   {Variable} 'Added' -> 'float'
1207  [004]     9             {Line}
1208  [004]    10             {Line}
1209  [003]                 {Parameter} 'Param' -> 'char'
1210  [003]                 {TypeAlias} 'FLOAT' -> 'float'
1211  [003]                 {TypeAlias} 'INT' -> 'int'
1212  [003]                 {Variable} 'Value' -> 'int'
1213  [003]     3           {Line}
1214  [003]     5           {Line}
1215  [003]    13           {Line}
1216
1217CodeView - MSVC (Windows)
1218^^^^^^^^^^^^^^^^^^^^^^^^^
1219
1220.. code-block:: none
1221
1222  Logical View:
1223  [000]           {File} 'pr-44884-codeview-msvc.o' -> COFF-i386
1224
1225  [001]             {CompileUnit} 'pr-44884.cpp'
1226  [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
1227  [002]               {Function} extern not_inlined 'bar' -> 'int'
1228  [003]                 {Variable} 'Input' -> 'float'
1229  [003]     1           {Line}
1230  [002]               {Function} extern not_inlined 'foo' -> 'unsigned'
1231  [003]                 {Block}
1232  [004]                   {Block}
1233  [005]                     {Variable} 'Added' -> 'float'
1234  [004]                   {TypeAlias} 'FLOAT' -> 'float'
1235  [004]     9             {Line}
1236  [004]    10             {Line}
1237  [003]                 {TypeAlias} 'INT' -> 'int'
1238  [003]                 {Variable} 'Param' -> 'char'
1239  [003]                 {Variable} 'Value' -> 'int'
1240  [003]     3           {Line}
1241  [003]     5           {Line}
1242  [003]    13           {Line}
1243  [003]    14           {Line}
1244
1245DWARF - Clang (Linux)
1246^^^^^^^^^^^^^^^^^^^^^
1247
1248.. code-block:: none
1249
1250  Logical View:
1251  [000]           {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64
1252
1253  [001]             {CompileUnit} 'pr-44884.cpp'
1254  [002]               {Producer} 'clang version 14.0.0'
1255  [002]     1         {Function} extern not_inlined 'bar' -> 'int'
1256  [003]     1           {Parameter} 'Input' -> 'float'
1257  [003]     1           {Line}
1258  [003]     1           {Line}
1259  [003]     1           {Line}
1260  [002]     3         {Function} extern not_inlined 'foo' -> 'unsigned int'
1261  [003]                 {Block}
1262  [004]     9             {Variable} 'Added' -> 'FLOAT'
1263  [004]     9             {Line}
1264  [004]     9             {Line}
1265  [004]     9             {Line}
1266  [004]     9             {Line}
1267  [004]     9             {Line}
1268  [004]    10             {Line}
1269  [004]    10             {Line}
1270  [004]    10             {Line}
1271  [004]    13             {Line}
1272  [003]     3           {Parameter} 'Param' -> 'char'
1273  [003]     7           {TypeAlias} 'FLOAT' -> 'float'
1274  [003]     4           {TypeAlias} 'INT' -> 'int'
1275  [003]     5           {Variable} 'Value' -> 'INT'
1276  [003]     3           {Line}
1277  [003]     5           {Line}
1278  [003]     5           {Line}
1279  [003]    13           {Line}
1280  [003]    13           {Line}
1281  [003]    13           {Line}
1282  [003]    13           {Line}
1283
1284DWARF - GCC (Linux)
1285^^^^^^^^^^^^^^^^^^^
1286
1287.. code-block:: none
1288
1289  Logical View:
1290  [000]           {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm
1291
1292  [001]             {CompileUnit} 'pr-44884.cpp'
1293  [002]               {Producer} 'GNU C++14 10.2.1 20201103'
1294  [002]     1         {Function} extern not_inlined 'bar' -> 'int'
1295  [003]     1           {Parameter} 'Input' -> 'float'
1296  [003]     1           {Line}
1297  [003]     1           {Line}
1298  [003]     1           {Line}
1299  [002]     3         {Function} extern not_inlined 'foo' -> 'unsigned int'
1300  [003]                 {Block}
1301  [004]                   {Block}
1302  [005]     9               {Variable} 'Added' -> 'FLOAT'
1303  [005]     9               {Line}
1304  [005]     9               {Line}
1305  [005]     9               {Line}
1306  [005]    10               {Line}
1307  [005]    13               {Line}
1308  [004]     7             {TypeAlias} 'FLOAT' -> 'float'
1309  [003]     3           {Parameter} 'Param' -> 'char'
1310  [003]     4           {TypeAlias} 'INT' -> 'int'
1311  [003]     5           {Variable} 'Value' -> 'INT'
1312  [003]     3           {Line}
1313  [003]     5           {Line}
1314  [003]    13           {Line}
1315  [003]    14           {Line}
1316  [003]    14           {Line}
1317
1318From the previous logical views, we can see that the Clang compiler
1319emits **both typedefs at the same lexical scope (3)**, which is wrong.
1320GCC and MSVC emit correct lexical scope for both typedefs.
1321
1322Using the :program:`llvm-debuginfo-analyzer` selection facilities, we
1323can produce a simple tabular output showing just the logical types that
1324are **Typedef**.
1325
1326.. code-block:: none
1327
1328  llvm-debuginfo-analyzer --attribute=level,format
1329                          --output-sort=name
1330                          --select-types=Typedef
1331                          --report=list
1332                          --print=types
1333                          pr-44884-*.o
1334
1335  Logical View:
1336  [000]           {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64
1337
1338  [001]           {CompileUnit} 'pr_44884.cpp'
1339  [003]           {TypeAlias} 'FLOAT' -> 'float'
1340  [003]           {TypeAlias} 'INT' -> 'int'
1341
1342  Logical View:
1343  [000]           {File} 'pr-44884-codeview-msvc.o' -> COFF-i386
1344
1345  [001]           {CompileUnit} 'pr_44884.cpp'
1346  [004]           {TypeAlias} 'FLOAT' -> 'float'
1347  [003]           {TypeAlias} 'INT' -> 'int'
1348
1349  Logical View:
1350  [000]           {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64
1351
1352  [001]           {CompileUnit} 'pr_44884.cpp'
1353  [003]     7     {TypeAlias} 'FLOAT' -> 'float'
1354  [003]     4     {TypeAlias} 'INT' -> 'int'
1355
1356  Logical View:
1357  [000]           {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm
1358
1359  [001]           {CompileUnit} 'pr_44884.cpp'
1360  [004]     7     {TypeAlias} 'FLOAT' -> 'float'
1361  [003]     4     {TypeAlias} 'INT' -> 'int'
1362
1363It also shows, that the CodeView debug information does not generate
1364source code line numbers for the those logical types. The logical view
1365is sorted by the types name.
1366
1367TEST CASE 4 - MISSING NESTED ENUMERATIONS
1368~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1369The below example is used to show different output generated by
1370:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
1371Codeview and ELF targets with recent versions of Clang, GCC and MSVC
1372(-O0 -g).
1373
1374.. code-block:: c++
1375
1376   1  struct Struct {
1377   2    union Union {
1378   3      enum NestedEnum { RED, BLUE };
1379   4    };
1380   5    Union U;
1381   6  };
1382   7
1383   8  Struct S;
1384   9  int test() {
1385  10    return S.U.BLUE;
1386  11  }
1387
1388The above test is used to illustrate a scope issue found in the Clang
1389compiler:
1390`PR46466 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=46466>`_ /
1391`PR45811 (GitHub LLVM) <https://github.com/llvm/llvm-project/issues/45811>`_
1392
1393These are the logical views that :program:`llvm-debuginfo-analyzer`
1394generates for 3 different compilers (MSVC, Clang and GCC), emitting
1395different debug information formats (CodeView, DWARF) on different
1396platforms.
1397
1398.. code-block:: none
1399
1400  llvm-debuginfo-analyzer --attribute=level,format,producer
1401                          --output-sort=name
1402                          --print=symbols,types
1403                          pr-46466-codeview-clang.o
1404                          pr-46466-codeview-msvc.o
1405                          pr-46466-dwarf-clang.o
1406                          pr-46466-dwarf-gcc.o
1407
1408CodeView - Clang (Windows)
1409^^^^^^^^^^^^^^^^^^^^^^^^^^
1410
1411.. code-block:: none
1412
1413  Logical View:
1414  [000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
1415
1416  [001]             {CompileUnit} 'pr-46466.cpp'
1417  [002]               {Producer} 'clang version 14.0.0'
1418  [002]               {Variable} extern 'S' -> 'Struct'
1419  [002]     1         {Struct} 'Struct'
1420  [003]                 {Member} public 'U' -> 'Union'
1421  [003]     2           {Union} 'Union'
1422  [004]     3             {Enumeration} 'NestedEnum' -> 'int'
1423  [005]                     {Enumerator} 'BLUE' = '0x1'
1424  [005]                     {Enumerator} 'RED' = '0x0'
1425
1426CodeView - MSVC (Windows)
1427^^^^^^^^^^^^^^^^^^^^^^^^^
1428
1429.. code-block:: none
1430
1431  Logical View:
1432  [000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
1433
1434  [001]             {CompileUnit} 'pr-46466.cpp'
1435  [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
1436  [002]               {Variable} extern 'S' -> 'Struct'
1437  [002]     1         {Struct} 'Struct'
1438  [003]                 {Member} public 'U' -> 'Union'
1439  [003]     2           {Union} 'Union'
1440  [004]     3             {Enumeration} 'NestedEnum' -> 'int'
1441  [005]                     {Enumerator} 'BLUE' = '0x1'
1442  [005]                     {Enumerator} 'RED' = '0x0'
1443
1444DWARF - Clang (Linux)
1445^^^^^^^^^^^^^^^^^^^^^
1446
1447.. code-block:: none
1448
1449  Logical View:
1450  [000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
1451
1452  [001]             {CompileUnit} 'pr-46466.cpp'
1453  [002]               {Producer} 'clang version 14.0.0'
1454  [002]     8         {Variable} extern 'S' -> 'Struct'
1455  [002]     1         {Struct} 'Struct'
1456  [003]     5           {Member} public 'U' -> 'Union'
1457
1458DWARF - GCC (Linux)
1459^^^^^^^^^^^^^^^^^^^
1460
1461.. code-block:: none
1462
1463  Logical View:
1464  [000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
1465
1466  [001]             {CompileUnit} 'pr-46466.cpp'
1467  [002]               {Producer} 'GNU C++14 9.3.0'
1468  [002]     8         {Variable} extern 'S' -> 'Struct'
1469  [002]     1         {Struct} 'Struct'
1470  [003]     5           {Member} public 'U' -> 'Union'
1471  [003]     2           {Union} 'Union'
1472  [004]     3             {Enumeration} 'NestedEnum' -> 'unsigned int'
1473  [005]                     {Enumerator} 'BLUE' = '0x1'
1474  [005]                     {Enumerator} 'RED' = '0x0'
1475
1476From the previous logical views, we can see that the DWARF debug
1477information generated by the Clang compiler does not include any
1478references to the enumerators **RED** and **BLUE**. The DWARF
1479generated by GCC, CodeView generated by Clang and MSVC, they do
1480include such references.
1481
1482Using the :program:`llvm-debuginfo-analyzer` selection facilities, we
1483can produce a logical view showing just the logical types that are
1484**Enumerator** and its parents. The logical view is sorted by the types
1485name.
1486
1487.. code-block:: none
1488
1489  llvm-debuginfo-analyzer --attribute=format,level
1490                          --output-sort=name
1491                          --select-types=Enumerator
1492                          --report=parents
1493                          --print=types
1494                          pr-46466-*.o
1495
1496.. code-block:: none
1497
1498  Logical View:
1499  [000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
1500
1501  [001]             {CompileUnit} 'pr-46466.cpp'
1502  [002]     1         {Struct} 'Struct'
1503  [003]     2           {Union} 'Union'
1504  [004]     3             {Enumeration} 'NestedEnum' -> 'int'
1505  [005]                     {Enumerator} 'BLUE' = '0x1'
1506  [005]                     {Enumerator} 'RED' = '0x0'
1507
1508  Logical View:
1509  [000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
1510
1511  [001]             {CompileUnit} 'pr-46466.cpp'
1512  [002]     1         {Struct} 'Struct'
1513  [003]     2           {Union} 'Union'
1514  [004]     3             {Enumeration} 'NestedEnum' -> 'int'
1515  [005]                     {Enumerator} 'BLUE' = '0x1'
1516  [005]                     {Enumerator} 'RED' = '0x0'
1517
1518  Logical View:
1519  [000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
1520
1521  [001]             {CompileUnit} 'pr-46466.cpp'
1522
1523  Logical View:
1524  [000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
1525
1526  [001]             {CompileUnit} 'pr-46466.cpp'
1527  [002]     1         {Struct} 'Struct'
1528  [003]     2           {Union} 'Union'
1529  [004]     3             {Enumeration} 'NestedEnum' -> 'unsigned int'
1530  [005]                     {Enumerator} 'BLUE' = '0x1'
1531  [005]                     {Enumerator} 'RED' = '0x0'
1532
1533Using the :program:`llvm-debuginfo-analyzer` selection facilities, we
1534can produce a simple tabular output including a summary for the logical
1535types that are **Enumerator**. The logical view is sorted by the types
1536name.
1537
1538.. code-block:: none
1539
1540  llvm-debuginfo-analyzer --attribute=format,level
1541                          --output-sort=name
1542                          --select-types=Enumerator
1543                          --print=types,summary
1544                          pr-46466-*.o
1545
1546.. code-block:: none
1547
1548  Logical View:
1549  [000]           {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
1550
1551  [001]           {CompileUnit} 'pr-46466.cpp'
1552  [005]           {Enumerator} 'BLUE' = '0x1'
1553  [005]           {Enumerator} 'RED' = '0x0'
1554
1555  -----------------------------
1556  Element      Total      Found
1557  -----------------------------
1558  Scopes           5          0
1559  Symbols          2          0
1560  Types            6          2
1561  Lines            0          0
1562  -----------------------------
1563  Total           13          2
1564
1565  Logical View:
1566  [000]           {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
1567
1568  [001]           {CompileUnit} 'pr-46466.cpp'
1569  [005]           {Enumerator} 'BLUE' = '0x1'
1570  [005]           {Enumerator} 'RED' = '0x0'
1571
1572  -----------------------------
1573  Element      Total      Found
1574  -----------------------------
1575  Scopes           5          0
1576  Symbols          2          0
1577  Types            7          2
1578  Lines            0          0
1579  -----------------------------
1580  Total           14          2
1581
1582  Logical View:
1583  [000]           {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
1584
1585  [001]           {CompileUnit} 'pr-46466.cpp'
1586
1587  -----------------------------
1588  Element      Total      Found
1589  -----------------------------
1590  Scopes           4          0
1591  Symbols          0          0
1592  Types            0          0
1593  Lines            0          0
1594  -----------------------------
1595  Total            4          0
1596
1597  Logical View:
1598  [000]           {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
1599
1600  [001]           {CompileUnit} 'pr-46466.cpp'
1601  [005]           {Enumerator} 'BLUE' = '0x1'
1602  [005]           {Enumerator} 'RED' = '0x0'
1603
1604  -----------------------------
1605  Element      Total      Found
1606  -----------------------------
1607  Scopes           5          0
1608  Symbols          0          0
1609  Types            2          2
1610  Lines            0          0
1611  -----------------------------
1612  Total            7          2
1613
1614From the values printed under the **Found** column, we can see that no
1615**Types** were found in the DWARF debug information generated by Clang.
1616
1617TEST CASE 5 - INCORRECT LEXICAL SCOPE FOR VARIABLE
1618~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1619The below example is used to show different output generated by
1620:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
1621Codeview and ELF targets with recent versions of Clang, GCC and MSVC
1622(-O0 -g).
1623
1624.. code-block:: c++
1625
1626  // definitions.h
1627  #ifdef _MSC_VER
1628    #define forceinline __forceinline
1629  #elif defined(__clang__)
1630    #if __has_attribute(__always_inline__)
1631      #define forceinline inline __attribute__((__always_inline__))
1632    #else
1633      #define forceinline inline
1634    #endif
1635  #elif defined(__GNUC__)
1636    #define forceinline inline __attribute__((__always_inline__))
1637  #else
1638    #define forceinline inline
1639    #error
1640  #endif
1641
1642As the test is dependent on inline compiler options, the above header
1643file defines *forceinline*.
1644
1645.. code-block:: c++
1646
1647   #include "definitions.h"
1648
1649.. code-block:: c++
1650
1651   1  #include "definitions.h"
1652   2  forceinline int InlineFunction(int Param) {
1653   3    int Var_1 = Param;
1654   4    {
1655   5      int Var_2 = Param + Var_1;
1656   6      Var_1 = Var_2;
1657   7    }
1658   8    return Var_1;
1659   9  }
1660  10
1661  11  int test(int Param_1, int Param_2) {
1662  12    int A = Param_1;
1663  13    A += InlineFunction(Param_2);
1664  14    return A;
1665  15  }
1666
1667The above test is used to illustrate a variable issue found in the Clang
1668compiler:
1669`PR43860 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=43860>`_ /
1670`PR43205 (GitHub) <https://github.com/llvm/llvm-project/issues/43205>`_
1671
1672These are the logical views that :program:`llvm-debuginfo-analyzer`
1673generates for 3 different compilers (MSVC, Clang and GCC), emitting
1674different debug information formats (CodeView, DWARF) on different
1675platforms.
1676
1677.. code-block:: none
1678
1679  llvm-debuginfo-analyzer --attribute=level,format,producer
1680                          --output-sort=name
1681                          --print=symbols
1682                          pr-43860-codeview-clang.o
1683                          pr-43860-codeview-msvc.o
1684                          pr-43860-dwarf-clang.o
1685                          pr-43860-dwarf-gcc.o
1686
1687CODEVIEW - Clang (Windows)
1688^^^^^^^^^^^^^^^^^^^^^^^^^^
1689
1690.. code-block:: none
1691
1692  Logical View:
1693  [000]           {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64
1694
1695  [001]             {CompileUnit} 'pr-43860.cpp'
1696  [002]               {Producer} 'clang version 14.0.0'
1697  [002]     2         {Function} inlined 'InlineFunction' -> 'int'
1698  [003]                 {Parameter} '' -> 'int'
1699  [002]               {Function} extern not_inlined 'test' -> 'int'
1700  [003]                 {Variable} 'A' -> 'int'
1701  [003]                 {InlinedFunction} inlined 'InlineFunction' -> 'int'
1702  [004]                   {Parameter} 'Param' -> 'int'
1703  [004]                   {Variable} 'Var_1' -> 'int'
1704  [004]                   {Variable} 'Var_2' -> 'int'
1705  [003]                 {Parameter} 'Param_1' -> 'int'
1706  [003]                 {Parameter} 'Param_2' -> 'int'
1707
1708CODEVIEW - MSVC (Windows)
1709^^^^^^^^^^^^^^^^^^^^^^^^^
1710
1711.. code-block:: none
1712
1713  Logical View:
1714  [000]           {File} 'pr-43860-codeview-msvc.o' -> COFF-i386
1715
1716  [001]             {CompileUnit} 'pr-43860.cpp'
1717  [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
1718  [002]               {Function} extern not_inlined 'InlineFunction' -> 'int'
1719  [003]                 {Block}
1720  [004]                   {Variable} 'Var_2' -> 'int'
1721  [003]                 {Variable} 'Param' -> 'int'
1722  [003]                 {Variable} 'Var_1' -> 'int'
1723  [002]               {Function} extern not_inlined 'test' -> 'int'
1724  [003]                 {Variable} 'A' -> 'int'
1725  [003]                 {Variable} 'Param_1' -> 'int'
1726  [003]                 {Variable} 'Param_2' -> 'int'
1727
1728DWARF - Clang (Linux)
1729^^^^^^^^^^^^^^^^^^^^^
1730
1731.. code-block:: none
1732
1733  Logical View:
1734  [000]           {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64
1735
1736  [001]             {CompileUnit} 'pr-43860.cpp'
1737  [002]               {Producer} 'clang version 14.0.0'
1738  [002]     2         {Function} extern inlined 'InlineFunction' -> 'int'
1739  [003]                 {Block}
1740  [004]     5             {Variable} 'Var_2' -> 'int'
1741  [003]     2           {Parameter} 'Param' -> 'int'
1742  [003]     3           {Variable} 'Var_1' -> 'int'
1743  [002]    11         {Function} extern not_inlined 'test' -> 'int'
1744  [003]    12           {Variable} 'A' -> 'int'
1745  [003]    13           {InlinedFunction} inlined 'InlineFunction' -> 'int'
1746  [004]                   {Block}
1747  [005]                     {Variable} 'Var_2' -> 'int'
1748  [004]                   {Parameter} 'Param' -> 'int'
1749  [004]                   {Variable} 'Var_1' -> 'int'
1750  [003]    11           {Parameter} 'Param_1' -> 'int'
1751  [003]    11           {Parameter} 'Param_2' -> 'int'
1752
1753DWARF - GCC (Linux)
1754^^^^^^^^^^^^^^^^^^^
1755
1756.. code-block:: none
1757
1758  Logical View:
1759  [000]           {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64
1760
1761  [001]             {CompileUnit} 'pr-43860.cpp'
1762  [002]               {Producer} 'GNU C++14 9.3.0'
1763  [002]     2         {Function} extern declared_inlined 'InlineFunction' -> 'int'
1764  [003]                 {Block}
1765  [004]     5             {Variable} 'Var_2' -> 'int'
1766  [003]     2           {Parameter} 'Param' -> 'int'
1767  [003]     3           {Variable} 'Var_1' -> 'int'
1768  [002]    11         {Function} extern not_inlined 'test' -> 'int'
1769  [003]    12           {Variable} 'A' -> 'int'
1770  [003]    13           {InlinedFunction} declared_inlined 'InlineFunction' -> 'int'
1771  [004]                   {Block}
1772  [005]                     {Variable} 'Var_2' -> 'int'
1773  [004]                   {Parameter} 'Param' -> 'int'
1774  [004]                   {Variable} 'Var_1' -> 'int'
1775  [003]    11           {Parameter} 'Param_1' -> 'int'
1776  [003]    11           {Parameter} 'Param_2' -> 'int'
1777
1778From the previous logical views, we can see that the CodeView debug
1779information generated by the Clang compiler shows the variables **Var_1**
1780and **Var_2** are at the same lexical scope (**4**) in the function
1781**InlineFuction**. The DWARF generated by GCC/Clang and CodeView
1782generated by MSVC, show those variables at the correct lexical scope:
1783**3** and **4** respectively.
1784
1785Using the :program:`llvm-debuginfo-analyzer` selection facilities, we
1786can produce a simple tabular output showing just the logical elements
1787that have in their name the *var* pattern. The logical view is sorted
1788by the variables name.
1789
1790.. code-block:: none
1791
1792  llvm-debuginfo-analyzer --attribute=level,format
1793                          --output-sort=name
1794                          --select-regex --select-nocase --select=Var
1795                          --report=list
1796                          --print=symbols
1797                          pr-43860-*.o
1798
1799.. code-block:: none
1800
1801  Logical View:
1802  [000]           {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64
1803
1804  [001]           {CompileUnit} 'pr-43860.cpp'
1805  [004]           {Variable} 'Var_1' -> 'int'
1806  [004]           {Variable} 'Var_2' -> 'int'
1807
1808  Logical View:
1809  [000]           {File} 'pr-43860-codeview-msvc.o' -> COFF-i386
1810
1811  [001]           {CompileUnit} 'pr-43860.cpp'
1812  [003]           {Variable} 'Var_1' -> 'int'
1813  [004]           {Variable} 'Var_2' -> 'int'
1814
1815  Logical View:
1816  [000]           {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64
1817
1818  [001]           {CompileUnit} 'pr-43860.cpp'
1819  [004]           {Variable} 'Var_1' -> 'int'
1820  [003]     3     {Variable} 'Var_1' -> 'int'
1821  [005]           {Variable} 'Var_2' -> 'int'
1822  [004]     5     {Variable} 'Var_2' -> 'int'
1823
1824  Logical View:
1825  [000]           {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64
1826
1827  [001]           {CompileUnit} 'pr-43860.cpp'
1828  [004]           {Variable} 'Var_1' -> 'int'
1829  [003]     3     {Variable} 'Var_1' -> 'int'
1830  [005]           {Variable} 'Var_2' -> 'int'
1831  [004]     5     {Variable} 'Var_2' -> 'int'
1832
1833It also shows, that the CodeView debug information does not generate
1834source code line numbers for the those logical symbols. The logical
1835view is sorted by the types name.
1836
1837TEST CASE 6 - FULL LOGICAL VIEW
1838~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1839For advanced users, :program:`llvm-debuginfo-analyzer` can display low
1840level information that includes offsets within the debug information
1841section, debug location operands, linkage names, etc.
1842
1843.. code-block:: none
1844
1845  llvm-debuginfo-analyzer --attribute=all
1846                          --print=all
1847                          test-dwarf-clang.o
1848
1849  Logical View:
1850  [0x0000000000][000]            {File} 'test-dwarf-clang.o' -> elf64-x86-64
1851
1852  [0x000000000b][001]              {CompileUnit} 'test.cpp'
1853  [0x000000000b][002]                {Producer} 'clang version 12.0.0'
1854                                     {Directory} ''
1855                                     {File} 'test.cpp'
1856                                     {Public} 'foo' [0x0000000000:0x000000003a]
1857  [0x000000000b][002]                {Range} Lines 2:9 [0x0000000000:0x000000003a]
1858  [0x00000000bc][002]                {BaseType} 'bool'
1859  [0x0000000099][002]                {BaseType} 'int'
1860  [0x00000000b5][002]                {BaseType} 'unsigned int'
1861
1862  [0x00000000a0][002]   {Source} '/test.cpp'
1863  [0x00000000a0][002]      1         {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int'
1864  [0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
1865  [0x000000002a][003]                  {Range} Lines 2:9 [0x0000000000:0x000000003a]
1866  [0x000000002a][003]                  {Linkage}  0x2 '_Z3fooPKijb'
1867  [0x0000000071][003]                  {Block}
1868  [0x0000000071][004]                    {Range} Lines 5:8 [0x000000001c:0x000000002f]
1869  [0x000000007e][004]      5             {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
1870  [0x000000007e][005]                      {Coverage} 100.00%
1871  [0x000000007f][005]                      {Location}
1872  [0x000000007f][006]                        {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]
1873  [0x000000001c][004]      5             {Line} {NewStatement} '/test.cpp'
1874  [0x000000001c][004]                    {Code} 'movl	$0x7, -0x1c(%rbp)'
1875  [0x0000000023][004]      6             {Line} {NewStatement} '/test.cpp'
1876  [0x0000000023][004]                    {Code} 'movl	$0x7, -0x4(%rbp)'
1877  [0x000000002a][004]                    {Code} 'jmp	0x6'
1878  [0x000000002f][004]      8             {Line} {NewStatement} '/test.cpp'
1879  [0x000000002f][004]                    {Code} 'movl	-0x14(%rbp), %eax'
1880  [0x0000000063][003]      2           {Parameter} 'ParamBool' -> [0x00000000bc]'bool'
1881  [0x0000000063][004]                    {Coverage} 100.00%
1882  [0x0000000064][004]                    {Location}
1883  [0x0000000064][005]                      {Entry} Stack Offset: -21 (0xffffffffffffffeb) [DW_OP_fbreg]
1884  [0x0000000047][003]      2           {Parameter} 'ParamPtr' -> [0x00000000a0]'INTPTR'
1885  [0x0000000047][004]                    {Coverage} 100.00%
1886  [0x0000000048][004]                    {Location}
1887  [0x0000000048][005]                      {Entry} Stack Offset: -16 (0xfffffffffffffff0) [DW_OP_fbreg]
1888  [0x0000000055][003]      2           {Parameter} 'ParamUnsigned' -> [0x00000000b5]'unsigned int'
1889  [0x0000000055][004]                    {Coverage} 100.00%
1890  [0x0000000056][004]                    {Location}
1891  [0x0000000056][005]                      {Entry} Stack Offset: -20 (0xffffffffffffffec) [DW_OP_fbreg]
1892  [0x000000008d][003]      4           {TypeAlias} 'INTEGER' -> [0x0000000099]'int'
1893  [0x0000000000][003]      2           {Line} {NewStatement} '/test.cpp'
1894  [0x0000000000][003]                  {Code} 'pushq	%rbp'
1895  [0x0000000001][003]                  {Code} 'movq	%rsp, %rbp'
1896  [0x0000000004][003]                  {Code} 'movb	%dl, %al'
1897  [0x0000000006][003]                  {Code} 'movq	%rdi, -0x10(%rbp)'
1898  [0x000000000a][003]                  {Code} 'movl	%esi, -0x14(%rbp)'
1899  [0x000000000d][003]                  {Code} 'andb	$0x1, %al'
1900  [0x000000000f][003]                  {Code} 'movb	%al, -0x15(%rbp)'
1901  [0x0000000012][003]      3           {Line} {NewStatement} {PrologueEnd} '/test.cpp'
1902  [0x0000000012][003]                  {Code} 'testb	$0x1, -0x15(%rbp)'
1903  [0x0000000016][003]                  {Code} 'je	0x13'
1904  [0x0000000032][003]      8           {Line} '/test.cpp'
1905  [0x0000000032][003]                  {Code} 'movl	%eax, -0x4(%rbp)'
1906  [0x0000000035][003]      9           {Line} {NewStatement} '/test.cpp'
1907  [0x0000000035][003]                  {Code} 'movl	-0x4(%rbp), %eax'
1908  [0x0000000038][003]                  {Code} 'popq	%rbp'
1909  [0x0000000039][003]                  {Code} 'retq'
1910  [0x000000003a][003]      9           {Line} {NewStatement} {EndSequence} '/test.cpp'
1911
1912  -----------------------------
1913  Element      Total    Printed
1914  -----------------------------
1915  Scopes           3          3
1916  Symbols          4          4
1917  Types            5          5
1918  Lines           25         25
1919  -----------------------------
1920  Total           37         37
1921
1922  Scope Sizes:
1923         189 (100.00%) : [0x000000000b][001]              {CompileUnit} 'test.cpp'
1924         110 ( 58.20%) : [0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
1925          27 ( 14.29%) : [0x0000000071][003]                  {Block}
1926
1927  Totals by lexical level:
1928  [001]:        189 (100.00%)
1929  [002]:        110 ( 58.20%)
1930  [003]:         27 ( 14.29%)
1931
1932The **Scope Sizes** table shows the contribution in bytes to the debug
1933information by each scope, which can be used to determine unexpected
1934size changes in the DWARF sections between different versions of the
1935same toolchain.
1936
1937.. code-block:: none
1938
1939  [0x000000002a][002]      2         {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
1940  [0x000000002a][003]                  {Range} Lines 2:9 [0x0000000000:0x000000003a]
1941  [0x000000002a][003]                  {Linkage}  0x2 '_Z3fooPKijb'
1942  [0x0000000071][003]                  {Block}
1943  [0x0000000071][004]                    {Range} Lines 5:8 [0x000000001c:0x000000002f]
1944  [0x000000007e][004]      5             {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
1945  [0x000000007e][005]                      {Coverage} 100.00%
1946  [0x000000007f][005]                      {Location}
1947  [0x000000007f][006]                        {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]
1948
1949The **{Range}** attribute describe the line ranges for a logical scope.
1950For this case, the function **foo** is within the lines **2** and **9**.
1951
1952The **{Coverage}** and **{Location}** attributes describe the debug
1953location and coverage for logical symbols. For optimized code, the
1954coverage value decreases and it affects the program debuggability.
1955
1956WEBASSEMBLY SUPPORT
1957~~~~~~~~~~~~~~~~~~~
1958The below example is used to show the WebAssembly output generated by
1959:program:`llvm-debuginfo-analyzer`. We compiled the example for a
1960WebAssembly 32-bit target with Clang (-O0 -g --target=wasm32):
1961
1962.. code-block:: c++
1963
1964  1  using INTPTR = const int *;
1965  2  int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {
1966  3    if (ParamBool) {
1967  4      typedef int INTEGER;
1968  5      const INTEGER CONSTANT = 7;
1969  6      return CONSTANT;
1970  7    }
1971  8    return ParamUnsigned;
1972  9  }
1973
1974PRINT BASIC DETAILS
1975^^^^^^^^^^^^^^^^^^^
1976The following command prints basic details for all the logical elements
1977sorted by the debug information internal offset; it includes its lexical
1978level and debug info format.
1979
1980.. code-block:: none
1981
1982  llvm-debuginfo-analyzer --attribute=level,format
1983                          --output-sort=offset
1984                          --print=scopes,symbols,types,lines,instructions
1985                          test-clang.o
1986
1987or
1988
1989.. code-block:: none
1990
1991  llvm-debuginfo-analyzer --attribute=level,format
1992                          --output-sort=offset
1993                          --print=elements
1994                          test-clang.o
1995
1996Each row represents an element that is present within the debug
1997information. The first column represents the scope level, followed by
1998the associated line number (if any), and finally the description of
1999the element.
2000
2001.. code-block:: none
2002
2003  Logical View:
2004  [000]           {File} 'test-clang.o' -> WASM
2005
2006  [001]             {CompileUnit} 'test.cpp'
2007  [002]     2         {Function} extern not_inlined 'foo' -> 'int'
2008  [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
2009  [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
2010  [003]     2           {Parameter} 'ParamBool' -> 'bool'
2011  [003]                 {Block}
2012  [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
2013  [004]     5             {Line}
2014  [004]                   {Code} 'i32.const	7'
2015  [004]                   {Code} 'local.set	10'
2016  [004]                   {Code} 'local.get	5'
2017  [004]                   {Code} 'local.get	10'
2018  [004]                   {Code} 'i32.store	12'
2019  [004]     6             {Line}
2020  [004]                   {Code} 'i32.const	7'
2021  [004]                   {Code} 'local.set	11'
2022  [004]                   {Code} 'local.get	5'
2023  [004]                   {Code} 'local.get	11'
2024  [004]                   {Code} 'i32.store	28'
2025  [004]                   {Code} 'br      	1'
2026  [004]     -             {Line}
2027  [004]                   {Code} 'end'
2028  [003]     4           {TypeAlias} 'INTEGER' -> 'int'
2029  [003]     2           {Line}
2030  [003]                 {Code} 'nop'
2031  [003]                 {Code} 'end'
2032  [003]                 {Code} 'i64.div_s'
2033  [003]                 {Code} 'global.get	0'
2034  [003]                 {Code} 'local.set	3'
2035  [003]                 {Code} 'i32.const	32'
2036  [003]                 {Code} 'local.set	4'
2037  [003]                 {Code} 'local.get	3'
2038  [003]                 {Code} 'local.get	4'
2039  [003]                 {Code} 'i32.sub'
2040  [003]                 {Code} 'local.set	5'
2041  [003]                 {Code} 'local.get	5'
2042  [003]                 {Code} 'local.get	0'
2043  [003]                 {Code} 'i32.store	24'
2044  [003]                 {Code} 'local.get	5'
2045  [003]                 {Code} 'local.get	1'
2046  [003]                 {Code} 'i32.store	20'
2047  [003]                 {Code} 'local.get	2'
2048  [003]                 {Code} 'local.set	6'
2049  [003]                 {Code} 'local.get	5'
2050  [003]                 {Code} 'local.get	6'
2051  [003]                 {Code} 'i32.store8	19'
2052  [003]     3           {Line}
2053  [003]                 {Code} 'local.get	5'
2054  [003]                 {Code} 'i32.load8_u	19'
2055  [003]                 {Code} 'local.set	7'
2056  [003]     3           {Line}
2057  [003]                 {Code} 'i32.const	1'
2058  [003]                 {Code} 'local.set	8'
2059  [003]                 {Code} 'local.get	7'
2060  [003]                 {Code} 'local.get	8'
2061  [003]                 {Code} 'i32.and'
2062  [003]                 {Code} 'local.set	9'
2063  [003]                 {Code} 'block'
2064  [003]                 {Code} 'block'
2065  [003]                 {Code} 'local.get	9'
2066  [003]                 {Code} 'i32.eqz'
2067  [003]                 {Code} 'br_if   	0'
2068  [003]     8           {Line}
2069  [003]                 {Code} 'local.get	5'
2070  [003]                 {Code} 'i32.load	20'
2071  [003]                 {Code} 'local.set	12'
2072  [003]     8           {Line}
2073  [003]                 {Code} 'local.get	5'
2074  [003]                 {Code} 'local.get	12'
2075  [003]                 {Code} 'i32.store	28'
2076  [003]     -           {Line}
2077  [003]                 {Code} 'end'
2078  [003]     9           {Line}
2079  [003]                 {Code} 'local.get	5'
2080  [003]                 {Code} 'i32.load	28'
2081  [003]                 {Code} 'local.set	13'
2082  [003]                 {Code} 'local.get	13'
2083  [003]                 {Code} 'return'
2084  [003]                 {Code} 'end'
2085  [003]     9           {Line}
2086  [003]                 {Code} 'unreachable'
2087  [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
2088
2089SELECT LOGICAL ELEMENTS
2090^^^^^^^^^^^^^^^^^^^^^^^
2091The following prints all *instructions*, *symbols* and *types* that
2092contain **'block'** or **'.store'** in their names or types, using a tab
2093layout and given the number of matches.
2094
2095.. code-block:: none
2096
2097  llvm-debuginfo-analyzer --attribute=level
2098                          --select-nocase --select-regex
2099                          --select=BLOCK --select=.store
2100                          --report=list
2101                          --print=symbols,types,instructions,summary
2102                          test-clang.o
2103
2104  Logical View:
2105  [000]           {File} 'test-clang.o'
2106
2107  [001]           {CompileUnit} 'test.cpp'
2108  [003]           {Code} 'block'
2109  [003]           {Code} 'block'
2110  [004]           {Code} 'i32.store	12'
2111  [003]           {Code} 'i32.store	20'
2112  [003]           {Code} 'i32.store	24'
2113  [004]           {Code} 'i32.store	28'
2114  [003]           {Code} 'i32.store	28'
2115  [003]           {Code} 'i32.store8	19'
2116
2117  -----------------------------
2118  Element      Total    Printed
2119  -----------------------------
2120  Scopes           3          0
2121  Symbols          4          0
2122  Types            2          0
2123  Lines           62          8
2124  -----------------------------
2125  Total           71          8
2126
2127COMPARISON MODE
2128^^^^^^^^^^^^^^^
2129Given the previous example we found the above debug information issue
2130(related to the previous invalid scope location for the **'typedef int
2131INTEGER'**) by comparing against another compiler.
2132
2133Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern
2134with the printing mode to obtain the following logical view output.
2135
2136.. code-block:: none
2137
2138  llvm-debuginfo-analyzer --attribute=level
2139                          --select-regex --select-nocase --select=INTe
2140                          --report=list
2141                          --print=symbols,types
2142                          test-clang.o test-dwarf-gcc.o
2143
2144  Logical View:
2145  [000]           {File} 'test-clang.o'
2146
2147  [001]           {CompileUnit} 'test.cpp'
2148  [003]     4     {TypeAlias} 'INTEGER' -> 'int'
2149  [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
2150
2151  Logical View:
2152  [000]           {File} 'test-dwarf-gcc.o'
2153
2154  [001]           {CompileUnit} 'test.cpp'
2155  [004]     4     {TypeAlias} 'INTEGER' -> 'int'
2156  [004]     5     {Variable} 'CONSTANT' -> 'const INTEGER'
2157
2158The output shows that both objects contain the same elements. But the
2159**'typedef INTEGER'** is located at different scope level. The GCC
2160generated object, shows **'4'**, which is the correct value.
2161
2162There are 2 comparison methods: logical view and logical elements.
2163
2164LOGICAL VIEW
2165""""""""""""
2166It compares the logical view as a whole unit; for a match, each compared
2167logical element must have the same parents and children.
2168
2169The output shows in view form the **missing (-), added (+)** elements,
2170giving more context by swapping the reference and target object files.
2171
2172.. code-block:: none
2173
2174  llvm-debuginfo-analyzer --attribute=level
2175                          --compare=types
2176                          --report=view
2177                          --print=symbols,types
2178                          test-clang.o test-dwarf-gcc.o
2179
2180  Reference: 'test-clang.o'
2181  Target:    'test-dwarf-gcc.o'
2182
2183  Logical View:
2184   [000]           {File} 'test-clang.o'
2185
2186   [001]             {CompileUnit} 'test.cpp'
2187   [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
2188   [002]     2         {Function} extern not_inlined 'foo' -> 'int'
2189   [003]                 {Block}
2190   [004]     5             {Variable} 'CONSTANT' -> 'const INTEGER'
2191  +[004]     4             {TypeAlias} 'INTEGER' -> 'int'
2192   [003]     2           {Parameter} 'ParamBool' -> 'bool'
2193   [003]     2           {Parameter} 'ParamPtr' -> 'INTPTR'
2194   [003]     2           {Parameter} 'ParamUnsigned' -> 'unsigned int'
2195  -[003]     4           {TypeAlias} 'INTEGER' -> 'int'
2196
2197The output shows the merging view path (reference and target) with the
2198missing and added elements.
2199
2200LOGICAL ELEMENTS
2201""""""""""""""""
2202It compares individual logical elements without considering if their
2203parents are the same. For both comparison methods, the equal criteria
2204includes the name, source code location, type, lexical scope level.
2205
2206.. code-block:: none
2207
2208  llvm-debuginfo-analyzer --attribute=level
2209                          --compare=types
2210                          --report=list
2211                          --print=symbols,types,summary
2212                          test-clang.o test-dwarf-gcc.o
2213
2214  Reference: 'test-clang.o'
2215  Target:    'test-dwarf-gcc.o'
2216
2217  (1) Missing Types:
2218  -[003]     4     {TypeAlias} 'INTEGER' -> 'int'
2219
2220  (1) Added Types:
2221  +[004]     4     {TypeAlias} 'INTEGER' -> 'int'
2222
2223  ----------------------------------------
2224  Element   Expected    Missing      Added
2225  ----------------------------------------
2226  Scopes           4          0          0
2227  Symbols          0          0          0
2228  Types            2          1          1
2229  Lines            0          0          0
2230  ----------------------------------------
2231  Total            6          1          1
2232
2233Changing the *Reference* and *Target* order:
2234
2235.. code-block:: none
2236
2237  llvm-debuginfo-analyzer --attribute=level
2238                          --compare=types
2239                          --report=list
2240                          --print=symbols,types,summary
2241                          test-dwarf-gcc.o test-clang.o
2242
2243  Reference: 'test-dwarf-gcc.o'
2244  Target:    'test-clang.o'
2245
2246  (1) Missing Types:
2247  -[004]     4     {TypeAlias} 'INTEGER' -> 'int'
2248
2249  (1) Added Types:
2250  +[003]     4     {TypeAlias} 'INTEGER' -> 'int'
2251
2252  ----------------------------------------
2253  Element   Expected    Missing      Added
2254  ----------------------------------------
2255  Scopes           4          0          0
2256  Symbols          0          0          0
2257  Types            2          1          1
2258  Lines            0          0          0
2259  ----------------------------------------
2260  Total            6          1          1
2261
2262As the *Reference* and *Target* are switched, the *Added Types* from
2263the first case now are listed as *Missing Types*.
2264
2265EXIT STATUS
2266-----------
2267:program:`llvm-debuginfo-analyzer` returns 0 if the input files were
2268parsed and printed successfully. Otherwise, it returns 1.
2269
2270LIMITATIONS AND KNOWN ISSUES
2271----------------------------
2272See :download:`Limitations <../../tools/llvm-debuginfo-analyzer/README.md>`.
2273
2274SEE ALSO
2275--------
2276:manpage:`llvm-dwarfdump`
2277