<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 24, 2015, at 8:35 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com" class="">aaron@aaronballman.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">This appears to have caused a bot to go red:<br class=""><br class=""><a href="http://bb.pgr.jp/builders/msbuild-llvmclang-x64-msc18-DA/builds/73" class="">http://bb.pgr.jp/builders/msbuild-llvmclang-x64-msc18-DA/builds/73</a><br class=""></div></blockquote><div><br class=""></div><div>I can’t make any sense of the failure. I don’t see why only this bot generates a different line table section. It would be nice to get access to the generated binary to investigate. I’m currently on leave, but I’ll look at that as soon as I get back. In the mean time, I’m disabling the tests on windows hosts in r233130 to get that bot green again.</div><div><br class=""></div><div>Fred</div><div><br class=""></div><blockquote type="cite" class=""><div class="">~Aaron<br class=""><br class="">On Sun, Mar 15, 2015 at 4:45 PM, Frederic Riss <<a href="mailto:friss@apple.com" class="">friss@apple.com</a>> wrote:<br class=""><blockquote type="cite" class="">Author: friss<br class="">Date: Sun Mar 15 15:45:43 2015<br class="">New Revision: 232333<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=232333&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=232333&view=rev</a><br class="">Log:<br class="">[dsymutil] Add support for linking line tables.<br class=""><br class="">This code comes with a lot of cruft that is meant to mimic darwin's<br class="">dsymutil behavior. A much simpler approach (described in the numerous<br class="">FIXMEs that I put in there) gives the right output for the vast<br class="">majority of cases. The extra corner cases that are handled differently<br class="">need to be investigated: they seem to correctly handle debug info that<br class="">is in the input, but that info looks suspicious in the first place.<br class=""><br class="">Anyway, the current code needs to handle this, but I plan to revisit it<br class="">as soon as the big round of validation against the classic dsymutil is<br class="">over.<br class=""><br class="">Modified:<br class="">    llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test<br class="">    llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test<br class="">    llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test<br class="">    llvm/trunk/tools/dsymutil/DwarfLinker.cpp<br class=""><br class="">Modified: llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test?rev=232333&r1=232332&r2=232333&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test?rev=232333&r1=232332&r2=232333&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test (original)<br class="">+++ llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test Sun Mar 15 15:45:43 2015<br class="">@@ -16,10 +16,12 @@ CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:    DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")<br class=""> CHECK:    DW_AT_language [DW_FORM_data2]       (DW_LANG_C99)<br class=""> CHECK:    DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000040] = "basic1.c")<br class="">+CHECK:    DW_AT_stmt_list [DW_FORM_data4]   (0x00000000)<br class=""> CHECK:    DW_AT_comp_dir [DW_FORM_strp]     ( .debug_str[0x00000049] = "/Inputs")<br class=""> CHECK:    DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000ea0)<br class=""> CHECK:    DW_TAG_subprogram [2] *<br class=""> CHECK:    DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000051] = "main")<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic1.c")<br class=""> CHECK:      DW_AT_decl_line [DW_FORM_data1]    (23)<br class=""> CHECK:      DW_AT_prototyped [DW_FORM_flag]    (0x01)<br class=""> CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0063 => {0x00000063})<br class="">@@ -30,12 +32,13 @@ CHECK:      DW_AT_high_pc [DW_FORM_addr]<br class=""> CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )<br class=""> CHECK:      DW_TAG_formal_parameter [3]<br class=""> CHECK:        DW_AT_name [DW_FORM_strp]     ( .debug_str[0x00000056] = "argc")<br class="">+CHECK:        DW_AT_decl_file [DW_FORM_data1]       ("/Inputs/basic1.c")<br class=""> CHECK:        DW_AT_decl_line [DW_FORM_data1]  (23)<br class=""> CHECK:        DW_AT_type [DW_FORM_ref4]     (cu + 0x0063 => {0x00000063})<br class=""> CHECK:        DW_AT_location [DW_FORM_block1]  (<0x02> 91 78 )<br class=""> CHECK:      DW_TAG_formal_parameter [3]<br class=""> CHECK:        DW_AT_name [DW_FORM_strp]     ( .debug_str[0x0000005b] = "argv")<br class="">-CHECK:        DW_AT_decl_file [DW_FORM_data1]  (0x01)<br class="">+CHECK:        DW_AT_decl_file [DW_FORM_data1]  ("/Inputs/basic1.c")<br class=""> CHECK:        DW_AT_decl_line [DW_FORM_data1]  (23)<br class=""> CHECK:        DW_AT_type [DW_FORM_ref4]     (cu + 0x006a => {0x0000006a})<br class=""> CHECK:        DW_AT_location [DW_FORM_block1]  (<0x02> 91 70 )<br class="">@@ -61,6 +64,7 @@ CHECK:  Compile Unit:<br class=""> CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:   DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")<br class=""> CHECK:   DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000069] = "basic2.c")<br class="">+CHECK:   DW_AT_stmt_list [DW_FORM_data4]   (0x0000003f)<br class=""> CHECK:   DW_AT_comp_dir [DW_FORM_strp]     ( .debug_str[0x00000049] = "/Inputs")<br class=""> CHECK:   DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000ed0)<br class=""> CHECK:    DW_TAG_base_type [4]<br class="">@@ -68,14 +72,17 @@ CHECK:      DW_AT_name [DW_FORM_strp]<br class=""> CHECK:    DW_TAG_variable [7]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000072] = "private_int")<br class=""> CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0026 => {0x000000a7})<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic2.c")<br class=""> BASIC:      DW_AT_location [DW_FORM_block1] (<0x09> 03 08 10 00 00 01 00 00 00 )<br class=""> ARCHIVE:    DW_AT_location [DW_FORM_block1] (<0x09> 03 04 10 00 00 01 00 00 00 )<br class=""> CHECK:    DW_TAG_variable [7]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000007e] = "baz")<br class=""> CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0026 => {0x000000a7})<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic2.c")<br class=""> CHECK:      DW_AT_location [DW_FORM_block1] (<0x09> 03 00 10 00 00 01 00 00 00 )<br class=""> CHECK:    DW_TAG_subprogram [2] *<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000082] = "foo")<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic2.c")<br class=""> CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0026 => {0x000000a7})<br class=""> CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000ed0)<br class=""> CHECK:      DW_AT_high_pc [DW_FORM_addr]    (0x0000000100000f19)<br class="">@@ -98,11 +105,13 @@ CHECK:  Compile Unit:<br class=""> CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:    DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")<br class=""> CHECK:    DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000008e] = "basic3.c")<br class="">+CHECK:    DW_AT_stmt_list [DW_FORM_data4]   (0x00000093)<br class=""> CHECK:    DW_AT_comp_dir [DW_FORM_strp]     ( .debug_str[0x00000049] = "/Inputs")<br class=""> CHECK:    DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000f40)<br class=""> CHECK:    DW_TAG_variable [9]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000097] = "val")<br class=""> CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x003c => {0x00000162})<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic3.c")<br class=""> BASIC:      DW_AT_location [DW_FORM_block1] (<0x09> 03 04 10 00 00 01 00 00 00 )<br class=""> ARCHIVE:    DW_AT_location [DW_FORM_block1] (<0x09> 03 08 10 00 00 01 00 00 00 )<br class=""> CHECK:    DW_TAG_volatile_type [10]<br class="">@@ -142,3 +151,39 @@ CHECK-NEXT:Address Range Header: length<br class=""> CHECK-NEXT:[0x0000000100000f40 - 0x0000000100000f84)<br class=""> CHECK-NEXT:[0x0000000100000f90 - 0x0000000100000fa9)<br class=""><br class="">+CHECK: .debug_line contents:<br class="">+CHECK:                Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic1.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000ea0     23      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000eb6     24      0      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000ec4     24      0      1   0             0  is_stmt end_sequence<br class="">+<br class="">+CHECK:                 Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic2.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000ed0     19      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000ee2     20      0      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f19     20      0      1   0             0  is_stmt end_sequence<br class="">+CHECK-NEXT: 0x0000000100000f20     14      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f24     15      0      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f37     15      0      1   0             0  is_stmt end_sequence<br class="">+<br class="">+CHECK:                 Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic3.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000f40     16      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f4b     17      0      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f58     18      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f6c     19      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f7b     20      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f84     20      0      1   0             0  is_stmt end_sequence<br class="">+CHECK-NEXT: 0x0000000100000f90     11      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f9b     12      0      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000fa9     12      0      1   0             0  is_stmt end_sequence<br class="">\ No newline at end of file<br class=""><br class="">Modified: llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test?rev=232333&r1=232332&r2=232333&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test?rev=232333&r1=232332&r2=232333&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test (original)<br class="">+++ llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test Sun Mar 15 15:45:43 2015<br class="">@@ -9,6 +9,7 @@ CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:    DW_AT_producer [DW_FORM_strp]        ( .debug_str[0x00000001] = "clang version 3.7.0 ")<br class=""> CHECK:    DW_AT_language [DW_FORM_data2]       (DW_LANG_C99)<br class=""> CHECK:    DW_AT_name [DW_FORM_strp]    ( .debug_str[0x00000016] = "basic1.c")<br class="">+CHECK:    DW_AT_stmt_list [DW_FORM_sec_offset]      (0x00000000)<br class=""> CHECK:    DW_AT_comp_dir [DW_FORM_strp]        ( .debug_str[0x0000001f] = "/Inputs")<br class=""> CHECK:    DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000f40)<br class=""> CHECK:    DW_AT_high_pc [DW_FORM_data4]     (0x0000000b)<br class="">@@ -17,12 +18,14 @@ CHECK:      DW_AT_low_pc [DW_FORM_addr]<br class=""> CHECK:      DW_AT_high_pc [DW_FORM_data4]      (0x0000000b)<br class=""> CHECK:      DW_AT_frame_base [DW_FORM_exprloc] (<0x1> 56 )<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]  ( .debug_str[0x00000027] = "main")<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic1.c")<br class=""> CHECK:      DW_AT_prototyped [DW_FORM_flag_present]    (true)<br class=""> CHECK:      DW_AT_type [DW_FORM_ref_addr]   (0x00000000000000a1)<br class=""> CHECK:      DW_AT_external [DW_FORM_flag_present]      (true)<br class=""> CHECK:      DW_TAG_formal_parameter [3]<br class=""> CHECK:        DW_AT_location [DW_FORM_exprloc] (<0x3> 55 93 04 )<br class=""> CHECK:        DW_AT_name [DW_FORM_strp]        ( .debug_str[0x0000002c] = "argc")<br class="">+CHECK:        DW_AT_decl_file [DW_FORM_data1]       ("/Inputs/basic1.c")<br class=""> CHECK:        DW_AT_type [DW_FORM_ref_addr] (0x00000000000000a1)<br class=""> CHECK:      DW_TAG_formal_parameter [4]<br class=""> CHECK:        DW_AT_location [DW_FORM_exprloc] (<0x1> 54 )<br class="">@@ -45,6 +48,7 @@ CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:    DW_AT_producer [DW_FORM_strp]        ( .debug_str[0x00000001] = "clang version 3.7.0 ")<br class=""> CHECK:    DW_AT_language [DW_FORM_data2]       (DW_LANG_C99)<br class=""> CHECK:    DW_AT_name [DW_FORM_strp]    ( .debug_str[0x0000003b] = "basic2.c")<br class="">+CHECK:    DW_AT_stmt_list [DW_FORM_sec_offset]      (0x00000044)<br class=""> CHECK:    DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000f50)<br class=""> CHECK:    DW_AT_high_pc [DW_FORM_data4]     (0x00000037)<br class=""> CHECK:    DW_TAG_base_type [7]<br class="">@@ -54,6 +58,7 @@ CHECK:      DW_AT_name [DW_FORM_strp] (<br class=""> CHECK:      DW_AT_location [DW_FORM_exprloc]   (<0x9> 03 00 10 00 00 01 00 00 00 )<br class=""> CHECK:    DW_TAG_variable [8]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]  ( .debug_str[0x0000004c] = "private_int")<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic2.c")<br class=""> CHECK:      DW_AT_location [DW_FORM_exprloc]   (<0x9> 03 08 10 00 00 01 00 00 00 )<br class=""> CHECK:    DW_TAG_subprogram [9]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]  ( .debug_str[0x00000058] = "inc")<br class="">@@ -64,6 +69,7 @@ CHECK:      DW_AT_low_pc [DW_FORM_addr]<br class=""> CHECK:      DW_AT_high_pc [DW_FORM_data4]      (0x00000037)<br class=""> CHECK:      DW_AT_frame_base [DW_FORM_exprloc] (<0x1> 56 )<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]  ( .debug_str[0x0000005c] = "foo")<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic2.c")<br class=""> CHECK:      DW_AT_prototyped [DW_FORM_flag_present]    (true)<br class=""> CHECK:      DW_AT_type [DW_FORM_ref4]  (cu + 0x002a => {0x000000a1})<br class=""> CHECK:      DW_TAG_formal_parameter [11]<br class="">@@ -82,10 +88,12 @@ CHECK:  Compile Unit: {{.*}} version = 0<br class=""> CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:    DW_AT_producer [DW_FORM_strp]        ( .debug_str[0x00000001] = "clang version 3.7.0 ")<br class=""> CHECK:    DW_AT_name [DW_FORM_strp]    ( .debug_str[0x00000064] = "basic3.c")<br class="">+CHECK:    DW_AT_stmt_list [DW_FORM_sec_offset]      (0x0000009a)<br class=""> CHECK:    DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000f90)<br class=""> CHECK:    DW_AT_high_pc [DW_FORM_data4]     (0x00000024)<br class=""> CHECK:    DW_TAG_variable [13]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]  ( .debug_str[0x0000006d] = "val")<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic3.c")<br class=""> CHECK:      DW_AT_location [DW_FORM_exprloc]   (<0x9> 03 04 10 00 00 01 00 00 00 )<br class=""> CHECK:    DW_TAG_volatile_type [14]<br class=""> CHECK:    DW_TAG_subprogram [15]<br class="">@@ -129,3 +137,45 @@ CHECK-NEXT: Address Range Header: length<br class=""> CHECK-NEXT: [0x0000000100000f50 - 0x0000000100000f87)<br class=""> CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x0000011b, addr_size = 0x08, seg_size = 0x00<br class=""> CHECK-NEXT: [0x0000000100000f90 - 0x0000000100000fb4)<br class="">+<br class="">+CHECK: .debug_line contents:<br class="">+CHECK:                 Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic1.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000f40     26      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f44     27     10      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f49     27      3      1   0             0<br class="">+CHECK-NEXT: 0x0000000100000f4b     27      3      1   0             0  end_sequence<br class="">+<br class="">+CHECK:                 Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic2.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000f50     19      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f54     20     18      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f5a     20     17      1   0             0<br class="">+CHECK-NEXT: 0x0000000100000f5c     20     10      1   0             0<br class="">+CHECK-NEXT: 0x0000000100000f61     15     10      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f70     20     23      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f74     20     36      1   0             0<br class="">+CHECK-NEXT: 0x0000000100000f83     20     31      1   0             0<br class="">+CHECK-NEXT: 0x0000000100000f85     20      3      1   0             0<br class="">+CHECK-NEXT: 0x0000000100000f87     20      3      1   0             0  end_sequence<br class="">+<br class="">+CHECK:                 Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic3.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000f90     16      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f94     12     10      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f9a     17      7      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f9f     12     10      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000fa7     20      1      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000fa9     19     18      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000fab     19     10      1   0             0<br class="">+CHECK-NEXT: 0x0000000100000fb2     20      1      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000fb4     20      1      1   0             0  is_stmt end_sequence<br class=""><br class="">Modified: llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test?rev=232333&r1=232332&r2=232333&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test?rev=232333&r1=232332&r2=232333&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test (original)<br class="">+++ llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test Sun Mar 15 15:45:43 2015<br class="">@@ -10,10 +10,12 @@ CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:    DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")<br class=""> CHECK:    DW_AT_language [DW_FORM_data2]       (DW_LANG_C99)<br class=""> CHECK:    DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000040] = "basic1.c")<br class="">+CHECK:    DW_AT_stmt_list [DW_FORM_data4]   (0x00000000)<br class=""> CHECK:    DW_AT_comp_dir [DW_FORM_strp]     ( .debug_str[0x00000049] = "/Inputs")<br class=""> CHECK:    DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000f40)<br class=""> CHECK:    DW_TAG_subprogram [2] *<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000051] = "main")<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic1.c")<br class=""> CHECK:      DW_AT_decl_line [DW_FORM_data1]    (23)<br class=""> CHECK:      DW_AT_prototyped [DW_FORM_flag]    (0x01)<br class=""> CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0063 => {0x00000063})<br class="">@@ -52,11 +54,13 @@ CHECK:  Compile Unit:<br class=""> CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:    DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")<br class=""> CHECK:    DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000069] = "basic2.c")<br class="">+CHECK:    DW_AT_stmt_list [DW_FORM_data4]   (0x0000003e)<br class=""> CHECK:    DW_AT_comp_dir [DW_FORM_strp]     ( .debug_str[0x00000049] = "/Inputs")<br class=""> CHECK:   DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000f50)<br class=""> CHECK:    DW_TAG_variable [7]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000072] = "private_int")<br class=""> CHECK:      DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000063)<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic2.c")<br class=""> CHECK:      DW_AT_location [DW_FORM_block1] (<0x09> 03 08 10 00 00 01 00 00 00 )<br class=""> CHECK:    DW_TAG_variable [7]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000007e] = "baz")<br class="">@@ -89,11 +93,13 @@ CHECK:  Compile Unit:<br class=""> CHECK:  DW_TAG_compile_unit [1] *<br class=""> CHECK:    DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)")<br class=""> CHECK:    DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000008e] = "basic3.c")<br class="">+CHECK:    DW_AT_stmt_list [DW_FORM_data4]   (0x0000007e)<br class=""> CHECK:    DW_AT_comp_dir [DW_FORM_strp]     ( .debug_str[0x00000049] = "/Inputs")<br class=""> CHECK:    DW_AT_low_pc [DW_FORM_addr]       (0x0000000100000f90)<br class=""> CHECK:    DW_TAG_variable [12]<br class=""> CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000097] = "val")<br class=""> CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x003c => {0x00000176})<br class="">+CHECK:      DW_AT_decl_file [DW_FORM_data1] ("/Inputs/basic3.c")<br class=""> CHECK:      DW_AT_location [DW_FORM_block1] (<0x09> 03 04 10 00 00 01 00 00 00 )<br class=""> CHECK:    DW_TAG_volatile_type [13]<br class=""> CHECK:      DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000063)<br class="">@@ -142,3 +148,39 @@ CHECK-NEXT: Address Range Header: length<br class=""> CHECK-NEXT: [0x0000000100000f50 - 0x0000000100000f89)<br class=""> CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x0000013a, addr_size = 0x08, seg_size = 0x00<br class=""> CHECK-NEXT: [0x0000000100000f90 - 0x0000000100000fb4)<br class="">+<br class="">+<br class="">+CHECK: .debug_line contents<br class="">+CHECK:                 Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic1.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000f40     23      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f44     24      0      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f4b     24      0      1   0             0  is_stmt end_sequence<br class="">+<br class="">+CHECK:                 Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic2.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000f50     19      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f54     20      0      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f63     15      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f72     20      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f89     20      0      1   0             0  is_stmt end_sequence<br class="">+<br class="">+CHECK:                 Dir  Mod Time   File Len   File Name<br class="">+CHECK-NEXT:                 ---- ---------- ---------- ---------------------------<br class="">+CHECK-NEXT: file_names[  1]    0 0x00000000 0x00000000 basic3.c<br class="">+CHECK: Address            Line   Column File   ISA Discriminator Flags<br class="">+CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------<br class="">+CHECK-NEXT: 0x0000000100000f90     16      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f94     12      0      1   0             0  is_stmt prologue_end<br class="">+CHECK-NEXT: 0x0000000100000f9a     17      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000f9f     12      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000fa7     20      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000fa9     19      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000fb2     20      0      1   0             0  is_stmt<br class="">+CHECK-NEXT: 0x0000000100000fb4     20      0      1   0             0  is_stmt end_sequence<br class=""><br class="">Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=232333&r1=232332&r2=232333&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=232333&r1=232332&r2=232333&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)<br class="">+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Sun Mar 15 15:45:43 2015<br class="">@@ -22,6 +22,7 @@<br class=""> #include "llvm/MC/MCAsmInfo.h"<br class=""> #include "llvm/MC/MCContext.h"<br class=""> #include "llvm/MC/MCCodeEmitter.h"<br class="">+#include "llvm/MC/MCDwarf.h"<br class=""> #include "llvm/MC/MCInstrInfo.h"<br class=""> #include "llvm/MC/MCObjectFileInfo.h"<br class=""> #include "llvm/MC/MCRegisterInfo.h"<br class="">@@ -339,6 +340,7 @@ class DwarfStreamer {<br class=""><br class="">   uint32_t RangesSectionSize;<br class="">   uint32_t LocSectionSize;<br class="">+  uint32_t LineSectionSize;<br class=""><br class=""> public:<br class="">   /// \brief Actually create the streamer and the ouptut file.<br class="">@@ -392,6 +394,14 @@ public:<br class="">   /// the entries from \p Dwarf and offseting them. Update the<br class="">   /// location attributes to point to the new entries.<br class="">   void emitLocationsForUnit(const CompileUnit &Unit, DWARFContext &Dwarf);<br class="">+<br class="">+  /// \brief Emit the line table described in \p Rows into the<br class="">+  /// debug_line section.<br class="">+  void emitLineTableForUnit(StringRef PrologueBytes, unsigned MinInstLength,<br class="">+                            std::vector<DWARFDebugLine::Row> &Rows,<br class="">+                            unsigned AdddressSize);<br class="">+<br class="">+  uint32_t getLineSectionSize() const { return LineSectionSize; }<br class=""> };<br class=""><br class=""> bool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) {<br class="">@@ -459,6 +469,7 @@ bool DwarfStreamer::init(Triple TheTripl<br class=""><br class="">   RangesSectionSize = 0;<br class="">   LocSectionSize = 0;<br class="">+  LineSectionSize = 0;<br class=""><br class="">   return true;<br class=""> }<br class="">@@ -694,6 +705,151 @@ void DwarfStreamer::emitLocationsForUnit<br class="">   }<br class=""> }<br class=""><br class="">+void DwarfStreamer::emitLineTableForUnit(StringRef PrologueBytes,<br class="">+                                         unsigned MinInstLength,<br class="">+                                         std::vector<DWARFDebugLine::Row> &Rows,<br class="">+                                         unsigned PointerSize) {<br class="">+  // Switch to the section where the table will be emitted into.<br class="">+  MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection());<br class="">+  MCSymbol *LineStartSym = MC->CreateTempSymbol();<br class="">+  MCSymbol *LineEndSym = MC->CreateTempSymbol();<br class="">+<br class="">+  // The first 4 bytes is the total length of the information for this<br class="">+  // compilation unit (not including these 4 bytes for the length).<br class="">+  Asm->EmitLabelDifference(LineEndSym, LineStartSym, 4);<br class="">+  Asm->OutStreamer.EmitLabel(LineStartSym);<br class="">+  // Copy Prologue.<br class="">+  MS->EmitBytes(PrologueBytes);<br class="">+  LineSectionSize += PrologueBytes.size() + 4;<br class="">+<br class="">+  SmallString<16> EncodingBuffer;<br class="">+  raw_svector_ostream EncodingOS(EncodingBuffer);<br class="">+<br class="">+  if (Rows.empty()) {<br class="">+    // We only have the dummy entry, dsymutil emits an entry with a 0<br class="">+    // address in that case.<br class="">+    MCDwarfLineAddr::Encode(*MC, INT64_MAX, 0, EncodingOS);<br class="">+    MS->EmitBytes(EncodingOS.str());<br class="">+    LineSectionSize += EncodingBuffer.size();<br class="">+    EncodingBuffer.resize(0);<br class="">+    MS->EmitLabel(LineEndSym);<br class="">+    return;<br class="">+  }<br class="">+<br class="">+  // Line table state machine fields<br class="">+  unsigned FileNum = 1;<br class="">+  unsigned LastLine = 1;<br class="">+  unsigned Column = 0;<br class="">+  unsigned IsStatement = 1;<br class="">+  unsigned Isa = 0;<br class="">+  uint64_t Address = -1ULL;<br class="">+<br class="">+  unsigned RowsSinceLastSequence = 0;<br class="">+<br class="">+  for (unsigned Idx = 0; Idx < Rows.size(); ++Idx) {<br class="">+    auto &Row = Rows[Idx];<br class="">+<br class="">+    int64_t AddressDelta;<br class="">+    if (Address == -1ULL) {<br class="">+      MS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);<br class="">+      MS->EmitULEB128IntValue(PointerSize + 1);<br class="">+      MS->EmitIntValue(dwarf::DW_LNE_set_address, 1);<br class="">+      MS->EmitIntValue(Row.Address, PointerSize);<br class="">+      LineSectionSize += 2 + PointerSize + getULEB128Size(PointerSize + 1);<br class="">+      AddressDelta = 0;<br class="">+    } else {<br class="">+      AddressDelta = (Row.Address - Address) / MinInstLength;<br class="">+    }<br class="">+<br class="">+    // FIXME: code copied and transfromed from<br class="">+    // MCDwarf.cpp::EmitDwarfLineTable. We should find a way to share<br class="">+    // this code, but the current compatibility requirement with<br class="">+    // classic dsymutil makes it hard. Revisit that once this<br class="">+    // requirement is dropped.<br class="">+<br class="">+    if (FileNum != Row.File) {<br class="">+      FileNum = Row.File;<br class="">+      MS->EmitIntValue(dwarf::DW_LNS_set_file, 1);<br class="">+      MS->EmitULEB128IntValue(FileNum);<br class="">+      LineSectionSize += 1 + getULEB128Size(FileNum);<br class="">+    }<br class="">+    if (Column != Row.Column) {<br class="">+      Column = Row.Column;<br class="">+      MS->EmitIntValue(dwarf::DW_LNS_set_column, 1);<br class="">+      MS->EmitULEB128IntValue(Column);<br class="">+      LineSectionSize += 1 + getULEB128Size(Column);<br class="">+    }<br class="">+<br class="">+    // FIXME: We should handle the discriminator here, but dsymutil<br class="">+    // doesn' consider it, thus ignore it for now.<br class="">+<br class="">+    if (Isa != Row.Isa) {<br class="">+      Isa = Row.Isa;<br class="">+      MS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);<br class="">+      MS->EmitULEB128IntValue(Isa);<br class="">+      LineSectionSize += 1 + getULEB128Size(Isa);<br class="">+    }<br class="">+    if (IsStatement != Row.IsStmt) {<br class="">+      IsStatement = Row.IsStmt;<br class="">+      MS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);<br class="">+      LineSectionSize += 1;<br class="">+    }<br class="">+    if (Row.BasicBlock) {<br class="">+      MS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1);<br class="">+      LineSectionSize += 1;<br class="">+    }<br class="">+<br class="">+    if (Row.PrologueEnd) {<br class="">+      MS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1);<br class="">+      LineSectionSize += 1;<br class="">+    }<br class="">+<br class="">+    if (Row.EpilogueBegin) {<br class="">+      MS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);<br class="">+      LineSectionSize += 1;<br class="">+    }<br class="">+<br class="">+    int64_t LineDelta = int64_t(Row.Line) - LastLine;<br class="">+    if (!Row.EndSequence) {<br class="">+      MCDwarfLineAddr::Encode(*MC, LineDelta, AddressDelta, EncodingOS);<br class="">+      MS->EmitBytes(EncodingOS.str());<br class="">+      LineSectionSize += EncodingBuffer.size();<br class="">+      EncodingBuffer.resize(0);<br class="">+      Address = Row.Address;<br class="">+      LastLine = Row.Line;<br class="">+      RowsSinceLastSequence++;<br class="">+    } else {<br class="">+      if (LineDelta) {<br class="">+        MS->EmitIntValue(dwarf::DW_LNS_advance_line, 1);<br class="">+        MS->EmitSLEB128IntValue(LineDelta);<br class="">+        LineSectionSize += 1 + getSLEB128Size(LineDelta);<br class="">+      }<br class="">+      if (AddressDelta) {<br class="">+        MS->EmitIntValue(dwarf::DW_LNS_advance_pc, 1);<br class="">+        MS->EmitULEB128IntValue(AddressDelta);<br class="">+        LineSectionSize += 1 + getULEB128Size(AddressDelta);<br class="">+      }<br class="">+      MCDwarfLineAddr::Encode(*MC, INT64_MAX, 0, EncodingOS);<br class="">+      MS->EmitBytes(EncodingOS.str());<br class="">+      LineSectionSize += EncodingBuffer.size();<br class="">+      EncodingBuffer.resize(0);<br class="">+<br class="">+      Address = -1ULL;<br class="">+      LastLine = FileNum = IsStatement = 1;<br class="">+      RowsSinceLastSequence = Column = Isa = 0;<br class="">+    }<br class="">+  }<br class="">+<br class="">+  if (RowsSinceLastSequence) {<br class="">+    MCDwarfLineAddr::Encode(*MC, INT64_MAX, 0, EncodingOS);<br class="">+    MS->EmitBytes(EncodingOS.str());<br class="">+    LineSectionSize += EncodingBuffer.size();<br class="">+    EncodingBuffer.resize(0);<br class="">+  }<br class="">+<br class="">+  MS->EmitLabel(LineEndSym);<br class="">+}<br class="">+<br class=""> /// \brief The core of the Dwarf linking logic.<br class=""> ///<br class=""> /// The link of the dwarf information from the object files will be<br class="">@@ -724,7 +880,7 @@ public:<br class=""><br class=""> private:<br class="">   /// \brief Called at the start of a debug object link.<br class="">-  void startDebugObject(DWARFContext &);<br class="">+  void startDebugObject(DWARFContext &, DebugMapObject &);<br class=""><br class="">   /// \brief Called at the end of a debug object link.<br class="">   void endDebugObject();<br class="">@@ -893,6 +1049,11 @@ private:<br class="">   /// compile_unit if it had one.<br class="">   void generateUnitRanges(CompileUnit &Unit) const;<br class=""><br class="">+  /// \brief Extract the line tables fromt he original dwarf, extract<br class="">+  /// the relevant parts according to the linked function ranges and<br class="">+  /// emit the result in the debug_line section.<br class="">+  void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf);<br class="">+<br class="">   /// \brief DIELoc objects that need to be destructed (but not freed!).<br class="">   std::vector<DIELoc *> DIELocs;<br class="">   /// \brief DIEBlock objects that need to be destructed (but not freed!).<br class="">@@ -931,6 +1092,14 @@ private:<br class=""><br class="">   /// \brief The Dwarf string pool<br class="">   NonRelocatableStringpool StringPool;<br class="">+<br class="">+  /// \brief This map is keyed by the entry PC of functions in that<br class="">+  /// debug object and the associated value is a pair storing the<br class="">+  /// corresponding end PC and the offset to apply to get the linked<br class="">+  /// address.<br class="">+  ///<br class="">+  /// See startDebugObject() for a more complete description of its use.<br class="">+  std::map<uint64_t, std::pair<uint64_t, int64_t>> Ranges;<br class=""> };<br class=""><br class=""> /// \brief Similar to DWARFUnitSection::getUnitForOffset(), but<br class="">@@ -1015,14 +1184,36 @@ static bool dieNeedsChildrenToBeMeaningf<br class="">   llvm_unreachable("Invalid Tag");<br class=""> }<br class=""><br class="">-void DwarfLinker::startDebugObject(DWARFContext &Dwarf) {<br class="">+void DwarfLinker::startDebugObject(DWARFContext &Dwarf, DebugMapObject &Obj) {<br class="">   Units.reserve(Dwarf.getNumCompileUnits());<br class="">   NextValidReloc = 0;<br class="">+  // Iterate over the debug map entries and put all the ones that are<br class="">+  // functions (because they have a size) into the Ranges map. This<br class="">+  // map is very similar to the FunctionRanges that are stored in each<br class="">+  // unit, with 2 notable differences:<br class="">+  //  - obviously this one is global, while the other ones are per-unit.<br class="">+  //  - this one contains not only the functions described in the DIE<br class="">+  // tree, but also the ones that are only in the debug map.<br class="">+  // The latter information is required to reproduce dsymutil's logic<br class="">+  // while linking line tables. The cases where this information<br class="">+  // matters look like bugs that need to be investigated, but for now<br class="">+  // we need to reproduce dsymutil's behavior.<br class="">+  // FIXME: Once we understood exactly if that information is needed,<br class="">+  // maybe totally remove this (or try to use it to do a real<br class="">+  // -gline-tables-only on Darwin.<br class="">+  for (const auto &Entry : Obj.symbols()) {<br class="">+    const auto &Mapping = Entry.getValue();<br class="">+    if (Mapping.Size)<br class="">+      Ranges[Mapping.ObjectAddress] = std::make_pair(<br class="">+          Mapping.ObjectAddress + Mapping.Size,<br class="">+          int64_t(Mapping.BinaryAddress) - Mapping.ObjectAddress);<br class="">+  }<br class=""> }<br class=""><br class=""> void DwarfLinker::endDebugObject() {<br class="">   Units.clear();<br class="">   ValidRelocs.clear();<br class="">+  Ranges.clear();<br class=""><br class="">   for (auto *Block : DIEBlocks)<br class="">     Block->~DIEBlock();<br class="">@@ -1259,6 +1450,8 @@ unsigned DwarfLinker::shouldKeepSubprogr<br class="">     HighPc = LowPc + *HighPcValue.getAsUnsignedConstant();<br class="">   }<br class=""><br class="">+  // Replace the debug map range with a more accurate one.<br class="">+  Ranges[LowPc] = std::make_pair(HighPc, MyInfo.AddrAdjust);<br class="">   Unit.addFunctionRange(LowPc, HighPc, MyInfo.AddrAdjust);<br class="">   return Flags;<br class=""> }<br class="">@@ -1854,6 +2047,176 @@ void DwarfLinker::generateUnitRanges(Com<br class="">   Streamer->emitUnitRangesEntries(Unit, Attr != nullptr);<br class=""> }<br class=""><br class="">+/// \brief Insert the new line info sequence \p Seq into the current<br class="">+/// set of already linked line info \p Rows.<br class="">+static void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,<br class="">+                               std::vector<DWARFDebugLine::Row> &Rows) {<br class="">+  if (Seq.empty())<br class="">+    return;<br class="">+<br class="">+  if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {<br class="">+    Rows.insert(Rows.end(), Seq.begin(), Seq.end());<br class="">+    Seq.clear();<br class="">+    return;<br class="">+  }<br class="">+<br class="">+  auto InsertPoint = std::lower_bound(<br class="">+      Rows.begin(), Rows.end(), Seq.front(),<br class="">+      [](const DWARFDebugLine::Row &LHS, const DWARFDebugLine::Row &RHS) {<br class="">+        return LHS.Address < RHS.Address;<br class="">+      });<br class="">+<br class="">+  // FIXME: this only removes the unneeded end_sequence if the<br class="">+  // sequences have been inserted in order. using a global sort like<br class="">+  // described in patchLineTableForUnit() and delaying the end_sequene<br class="">+  // elimination to emitLineTableForUnit() we can get rid of all of them.<br class="">+  if (InsertPoint != Rows.end() &&<br class="">+      InsertPoint->Address == Seq.front().Address && InsertPoint->EndSequence) {<br class="">+    *InsertPoint = Seq.front();<br class="">+    Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());<br class="">+  } else {<br class="">+    Rows.insert(InsertPoint, Seq.begin(), Seq.end());<br class="">+  }<br class="">+<br class="">+  Seq.clear();<br class="">+}<br class="">+<br class="">+/// \brief Extract the line table for \p Unit from \p OrigDwarf, and<br class="">+/// recreate a relocated version of these for the address ranges that<br class="">+/// are present in the binary.<br class="">+void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,<br class="">+                                        DWARFContext &OrigDwarf) {<br class="">+  const DWARFDebugInfoEntryMinimal *CUDie =<br class="">+      Unit.getOrigUnit().getCompileUnitDIE();<br class="">+  uint64_t StmtList = CUDie->getAttributeValueAsSectionOffset(<br class="">+      &Unit.getOrigUnit(), dwarf::DW_AT_stmt_list, -1ULL);<br class="">+  if (StmtList == -1ULL)<br class="">+    return;<br class="">+<br class="">+  // Update the cloned DW_AT_stmt_list with the correct debug_line offset.<br class="">+  if (auto *OutputDIE = Unit.getOutputUnitDIE()) {<br class="">+    const auto &Abbrev = OutputDIE->getAbbrev().getData();<br class="">+    auto Stmt = std::find_if(<br class="">+        Abbrev.begin(), Abbrev.end(), [](const DIEAbbrevData &AbbrevData) {<br class="">+          return AbbrevData.getAttribute() == dwarf::DW_AT_stmt_list;<br class="">+        });<br class="">+    assert(Stmt < Abbrev.end() && "Didn't find DW_AT_stmt_list in cloned DIE!");<br class="">+    DIEInteger *StmtAttr =<br class="">+        cast<DIEInteger>(OutputDIE->getValues()[Stmt - Abbrev.begin()]);<br class="">+    StmtAttr->setValue(Streamer->getLineSectionSize());<br class="">+  }<br class="">+<br class="">+  // Parse the original line info for the unit.<br class="">+  DWARFDebugLine::LineTable LineTable;<br class="">+  uint32_t StmtOffset = StmtList;<br class="">+  StringRef LineData = OrigDwarf.getLineSection().Data;<br class="">+  DataExtractor LineExtractor(LineData, OrigDwarf.isLittleEndian(),<br class="">+                              Unit.getOrigUnit().getAddressByteSize());<br class="">+  LineTable.parse(LineExtractor, &OrigDwarf.getLineSection().Relocs,<br class="">+                  &StmtOffset);<br class="">+<br class="">+  // This vector is the output line table.<br class="">+  std::vector<DWARFDebugLine::Row> NewRows;<br class="">+  NewRows.reserve(LineTable.Rows.size());<br class="">+<br class="">+  // Current sequence of rows being extracted, before being inserted<br class="">+  // in NewRows.<br class="">+  std::vector<DWARFDebugLine::Row> Seq;<br class="">+  const auto &FunctionRanges = Unit.getFunctionRanges();<br class="">+  auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;<br class="">+<br class="">+  // FIXME: This logic is meant to generate exactly the same output as<br class="">+  // Darwin's classic dsynutil. There is a nicer way to implement this<br class="">+  // by simply putting all the relocated line info in NewRows and simply<br class="">+  // sorting NewRows before passing it to emitLineTableForUnit. This<br class="">+  // should be correct as sequences for a function should stay<br class="">+  // together in the sorted output. There are a few corner cases that<br class="">+  // look suspicious though, and that required to implement the logic<br class="">+  // this way. Revisit that once initial validation is finished.<br class="">+<br class="">+  // Iterate over the object file line info and extract the sequences<br class="">+  // that correspond to linked functions.<br class="">+  for (auto &Row : LineTable.Rows) {<br class="">+    // Check wether we stepped out of the range. The range is<br class="">+    // half-open, but consider accept the end address of the range if<br class="">+    // it is marked as end_sequence in the input (because in that<br class="">+    // case, the relocation offset is accurate and that entry won't<br class="">+    // serve as the start of another function).<br class="">+    if (CurrRange == InvalidRange || Row.Address < CurrRange.start() ||<br class="">+        Row.Address > CurrRange.stop() ||<br class="">+        (Row.Address == CurrRange.stop() && !Row.EndSequence)) {<br class="">+      // We just stepped out of a known range. Insert a end_sequence<br class="">+      // corresponding to the end of the range.<br class="">+      uint64_t StopAddress = CurrRange != InvalidRange<br class="">+                                 ? CurrRange.stop() + CurrRange.value()<br class="">+                                 : -1ULL;<br class="">+      CurrRange = FunctionRanges.find(Row.Address);<br class="">+      bool CurrRangeValid =<br class="">+          CurrRange != InvalidRange && CurrRange.start() <= Row.Address;<br class="">+      if (!CurrRangeValid) {<br class="">+        CurrRange = InvalidRange;<br class="">+        if (StopAddress != -1ULL) {<br class="">+          // Try harder by looking in the DebugMapObject function<br class="">+          // ranges map. There are corner cases where this finds a<br class="">+          // valid entry. It's unclear if this is right or wrong, but<br class="">+          // for now do as dsymutil.<br class="">+          // FIXME: Understand exactly what cases this addresses and<br class="">+          // potentially remove it along with the Ranges map.<br class="">+          auto Range = Ranges.lower_bound(Row.Address);<br class="">+          if (Range != Ranges.begin() && Range != Ranges.end())<br class="">+            --Range;<br class="">+<br class="">+          if (Range != Ranges.end() && Range->first <= Row.Address &&<br class="">+              Range->second.first >= Row.Address) {<br class="">+            StopAddress = Row.Address + Range->second.second;<br class="">+          }<br class="">+        }<br class="">+      }<br class="">+      if (StopAddress != -1ULL && !Seq.empty()) {<br class="">+        // Insert end sequence row with the computed end address, but<br class="">+        // the same line as the previous one.<br class="">+        Seq.emplace_back(Seq.back());<br class="">+        Seq.back().Address = StopAddress;<br class="">+        Seq.back().EndSequence = 1;<br class="">+        Seq.back().PrologueEnd = 0;<br class="">+        Seq.back().BasicBlock = 0;<br class="">+        Seq.back().EpilogueBegin = 0;<br class="">+        insertLineSequence(Seq, NewRows);<br class="">+      }<br class="">+<br class="">+      if (!CurrRangeValid)<br class="">+        continue;<br class="">+    }<br class="">+<br class="">+    // Ignore empty sequences.<br class="">+    if (Row.EndSequence && Seq.empty())<br class="">+      continue;<br class="">+<br class="">+    // Relocate row address and add it to the current sequence.<br class="">+    Row.Address += CurrRange.value();<br class="">+    Seq.emplace_back(Row);<br class="">+<br class="">+    if (Row.EndSequence)<br class="">+      insertLineSequence(Seq, NewRows);<br class="">+  }<br class="">+<br class="">+  // Finished extracting, now emit the line tables.<br class="">+  uint32_t PrologueEnd = StmtList + 10 + LineTable.Prologue.PrologueLength;<br class="">+  // FIXME: LLVM hardcodes it's prologue values. We just copy the<br class="">+  // prologue over and that works because we act as both producer and<br class="">+  // consumer. It would be nicer to have a real configurable line<br class="">+  // table emitter.<br class="">+  if (LineTable.Prologue.Version != 2 ||<br class="">+      LineTable.Prologue.DefaultIsStmt != DWARF2_LINE_DEFAULT_IS_STMT ||<br class="">+      LineTable.Prologue.LineBase != -5 || LineTable.Prologue.LineRange != 14 ||<br class="">+      LineTable.Prologue.OpcodeBase != 13)<br class="">+    reportWarning("line table paramters mismatch. Cannot emit.");<br class="">+  else<br class="">+    Streamer->emitLineTableForUnit(LineData.slice(StmtList + 4, PrologueEnd),<br class="">+                                   LineTable.Prologue.MinInstLength, NewRows,<br class="">+                                   Unit.getOrigUnit().getAddressByteSize());<br class="">+}<br class="">+<br class=""> bool DwarfLinker::link(const DebugMap &Map) {<br class=""><br class="">   if (Map.begin() == Map.end()) {<br class="">@@ -1888,7 +2251,7 @@ bool DwarfLinker::link(const DebugMap &M<br class=""><br class="">     // Setup access to the debug info.<br class="">     DWARFContextInMemory DwarfContext(*ErrOrObj);<br class="">-    startDebugObject(DwarfContext);<br class="">+    startDebugObject(DwarfContext, *Obj);<br class=""><br class="">     // In a first phase, just read in the debug info and store the DIE<br class="">     // parent links that we will use during the next phase.<br class="">@@ -1927,7 +2290,13 @@ bool DwarfLinker::link(const DebugMap &M<br class="">                                   11 /* Unit Header size */);<br class="">         CurrentUnit.setOutputUnitDIE(OutputDIE);<br class="">         OutputDebugInfoSize = CurrentUnit.computeNextUnitOffset();<br class="">-        if (!OutputDIE || Options.NoOutput)<br class="">+        if (Options.NoOutput)<br class="">+          continue;<br class="">+        // FIXME: for compatibility with the classic dsymutil, we emit<br class="">+        // an empty line table for the unit, even if the unit doesn't<br class="">+        // actually exist in the DIE tree.<br class="">+        patchLineTableForUnit(CurrentUnit, DwarfContext);<br class="">+        if (!OutputDIE)<br class="">           continue;<br class="">         patchRangesForUnit(CurrentUnit, DwarfContext);<br class="">         Streamer->emitLocationsForUnit(CurrentUnit, DwarfContext);<br class=""><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@cs.uiuc.edu" class="">llvm-commits@cs.uiuc.edu</a><br class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits<br class=""></blockquote></div></blockquote></div><br class=""></body></html>