Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
LLVM-DEBUGINFO-ANALYZER(1)	     LLVM	    LLVM-DEBUGINFO-ANALYZER(1)

NAME
       llvm-debuginfo-analyzer	-  Print a logical representation of low-level
       debug information.

        SYNOPSIS

        DESCRIPTION

        OPTIONS

	  GENERAL

	  ATTRIBUTES

	  PRINT

	  OUTPUT

	  REPORT

	  SELECTION

	    ELEMENTS

	    LINES

	    SCOPES

	    SYMBOLS

	    TYPES

	  COMPARE

	  WARNING

	  INTERNAL

        EXAMPLES

	  TEST	CASE 1 - GENERAL OPTIONS

	    PRINTING MODE

	      BASIC DETAILS

	      SELECT LOGICAL ELEMENTS

	    COMPARISON	MODE

	      LOGICAL VIEW

	      LOGICAL ELEMENTS

	  TEST	CASE 2 - ASSEMBLER INSTRUCTIONS

	    CodeView -	Clang (Windows)

	    CodeView -	MSVC (Windows)

	    DWARF - Clang (Linux)

	    DWARF - GCC (Linux)

	  TEST	CASE 3 - INCORRECT LEXICAL SCOPE FOR TYPEDEF

	    CodeView -	Clang (Windows)

	    CodeView -	MSVC (Windows)

	    DWARF - Clang (Linux)

	    DWARF - GCC (Linux)

	  TEST	CASE 4 - MISSING NESTED	ENUMERATIONS

	    CodeView -	Clang (Windows)

	    CodeView -	MSVC (Windows)

	    DWARF - Clang (Linux)

	    DWARF - GCC (Linux)

	  TEST	CASE 5 - INCORRECT LEXICAL SCOPE FOR VARIABLE

	    CODEVIEW -	Clang (Windows)

	    CODEVIEW -	MSVC (Windows)

	    DWARF - Clang (Linux)

	    DWARF - GCC (Linux)

	  TEST	CASE 6 - FULL LOGICAL VIEW

        EXIT STATUS

        SEE ALSO

SYNOPSIS
       llvm-debuginfo-analyzer [options] [filename ...]

DESCRIPTION
       llvm-debuginfo-analyzer parses debug and	text sections in binary	object
       files and prints	their contents in a logical view,  which  is  a	 human
       readable	representation that closely matches the	structure of the orig-
       inal  user  source  code.  Supported  object  file formats include ELF,
       Mach-O, PDB and COFF.

       The logical view	abstracts the complexity associated with the different
       low-level representations of the	debugging information that is embedded
       in the object file. llvm-debuginfo-analyzer produces a  canonical  view
       of  the	debug  information regardless of how it	is formatted. The same
       logical view will be seen regardless of object  file  format,  assuming
       the  debug  information	correctly  represents the same original	source
       code.

       The logical view	includes the following logical elements: type,	scope,
       symbol  and  line,  which  are  the basic software elements used	in the
       C/C++ programming language. Each	logical	element	has a set  of  attrib-
       utes,  such  as	types, classes,	functions, variables, parameters, etc.
       The --attribute can be used to specify which attributes to include when
       printing	a logical element. A logical element may have a	kind that  de-
       scribes	specific types of elements. For	instance, a scope could	have a
       kind value of function, class, namespace.

       llvm-debuginfo-analyzer defaults	to print a pre-defined layout of logi-
       cal elements and	attributes. The	command	line options can  be  used  to
       control	the  printed  elements	(--print),  using a specific layout (-
       --report), matching a given pattern (--select, --select-offsets). Also,
       the output can be  limited  to  specified  logical  elements  using  (-
       --select-lines, --select-scopes,	--select-symbols, --select-types).

       llvm-debuginfo-analyzer	can  also  compare  a  set of logical views (-
       --compare), to find differences and identify possible debug information
       syntax issues (--warning) in any	object file.

OPTIONS
       llvm-debuginfo-analyzer options are separated into several  categories,
       each tailored to	a different purpose:

	   GENERAL - Standard LLVM options to display help, version, etc.

	   ATTRIBUTES - Describe how to include different details when	print-
	    ing	an element.

	   PRINT  - Specify which elements will be included when printing the
	    view.

	   OUTPUT - Describe the supported formats when printing the view.

	   REPORT - Describe the format layouts for view printing.

	   SELECTION -	Allows to use specific criteria	or conditions  to  se-
	    lect which elements	to print.

	   COMPARE - Compare logical views and	print missing and/or added el-
	    ements.

	   WARNING  -	Print the warnings detected during the creation	of the
	    view.

	   INTERNAL - Internal	analysis of the	logical	view.

   GENERAL
       This section describes the standard help	options, used to  display  the
       usage, version, response	files, etc.

       -h, --help
	      Show help	and usage for this command. (--help-hidden for more).

       --help-list
	      Show  help  and  usage for this command without grouping the op-
	      tions into categories (--help-list-hidden	for more).

       --help-hidden
	      Display all available options.

       --print-all-options
	      Print all	option values after command line parsing.

       --print-options
	      Print non-default	options	after command line parsing

       --version
	      Display the version of the tool.

       @<FILE>
	      Read command-line	options	from <FILE>.

       If no input file	is specified, llvm-debuginfo-analyzer defaults to read
       a.out and return	an error when no input file is found.

       If - is used as the input file, llvm-debuginfo-analyzer reads the input
       from its	standard input stream.

   ATTRIBUTES
       The following options enable attributes given for the printed elements.
       The attributes are divided in categories	based on the type of data  be-
       ing  added,  such as: internal offsets in the binary file, location de-
       scriptors, register names, user source  filenames,  additional  element
       transformations,	toolchain name,	binary file format, etc.

       --attribute=<value[,value,...]>
	      With value being one of the options in the following lists.

		 =all: Include all the below attributes.
		 =extended: Add	low-level attributes.
		 =standard: Add	standard high-level attributes.

	      The  following  attributes  describe the most common information
	      for a logical element. They help to identify the	lexical	 scope
	      level;  the  element  visibility across modules (global, local);
	      the toolchain name that produced the binary file.

		 =global: Element referenced across Compile Units.
		 =format: Object file format name.
		 =level: Lexical scope level (File=0, Compile Unit=1).
		 =local: Element referenced only in the	Compile	Unit.
		 =producer: Toolchain identification name.

	      The following attributes describe	files and directory names from
	      the user source code, where the elements	are  declared  or  de-
	      fined;  functions	 with  public visibility across	modules. These
	      options allow to map the elements	to their user  code  location,
	      for cross	references purposes.

		 =directories: Directories referenced in the debug information.
		 =filename: Filename where the element is defined.
		 =files: Files referenced in the debug information.
		 =pathname: Pathname where the object is defined.
		 =publics: Function names that are public.

	      The  following  attributes  describe  additional logical element
	      source transformations, in order to display built-in types (int,
	      bool, etc.); parameters and arguments used during	 template  in-
	      stantiation;  parent  name  hierarchy; array dimensions informa-
	      tion; compiler generated elements	and the	underlying types asso-
	      ciated with the types aliases.

		 =argument: Template parameters	replaced by its	arguments.
		 =base:	Base types (int, bool, etc.).
		 =generated: Compiler generated	elements.
		 =encoded: Template arguments encoded in the template name.
		 =qualified: The element type include parents in its name.
		 =reference: Element declaration and definition	references.
		 =subrange: Subrange encoding information for arrays.
		 =typename: Template parameters.
		 =underlying: Underlying type for type definitions.

	      The following attributes describe	the debug location information
	      for a symbol or scope. It	includes the symbol percentage	cover-
	      age  and any gaps	within the location layout; ranges determining
	      the code sections	attached to a function.	When  descriptors  are
	      used, the	target processor registers are displayed.

		 =coverage: Symbol location coverage.
		 =gaps:	Missing	debug location (gaps).
		 =location: Symbol debug location.
		 =range: Debug location	ranges.
		 =register: Processor register names.

	      The  following attributes	are associated with low	level details,
	      such as: offsets in the binary file; discriminators added	to the
	      lines of inlined functions in order to distinguish specific  in-
	      stances; debug lines state machine registers; elements discarded
	      by  the  compiler	 (inlining)  or	 by  the  linker optimizations
	      (dead-stripping);	system compile units generated by the MS tool-
	      chain in PDBs.

		 =discarded: Discarded elements	by the linker.
		 =discriminator: Discriminators	for inlined function instances.
		 =inserted: Generated inlined abstract references.
		 =linkage: Object file linkage name.
		 =offset: Debug	information offset.
		 =qualifier: Line qualifiers (Newstatement, BasicBlock,	etc).
		 =zero:	Zero line numbers.

	      The following attribute described	specific information  for  the
	      PE/COFF file format. It includes MS runtime types.

		 =system: Display PDB's	MS system elements.

	      The above	attributes are grouped into standard and extended cat-
	      egories that can be enabled.

	      The  standard  group,  contains those attributes that add	suffi-
	      cient information	to describe a logical  element	and  that  can
	      cover  the  normal  situations while dealing with	debug informa-
	      tion.

		 =base
		 =coverage
		 =directories
		 =discriminator
		 =filename
		 =files
		 =format
		 =level
		 =producer
		 =publics
		 =range
		 =reference
		 =zero

	      The extended group, contains those  attributes  that  require  a
	      more  extended  knowledge	 about debug information. They are in-
	      tended when a lower level	of detail is required.

		 =argument
		 =discarded
		 =encoded
		 =gaps
		 =generated
		 =global
		 =inserted
		 =linkage
		 =local
		 =location
		 =offset
		 =operation
		 =pathname
		 =qualified
		 =qualifier
		 =register
		 =subrange
		 =system
		 =typename

   PRINT
       The following options describe the elements to print. The  layout  used
       is  determined  by  the	--report. In the tree layout, all the elements
       have their enclosing lexical scopes printed, even when  not  explicitly
       specified.

       --print=<value[,value,...]>
	      With value being one of the options in the following lists.

		 =all: Include all the below attributes.

	      The  following options print the requested elements; in the case
	      of any given select conditions (--select), only  those  elements
	      that match them, will be printed.	The elements value is a	conve-
	      nient  way  to  specify instructions, lines, scopes, symbols and
	      types all	at once.

		 =elements: Instructions, lines, scopes, symbols and types.
		 =instructions:	Assembler instructions for code	sections.
		 =lines: Source	lines referenced in the	debug information.
		 =scopes: Lexical blocks (function, class, namespace, etc).
		 =symbols: Symbols (variable, member, parameter, etc).
		 =types: Types (pointer, reference, type alias,	etc).

	      The following options print information,	collected  during  the
	      creation	of  the	 elements, such	as: scope contributions	to the
	      debug information;  summary  of  elements	 created,  printed  or
	      matched (--select); warnings produced during the view creation.

		 =sizes: Debug Information scopes contributions.
		 =summary: Summary of elements allocated, selected or printed.
		 =warnings: Warnings detected.

	      Note: The	--print=sizes option is	ELF specific.

   OUTPUT
       The following options describe how to control the output	generated when
       printing	the logical elements.

       --output-file=<path>
	      Redirect	the  output  to	a file specified by <path>, where - is
	      the standard output stream.

       llvm-debuginfo-analyzer has the concept of split	view.  When  redirect-
       ing  the	 output	from a complex binary format, it is divided into indi-
       vidual files, each one containing the logical view output for a	single
       compilation unit.

       --output-folder=<name>
	      The  folder  to  write  a	 file per compilation unit when	--out-
	      put=split	is specified.

       --output-level=<level>
	      Only print elements up to	the given lexical level	value. The in-
	      put file is at lexical level zero	and a compilation unit	is  at
	      lexical level one.

       --output=<value[,value,...]>
	      With value being one of the options in the following lists.

		 =all: Include all the below outputs.

		 =json:	Use JSON as the	output format (Not implemented).
		 =split: Split the output by Compile Units.
		 =text:	Use a free form	text output.

       --output-sort=<key>
	      Primary  key  when ordering the elements in the output (default:
	      line).  Sorting by logical element kind, requires	be familiarity
	      with  the	 element  kind	selection   options   (--select-lines,
	      --select-scopes, --select-symbols, --select-types), as those op-
	      tions describe the different logical element kinds.

		 =kind:	Sort by	element	kind.
		 =line:	Sort by	element	line number.
		 =name:	Sort by	element	name.
		 =offset: Sort by element offset.

   REPORT
       Depending  on the task being executed (print, compare, select), several
       layouts are supported to	display	the elements in	a more	suitable  way,
       to make the output easier to understand.

       --report=<value[,value,...]>
	      With value being one of the options in the following list.

		 =all: Include all the below reports.

		 =children: Elements and children are displayed	in a tree format.
		 =list:	Elements are displayed in a tabular format.
		 =parents: Elements and	parents	are displayed in a tree	format.
		 =view:	Elements, parents and children are displayed in	a tree format.

       The list	layout presents	the logical elements in	a tabular form without
       any parent-child	relationship. This may be the preferred	way to display
       elements	 that  match specific conditions when comparing	logical	views,
       making it easier	to find	differences.

       The children, parents and view layout displays the elements in  a  tree
       format,	with  the scopes representing their nodes, and types, symbols,
       lines and other scopes representing the children. The layout shows  the
       lexical scoping relationship between elements, with the binary file be-
       ing  the	 tree  root  (level 0) and each	compilation unit being a child
       (level 1).

       The children layout includes the	elements that match any	given criteria
       (--select) or (--compare) and its children.

       The parents layout includes the elements	that match any given  criteria
       (--select) or (--compare) and its parents.

       The  combined  view  layout  includes the elements that match any given
       criteria	(--select) or (--compare), its parents and children.

       Notes:

       1. When a selection criteria (--select) is specified with no report op-
	  tion,	the list layout	is selected.

       2. The comparison mode always uses the view layout.

   SELECTION
       When printing an	element, different data	can be included	and it	varies
       (--attribute)  from data	directly associated with the binary file (off-
       set) to high level details such as coverage, lexical scope level, loca-
       tion. As	the printed output can reach a considerable size, several  se-
       lection options,	enable printing	of specific elements.

       The  pattern  matching can ignore the case (--select-nocase) and	be ex-
       tended to use regular expressions (--select-regex).

   ELEMENTS
       The following options allow printing of elements	that match  the	 given
       <pattern>, offset <value> or an element <condition>.

       --select=<pattern>
	      Print  all  elements whose name or line number matches the given
	      <pattern>.

       --select-offsets=<value[,value,...]>
	      Print all	elements whose offset matches the  given  values.  See
	      --attribute option.

       --select-elements=<condition[,condition,...]>
	      Print all	elements that satisfy the given	<condition>. With con-
	      dition being one of the options in the following list.

		 =discarded: Discarded elements	by the linker.
		 =global: Element referenced across Compile Units.
		 =optimized: Optimized inlined abstract	references.

       --select-nocase
	      Pattern matching is case-insensitive when	using --select.

       --select-regex
	      Treat  any <pattern> strings as regular expressions when select-
	      ing with --select	option.	If --select-nocase is  specified,  the
	      regular expression becomes case-insensitive.

       If  the	<pattern> criteria is too general, a more selective option can
       be specified to target a	particular  category  of  elements:  lines  (-
       --select-lines),	 scopes	 (--select-scopes), symbols (--select-symbols)
       and types (--select-types).  These options require knowledge of the de-
       bug information format (DWARF, CodeView,	COFF), as the given  kind  de-
       scribes a very specific type of element.

   LINES
       The  following  options	allow  printing	 of lines that match the given
       <kind>.	The given criteria describes the debug line state machine reg-
       isters.

       --select-lines=<kind[,kind,...]>
	      With kind	being one of the options in the	following list.

		 =AlwaysStepInto: marks	an always step into.
		 =BasicBlock: Marks a new basic	block.
		 =Discriminator: Line that has a discriminator.
		 =EndSequence: Marks the end in	the sequence of	lines.
		 =EpilogueBegin: Marks the start of a function epilogue.
		 =LineDebug: Lines that	correspond to debug lines.
		 =LineAssembler: Lines that correspond to disassembly text.
		 =NeverStepInto: marks a never step into.
		 =NewStatement:	Marks a	new statement.
		 =PrologueEnd: Marks the end of	a function prologue.

   SCOPES
       The following options allow printing of scopes  that  match  the	 given
       <kind>.

       --select-scopes=<kind[,kind,...]>
	      With kind	being one of the options in the	following list.

		 =Aggregate: A class, structure	or union.
		 =Array: An array.
		 =Block: A generic block (lexical block	or exception block).
		 =CallSite: A call site.
		 =CatchBlock: An exception block.
		 =Class: A class.
		 =CompileUnit: A compile unit.
		 =EntryPoint: A	subroutine entry point.
		 =Enumeration: An enumeration.
		 =Function: A function.
		 =FunctionType:	A function pointer.
		 =InlinedFunction: An inlined function.
		 =Label: A label.
		 =LexicalBlock:	A lexical block.
		 =Namespace: A namespace.
		 =Root:	The element representing the main scope.
		 =Structure: A structure.
		 =Subprogram: A	subprogram.
		 =Template: A template definition.
		 =TemplateAlias: A template alias.
		 =TemplatePack:	A template pack.
		 =TryBlock: An exception try block.
		 =Union: A union.

   SYMBOLS
       The  following  options	allow printing of symbols that match the given
       <kind>.

       --select-symbols=<kind[,kind,...]>
	      With kind	being one of the options in the	following list.

		 =CallSiteParameter: A call site parameter.
		 =Constant: A constant symbol.
		 =Inheritance: A base class.
		 =Member: A member class.
		 =Parameter: A parameter to function.
		 =Unspecified: Unspecified parameters to function.
		 =Variable: A variable.

   TYPES
       The following options allow printing of	types  that  match  the	 given
       <kind>.

       --select-types=<kind[,kind,...]>
	      With kind	being one of the options in the	following list.

		 =Base:	Base type (integer, boolean, etc).
		 =Const: Constant specifier.
		 =Enumerator: Enumerator.
		 =Import: Import declaration.
		 =ImportDeclaration: Import declaration.
		 =ImportModule:	Import module.
		 =Pointer: Pointer type.
		 =PointerMember: Pointer to member function.
		 =Reference: Reference type.
		 =Restrict: Restrict specifier.
		 =RvalueReference: R-value reference.
		 =Subrange: Array subrange.
		 =TemplateParam: Template parameter.
		 =TemplateTemplateParam: Template template parameter.
		 =TemplateTypeParam: Template type parameter.
		 =TemplateValueParam: Template value parameter.
		 =Typedef: Type	definition.
		 =Unspecified: Unspecified type.
		 =Volatile: Volatile specifier.

   COMPARE
       When  dealing  with  debug  information,	 there are situations when the
       printing	of the elements	is not the correct approach. That is the case,
       when we are interested in the effects caused by different  versions  of
       the same	toolchain, or the impact of specific compiler optimizations.

       For  those  cases, we are looking to see	which elements have been added
       or removed. Due to the complicated debug	information format, it is very
       difficult to use	a regular diff tool to find those elements;  even  im-
       possible	when dealing with different debug formats.

       llvm-debuginfo-analyzer supports	a logical element comparison, allowing
       to find semantic	differences between logical views, produced by differ-
       ent toolchain versions or even debug information	formats.

       When  comparing logical views created from different debug formats, its
       accuracy	depends	on how close the debug information represents the user
       code. For instance, a logical view created  from	 a  binary  file  with
       DWARF  debug  information may include more detailed data	than a logical
       view created from a binary file with CodeView/COFF debug	information.

       The following options describe the elements to compare.

       --compare=<value[,value,...]>
	      With value being one of the options in the following list.

		 =all: Include all the below elements.

		 =lines: Include lines.
		 =scopes: Include scopes.
		 =symbols: Include symbols.
		 =types: Include types.

       llvm-debuginfo-analyzer takes the first binary file on the command line
       as the reference	and the	second one as the target.  To get a  more  de-
       scriptive  report, the comparison is done twice.	The reference and tar-
       get views are swapped, in order to produce those	missing	elements  from
       the target view and those added elements	to the reference view.

       See --report options on how to describe the comparison reports.

   WARNING
       When reading the	input object files, llvm-debuginfo-analyzer can	detect
       issues  in the raw debug	information. These may not be considered fatal
       to the purpose of printing a logical view but they can give an  indica-
       tion about the quality and potentially expose issues with the generated
       debug information.

       The  following  options	describe the warnings to be recorded for later
       printing, if they are requested by --print.

       --warning=<value[,value,...]>
	      With value being one of the options in the following list.

		 =all: Include all the below warnings.

	      The following options collect additional information during  the
	      creation of the logical view, to include invalid coverage	values
	      and  locations  for symbols; invalid code	ranges;	lines that are
	      zero.

		 =coverages: Invalid symbol coverages values.
		 =lines: Debug lines that are zero.
		 =locations: Invalid symbol locations.
		 =ranges: Invalid code ranges.

   INTERNAL
	  For a	better understanding of	the logical view, access to  more  de-
	  tailed internal information could be needed. Such data would help to
	  identify  debug  information	processed or incorrect logical element
	  management.  Typically these kind of options are available  only  in
	  debug	builds.

	  llvm-debuginfo-analyzer  supports these advanced options in both re-
	  lease	and debug builds, with the exception of	the unique ID that  is
	  generated only in debug builds.

       --internal=<value[,value,...]>
	      With value being one of the options in the following list.

		 =all: Include all the below options.

	      The  following options allow to check the	integrity of the logi-
	      cal view;	collect	the debug tags that are	processed or  not  im-
	      plemented; ignore	the logical element line number, to facilitate
	      the  logical  view  comparison  when  using  external comparison
	      tools; print the command line options used to invoke llvm-debug-
	      info-analyzer.

		 =id: Print unique element ID.
		 =cmdline: Print command line.
		 =integrity: Check elements integrity.
		 =none:	Ignore element line number.
		 =tag: Debug information tags.

	      Note: For	ELF format, the	collected  tags	 represent  the	 debug
	      tags  that are not processed. For	PE/COFF	format,	they represent
	      the tags that are	processed.

EXAMPLES
       This section includes some  real	 binary	 files	to  show  how  to  use
       llvm-debuginfo-analyzer	to print a logical view	and to diagnose	possi-
       ble debug information issues.

   TEST	CASE 1 - GENERAL OPTIONS
       The below example  is  used  to	show  different	 output	 generated  by
       llvm-debuginfo-analyzer.	 We compiled the example for an	X86 ELF	target
       with Clang (-O0 -g):

	  1  using INTPTR = const int *;
	  2  int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {
	  3    if (ParamBool) {
	  4	 typedef int INTEGER;
	  5	 const INTEGER CONSTANT	= 7;
	  6	 return	CONSTANT;
	  7    }
	  8    return ParamUnsigned;
	  9  }

   PRINTING MODE
       In this mode llvm-debuginfo-analyzer prints the logical	view  or  por-
       tions of	it, based on criteria patterns (including regular expressions)
       to select the kind of logical elements to be included in	the output.

   BASIC DETAILS
       The following command prints basic details for all the logical elements
       sorted  by the debug information	internal offset; it includes its lexi-
       cal level and debug info	format.

	  llvm-debuginfo-analyzer --attribute=level,format
				  --output-sort=offset
				  --print=scopes,symbols,types,lines,instructions
				  test-dwarf-clang.o

       or

	  llvm-debuginfo-analyzer --attribute=level,format
				  --output-sort=offset
				  --print=elements
				  test-dwarf-clang.o

       Each row	represents an element that is present within the debug	infor-
       mation.	The  first  column represents the scope	level, followed	by the
       associated line number (if any),	and finally the	description of the el-
       ement.

	  Logical View:
	  [000]		  {File} 'test-dwarf-clang.o' -> elf64-x86-64

	  [001]		    {CompileUnit} 'test.cpp'
	  [002]	    2	      {Function} extern	not_inlined 'foo' -> 'int'
	  [003]	    2		{Parameter} 'ParamPtr' -> 'INTPTR'
	  [003]	    2		{Parameter} 'ParamUnsigned' -> 'unsigned int'
	  [003]	    2		{Parameter} 'ParamBool'	-> 'bool'
	  [003]			{Block}
	  [004]	    5		  {Variable} 'CONSTANT'	-> 'const INTEGER'
	  [004]	    5		  {Line}
	  [004]			  {Code} 'movl	$0x7, -0x1c(%rbp)'
	  [004]	    6		  {Line}
	  [004]			  {Code} 'movl	$0x7, -0x4(%rbp)'
	  [004]			  {Code} 'jmp	0x6'
	  [004]	    8		  {Line}
	  [004]			  {Code} 'movl	-0x14(%rbp), %eax'
	  [003]	    4		{TypeAlias} 'INTEGER' -> 'int'
	  [003]	    2		{Line}
	  [003]			{Code} 'pushq	%rbp'
	  [003]			{Code} 'movq	%rsp, %rbp'
	  [003]			{Code} 'movb	%dl, %al'
	  [003]			{Code} 'movq	%rdi, -0x10(%rbp)'
	  [003]			{Code} 'movl	%esi, -0x14(%rbp)'
	  [003]			{Code} 'andb	$0x1, %al'
	  [003]			{Code} 'movb	%al, -0x15(%rbp)'
	  [003]	    3		{Line}
	  [003]			{Code} 'testb	$0x1, -0x15(%rbp)'
	  [003]			{Code} 'je	0x13'
	  [003]	    8		{Line}
	  [003]			{Code} 'movl	%eax, -0x4(%rbp)'
	  [003]	    9		{Line}
	  [003]			{Code} 'movl	-0x4(%rbp), %eax'
	  [003]			{Code} 'popq	%rbp'
	  [003]			{Code} 'retq'
	  [003]	    9		{Line}
	  [002]	    1	      {TypeAlias} 'INTPTR' -> '* const int'

       On closer inspection, we	can see	what could be a	potential debug	issue:

	  [003]			{Block}
	  [003]	    4		{TypeAlias} 'INTEGER' -> 'int'

       The 'INTEGER' definition	is at level [003], the same lexical  scope  as
       the anonymous {Block} ('true' branch for	the 'if' statement) whereas in
       the  original  source code the typedef statement	is clearly inside that
       block, so the 'INTEGER' definition should also be at level [004]	inside
       the block.

   SELECT LOGICAL ELEMENTS
       The following prints all	instructions, symbols and types	 that  contain
       'inte'  or 'movl' in their names	or types, using	a tab layout and given
       the number of matches.

	  llvm-debuginfo-analyzer --attribute=level
				  --select-nocase --select-regex
				  --select=INTe	--select=movl
				  --report=list
				  --print=symbols,types,instructions,summary
				  test-dwarf-clang.o

	  Logical View:
	  [000]		  {File} 'test-dwarf-clang.o'

	  [001]		  {CompileUnit}	'test.cpp'
	  [003]		  {Code} 'movl	$0x7, -0x1c(%rbp)'
	  [003]		  {Code} 'movl	$0x7, -0x4(%rbp)'
	  [003]		  {Code} 'movl	%eax, -0x4(%rbp)'
	  [003]		  {Code} 'movl	%esi, -0x14(%rbp)'
	  [003]		  {Code} 'movl	-0x14(%rbp), %eax'
	  [003]		  {Code} 'movl	-0x4(%rbp), %eax'
	  [003]	    4	  {TypeAlias} 'INTEGER'	-> 'int'
	  [004]	    5	  {Variable} 'CONSTANT'	-> 'const INTEGER'

	  -----------------------------
	  Element      Total	  Found
	  -----------------------------
	  Scopes	   3	      0
	  Symbols	   4	      1
	  Types		   2	      1
	  Lines		  17	      6
	  -----------------------------
	  Total		  26	      8

   COMPARISON MODE
       In this mode llvm-debuginfo-analyzer compares logical views to  produce
       a  report  with the logical elements that are missing or	added.	This a
       very powerful aid in finding semantic differences in the	debug informa-
       tion produced by	different toolchain versions or	even  completely  dif-
       ferent  toolchains  altogether  (For example a compiler producing DWARF
       can be directly compared	against	a completely different	compiler  that
       produces	CodeView).

       Given  the  previous example we found the above debug information issue
       (related	to the previous	invalid	scope location for  the	 'typedef  int
       INTEGER') by comparing against another compiler.

       Using  GCC  to generate test-dwarf-gcc.o, we can	apply a	selection pat-
       tern with the printing mode to obtain the following logical  view  out-
       put.

	  llvm-debuginfo-analyzer --attribute=level
				  --select-regex --select-nocase --select=INTe
				  --report=list
				  --print=symbols,types
				  test-dwarf-clang.o test-dwarf-gcc.o

	  Logical View:
	  [000]		  {File} 'test-dwarf-clang.o'

	  [001]		  {CompileUnit}	'test.cpp'
	  [003]	    4	  {TypeAlias} 'INTEGER'	-> 'int'
	  [004]	    5	  {Variable} 'CONSTANT'	-> 'const INTEGER'

	  Logical View:
	  [000]		  {File} 'test-dwarf-gcc.o'

	  [001]		  {CompileUnit}	'test.cpp'
	  [004]	    4	  {TypeAlias} 'INTEGER'	-> 'int'
	  [004]	    5	  {Variable} 'CONSTANT'	-> 'const INTEGER'

       The  output  shows that both objects contain the	same elements. But the
       'typedef	INTEGER' is located at different scope level. The  GCC	gener-
       ated object, shows '4', which is	the correct value.

       Note  that  there  is no	requirement that GCC must produce identical or
       similar DWARF to	Clang to allow the comparison.	We're  only  comparing
       the  semantics. The same	case when comparing CodeView debug information
       generated by MSVC and Clang.

       There are 2 comparison methods: logical view and	logical	elements.

   LOGICAL VIEW
       It compares the logical view as a whole unit; for a  match,  each  com-
       pared logical element must have the same	parents	and children.

       Using  the llvm-debuginfo-analyzer comparison functionality, that issue
       can be seen in a	more global context,  that  can	 include  the  logical
       view.

       The output shows	in view	form the missing (-), added (+)	elements, giv-
       ing more	context	by swapping the	reference and target object files.

	  llvm-debuginfo-analyzer --attribute=level
				  --compare=types
				  --report=view
				  --print=symbols,types
				  test-dwarf-clang.o test-dwarf-gcc.o

	  Reference: 'test-dwarf-clang.o'
	  Target:    'test-dwarf-gcc.o'

	  Logical View:
	   [000]	   {File} 'test-dwarf-clang.o'

	   [001]	     {CompileUnit} 'test.cpp'
	   [002]     1	       {TypeAlias} 'INTPTR' -> '* const	int'
	   [002]     2	       {Function} extern not_inlined 'foo' -> 'int'
	   [003]		 {Block}
	   [004]     5		   {Variable} 'CONSTANT' -> 'const INTEGER'
	  +[004]     4		   {TypeAlias} 'INTEGER' -> 'int'
	   [003]     2		 {Parameter} 'ParamBool' -> 'bool'
	   [003]     2		 {Parameter} 'ParamPtr'	-> 'INTPTR'
	   [003]     2		 {Parameter} 'ParamUnsigned' ->	'unsigned int'
	  -[003]     4		 {TypeAlias} 'INTEGER' -> 'int'

       The  output shows the merging view path (reference and target) with the
       missing and added elements.

   LOGICAL ELEMENTS
       It compares individual logical elements without	considering  if	 their
       parents	are  the same. For both	comparison methods, the	equal criteria
       includes	the name, source code location,	type, lexical scope level.

	  llvm-debuginfo-analyzer --attribute=level
				  --compare=types
				  --report=list
				  --print=symbols,types,summary
				  test-dwarf-clang.o test-dwarf-gcc.o

	  Reference: 'test-dwarf-clang.o'
	  Target:    'test-dwarf-gcc.o'

	  (1) Missing Types:
	  -[003]     4	   {TypeAlias} 'INTEGER' -> 'int'

	  (1) Added Types:
	  +[004]     4	   {TypeAlias} 'INTEGER' -> 'int'

	  ----------------------------------------
	  Element   Expected	Missing	     Added
	  ----------------------------------------
	  Scopes	   4	      0		 0
	  Symbols	   0	      0		 0
	  Types		   2	      1		 1
	  Lines		   0	      0		 0
	  ----------------------------------------
	  Total		   6	      1		 1

       Changing	the Reference and Target order:

	  llvm-debuginfo-analyzer --attribute=level
				  --compare=types
				  --report=list
				  --print=symbols,types,summary
				  test-dwarf-gcc.o test-dwarf-clang.o

	  Reference: 'test-dwarf-gcc.o'
	  Target:    'test-dwarf-clang.o'

	  (1) Missing Types:
	  -[004]     4	   {TypeAlias} 'INTEGER' -> 'int'

	  (1) Added Types:
	  +[003]     4	   {TypeAlias} 'INTEGER' -> 'int'

	  ----------------------------------------
	  Element   Expected	Missing	     Added
	  ----------------------------------------
	  Scopes	   4	      0		 0
	  Symbols	   0	      0		 0
	  Types		   2	      1		 1
	  Lines		   0	      0		 0
	  ----------------------------------------
	  Total		   6	      1		 1

       As the Reference	and Target are switched,  the  Added  Types  from  the
       first case now are listed as Missing Types.

   TEST	CASE 2 - ASSEMBLER INSTRUCTIONS
       The  below  example  is	used  to  show	different  output generated by
       llvm-debuginfo-analyzer.	We compiled the	example	for  an	 X86  Codeview
       and  ELF	 targets  with recent versions of Clang, GCC and MSVC (-O0 -g)
       for Windows and Linux.

	  1  extern int	printf(const char * format, ...	);
	  2
	  3  int main()
	  4  {
	  5    printf("Hello, World\n");
	  6    return 0;
	  7  }

       These are the logical views that	llvm-debuginfo-analyzer	generates  for
       3  different  compilers (MSVC, Clang and	GCC), emitting different debug
       information formats (CodeView, DWARF) on	Windows	and Linux.

	  llvm-debuginfo-analyzer --attribute=level,format,producer
				  --print=lines,instructions
				  hello-world-codeview-clang.o
				  hello-world-codeview-msvc.o
				  hello-world-dwarf-clang.o
				  hello-world-dwarf-gcc.o

   CodeView - Clang (Windows)
	  Logical View:
	  [000]		  {File} 'hello-world-codeview-clang.o'	-> COFF-x86-64

	  [001]		    {CompileUnit} 'hello-world.cpp'
	  [002]		      {Producer} 'clang	version	14.0.0'
	  [002]		      {Function} extern	not_inlined 'main' -> 'int'
	  [003]	    4		{Line}
	  [003]			{Code} 'subq	$0x28, %rsp'
	  [003]			{Code} 'movl	$0x0, 0x24(%rsp)'
	  [003]	    5		{Line}
	  [003]			{Code} 'leaq	(%rip),	%rcx'
	  [003]			{Code} 'callq	0x0'
	  [003]	    6		{Line}
	  [003]			{Code} 'xorl	%eax, %eax'
	  [003]			{Code} 'addq	$0x28, %rsp'
	  [003]			{Code} 'retq'

   CodeView - MSVC (Windows)
	  Logical View:
	  [000]		  {File} 'hello-world-codeview-msvc.o' -> COFF-i386

	  [001]		    {CompileUnit} 'hello-world.cpp'
	  [002]		      {Producer} 'Microsoft (R)	Optimizing Compiler'
	  [002]		      {Function} extern	not_inlined 'main' -> 'int'
	  [003]	    4		{Line}
	  [003]			{Code} 'pushl	%ebp'
	  [003]			{Code} 'movl	%esp, %ebp'
	  [003]	    5		{Line}
	  [003]			{Code} 'pushl	$0x0'
	  [003]			{Code} 'calll	0x0'
	  [003]			{Code} 'addl	$0x4, %esp'
	  [003]	    6		{Line}
	  [003]			{Code} 'xorl	%eax, %eax'
	  [003]	    7		{Line}
	  [003]			{Code} 'popl	%ebp'
	  [003]			{Code} 'retl'

   DWARF - Clang (Linux)
	  Logical View:
	  [000]		  {File} 'hello-world-dwarf-clang.o' ->	elf64-x86-64

	  [001]		    {CompileUnit} 'hello-world.cpp'
	  [002]		      {Producer} 'clang	version	14.0.0'
	  [002]	    3	      {Function} extern	not_inlined 'main' -> 'int'
	  [003]	    4		{Line}
	  [003]			{Code} 'pushq	%rbp'
	  [003]			{Code} 'movq	%rsp, %rbp'
	  [003]			{Code} 'subq	$0x10, %rsp'
	  [003]			{Code} 'movl	$0x0, -0x4(%rbp)'
	  [003]	    5		{Line}
	  [003]			{Code} 'movabsq	$0x0, %rdi'
	  [003]			{Code} 'movb	$0x0, %al'
	  [003]			{Code} 'callq	0x0'
	  [003]	    6		{Line}
	  [003]			{Code} 'xorl	%eax, %eax'
	  [003]			{Code} 'addq	$0x10, %rsp'
	  [003]			{Code} 'popq	%rbp'
	  [003]			{Code} 'retq'
	  [003]	    6		{Line}

   DWARF - GCC (Linux)
	  Logical View:
	  [000]		  {File} 'hello-world-dwarf-gcc.o' -> elf64-x86-64

	  [001]		    {CompileUnit} 'hello-world.cpp'
	  [002]		      {Producer} 'GNU C++14 9.3.0'
	  [002]	    3	      {Function} extern	not_inlined 'main' -> 'int'
	  [003]	    4		{Line}
	  [003]			{Code} 'endbr64'
	  [003]			{Code} 'pushq	%rbp'
	  [003]			{Code} 'movq	%rsp, %rbp'
	  [003]	    5		{Line}
	  [003]			{Code} 'leaq	(%rip),	%rdi'
	  [003]			{Code} 'movl	$0x0, %eax'
	  [003]			{Code} 'callq	0x0'
	  [003]	    6		{Line}
	  [003]			{Code} 'movl	$0x0, %eax'
	  [003]	    7		{Line}
	  [003]			{Code} 'popq	%rbp'
	  [003]			{Code} 'retq'
	  [003]	    7		{Line}

       The logical views shows the intermixed  lines  and  assembler  instruc-
       tions,  allowing	 to  compare the code generated	by the different tool-
       chains.

   TEST	CASE 3 - INCORRECT LEXICAL SCOPE FOR TYPEDEF
       The below example  is  used  to	show  different	 output	 generated  by
       llvm-debuginfo-analyzer.	 We  compiled  the example for an X86 Codeview
       and ELF targets with recent versions of Clang, GCC and MSVC (-O0	-g).

	   1  int bar(float Input) { return (int)Input;	}
	   2
	   3  unsigned foo(char	Param) {
	   4	typedef	int INT;		// ** Definition for INT **
	   5	INT Value = Param;
	   6	{
	   7	  typedef float	FLOAT;		// ** Definition for FLOAT **
	   8	  {
	   9	    FLOAT Added	= Value	+ Param;
	  10	    Value = bar(Added);
	  11	  }
	  12	}
	  13	return Value + Param;
	  14  }

       The above test is used to illustrate a scope issue found	in  the	 Clang
       compiler: PR44884 (Bugs LLVM) / PR44229 (GitHub LLVM)

       The  lines  4  and  7 contains 2	typedefs, defined at different lexical
       scopes.

	  4    typedef int INT;
	  7	 typedef float FLOAT;

       These are the logical views that	llvm-debuginfo-analyzer	generates  for
       3  different  compilers (MSVC, Clang and	GCC), emitting different debug
       information formats (CodeView, DWARF) on	different platforms.

	  llvm-debuginfo-analyzer --attribute=level,format,producer
				  --print=symbols,types,lines
				  --output-sort=kind
				  pr-44884-codeview-clang.o
				  pr-44884-codeview-msvc.o
				  pr-44884-dwarf-clang.o
				  pr-44884-dwarf-gcc.o

   CodeView - Clang (Windows)
	  Logical View:
	  [000]		  {File} 'pr-44884-codeview-clang.o' ->	COFF-x86-64

	  [001]		    {CompileUnit} 'pr-44884.cpp'
	  [002]		      {Producer} 'clang	version	14.0.0'
	  [002]		      {Function} extern	not_inlined 'bar' -> 'int'
	  [003]			{Parameter} 'Input' -> 'float'
	  [003]	    1		{Line}
	  [002]		      {Function} extern	not_inlined 'foo' -> 'unsigned'
	  [003]			{Block}
	  [004]			  {Variable} 'Added' ->	'float'
	  [004]	    9		  {Line}
	  [004]	   10		  {Line}
	  [003]			{Parameter} 'Param' -> 'char'
	  [003]			{TypeAlias} 'FLOAT' -> 'float'
	  [003]			{TypeAlias} 'INT' -> 'int'
	  [003]			{Variable} 'Value' -> 'int'
	  [003]	    3		{Line}
	  [003]	    5		{Line}
	  [003]	   13		{Line}

   CodeView - MSVC (Windows)
	  Logical View:
	  [000]		  {File} 'pr-44884-codeview-msvc.o' -> COFF-i386

	  [001]		    {CompileUnit} 'pr-44884.cpp'
	  [002]		      {Producer} 'Microsoft (R)	Optimizing Compiler'
	  [002]		      {Function} extern	not_inlined 'bar' -> 'int'
	  [003]			{Variable} 'Input' -> 'float'
	  [003]	    1		{Line}
	  [002]		      {Function} extern	not_inlined 'foo' -> 'unsigned'
	  [003]			{Block}
	  [004]			  {Block}
	  [005]			    {Variable} 'Added' -> 'float'
	  [004]			  {TypeAlias} 'FLOAT' -> 'float'
	  [004]	    9		  {Line}
	  [004]	   10		  {Line}
	  [003]			{TypeAlias} 'INT' -> 'int'
	  [003]			{Variable} 'Param' -> 'char'
	  [003]			{Variable} 'Value' -> 'int'
	  [003]	    3		{Line}
	  [003]	    5		{Line}
	  [003]	   13		{Line}
	  [003]	   14		{Line}

   DWARF - Clang (Linux)
	  Logical View:
	  [000]		  {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64

	  [001]		    {CompileUnit} 'pr-44884.cpp'
	  [002]		      {Producer} 'clang	version	14.0.0'
	  [002]	    1	      {Function} extern	not_inlined 'bar' -> 'int'
	  [003]	    1		{Parameter} 'Input' -> 'float'
	  [003]	    1		{Line}
	  [003]	    1		{Line}
	  [003]	    1		{Line}
	  [002]	    3	      {Function} extern	not_inlined 'foo' -> 'unsigned int'
	  [003]			{Block}
	  [004]	    9		  {Variable} 'Added' ->	'FLOAT'
	  [004]	    9		  {Line}
	  [004]	    9		  {Line}
	  [004]	    9		  {Line}
	  [004]	    9		  {Line}
	  [004]	    9		  {Line}
	  [004]	   10		  {Line}
	  [004]	   10		  {Line}
	  [004]	   10		  {Line}
	  [004]	   13		  {Line}
	  [003]	    3		{Parameter} 'Param' -> 'char'
	  [003]	    7		{TypeAlias} 'FLOAT' -> 'float'
	  [003]	    4		{TypeAlias} 'INT' -> 'int'
	  [003]	    5		{Variable} 'Value' -> 'INT'
	  [003]	    3		{Line}
	  [003]	    5		{Line}
	  [003]	    5		{Line}
	  [003]	   13		{Line}
	  [003]	   13		{Line}
	  [003]	   13		{Line}
	  [003]	   13		{Line}

   DWARF - GCC (Linux)
	  Logical View:
	  [000]		  {File} 'pr-44884-dwarf-gcc.o'	-> elf32-littlearm

	  [001]		    {CompileUnit} 'pr-44884.cpp'
	  [002]		      {Producer} 'GNU C++14 10.2.1 20201103'
	  [002]	    1	      {Function} extern	not_inlined 'bar' -> 'int'
	  [003]	    1		{Parameter} 'Input' -> 'float'
	  [003]	    1		{Line}
	  [003]	    1		{Line}
	  [003]	    1		{Line}
	  [002]	    3	      {Function} extern	not_inlined 'foo' -> 'unsigned int'
	  [003]			{Block}
	  [004]			  {Block}
	  [005]	    9		    {Variable} 'Added' -> 'FLOAT'
	  [005]	    9		    {Line}
	  [005]	    9		    {Line}
	  [005]	    9		    {Line}
	  [005]	   10		    {Line}
	  [005]	   13		    {Line}
	  [004]	    7		  {TypeAlias} 'FLOAT' -> 'float'
	  [003]	    3		{Parameter} 'Param' -> 'char'
	  [003]	    4		{TypeAlias} 'INT' -> 'int'
	  [003]	    5		{Variable} 'Value' -> 'INT'
	  [003]	    3		{Line}
	  [003]	    5		{Line}
	  [003]	   13		{Line}
	  [003]	   14		{Line}
	  [003]	   14		{Line}

       From the	previous logical views,	we can see  that  the  Clang  compiler
       emits both typedefs at the same lexical scope (3), which	is wrong.  GCC
       and MSVC	emit correct lexical scope for both typedefs.

       Using  the llvm-debuginfo-analyzer selection facilities,	we can produce
       a simple	tabular	output showing just the	logical	types that  are	 Type-
       def.

	  llvm-debuginfo-analyzer --attribute=level,format
				  --output-sort=name
				  --select-types=Typedef
				  --report=list
				  --print=types
				  pr-44884-*.o

	  Logical View:
	  [000]		  {File} 'pr-44884-codeview-clang.o' ->	COFF-x86-64

	  [001]		  {CompileUnit}	'pr_44884.cpp'
	  [003]		  {TypeAlias} 'FLOAT' -> 'float'
	  [003]		  {TypeAlias} 'INT' -> 'int'

	  Logical View:
	  [000]		  {File} 'pr-44884-codeview-msvc.o' -> COFF-i386

	  [001]		  {CompileUnit}	'pr_44884.cpp'
	  [004]		  {TypeAlias} 'FLOAT' -> 'float'
	  [003]		  {TypeAlias} 'INT' -> 'int'

	  Logical View:
	  [000]		  {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64

	  [001]		  {CompileUnit}	'pr_44884.cpp'
	  [003]	    7	  {TypeAlias} 'FLOAT' -> 'float'
	  [003]	    4	  {TypeAlias} 'INT' -> 'int'

	  Logical View:
	  [000]		  {File} 'pr-44884-dwarf-gcc.o'	-> elf32-littlearm

	  [001]		  {CompileUnit}	'pr_44884.cpp'
	  [004]	    7	  {TypeAlias} 'FLOAT' -> 'float'
	  [003]	    4	  {TypeAlias} 'INT' -> 'int'

       It  also	 shows,	 that the CodeView debug information does not generate
       source code line	numbers	for the	those logical types. The logical  view
       is sorted by the	types name.

   TEST	CASE 4 - MISSING NESTED	ENUMERATIONS
       The  below  example  is	used  to  show	different  output generated by
       llvm-debuginfo-analyzer.	We compiled the	example	for  an	 X86  Codeview
       and ELF targets with recent versions of Clang, GCC and MSVC (-O0	-g).

	   1  struct Struct {
	   2	union Union {
	   3	  enum NestedEnum { RED, BLUE };
	   4	};
	   5	Union U;
	   6  };
	   7
	   8  Struct S;
	   9  int test() {
	  10	return S.U.BLUE;
	  11  }

       The  above  test	is used	to illustrate a	scope issue found in the Clang
       compiler: PR46466 (Bugs LLVM) / PR45811 (GitHub LLVM)

       These are the logical views that	llvm-debuginfo-analyzer	generates  for
       3  different  compilers (MSVC, Clang and	GCC), emitting different debug
       information formats (CodeView, DWARF) on	different platforms.

	  llvm-debuginfo-analyzer --attribute=level,format,producer
				  --output-sort=name
				  --print=symbols,types
				  pr-46466-codeview-clang.o
				  pr-46466-codeview-msvc.o
				  pr-46466-dwarf-clang.o
				  pr-46466-dwarf-gcc.o

   CodeView - Clang (Windows)
	  Logical View:
	  [000]		  {File} 'pr-46466-codeview-clang.o' ->	COFF-x86-64

	  [001]		    {CompileUnit} 'pr-46466.cpp'
	  [002]		      {Producer} 'clang	version	14.0.0'
	  [002]		      {Variable} extern	'S' -> 'Struct'
	  [002]	    1	      {Struct} 'Struct'
	  [003]			{Member} public	'U' -> 'Union'
	  [003]	    2		{Union}	'Union'
	  [004]	    3		  {Enumeration}	'NestedEnum' ->	'int'
	  [005]			    {Enumerator} 'BLUE'	= '0x1'
	  [005]			    {Enumerator} 'RED' = '0x0'

   CodeView - MSVC (Windows)
	  Logical View:
	  [000]		  {File} 'pr-46466-codeview-msvc.o' -> COFF-i386

	  [001]		    {CompileUnit} 'pr-46466.cpp'
	  [002]		      {Producer} 'Microsoft (R)	Optimizing Compiler'
	  [002]		      {Variable} extern	'S' -> 'Struct'
	  [002]	    1	      {Struct} 'Struct'
	  [003]			{Member} public	'U' -> 'Union'
	  [003]	    2		{Union}	'Union'
	  [004]	    3		  {Enumeration}	'NestedEnum' ->	'int'
	  [005]			    {Enumerator} 'BLUE'	= '0x1'
	  [005]			    {Enumerator} 'RED' = '0x0'

   DWARF - Clang (Linux)
	  Logical View:
	  [000]		  {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64

	  [001]		    {CompileUnit} 'pr-46466.cpp'
	  [002]		      {Producer} 'clang	version	14.0.0'
	  [002]	    8	      {Variable} extern	'S' -> 'Struct'
	  [002]	    1	      {Struct} 'Struct'
	  [003]	    5		{Member} public	'U' -> 'Union'

   DWARF - GCC (Linux)
	  Logical View:
	  [000]		  {File} 'pr-46466-dwarf-gcc.o'	-> elf64-x86-64

	  [001]		    {CompileUnit} 'pr-46466.cpp'
	  [002]		      {Producer} 'GNU C++14 9.3.0'
	  [002]	    8	      {Variable} extern	'S' -> 'Struct'
	  [002]	    1	      {Struct} 'Struct'
	  [003]	    5		{Member} public	'U' -> 'Union'
	  [003]	    2		{Union}	'Union'
	  [004]	    3		  {Enumeration}	'NestedEnum' ->	'unsigned int'
	  [005]			    {Enumerator} 'BLUE'	= '0x1'
	  [005]			    {Enumerator} 'RED' = '0x0'

       From the	previous logical views,	we can see that	the DWARF debug	infor-
       mation generated	by the Clang compiler does not include any  references
       to  the	enumerators RED	and BLUE. The DWARF generated by GCC, CodeView
       generated by Clang and MSVC, they do include such references.

       Using the llvm-debuginfo-analyzer selection facilities, we can  produce
       a  logical  view	showing	just the logical types that are	Enumerator and
       its parents. The	logical	view is	sorted by the types name.

	  llvm-debuginfo-analyzer --attribute=format,level
				  --output-sort=name
				  --select-types=Enumerator
				  --report=parents
				  --print=types
				  pr-46466-*.o

	  Logical View:
	  [000]		  {File} 'pr-46466-codeview-clang.o' ->	COFF-x86-64

	  [001]		    {CompileUnit} 'pr-46466.cpp'
	  [002]	    1	      {Struct} 'Struct'
	  [003]	    2		{Union}	'Union'
	  [004]	    3		  {Enumeration}	'NestedEnum' ->	'int'
	  [005]			    {Enumerator} 'BLUE'	= '0x1'
	  [005]			    {Enumerator} 'RED' = '0x0'

	  Logical View:
	  [000]		  {File} 'pr-46466-codeview-msvc.o' -> COFF-i386

	  [001]		    {CompileUnit} 'pr-46466.cpp'
	  [002]	    1	      {Struct} 'Struct'
	  [003]	    2		{Union}	'Union'
	  [004]	    3		  {Enumeration}	'NestedEnum' ->	'int'
	  [005]			    {Enumerator} 'BLUE'	= '0x1'
	  [005]			    {Enumerator} 'RED' = '0x0'

	  Logical View:
	  [000]		  {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64

	  [001]		    {CompileUnit} 'pr-46466.cpp'

	  Logical View:
	  [000]		  {File} 'pr-46466-dwarf-gcc.o'	-> elf64-x86-64

	  [001]		    {CompileUnit} 'pr-46466.cpp'
	  [002]	    1	      {Struct} 'Struct'
	  [003]	    2		{Union}	'Union'
	  [004]	    3		  {Enumeration}	'NestedEnum' ->	'unsigned int'
	  [005]			    {Enumerator} 'BLUE'	= '0x1'
	  [005]			    {Enumerator} 'RED' = '0x0'

       Using the llvm-debuginfo-analyzer selection facilities, we can  produce
       a  simple tabular output	including a summary for	the logical types that
       are Enumerator. The logical view	is sorted by the types name.

	  llvm-debuginfo-analyzer --attribute=format,level
				  --output-sort=name
				  --select-types=Enumerator
				  --print=types,summary
				  pr-46466-*.o

	  Logical View:
	  [000]		  {File} 'pr-46466-codeview-clang.o' ->	COFF-x86-64

	  [001]		  {CompileUnit}	'pr-46466.cpp'
	  [005]		  {Enumerator} 'BLUE' =	'0x1'
	  [005]		  {Enumerator} 'RED' = '0x0'

	  -----------------------------
	  Element      Total	  Found
	  -----------------------------
	  Scopes	   5	      0
	  Symbols	   2	      0
	  Types		   6	      2
	  Lines		   0	      0
	  -----------------------------
	  Total		  13	      2

	  Logical View:
	  [000]		  {File} 'pr-46466-codeview-msvc.o' -> COFF-i386

	  [001]		  {CompileUnit}	'pr-46466.cpp'
	  [005]		  {Enumerator} 'BLUE' =	'0x1'
	  [005]		  {Enumerator} 'RED' = '0x0'

	  -----------------------------
	  Element      Total	  Found
	  -----------------------------
	  Scopes	   5	      0
	  Symbols	   2	      0
	  Types		   7	      2
	  Lines		   0	      0
	  -----------------------------
	  Total		  14	      2

	  Logical View:
	  [000]		  {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64

	  [001]		  {CompileUnit}	'pr-46466.cpp'

	  -----------------------------
	  Element      Total	  Found
	  -----------------------------
	  Scopes	   4	      0
	  Symbols	   0	      0
	  Types		   0	      0
	  Lines		   0	      0
	  -----------------------------
	  Total		   4	      0

	  Logical View:
	  [000]		  {File} 'pr-46466-dwarf-gcc.o'	-> elf64-x86-64

	  [001]		  {CompileUnit}	'pr-46466.cpp'
	  [005]		  {Enumerator} 'BLUE' =	'0x1'
	  [005]		  {Enumerator} 'RED' = '0x0'

	  -----------------------------
	  Element      Total	  Found
	  -----------------------------
	  Scopes	   5	      0
	  Symbols	   0	      0
	  Types		   2	      2
	  Lines		   0	      0
	  -----------------------------
	  Total		   7	      2

       From the	values printed under the Found column,	we  can	 see  that  no
       Types were found	in the DWARF debug information generated by Clang.

   TEST	CASE 5 - INCORRECT LEXICAL SCOPE FOR VARIABLE
       The  below  example  is	used  to  show	different  output generated by
       llvm-debuginfo-analyzer.	We compiled the	example	for  an	 X86  Codeview
       and ELF targets with recent versions of Clang, GCC and MSVC (-O0	-g).

	  // definitions.h
	  #ifdef _MSC_VER
	    #define forceinline	__forceinline
	  #elif	defined(__clang__)
	    #if	__has_attribute(__always_inline__)
	      #define forceinline inline __attribute__((__always_inline__))
	    #else
	      #define forceinline inline
	    #endif
	  #elif	defined(__GNUC__)
	    #define forceinline	inline __attribute__((__always_inline__))
	  #else
	    #define forceinline	inline
	    #error
	  #endif

       As  the	test is	dependent on inline compiler options, the above	header
       file defines forceinline.

	  #include "definitions.h"

	   1  #include "definitions.h"
	   2  forceinline int InlineFunction(int Param)	{
	   3	int Var_1 = Param;
	   4	{
	   5	  int Var_2 = Param + Var_1;
	   6	  Var_1	= Var_2;
	   7	}
	   8	return Var_1;
	   9  }
	  10
	  11  int test(int Param_1, int	Param_2) {
	  12	int A =	Param_1;
	  13	A += InlineFunction(Param_2);
	  14	return A;
	  15  }

       The above test is used to illustrate a  variable	 issue	found  in  the
       Clang compiler: PR43860 (Bugs LLVM) / PR43205 (GitHub)

       These  are the logical views that llvm-debuginfo-analyzer generates for
       3 different compilers (MSVC, Clang and GCC), emitting  different	 debug
       information formats (CodeView, DWARF) on	different platforms.

	  llvm-debuginfo-analyzer --attribute=level,format,producer
				  --output-sort=name
				  --print=symbols
				  pr-43860-codeview-clang.o
				  pr-43860-codeview-msvc.o
				  pr-43860-dwarf-clang.o
				  pr-43860-dwarf-gcc.o

   CODEVIEW - Clang (Windows)
	  Logical View:
	  [000]		  {File} 'pr-43860-codeview-clang.o' ->	COFF-x86-64

	  [001]		    {CompileUnit} 'pr-43860.cpp'
	  [002]		      {Producer} 'clang	version	14.0.0'
	  [002]	    2	      {Function} inlined 'InlineFunction' -> 'int'
	  [003]			{Parameter} '' -> 'int'
	  [002]		      {Function} extern	not_inlined 'test' -> 'int'
	  [003]			{Variable} 'A' -> 'int'
	  [003]			{InlinedFunction} inlined 'InlineFunction' -> 'int'
	  [004]			  {Parameter} 'Param' -> 'int'
	  [004]			  {Variable} 'Var_1' ->	'int'
	  [004]			  {Variable} 'Var_2' ->	'int'
	  [003]			{Parameter} 'Param_1' -> 'int'
	  [003]			{Parameter} 'Param_2' -> 'int'

   CODEVIEW - MSVC (Windows)
	  Logical View:
	  [000]		  {File} 'pr-43860-codeview-msvc.o' -> COFF-i386

	  [001]		    {CompileUnit} 'pr-43860.cpp'
	  [002]		      {Producer} 'Microsoft (R)	Optimizing Compiler'
	  [002]		      {Function} extern	not_inlined 'InlineFunction' ->	'int'
	  [003]			{Block}
	  [004]			  {Variable} 'Var_2' ->	'int'
	  [003]			{Variable} 'Param' -> 'int'
	  [003]			{Variable} 'Var_1' -> 'int'
	  [002]		      {Function} extern	not_inlined 'test' -> 'int'
	  [003]			{Variable} 'A' -> 'int'
	  [003]			{Variable} 'Param_1' ->	'int'
	  [003]			{Variable} 'Param_2' ->	'int'

   DWARF - Clang (Linux)
	  Logical View:
	  [000]		  {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64

	  [001]		    {CompileUnit} 'pr-43860.cpp'
	  [002]		      {Producer} 'clang	version	14.0.0'
	  [002]	    2	      {Function} extern	inlined	'InlineFunction' -> 'int'
	  [003]			{Block}
	  [004]	    5		  {Variable} 'Var_2' ->	'int'
	  [003]	    2		{Parameter} 'Param' -> 'int'
	  [003]	    3		{Variable} 'Var_1' -> 'int'
	  [002]	   11	      {Function} extern	not_inlined 'test' -> 'int'
	  [003]	   12		{Variable} 'A' -> 'int'
	  [003]	   14		{InlinedFunction} inlined 'InlineFunction' -> 'int'
	  [004]			  {Block}
	  [005]			    {Variable} 'Var_2' -> 'int'
	  [004]			  {Parameter} 'Param' -> 'int'
	  [004]			  {Variable} 'Var_1' ->	'int'
	  [003]	   11		{Parameter} 'Param_1' -> 'int'
	  [003]	   11		{Parameter} 'Param_2' -> 'int'

   DWARF - GCC (Linux)
	  Logical View:
	  [000]		  {File} 'pr-43860-dwarf-gcc.o'	-> elf64-x86-64

	  [001]		    {CompileUnit} 'pr-43860.cpp'
	  [002]		      {Producer} 'GNU C++14 9.3.0'
	  [002]	    2	      {Function} extern	declared_inlined 'InlineFunction' -> 'int'
	  [003]			{Block}
	  [004]	    5		  {Variable} 'Var_2' ->	'int'
	  [003]	    2		{Parameter} 'Param' -> 'int'
	  [003]	    3		{Variable} 'Var_1' -> 'int'
	  [002]	   11	      {Function} extern	not_inlined 'test' -> 'int'
	  [003]	   12		{Variable} 'A' -> 'int'
	  [003]	   13		{InlinedFunction} declared_inlined 'InlineFunction' -> 'int'
	  [004]			  {Block}
	  [005]			    {Variable} 'Var_2' -> 'int'
	  [004]			  {Parameter} 'Param' -> 'int'
	  [004]			  {Variable} 'Var_1' ->	'int'
	  [003]	   11		{Parameter} 'Param_1' -> 'int'
	  [003]	   11		{Parameter} 'Param_2' -> 'int'

       From the	previous logical views,	we can see that	the CodeView debug in-
       formation generated by the Clang	compiler shows the variables Var_1 and
       Var_2  are at the same lexical scope (4)	in the function	InlineFuction.
       The DWARF generated by GCC/Clang	and CodeView generated by  MSVC,  show
       those variables at the correct lexical scope: 3 and 4 respectively.

       Using  the llvm-debuginfo-analyzer selection facilities,	we can produce
       a simple	tabular	output showing just the	logical	elements that have  in
       their name the var pattern. The logical view is sorted by the variables
       name.

	  llvm-debuginfo-analyzer --attribute=level,format
				  --output-sort=name
				  --select-regex --select-nocase --select=Var
				  --report=list
				  --print=symbols
				  pr-43860-*.o

	  Logical View:
	  [000]		  {File} 'pr-43860-codeview-clang.o' ->	COFF-x86-64

	  [001]		  {CompileUnit}	'pr-43860.cpp'
	  [004]		  {Variable} 'Var_1' ->	'int'
	  [004]		  {Variable} 'Var_2' ->	'int'

	  Logical View:
	  [000]		  {File} 'pr-43860-codeview-msvc.o' -> COFF-i386

	  [001]		  {CompileUnit}	'pr-43860.cpp'
	  [003]		  {Variable} 'Var_1' ->	'int'
	  [004]		  {Variable} 'Var_2' ->	'int'

	  Logical View:
	  [000]		  {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64

	  [001]		  {CompileUnit}	'pr-43860.cpp'
	  [004]		  {Variable} 'Var_1' ->	'int'
	  [003]	    3	  {Variable} 'Var_1' ->	'int'
	  [005]		  {Variable} 'Var_2' ->	'int'
	  [004]	    5	  {Variable} 'Var_2' ->	'int'

	  Logical View:
	  [000]		  {File} 'pr-43860-dwarf-gcc.o'	-> elf64-x86-64

	  [001]		  {CompileUnit}	'pr-43860.cpp'
	  [004]		  {Variable} 'Var_1' ->	'int'
	  [003]	    3	  {Variable} 'Var_1' ->	'int'
	  [005]		  {Variable} 'Var_2' ->	'int'
	  [004]	    5	  {Variable} 'Var_2' ->	'int'

       It  also	 shows,	 that the CodeView debug information does not generate
       source code line	numbers	for the	those  logical	symbols.  The  logical
       view is sorted by the types name.

   TEST	CASE 6 - FULL LOGICAL VIEW
       For  advanced  users, llvm-debuginfo-analyzer can display low level in-
       formation that includes offsets within the debug	 information  section,
       debug location operands,	linkage	names, etc.

	  llvm-debuginfo-analyzer --attribute=all
				  --print=all
				  test-dwarf-clang.o

	  Logical View:
	  [0x0000000000][000]		 {File}	'test-dwarf-clang.o' ->	elf64-x86-64

	  [0x000000000b][001]		   {CompileUnit} 'test.cpp'
	  [0x000000000b][002]		     {Producer}	'clang version 12.0.0'
					     {Directory} ''
					     {File} 'test.cpp'
					     {Public} 'foo' [0x0000000000:0x000000003a]
	  [0x000000000b][002]		     {Range} Lines 2:9 [0x0000000000:0x000000003a]
	  [0x00000000bc][002]		     {BaseType}	'bool'
	  [0x0000000099][002]		     {BaseType}	'int'
	  [0x00000000b5][002]		     {BaseType}	'unsigned int'

	  [0x00000000a0][002]	{Source} '/test.cpp'
	  [0x00000000a0][002]	   1	     {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int'
	  [0x000000002a][002]	   2	     {Function}	extern not_inlined 'foo' -> [0x0000000099]'int'
	  [0x000000002a][003]		       {Range} Lines 2:9 [0x0000000000:0x000000003a]
	  [0x000000002a][003]		       {Linkage}  0x2 '_Z3fooPKijb'
	  [0x0000000071][003]		       {Block}
	  [0x0000000071][004]			 {Range} Lines 5:8 [0x000000001c:0x000000002f]
	  [0x000000007e][004]	   5		 {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
	  [0x000000007e][005]			   {Coverage} 100.00%
	  [0x000000007f][005]			   {Location}
	  [0x000000007f][006]			     {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]
	  [0x000000001c][004]	   5		 {Line}	{NewStatement} '/test.cpp'
	  [0x000000001c][004]			 {Code}	'movl	$0x7, -0x1c(%rbp)'
	  [0x0000000023][004]	   6		 {Line}	{NewStatement} '/test.cpp'
	  [0x0000000023][004]			 {Code}	'movl	$0x7, -0x4(%rbp)'
	  [0x000000002a][004]			 {Code}	'jmp	0x6'
	  [0x000000002f][004]	   8		 {Line}	{NewStatement} '/test.cpp'
	  [0x000000002f][004]			 {Code}	'movl	-0x14(%rbp), %eax'
	  [0x0000000063][003]	   2	       {Parameter} 'ParamBool' -> [0x00000000bc]'bool'
	  [0x0000000063][004]			 {Coverage} 100.00%
	  [0x0000000064][004]			 {Location}
	  [0x0000000064][005]			   {Entry} Stack Offset: -21 (0xffffffffffffffeb) [DW_OP_fbreg]
	  [0x0000000047][003]	   2	       {Parameter} 'ParamPtr' -> [0x00000000a0]'INTPTR'
	  [0x0000000047][004]			 {Coverage} 100.00%
	  [0x0000000048][004]			 {Location}
	  [0x0000000048][005]			   {Entry} Stack Offset: -16 (0xfffffffffffffff0) [DW_OP_fbreg]
	  [0x0000000055][003]	   2	       {Parameter} 'ParamUnsigned' -> [0x00000000b5]'unsigned int'
	  [0x0000000055][004]			 {Coverage} 100.00%
	  [0x0000000056][004]			 {Location}
	  [0x0000000056][005]			   {Entry} Stack Offset: -20 (0xffffffffffffffec) [DW_OP_fbreg]
	  [0x000000008d][003]	   4	       {TypeAlias} 'INTEGER' ->	[0x0000000099]'int'
	  [0x0000000000][003]	   2	       {Line} {NewStatement} '/test.cpp'
	  [0x0000000000][003]		       {Code} 'pushq	%rbp'
	  [0x0000000001][003]		       {Code} 'movq	%rsp, %rbp'
	  [0x0000000004][003]		       {Code} 'movb	%dl, %al'
	  [0x0000000006][003]		       {Code} 'movq	%rdi, -0x10(%rbp)'
	  [0x000000000a][003]		       {Code} 'movl	%esi, -0x14(%rbp)'
	  [0x000000000d][003]		       {Code} 'andb	$0x1, %al'
	  [0x000000000f][003]		       {Code} 'movb	%al, -0x15(%rbp)'
	  [0x0000000012][003]	   3	       {Line} {NewStatement} {PrologueEnd} '/test.cpp'
	  [0x0000000012][003]		       {Code} 'testb	$0x1, -0x15(%rbp)'
	  [0x0000000016][003]		       {Code} 'je	0x13'
	  [0x0000000032][003]	   8	       {Line} '/test.cpp'
	  [0x0000000032][003]		       {Code} 'movl	%eax, -0x4(%rbp)'
	  [0x0000000035][003]	   9	       {Line} {NewStatement} '/test.cpp'
	  [0x0000000035][003]		       {Code} 'movl	-0x4(%rbp), %eax'
	  [0x0000000038][003]		       {Code} 'popq	%rbp'
	  [0x0000000039][003]		       {Code} 'retq'
	  [0x000000003a][003]	   9	       {Line} {NewStatement} {EndSequence} '/test.cpp'

	  -----------------------------
	  Element      Total	Printed
	  -----------------------------
	  Scopes	   3	      3
	  Symbols	   4	      4
	  Types		   5	      5
	  Lines		  25	     25
	  -----------------------------
	  Total		  37	     37

	  Scope	Sizes:
		 189 (100.00%) : [0x000000000b][001]		  {CompileUnit}	'test.cpp'
		 110 ( 58.20%) : [0x000000002a][002]	  2	    {Function} extern not_inlined 'foo'	-> [0x0000000099]'int'
		  27 ( 14.29%) : [0x0000000071][003]		      {Block}

	  Totals by lexical level:
	  [001]:	189 (100.00%)
	  [002]:	110 ( 58.20%)
	  [003]:	 27 ( 14.29%)

       The  Scope Sizes	table shows the	contribution in	bytes to the debug in-
       formation by each scope,	which can be used to determine unexpected size
       changes in the DWARF sections between different versions	 of  the  same
       toolchain.

	  [0x000000002a][002]	   2	     {Function}	extern not_inlined 'foo' -> [0x0000000099]'int'
	  [0x000000002a][003]		       {Range} Lines 2:9 [0x0000000000:0x000000003a]
	  [0x000000002a][003]		       {Linkage}  0x2 '_Z3fooPKijb'
	  [0x0000000071][003]		       {Block}
	  [0x0000000071][004]			 {Range} Lines 5:8 [0x000000001c:0x000000002f]
	  [0x000000007e][004]	   5		 {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
	  [0x000000007e][005]			   {Coverage} 100.00%
	  [0x000000007f][005]			   {Location}
	  [0x000000007f][006]			     {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]

       The  {Range}  attribute	describe  the line ranges for a	logical	scope.
       For this	case, the function foo is within the lines 2 and 9.

       The {Coverage} and {Location} attributes	describe  the  debug  location
       and  coverage  for  logical  symbols.  For optimized code, the coverage
       value decreases and it affects the program debuggability.

EXIT STATUS
       llvm-debuginfo-analyzer returns 0 if the	input files  were  parsed  and
       printed successfully. Otherwise,	it returns 1.

SEE ALSO
       llvm-dwarfdump

AUTHOR
       Maintained by the LLVM Team (https://llvm.org/).

COPYRIGHT
       2003-2025, LLVM Project

18				  2025-04-13	    LLVM-DEBUGINFO-ANALYZER(1)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=llvm-debuginfo-analyzer-cheriot&sektion=1&manpath=FreeBSD+Ports+14.3.quarterly>

home | help