@@ -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:
+ /* Source is displayed on next line and not in a column. */
+ break;
default:
printf (_("\t(Unknown format content type %" PRIu64 ")"),
content_type);
@@ -5861,8 +5865,8 @@ 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 for better screen layout. */
+ for (int namesourcepass = 0; namesourcepass < 3; namesourcepass++)
{
format = format_start;
data = datapass;
@@ -5872,13 +5876,32 @@ 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))
+ || ((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,78 @@
+ .text
+ .p2align 4, 0x90
+ .globl main
+ .type main, %function
+main:
+ .size main, .-main
+ .section .debug_line_str,"",%progbits
+.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
+ .4byte .Ldebug_addr_end0-.Ldebug_addr_start0 /* Length of contribution */
+.Ldebug_addr_start0:
+ .2byte 5 /* DWARF version number */
+ .byte 8 /* Address size */
+ .byte 0 /* Segment selector size */
+.Laddr_table_base0:
+ .quad .Lbegin_func_main
+.Ldebug_addr_end0:
+ .section .debug_line,"",%progbits
+.Lline_table_start0:
+ .4byte 0x39 /* prologue header length */
+ .2byte 0x5 /* dwarf version */
+
+ .byte 0x08 /* address size */
+ .byte 0x00 /* segment selector */
+
+ .4byte 0x3E /* header length = 62 */
+
+ .byte 0x01 /* min instruction length = 1 */
+ .byte 0x01 /* max ops per instruction = 1 */
+ .byte 0x01 /* default is statement */
+ .byte 0xfb /* line base */
+ .byte 0x0e /* line range = 14 */
+ .byte 0x0d /* opcode base = 13 */
+
+ .byte 0x00 /* operand counts for standard opcodes */
+ .byte 0x01
+ .byte 0x01
+ .byte 0x01
+ .byte 0x01
+ .byte 0x00
+ .byte 0x00
+ .byte 0x00
+ .byte 0x01
+ .byte 0x00
+ .byte 0x00
+ .byte 0x01
+
+ .byte 0x01 /* directory entry format count = 1 */
+ .uleb128 0x01 /* the path ... */
+ .uleb128 0x1f /* is a DW_FORM_line_strp */
+
+ .byte 0x01 /* directories count = 1 */
+ .4byte 0x00 /* offset of path string */
+
+ .byte 0x03 /* file entry format count = 3 */
+ .uleb128 0x01 /* the path ... */
+ .uleb128 0x1f /* is a DW_FORM_line_strp */
+ .uleb128 0x02 /* the directory index ... */
+ .uleb128 0x0f /* is a DW_FORM_udata */
+ .uleb128 0x2001 /* the source ... */
+ .uleb128 0x1f /* is a DW_FORM_line_strp */
+
+ .byte 0x01 /* file names count = 1 */
+ .4byte 0x0f /* offset of path string */
+ .byte 0x00 /* directory index */
+ .4byte 0x17 /* offset of source code */
+
+ .byte 0x04 /* set file index to 0 */
+ .uleb128 0x0
+
+ .byte 0x00 /* end sequence */
+ .byte 0x01
+ .byte 0x01
new file mode 100644
@@ -0,0 +1,18 @@
+#objdump: --dwarf=rawline
+#name: objdump (objdump --dwarf=rawline with embedded source)
+#source: dw5-embedded-source.S
+# Nicely print embedded source when displaying the line program in raw format
+
+#...
+ 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 0x2f, lines 1, columns 3\):
+ Entry Dir Name
+ 0 0 \(indirect line string, offset: 0xf\): small.c
+ Source: \(indirect line string, offset: 0x17\): int main\(\) {
+ return 0;
+}
+#...
@@ -615,6 +615,10 @@ if { ![is_elf_format] } then {
file_on_host delete $output
}
+if { [is_elf_format] } then {
+ run_dump_test dw5-embedded-source
+}
+
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
};