[llvm] [llvm-debuginfo-analyzer] Add support for WebAssembly binary format. (PR #82588)
Derek Schuff via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 4 16:58:27 PST 2024
================
@@ -1952,6 +1953,315 @@ 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.
+WEBASSEMBLY SUPPORT
+~~~~~~~~~~~~~~~~~~~
+The below example is used to show the WebAssembly output generated by
+:program:`llvm-debuginfo-analyzer`. We compiled the example for a
+WebAssembly 32-bit target with Clang (-O0 -g --target=wasm32):
+
+.. code-block:: c++
+
+ 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 }
+
+PRINT BASIC DETAILS
+^^^^^^^^^^^^^^^^^^^
+The following command prints basic details for all the logical elements
+sorted by the debug information internal offset; it includes its lexical
+level and debug info format.
+
+.. code-block:: none
+
+ llvm-debuginfo-analyzer --attribute=level,format
+ --output-sort=offset
+ --print=scopes,symbols,types,lines,instructions
+ test-clang.wasm
+
+or
+
+.. code-block:: none
+
+ llvm-debuginfo-analyzer --attribute=level,format
+ --output-sort=offset
+ --print=elements
+ test-clang.wasm
+
+Each row represents an element that is present within the debug
+information. The first column represents the scope level, followed by
+the associated line number (if any), and finally the description of
+the element.
+
+.. code-block:: none
+
+ Logical View:
+ [000] {File} 'test-clang.wasm' -> WASM
+
+ [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} 'i32.const 7'
+ [004] {Code} 'local.set 10'
+ [004] {Code} 'local.get 5'
+ [004] {Code} 'local.get 10'
+ [004] {Code} 'i32.store 12'
+ [004] 6 {Line}
+ [004] {Code} 'i32.const 7'
+ [004] {Code} 'local.set 11'
+ [004] {Code} 'local.get 5'
+ [004] {Code} 'local.get 11'
+ [004] {Code} 'i32.store 28'
+ [004] {Code} 'br 1'
+ [004] - {Line}
+ [004] {Code} 'end'
+ [003] 4 {TypeAlias} 'INTEGER' -> 'int'
+ [003] 2 {Line}
+ [003] {Code} 'nop'
+ [003] {Code} 'end'
+ [003] {Code} 'i64.div_s'
+ [003] {Code} 'global.get 0'
+ [003] {Code} 'local.set 3'
+ [003] {Code} 'i32.const 32'
+ [003] {Code} 'local.set 4'
+ [003] {Code} 'local.get 3'
+ [003] {Code} 'local.get 4'
+ [003] {Code} 'i32.sub'
+ [003] {Code} 'local.set 5'
+ [003] {Code} 'local.get 5'
+ [003] {Code} 'local.get 0'
+ [003] {Code} 'i32.store 24'
+ [003] {Code} 'local.get 5'
+ [003] {Code} 'local.get 1'
+ [003] {Code} 'i32.store 20'
+ [003] {Code} 'local.get 2'
+ [003] {Code} 'local.set 6'
+ [003] {Code} 'local.get 5'
+ [003] {Code} 'local.get 6'
+ [003] {Code} 'i32.store8 19'
+ [003] 3 {Line}
+ [003] {Code} 'local.get 5'
+ [003] {Code} 'i32.load8_u 19'
+ [003] {Code} 'local.set 7'
+ [003] 3 {Line}
+ [003] {Code} 'i32.const 1'
+ [003] {Code} 'local.set 8'
+ [003] {Code} 'local.get 7'
+ [003] {Code} 'local.get 8'
+ [003] {Code} 'i32.and'
+ [003] {Code} 'local.set 9'
+ [003] {Code} 'block'
+ [003] {Code} 'block'
+ [003] {Code} 'local.get 9'
+ [003] {Code} 'i32.eqz'
+ [003] {Code} 'br_if 0'
+ [003] 8 {Line}
+ [003] {Code} 'local.get 5'
+ [003] {Code} 'i32.load 20'
+ [003] {Code} 'local.set 12'
+ [003] 8 {Line}
+ [003] {Code} 'local.get 5'
+ [003] {Code} 'local.get 12'
+ [003] {Code} 'i32.store 28'
+ [003] - {Line}
+ [003] {Code} 'end'
+ [003] 9 {Line}
+ [003] {Code} 'local.get 5'
+ [003] {Code} 'i32.load 28'
+ [003] {Code} 'local.set 13'
+ [003] {Code} 'local.get 13'
+ [003] {Code} 'return'
+ [003] {Code} 'end'
+ [003] 9 {Line}
+ [003] {Code} 'unreachable'
+ [002] 1 {TypeAlias} 'INTPTR' -> '* const int'
+
+SELECT LOGICAL ELEMENTS
+^^^^^^^^^^^^^^^^^^^^^^^
+The following prints all *instructions*, *symbols* and *types* that
+contain **'block'** or **'.store'** in their names or types, using a tab
+layout and given the number of matches.
+
+.. code-block:: none
+
+ llvm-debuginfo-analyzer --attribute=level
+ --select-nocase --select-regex
+ --select=BLOCK --select=.store
+ --report=list
+ --print=symbols,types,instructions,summary
+ test-clang.wasm
+
+ Logical View:
+ [000] {File} 'test-clang.wasm'
+
+ [001] {CompileUnit} 'test.cpp'
+ [003] {Code} 'block'
+ [003] {Code} 'block'
+ [004] {Code} 'i32.store 12'
+ [003] {Code} 'i32.store 20'
+ [003] {Code} 'i32.store 24'
+ [004] {Code} 'i32.store 28'
+ [003] {Code} 'i32.store 28'
+ [003] {Code} 'i32.store8 19'
+
+ -----------------------------
+ Element Total Printed
+ -----------------------------
+ Scopes 3 0
+ Symbols 4 0
+ Types 2 0
+ Lines 62 8
+ -----------------------------
+ Total 71 8
+
+COMPARISON MODE
+^^^^^^^^^^^^^^^
+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 pattern
----------------
dschuff wrote:
copypasta? (gcc doesn't actually support wasm, right? have you tried a use case like this?)
https://github.com/llvm/llvm-project/pull/82588
More information about the llvm-commits
mailing list