[BOLT][DWARF] Fix adding DW_AT_GNU_ranges_base
authorAlexander Yermolovich <ayermolo@meta.com>
Thu, 13 Jul 2023 17:54:37 +0000 (10:54 -0700)
committerAlexander Yermolovich <ayermolo@meta.com>
Thu, 13 Jul 2023 17:54:48 +0000 (10:54 -0700)
There are cases in DWARF4 when Skeleton CU has ranges, but dwo CU doesn't.
Bug was introduced in new DWARFRewriter where for DWARF4 it would fall through
to DWARF5 case.

Reviewed By: maksfb

Differential Revision: https://reviews.llvm.org/D155033

bolt/lib/Rewrite/DWARFRewriter.cpp
bolt/test/X86/Inputs/dwarf4-df-no-base.s [new file with mode: 0644]
bolt/test/X86/dwarf4-df-no-base.test [new file with mode: 0644]

index a77cdb3..85224dd 100644 (file)
@@ -1205,7 +1205,7 @@ void DWARFRewriter::updateDWARFObjectAddressRanges(
 
     // If we are at this point we are in the CU/Skeleton CU, and
     // DW_AT_GNU_ranges_base or DW_AT_rnglists_base doesn't exist.
-    if (Unit.getVersion() < 4)
+    if (Unit.getVersion() <= 4)
       DIEBldr.addValue(&Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4,
                        DIEInteger(*RangesBase));
     else if (Unit.getVersion() == 5)
diff --git a/bolt/test/X86/Inputs/dwarf4-df-no-base.s b/bolt/test/X86/Inputs/dwarf4-df-no-base.s
new file mode 100644 (file)
index 0000000..8599dd0
--- /dev/null
@@ -0,0 +1,284 @@
+# int foo() { return 0; }
+# int main() { return foo(); }
+# clang++ -ffunction-sections -g2 -gdwarf-4 -gsplit-dwarf -S main.cpp
+
+       .text
+       .file   "main.cpp"
+       .section        .text._Z3foov,"ax",@progbits
+       .globl  _Z3foov                         # -- Begin function _Z3foov
+       .p2align        4, 0x90
+       .type   _Z3foov,@function
+_Z3foov:                                # @_Z3foov
+.Lfunc_begin0:
+       .file   1 "." "main.cpp"
+       .loc    1 1 0                           # main.cpp:1:0
+       .cfi_startproc
+# %bb.0:                                # %entry
+       pushq   %rbp
+       .cfi_def_cfa_offset 16
+       .cfi_offset %rbp, -16
+       movq    %rsp, %rbp
+       .cfi_def_cfa_register %rbp
+.Ltmp0:
+       .loc    1 1 13 prologue_end             # main.cpp:1:13
+       xorl    %eax, %eax
+       .loc    1 1 13 epilogue_begin is_stmt 0 # main.cpp:1:13
+       popq    %rbp
+       .cfi_def_cfa %rsp, 8
+       retq
+.Ltmp1:
+.Lfunc_end0:
+       .size   _Z3foov, .Lfunc_end0-_Z3foov
+       .cfi_endproc
+                                        # -- End function
+       .section        .text.main,"ax",@progbits
+       .globl  main                            # -- Begin function main
+       .p2align        4, 0x90
+       .type   main,@function
+main:                                   # @main
+.Lfunc_begin1:
+       .loc    1 2 0 is_stmt 1                 # main.cpp:2:0
+       .cfi_startproc
+# %bb.0:                                # %entry
+       pushq   %rbp
+       .cfi_def_cfa_offset 16
+       .cfi_offset %rbp, -16
+       movq    %rsp, %rbp
+       .cfi_def_cfa_register %rbp
+       subq    $16, %rsp
+       movl    $0, -4(%rbp)
+.Ltmp2:
+       .loc    1 2 21 prologue_end             # main.cpp:2:21
+       callq   _Z3foov
+       .loc    1 2 14 epilogue_begin is_stmt 0 # main.cpp:2:14
+       addq    $16, %rsp
+       popq    %rbp
+       .cfi_def_cfa %rsp, 8
+       retq
+.Ltmp3:
+.Lfunc_end1:
+       .size   main, .Lfunc_end1-main
+       .cfi_endproc
+                                        # -- End function
+       .section        .debug_abbrev,"",@progbits
+       .byte   1                               # Abbreviation Code
+       .byte   17                              # DW_TAG_compile_unit
+       .byte   0                               # DW_CHILDREN_no
+       .byte   16                              # DW_AT_stmt_list
+       .byte   23                              # DW_FORM_sec_offset
+       .byte   27                              # DW_AT_comp_dir
+       .byte   14                              # DW_FORM_strp
+       .ascii  "\264B"                         # DW_AT_GNU_pubnames
+       .byte   25                              # DW_FORM_flag_present
+       .ascii  "\260B"                         # DW_AT_GNU_dwo_name
+       .byte   14                              # DW_FORM_strp
+       .ascii  "\261B"                         # DW_AT_GNU_dwo_id
+       .byte   7                               # DW_FORM_data8
+       .byte   17                              # DW_AT_low_pc
+       .byte   1                               # DW_FORM_addr
+       .byte   85                              # DW_AT_ranges
+       .byte   23                              # DW_FORM_sec_offset
+       .ascii  "\263B"                         # DW_AT_GNU_addr_base
+       .byte   23                              # DW_FORM_sec_offset
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   0                               # EOM(3)
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+       .short  4                               # DWARF version number
+       .long   .debug_abbrev                   # Offset Into Abbrev. Section
+       .byte   8                               # Address Size (in bytes)
+       .byte   1                               # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
+       .long   .Lline_table_start0             # DW_AT_stmt_list
+       .long   .Lskel_string0                  # DW_AT_comp_dir
+                                        # DW_AT_GNU_pubnames
+       .long   .Lskel_string1                  # DW_AT_GNU_dwo_name
+       .quad   -252790171939032967             # DW_AT_GNU_dwo_id
+       .quad   0                               # DW_AT_low_pc
+       .long   .Ldebug_ranges0                 # DW_AT_ranges
+       .long   .Laddr_table_base0              # DW_AT_GNU_addr_base
+.Ldebug_info_end0:
+       .section        .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+       .quad   .Lfunc_begin0
+       .quad   .Lfunc_end0
+       .quad   .Lfunc_begin1
+       .quad   .Lfunc_end1
+       .quad   0
+       .quad   0
+       .section        .debug_str,"MS",@progbits,1
+.Lskel_string0:
+       .asciz  "." # string offset=0
+.Lskel_string1:
+       .asciz  "main.dwo"                      # string offset=58
+       .section        .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+       .asciz  "_Z3foov"                       # string offset=0
+.Linfo_string1:
+       .asciz  "foo"                           # string offset=8
+.Linfo_string2:
+       .asciz  "int"                           # string offset=12
+.Linfo_string3:
+       .asciz  "main"                          # string offset=16
+.Linfo_string4:
+       .asciz  "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 640e07c49037cca41a1bfbeb916b569d8c950aea)" # string offset=21
+.Linfo_string5:
+       .asciz  "main.cpp"                      # string offset=126
+.Linfo_string6:
+       .asciz  "main.dwo"                      # string offset=135
+       .section        .debug_str_offsets.dwo,"e",@progbits
+       .long   0
+       .long   8
+       .long   12
+       .long   16
+       .long   21
+       .long   126
+       .long   135
+       .section        .debug_info.dwo,"e",@progbits
+       .long   .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+       .short  4                               # DWARF version number
+       .long   0                               # Offset Into Abbrev. Section
+       .byte   8                               # Address Size (in bytes)
+       .byte   1                               # Abbrev [1] 0xb:0x32 DW_TAG_compile_unit
+       .byte   4                               # DW_AT_producer
+       .short  33                              # DW_AT_language
+       .byte   5                               # DW_AT_name
+       .byte   6                               # DW_AT_GNU_dwo_name
+       .quad   -252790171939032967             # DW_AT_GNU_dwo_id
+       .byte   2                               # Abbrev [2] 0x19:0x10 DW_TAG_subprogram
+       .byte   0                               # DW_AT_low_pc
+       .long   .Lfunc_end0-.Lfunc_begin0       # DW_AT_high_pc
+       .byte   1                               # DW_AT_frame_base
+       .byte   86
+       .byte   0                               # DW_AT_linkage_name
+       .byte   1                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   1                               # DW_AT_decl_line
+       .long   56                              # DW_AT_type
+                                        # DW_AT_external
+       .byte   3                               # Abbrev [3] 0x29:0xf DW_TAG_subprogram
+       .byte   1                               # DW_AT_low_pc
+       .long   .Lfunc_end1-.Lfunc_begin1       # DW_AT_high_pc
+       .byte   1                               # DW_AT_frame_base
+       .byte   86
+       .byte   3                               # DW_AT_name
+       .byte   1                               # DW_AT_decl_file
+       .byte   2                               # DW_AT_decl_line
+       .long   56                              # DW_AT_type
+                                        # DW_AT_external
+       .byte   4                               # Abbrev [4] 0x38:0x4 DW_TAG_base_type
+       .byte   2                               # DW_AT_name
+       .byte   5                               # DW_AT_encoding
+       .byte   4                               # DW_AT_byte_size
+       .byte   0                               # End Of Children Mark
+.Ldebug_info_dwo_end0:
+       .section        .debug_abbrev.dwo,"e",@progbits
+       .byte   1                               # Abbreviation Code
+       .byte   17                              # DW_TAG_compile_unit
+       .byte   1                               # DW_CHILDREN_yes
+       .byte   37                              # DW_AT_producer
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   19                              # DW_AT_language
+       .byte   5                               # DW_FORM_data2
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .ascii  "\260B"                         # DW_AT_GNU_dwo_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .ascii  "\261B"                         # DW_AT_GNU_dwo_id
+       .byte   7                               # DW_FORM_data8
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   2                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   0                               # DW_CHILDREN_no
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .byte   64                              # DW_AT_frame_base
+       .byte   24                              # DW_FORM_exprloc
+       .byte   110                             # DW_AT_linkage_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   73                              # DW_AT_type
+       .byte   19                              # DW_FORM_ref4
+       .byte   63                              # DW_AT_external
+       .byte   25                              # DW_FORM_flag_present
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   3                               # Abbreviation Code
+       .byte   46                              # DW_TAG_subprogram
+       .byte   0                               # DW_CHILDREN_no
+       .byte   17                              # DW_AT_low_pc
+       .ascii  "\201>"                         # DW_FORM_GNU_addr_index
+       .byte   18                              # DW_AT_high_pc
+       .byte   6                               # DW_FORM_data4
+       .byte   64                              # DW_AT_frame_base
+       .byte   24                              # DW_FORM_exprloc
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   58                              # DW_AT_decl_file
+       .byte   11                              # DW_FORM_data1
+       .byte   59                              # DW_AT_decl_line
+       .byte   11                              # DW_FORM_data1
+       .byte   73                              # DW_AT_type
+       .byte   19                              # DW_FORM_ref4
+       .byte   63                              # DW_AT_external
+       .byte   25                              # DW_FORM_flag_present
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   4                               # Abbreviation Code
+       .byte   36                              # DW_TAG_base_type
+       .byte   0                               # DW_CHILDREN_no
+       .byte   3                               # DW_AT_name
+       .ascii  "\202>"                         # DW_FORM_GNU_str_index
+       .byte   62                              # DW_AT_encoding
+       .byte   11                              # DW_FORM_data1
+       .byte   11                              # DW_AT_byte_size
+       .byte   11                              # DW_FORM_data1
+       .byte   0                               # EOM(1)
+       .byte   0                               # EOM(2)
+       .byte   0                               # EOM(3)
+       .section        .debug_addr,"",@progbits
+.Laddr_table_base0:
+       .quad   .Lfunc_begin0
+       .quad   .Lfunc_begin1
+       .section        .debug_gnu_pubnames,"",@progbits
+       .long   .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
+.LpubNames_start0:
+       .short  2                               # DWARF Version
+       .long   .Lcu_begin0                     # Offset of Compilation Unit Info
+       .long   48                              # Compilation Unit Length
+       .long   41                              # DIE offset
+       .byte   48                              # Attributes: FUNCTION, EXTERNAL
+       .asciz  "main"                          # External Name
+       .long   25                              # DIE offset
+       .byte   48                              # Attributes: FUNCTION, EXTERNAL
+       .asciz  "foo"                           # External Name
+       .long   0                               # End Mark
+.LpubNames_end0:
+       .section        .debug_gnu_pubtypes,"",@progbits
+       .long   .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
+.LpubTypes_start0:
+       .short  2                               # DWARF Version
+       .long   .Lcu_begin0                     # Offset of Compilation Unit Info
+       .long   48                              # Compilation Unit Length
+       .long   56                              # DIE offset
+       .byte   144                             # Attributes: TYPE, STATIC
+       .asciz  "int"                           # External Name
+       .long   0                               # End Mark
+.LpubTypes_end0:
+       .ident  "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 640e07c49037cca41a1bfbeb916b569d8c950aea)"
+       .section        ".note.GNU-stack","",@progbits
+       .addrsig
+       .addrsig_sym _Z3foov
+       .section        .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/dwarf4-df-no-base.test b/bolt/test/X86/dwarf4-df-no-base.test
new file mode 100644 (file)
index 0000000..e5274cb
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-no-base.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --debug-info main.exe | FileCheck -check-prefix=PRE-BOLT-MAIN %s
+; RUN: llvm-dwarfdump --debug-info main.exe.bolt | FileCheck -check-prefix=BOLT-MAIN %s
+
+; Tests whether we add DW_AT_GNU_ranges_base, if it's not present when Skeleton CU has
+; DW_AT_ranges.
+
+; PRE-BOLT-MAIN-NOT: DW_AT_GNU_ranges_base
+; BOLT-MAIN: DW_AT_GNU_ranges_base