<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>