@@ -5847,6 +5847,10 @@ display_formatted_table (unsigned char *data,
case DW_LNCT_MD5:
printf (_("\tMD5\t\t\t"));
break;
+ case DW_LNCT_LLVM_source:
+ case DW_LNCT_source:
+ /* Skip source ... display on next line. */
+ break;
default:
printf (_("\t(Unknown format content type %" PRIu64 ")"),
content_type);
@@ -5861,8 +5865,10 @@ display_formatted_table (unsigned char *data,
unsigned char *datapass = data;
printf (" %d", last_entry++);
- /* Delay displaying name as the last entry for better screen layout. */
- for (namepass = 0; namepass < 2; namepass++)
+ /* Delay displaying name/source as the last entry for better screen
+ layout. */
+ int namesourcepass;
+ for (namesourcepass = 0; namesourcepass < 3; namesourcepass++)
{
format = format_start;
data = datapass;
@@ -5872,13 +5878,31 @@ display_formatted_table (unsigned char *data,
READ_ULEB (content_type, format, end);
READ_ULEB (form, format, end);
- bool do_loc = (content_type == DW_LNCT_path) != (namepass == 1);
+
+ bool do_loc = (content_type == DW_LNCT_path)
+ != (namesourcepass == 1);
+ do_loc |= (content_type == DW_LNCT_LLVM_source
+ || content_type == DW_LNCT_source)
+ != (namesourcepass == 2);
+
+ char delimiter = '\t';
+
+ /* Print Source last (if available) and print it
+ starting on the next line. */
+ if (namesourcepass == 2 && (content_type == DW_LNCT_LLVM_source
+ || content_type == DW_LNCT_source))
+ {
+ delimiter = ' ';
+ putchar ('\n');
+ printf (" Source:");
+ }
data = read_and_display_attr_value (0, form, 0, start, data, end,
0, linfo->li_address_size,
linfo->li_offset_size,
linfo->li_version, NULL,
- do_loc, section, NULL, '\t',
- -1, false, 0, 0, false);
+ do_loc, section, NULL,
+ delimiter, -1, false, 0, 0,
+ false);
}
}
new file mode 100644
@@ -0,0 +1,257 @@
+ .text
+ .file "small.c"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin0:
+ #.loc 0 1 0 # small.c:1:0
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl $0, -4(%rbp)
+.Ltmp0:
+ xorl %eax, %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x2b DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 29 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .byte 2 # Abbrev [2] 0x23:0xf DW_TAG_subprogram
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 50 # DW_AT_type
+ # DW_AT_external
+ .byte 3 # Abbrev [3] 0x32:0x4 DW_TAG_base_type
+ .byte 4 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"",@progbits
+ .long 24 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang (with hand edits)" # string offset=0
+.Linfo_string1:
+ .asciz "small.c" # string offset=44
+.Linfo_string2:
+ .asciz "/path/to/code/"
+.Linfo_string3:
+ .asciz "main" # string offset=77
+.Linfo_string4:
+ .asciz "int" # string offset=82
+ .section .debug_str_offsets,"",@progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .long .Linfo_string3
+ .long .Linfo_string4
+ .section .debug_line_str,"MS",@progbits,1
+.Lline_string1:
+ .asciz "/path/to/code/" # string offset=0
+.Lline_string2:
+ .asciz "small.c" # string offset=15
+.Lline_string3:
+ .asciz "int main() {\n return 0;\n}\n"# string offset=23
+ .section .debug_addr,"",@progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
+ .byte 0x60
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x05
+ .byte 0x00
+ .byte 0x08
+ .byte 0x00
+ .byte 0x3E
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x01
+ .byte 0x01
+ .byte 0x01
+ .byte 0xfb
+ .byte 0x0e
+ .byte 0x0d
+ .byte 0x00
+ .byte 0x01
+ .byte 0x01
+ .byte 0x01
+ .byte 0x01
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x01
+ .byte 0x00
+ .byte 0x00
+ .byte 0x01
+ .byte 0x01
+ .byte 0x01
+ .byte 0x1f
+ .byte 0x01
+ .byte 0x00 # Offset to directory.
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x04
+ .byte 0x01
+ .byte 0x1f
+ .byte 0x02
+ .byte 0x0f # Offset to filename.
+ .byte 0x05
+ .byte 0x1e
+ .byte 0x81
+ .byte 0x40
+ .byte 0x1f
+ .byte 0x01
+ .byte 0x0f
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x03
+ .byte 0xad
+ .byte 0x19
+ .byte 0x9b
+ .byte 0xfa
+ .byte 0x21
+ .byte 0x80
+ .byte 0x26
+ .byte 0xd0
+ .byte 0xf1
+ .byte 0xbe
+ .byte 0x37
+ .byte 0x41
+ .byte 0x65
+ .byte 0xa1
+ .byte 0x6d
+ .byte 0x17 # Offset to source code.
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x04
+ .byte 0x00
+ .byte 0x00
+ .byte 0x09
+ .byte 0x02
+ .byte 0x10
+ .byte 0x11
+ .byte 0x40
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x01
+ .byte 0x05
+ .byte 0x05
+ .byte 0x0a
+ .byte 0xad
+ .byte 0x06
+ .byte 0x0b
+ .byte 0x2e
+ .byte 0x02
+ .byte 0x02
+ .byte 0x00
+ .byte 0x01
+ .byte 0x01
new file mode 100644
@@ -0,0 +1,13 @@
+#...
+ The Directory Table \(offset 0x22, lines 1, columns 1\):
+
+ Entry Name
+ 0 \(indirect line string, offset: 0\): \/path\/to\/code\/
+
+ The File Name Table \(offset 0x31, lines 1, columns 4\):
+ Entry Dir MD5 Name
+ 0 0 0x6da1654137bef1d0268021fa9b19ad03 \(indirect line string, offset: 0xf\): small.c
+ Source: \(indirect line string, offset: 0x17\): int main\(\) {
+ return 0;
+}
+#pass
@@ -615,6 +615,30 @@ if { ![is_elf_format] } then {
file_on_host delete $output
}
+# Test objdump --debug=rawline on a file containing dwarf-5 embedded source
+
+if { ![is_elf_format] } then {
+ unsupported "objdump --debug=rawline-embedded-source test"
+} elseif { ![binutils_assemble $srcdir/$subdir/dwarf-embedded-source.S tmpdir/dwarf-embedded-source.${obj}] } then {
+ fail "objdump --debug=rawline-embedded-source test"
+} else {
+ if [is_remote host] {
+ set op_testfile [remote_download host tmpdir/dwarf-embedded-source.${obj}]
+ } else {
+ set op_testfile tmpdir/dwarf-embedded-source.${obj}
+ }
+
+ set got [remote_exec host "$OBJDUMP $OBJDUMPFLAGS --dwarf=rawline $op_testfile" "" "/dev/null" "tmpdir/objdump.out"]
+
+ if { [regexp_diff tmpdir/objdump.out $srcdir/$subdir/dwarf-embedded-source.rawline] } then {
+ fail "objdump --debug=rawline-embedded-source test"
+ } else {
+ pass "objdump --debug=rawline-embedded-source test"
+ }
+
+ file_on_host delete $output
+}
+
proc test_build_id_debuglink {option} {
global srcdir
global subdir
@@ -293,7 +293,9 @@ enum dwarf_line_number_content_type
DW_LNCT_timestamp = 0x3,
DW_LNCT_size = 0x4,
DW_LNCT_MD5 = 0x5,
+ DW_LNCT_source = 0x6,
DW_LNCT_lo_user = 0x2000,
+ DW_LNCT_LLVM_source = 0x2001,
DW_LNCT_hi_user = 0x3fff
};