[lld] [llvm] [Symbolizer] Support for Missing Line Numbers. (PR #82240)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 08:56:06 PDT 2024


================
@@ -0,0 +1,489 @@
+##  Test  --skip-line-zero option.
+##
+##  This test illustrates the usage of handcrafted assembly to produce the following line table.
+##  Address            Line   Column File   ISA Discriminator OpIndex Flags
+##  ------------------ ------ ------ ------ --- ------------- ------- -------------
+##  0x00000000000030a0      1     80      1   0             0       0  is_stmt prologue_end
+##  0x00000000000030a6      1     80      1   0             0       0  is_stmt end_sequence
+##  0x0000000000001000      0     68      1   0             0       0  is_stmt prologue_end
+##  0x0000000000001008      2     39      1   0             0       0
+##  0x0000000000001010      3     68      1   0             0       0  is_stmt prologue_end
+##  0x0000000000001012      0     68      1   0             0       0
+##  0x0000000000001017      3     68      1   0             0       0
+##  0x0000000000001019      3     39      1   0             0       0
+##  0x0000000000001020      5     1       2   0             0       0  is_stmt prologue_end
+##  0x0000000000001026      5     1       2   0             0       0  is_stmt end_sequence
+
+# REQUIRES: x86-registered-target
+
+# RUN: rm -rf %t && split-file %s %t && cd %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux --fdebug-prefix-map=%t="" %s -o %t.o
+
+## Check that with '--skip-line-zero', the last non-zero line in the current sequence is displayed.
+## If it fails to find in the current sequence then return the orignal computed line-zero for the queried address.
+# RUN: llvm-symbolizer --obj=%t.o --skip-line-zero 0x1000 | FileCheck --strict-whitespace --match-full-lines --check-prefix=APPROX-FAIL-ACROSS-SEQ %s
+
+# APPROX-FAIL-ACROSS-SEQ:add
+# APPROX-FAIL-ACROSS-SEQ-NEXT:definitions.h:0:68
+
+## Check that with '--skip-line-zero', the last non-zero line in the current sequence is displayed.
+# RUN: llvm-symbolizer --obj=%t.o --skip-line-zero 0x1012 | FileCheck --strict-whitespace --match-full-lines --check-prefix=APPROX-WITHIN-SEQ %s
+
+# APPROX-WITHIN-SEQ:sub
+# APPROX-WITHIN-SEQ-NEXT:definitions.h:3:68 (approximate)
+
+## Check to ensure that '--skip-line-zero' only affects addresses having line-zero when more than one address is specified.
+# RUN: llvm-symbolizer --obj=%t.o --skip-line-zero 0x1012 0x1020 | FileCheck --strict-whitespace --match-full-lines --check-prefixes=APPROX-WITHIN-SEQ,NO-APPROX %s
+
+# NO-APPROX:main
+# NO-APPROX-NEXT:main.c:5:1
+
+## Check to ensure that '--skip-line-zero' with '--verbose' enabled displays correct approximate flag in verbose ouptut.
+# RUN: llvm-symbolizer --obj=%t.o --skip-line-zero --verbose 0x1012 | FileCheck --strict-whitespace --match-full-lines --check-prefix=APPROX-VERBOSE %s
+
+# APPROX-VERBOSE:sub
+# APPROX-VERBOSE-NEXT:  Filename: definitions.h
+# APPROX-VERBOSE-NEXT:  Function start filename: definitions.h
+# APPROX-VERBOSE-NEXT:  Function start line: 3
+# APPROX-VERBOSE-NEXT:  Function start address: 0x1010
+# APPROX-VERBOSE-NEXT:  Line: 3
+# APPROX-VERBOSE-NEXT:  Column: 68
+# APPROX-VERBOSE-NEXT:  Approximate: true
+
+## Check to ensure that '--skip-line-zero' with '--output-style=JSON' displays correct approximate flag in JSON output.
+# RUN: llvm-symbolizer --obj=%t.o --skip-line-zero --output-style=JSON 0x1012 | FileCheck --strict-whitespace --match-full-lines --check-prefix=APPROX-JSON %s
+
+# APPROX-JSON:[{"Address":"0x1012","ModuleName":"{{.*}}{{[/|\]+}}test{{[/|\]+}}tools{{[/|\]+}}llvm-symbolizer{{[/|\]+}}Output{{[/|\]+}}approximate-line-handcrafted.s.tmp.o","Symbol":[{"Approximate":true,"Column":68,"Discriminator":0,"FileName":"definitions.h","FunctionName":"sub","Line":3,"StartAddress":"0x1010","StartFileName":"definitions.h","StartLine":3}]}]
+
+#--- definitions.h
+#__attribute__((section(".dummy_section"))) int dummy_function(){ return 1234; }
+#extern inline int add(int x, int y) { return (dummy_function() + x + y); }
+#extern inline int sub(int x, int y) { return (dummy_function() - x - y); }
+
+#--- main.c
+#include "definitions.h"
+#int main(void) {
+# int x = 111;
+# int y = 322;
+# return add(x,y)+sub(y,x);
+#}
+
+#--- gen
+#clang -S -O3 -gdwarf-4 --target=x86_64-pc-linux -fdebug-prefix-map=/proc/self/cwd="" -fdebug-prefix-map=./="" main.c -o main.s
+
+#sed -i '1,83d' main.s                             # Delete .text and .dummy_section
+#sed -i '4c\	.quad 0x1000                            #.Lfunc_begin1 base address' main.s
+#sed -i '5c\	.quad 0x1010                            #.Lfunc_begin2-.Lfunc_begin1' main.s
+#sed -i '6c\	.quad 0x1012                            #.Ltmp2-.Lfunc_begin1' main.s
+#sed -i '9c\	.quad 0x1012                            #.Ltmp2-.Lfunc_begin1' main.s
+#sed -i '10c\	.quad 0x101a                              #.Lfunc_end2-.Lfunc_begin1' main.s
+#sed -i '156c\	.quad 0x30a0                            #.Lfunc_begin0 DW_AT_low_pc' main.s
+#sed -i '157c\	.long 0x30a6                            #.Lfunc_end0-.Lfunc_begin0(DW_AT_high_pc)' main.s
+#sed -i '167c\	.quad 0x1000                            #.Lfunc_begin1(DW_AT_low_pc)' main.s
+#sed -i '168c\	.long 0x1009                            #.Lfunc_end1-.Lfunc_begin1 DW_AT_high_pc' main.s
+#sed -i '194c\	.quad 0x1010                            #.Lfunc_begin2  DW_AT_low_pc' main.s
+#sed -i '195c\	.long 0x101a                            #.Lfunc_end2-.Lfunc_begin2  DW_AT_high_pc' main.s
+#sed -i '220c\	.quad 0x1020                            #.Lfunc_begin3 DW_AT_low_pc' main.s
+#sed -i '221c\	.long 0x1026                            #.Lfunc_end3-.Lfunc_begin3 DW_AT_high_pc' main.s
+#sed -i '252c\	.quad 0x30a0                            #.Lfunc_begin0' main.s
+#sed -i '253c\	.quad 0x30a6                            #.Lfunc_end0' main.s
+#sed -i '254c\	.quad 0x1000                            #.Lfunc_begin1' main.s
+#sed -i '255c\	.quad 0x30a6                            #.Lfunc_end3' main.s
+#sed -i '$a\	.long .Lunit_end - .Lunit_start     # unit length\
+#	.Lunit_start:\
+#	.short 4     # version\
+#	.long .Lprologue_end - .Lprologue_start # header length\
+#.Lprologue_start:\
+#	.byte 1                                      # minimum_instruction_length\
+#	.byte 1                                      # maximum_operations_per_instruction\
+#	.byte 1                                      # default_is_stmt\
+#	.byte -5                                     # line_base\
+#	.byte 14                                     # line_range\
+#	.byte 13                                     # opcode_base\
+#	.byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1     # arguments in standard opcodes\
+#	.byte 0                                      # end of include directories\
+#	.asciz "definitions.h"                       # filename\
+#	.byte 0                                      # reference to dir0\
+#	.byte 0                                      # modification time\
+#	.byte 0                                      # length of file (unavailable)\
+#	.asciz "main.c"                              # filename\
+#	.byte 0                                      # reference to dir0\
+#	.byte 0                                      # modification time\
+#	.byte 0                                      # length of file (unavailable)\
+#	.byte 0                                      # end of filenames\
+#.Lprologue_end:\
+#	.byte 0x05, 66                               # DW_LNS_set_column (80)\
+#	.byte 0x0a                                   # DW_LNS_set_prologue_end\
+#	.byte 0x00, 9, 2                             # DW_LNS_set_address\
+#	.quad 0x30a0                                 # Address Value (0x00000000000030a0)\
+#	.byte 0x01                                   # DW_LNS_copy\
+#	.byte 0x02                                   # DW_LNS_advance_pc\
+#	.uleb128 0x06                                # (addr +=6, op-index +=0)\
+#	.byte 0, 1, 1                                # DW_LNE_end_sequence\
+#	.byte 0x05, 68                               # DW_LNS_set_column (68)\
+#	.byte 0x0a                                   # DW_LNS_set_prologue_end\
+#	.byte 0x00, 9, 2                             # DW_LNE_set_address\
+#	.quad 0x1000                                 # Address Value (0x0000000000001000)\
+#	.byte 0x11                                   # (address += 0,  line += -1,  op-index += 0)\
+#	.byte 0x05, 39                               # DW_LNS_set_column (39)\
+#	.byte 0x06                                   # DW_LNS_negate_stmt\
+#	.byte 0x84                                   # (address += 8,  line += 2,  op-index += 0)\
+#	.byte 0x05, 68                               # DW_LNS_set_column (68)\
+#	.byte 0x06                                   # DW_LNS_negate_stmt\
+#	.byte 0x0a                                   # DW_LNS_set_prologue_end\
+#	.byte 0x83                                   # (address += 8,  line += 1,  op-index += 0)\
+#	.byte 0x06                                   # DW_LNS_negate_stmt\
+#	.byte 0x2b                                   # (address += 2,  line += -3,  op-index += 0)\
+#	.byte 0x5b                                   # (address += 5,  line += 3,  op-index += 0)\
+#	.byte 0x05, 39                               # DW_LNS_set_column (39)\
+#	.byte 0x2e                                   # (address += 2,  line += 0,  op-index += 0)\
+#	.byte 0x04, 2                                # DW_LNS_set_file (2)\
+#	.byte 0x05, 1                                # DW_LNS_set_column (1)\
+#	.byte 0x06                                   # DW_LNS_negate_stmt\
+#	.byte 0x0a                                   # DW_LNS_set_prologue_end\
+#	.byte 0x76                                   # (address += 7,  line += 2,  op-index += 0)\
+#	.byte 0x02                                   # DW_LNS_advance_pc\
+#	.uleb128 0x06                                # (addr += 6, op-index += 0)\
+#	.byte 0, 1, 1                                # DW_LNE_end_sequence\
+#	.Lunit_end:' main.s
+
+#sed -n p main.s
+
+#--- main.s
+	.section	.debug_loc,"", at progbits
----------------
ampandey-1995 wrote:

This is not possible , all the debug_* sections are required to get the line table section in object file. Note here we are not passing ```-g``` in llvm-mc, If I just include the line table section in the assembly and delete all the rest debug_* sections then there will be line-table created in the object file output by llvm-mc but then llvm-symbolizer will misbehave with that line table.  Those DIE's  are there because multiple functions are there and there offsets are also stored in debug_info and debug_loc section, removing some of the DIE's in debug_info section will ultmately cause problems in the llvm-symbolizer output. Ex with only .debug_line section in assembly.
```
~$ llvm-symbolizer --obj=main-short.o 0x30a0
??
??:0:0
```


 

https://github.com/llvm/llvm-project/pull/82240


More information about the llvm-commits mailing list