[PATCH] readelf: DWARF5: Handle ".loc 0"

H.J. Lu hjl.tools@gmail.com
Mon Jan 18 14:37:46 GMT 2021


DWARF5 uses slot 0 with ".file 0" and ".loc 0" directives.  Update DWARF
dumper to support ".loc 0".

Does it look correct?

H.J.
---
binutils/

	PR binutils/27202
	* dwarf.c (display_debug_lines_decoded): Allow slot 0 in file
	and directory tables for DWARF5.

gas/

	PR binutils/27202
	* testsuite/gas/elf/dwarf-5-loc0.d: New file.
	* testsuite/gas/elf/dwarf-5-loc0.s: Likewise.
	* testsuite/gas/elf/elf.exp: Run dwarf-5-loc0.
---
 binutils/dwarf.c                     | 43 ++++++++++++++++++++++------
 gas/testsuite/gas/elf/dwarf-5-loc0.d | 19 ++++++++++++
 gas/testsuite/gas/elf/dwarf-5-loc0.s | 19 ++++++++++++
 gas/testsuite/gas/elf/elf.exp        |  1 +
 4 files changed, 74 insertions(+), 8 deletions(-)
 create mode 100644 gas/testsuite/gas/elf/dwarf-5-loc0.d
 create mode 100644 gas/testsuite/gas/elf/dwarf-5-loc0.s

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 19475e6cec3..24587335be1 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -4754,6 +4754,7 @@ display_debug_lines_decoded (struct dwarf_section *  section,
       unsigned int n_files = 0;
       unsigned char **directory_table = NULL;
       dwarf_vma n_directories = 0;
+      bfd_boolean dwarf5_p = FALSE;
 
       if (const_strneq (section->name, ".debug_line.")
 	  /* Note: the following does not apply to .debug_line.dwo sections.
@@ -4780,6 +4781,8 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 						& end_of_sequence)) == NULL)
 	      return 0;
 
+	  dwarf5_p = linfo.li_version >= 5;
+
 	  /* PR 17531: file: 0522b371.  */
 	  if (linfo.li_line_range == 0)
 	    {
@@ -5069,7 +5072,7 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 	      unsigned int ix = file_table[0].directory_index;
 	      const char *directory;
 
-	      if (ix == 0)
+	      if (!dwarf5_p && ix == 0)
 		directory = ".";
 	      /* PR 20439 */
 	      else if (n_directories == 0)
@@ -5081,7 +5084,14 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 		  directory = _("<corrupt>");
 		}
 	      else
-		directory = (char *) directory_table[ix - 1];
+		{
+		  /* DWARF5 file and directory indices start at 0.  */
+		  if (!dwarf5_p)
+		    ix -= 1;
+		  directory = (char *) directory_table[ix];
+		  if (dwarf5_p && *directory == '\0')
+		    directory = ".";
+		}
 
 	      if (do_wide || strlen (directory) < 76)
 		printf (_("CU: %s/%s:\n"), directory, file_table[0].name);
@@ -5245,9 +5255,14 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 		state_machine_regs.file = uladv;
 
 		{
-		  unsigned file = state_machine_regs.file - 1;
+		  unsigned file;
 		  unsigned dir;
 
+		  /* DWARF5 file and directory indices start at 0.  */
+		  if (dwarf5_p)
+		    file = state_machine_regs.file;
+		  else
+		    file = state_machine_regs.file - 1;
 		  if (file_table == NULL || n_files == 0)
 		    printf (_("\n [Use file table entry %d]\n"), file);
 		  /* PR 20439 */
@@ -5256,7 +5271,8 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 		      warn (_("file index %u > number of files %u\n"), file + 1, n_files);
 		      printf (_("\n <over large file table index %u>"), file);
 		    }
-		  else if ((dir = file_table[file].directory_index) == 0)
+		  else if ((dir = file_table[file].directory_index) == 0
+			   && !dwarf5_p)
 		    /* If directory index is 0, that means current directory.  */
 		    printf ("\n./%s:[++]\n", file_table[file].name);
 		  else if (directory_table == NULL || n_directories == 0)
@@ -5270,9 +5286,15 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 		      printf (_("\n <over large directory table entry %u>\n"), dir);
 		    }
 		  else
-		    printf ("\n%s/%s:\n",
-			    /* The directory index starts counting at 1.  */
-			    directory_table[dir - 1], file_table[file].name);
+		    {
+		      /* Before DWARF5, the directory index starts
+			 counting at 1.  */
+		      if (!dwarf5_p)
+			dir -= 1;
+		      printf ("\n%s/%s:\n",
+			      directory_table[dir],
+			      file_table[file].name);
+		    }
 		}
 		break;
 
@@ -5362,7 +5384,12 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 
 	      if (file_table)
 		{
-		  unsigned indx = state_machine_regs.file - 1;
+		  unsigned indx;
+		  /* DWARF5 file and directory indices start at 0.  */
+		  if (dwarf5_p)
+		    indx = state_machine_regs.file;
+		  else
+		    indx = state_machine_regs.file - 1;
 		  /* PR 20439  */
 		  if (indx >= n_files)
 		    {
diff --git a/gas/testsuite/gas/elf/dwarf-5-loc0.d b/gas/testsuite/gas/elf/dwarf-5-loc0.d
new file mode 100644
index 00000000000..c8249f227b4
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf-5-loc0.d
@@ -0,0 +1,19 @@
+#as: --gdwarf-3
+#readelf: -x.rodata -wL
+#name: DWARF5 .loc 0
+# The riscv targets do not support the subtraction of symbols.
+#xfail: riscv*-*
+
+Hex dump of section '\.rodata':
+  0x00000000 01 *.*
+
+Contents of the \.debug_line section:
+
+CU: /tmp/tmp.c:
+File name +Line number +Starting address +View +Stmt
+
+/tmp/tmp.c:
+tmp\.c +1 +0 +x
+tmp\.c +2 +0 +x
+tmp\.c +3 +0 +1 +x
+tmp\.c +- +0x8
diff --git a/gas/testsuite/gas/elf/dwarf-5-loc0.s b/gas/testsuite/gas/elf/dwarf-5-loc0.s
new file mode 100644
index 00000000000..bafa3367d58
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf-5-loc0.s
@@ -0,0 +1,19 @@
+	.file "tmp.c"
+	.text
+	.balign 8
+	.globl _start
+_start:
+	.file 0 "/tmp" "tmp.c"
+	.loc 0 1 view 0
+
+	.section .rodata
+	.uleb128 .L1
+
+	.text
+	.globl func
+	.type func, %function
+func:
+	.loc 0 2 view -0
+	.loc 0 3 view .L1
+	.quad 0
+	.size func, .-func
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index a0f98eddd67..dc03c5b8c20 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -295,6 +295,7 @@ if { [is_elf_format] } then {
     run_dump_test "dwarf2-19" $dump_opts
     run_dump_test "dwarf2-20" $dump_opts
     run_dump_test "dwarf-5-file0" $dump_opts
+    run_dump_test "dwarf-5-loc0" $dump_opts
     run_dump_test "dwarf-4-cu" $dump_opts
     run_dump_test "dwarf-5-cu" $dump_opts
     run_dump_test "dwarf-5-nop-for-line-table" $dump_opts
-- 
2.29.2



More information about the Binutils mailing list