[PATCH] PR27463 Accept DW_FORM_sdata for DW_AT_decl/call_file

Mark Wielaard mark@klomp.org
Fri Feb 26 16:05:09 GMT 2021


Using DW_FORM_sdata for DW_AT_decl/call_file is somewhat inefficient
since file index numbers are always positive values. But it is a valid
form to encode a constant value. Accept DW_FORM_sdata as long as it
encodes a positive value. Extend the positive value check to
DW_FORM_implicit_const.

	* dwz.c (checksum_die): Accept DW_FORM_sdata for
        DW_AT_decl/call_file as long as the value is positive. Also
        check DW_FORM_implicit_const value is positive for these
        attributes.
	(die_eq_1): Handle DW_FORM_sdata for DW_AT_decl/call_file.
	(build_abbrevs_for_die): Likewise.
	(write_die): Likewise.
	* testsuite/dwz.tests/pr27463.sh: New test.
	* testsuite/lib/unavailable-dwarf-piece.exp: New testfile
	from gdb.
	* testsuite/dwz.tests/dwz-tests.exp: Add unavailable-dwarf-piece
	for pr25109.sh.
	* testsuite/dwz.tests/main.c (foo): New function and labels.
	(bar): Likewise.
	* Makefile (TEST_EXECS_DWARF_ASM): Add unavailable-dwarf-piece.

https://sourceware.org/bugzilla/show_bug.cgi?id=27463
---
 Makefile                                  |   3 +-
 dwz.c                                     |  51 +++++-
 testsuite/dwz.tests/dwz-tests.exp         |   3 +
 testsuite/dwz.tests/main.c                |  20 +++
 testsuite/dwz.tests/pr27463.sh            |   6 +
 testsuite/lib/unavailable-dwarf-piece.exp | 272 ++++++++++++++++++++++++++++++
 6 files changed, 352 insertions(+), 3 deletions(-)
 create mode 100644 testsuite/dwz.tests/pr27463.sh
 create mode 100644 testsuite/lib/unavailable-dwarf-piece.exp

diff --git a/Makefile b/Makefile
index 7969490..edd00d8 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,8 @@ clean:
 PWD:=$(shell pwd -P)
 
 TEST_SRC = $(srcdir)/testsuite/dwz.tests
-TEST_EXECS_DWARF_ASM = no-multifile-prop invalid-dw-at-stmt-list-encoding
+TEST_EXECS_DWARF_ASM = no-multifile-prop invalid-dw-at-stmt-list-encoding \
+		       unavailable-dwarf-piece
 TEST_EXECS_x86_64 = py-section-script dw2-skip-prologue \
 	implptr-64bit-d2o4a8r8t0 varval
 TEST_EXECS = hello dwz-for-test min two-typedef start hello-gold-gdb-index \
diff --git a/dwz.c b/dwz.c
index dcf39a9..f732694 100644
--- a/dwz.c
+++ b/dwz.c
@@ -3462,8 +3462,31 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
 	    case DW_FORM_data8: value = read_64 (ptr); handled = true; break;
 	    case DW_FORM_udata:
 	      value = read_uleb128 (ptr); handled = true; break;
+	    case DW_FORM_sdata:
+	      {
+		int64_t svalue = read_sleb128 (ptr);
+		if (svalue >= 0)
+		  {
+		    value = svalue; handled = true; break;
+		  }
+		else
+		  {
+		  negative:
+		    error (0, 0, "%s: negative value %" PRId64 " for %s",
+			   dso->filename, svalue,
+			   get_DW_AT_str (t->attr[i].attr));
+		    return 1;
+		  }
+	      }
 	    case DW_FORM_implicit_const:
-	      value = t->values[i]; handled = true; break;
+	      {
+		if (t->values[i] >= 0)
+		  {
+		    value = t->values[i]; handled = true; break;
+		  }
+		else
+		  goto negative;
+	      }
 	    default:
 	      error (0, 0, "%s: Unhandled %s for %s",
 		     dso->filename, get_DW_FORM_str (form),
@@ -3541,8 +3564,23 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
 	    case DW_FORM_data8: value = read_64 (ptr); handled = true; break;
 	    case DW_FORM_udata:
 	      value = read_uleb128 (ptr); handled = true; break;
+	    case DW_FORM_sdata:
+	      {
+		int64_t svalue = read_sleb128 (ptr);
+		if (svalue >= 0)
+		  {
+		    value = svalue; handled = true; break;
+		  }
+		else
+		  goto negative;
+	      }
 	    case DW_FORM_implicit_const:
-	      value = t->values[i]; handled = true; break;
+	      if (t->values[i] >= 0)
+		{
+		  value = t->values[i]; handled = true; break;
+		}
+	      else
+		goto negative;
 	    default:
 	      error (0, 0, "%s: Unhandled %s for %s",
 		     dso->filename, get_DW_FORM_str (form),
@@ -4775,6 +4813,7 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
 	    case DW_FORM_data4: value1 = read_32 (ptr1); break;
 	    case DW_FORM_data8: value1 = read_64 (ptr1); break;
 	    case DW_FORM_udata: value1 = read_uleb128 (ptr1); break;
+	    case DW_FORM_sdata: value1 = read_sleb128 (ptr1); break;
 	    case DW_FORM_implicit_const: value1 = t1->values[i]; break;
 	    default: abort ();
 	    }
@@ -4785,6 +4824,7 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
 	    case DW_FORM_data4: value2 = read_32 (ptr2); break;
 	    case DW_FORM_data8: value2 = read_64 (ptr2); break;
 	    case DW_FORM_udata: value2 = read_uleb128 (ptr2); break;
+	    case DW_FORM_sdata: value2 = read_sleb128 (ptr2); break;
 	    case DW_FORM_implicit_const: value2 = t2->values[j]; break;
 	    default: abort ();
 	    }
@@ -4867,6 +4907,7 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
 	    case DW_FORM_data4: value1 = read_32 (ptr1); break;
 	    case DW_FORM_data8: value1 = read_64 (ptr1); break;
 	    case DW_FORM_udata: value1 = read_uleb128 (ptr1); break;
+	    case DW_FORM_sdata: value1 = read_sleb128 (ptr1); break;
 	    case DW_FORM_implicit_const: value1 = t1->values[i]; break;
 	    default: abort ();
 	    }
@@ -4877,6 +4918,7 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
 	    case DW_FORM_data4: value2 = read_32 (ptr2); break;
 	    case DW_FORM_data8: value2 = read_64 (ptr2); break;
 	    case DW_FORM_udata: value2 = read_uleb128 (ptr2); break;
+	    case DW_FORM_sdata: value2 = read_sleb128 (ptr2); break;
 	    case DW_FORM_implicit_const: value2 = t2->values[j]; break;
 	    default: abort ();
 	    }
@@ -10665,6 +10707,7 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die,
 		    case DW_FORM_data4: value = read_32 (ptr); break;
 		    case DW_FORM_data8: value = read_64 (ptr); break;
 		    case DW_FORM_udata: value = read_uleb128 (ptr); break;
+		    case DW_FORM_sdata: value = read_sleb128 (ptr); break;
 		    case DW_FORM_implicit_const:
 		      value = reft->values[i];
 		      break;
@@ -12285,6 +12328,9 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die,
 		case DW_FORM_udata:
 		  value = read_uleb128 (inptr);
 		  break;
+		case DW_FORM_sdata:
+		  value = read_sleb128 (inptr);
+		  break;
 		case DW_FORM_implicit_const:
 		  /* DW_FORM_implicit_const should have been updated
 		     already when computing abbrevs.  */
@@ -12300,6 +12346,7 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die,
 		  case DW_FORM_data4: write_32 (ptr, value); break;
 		  case DW_FORM_data8: write_64 (ptr, value); break;
 		  case DW_FORM_udata: write_uleb128 (ptr, value); break;
+		  case DW_FORM_sdata: write_sleb128 (ptr, value); break;
 		  default: abort ();
 		}
 	      j++;
diff --git a/testsuite/dwz.tests/dwz-tests.exp b/testsuite/dwz.tests/dwz-tests.exp
index 0ad77ea..811767f 100644
--- a/testsuite/dwz.tests/dwz-tests.exp
+++ b/testsuite/dwz.tests/dwz-tests.exp
@@ -89,6 +89,9 @@ foreach test $tests {
     if { $basename == "pr25109.sh" } {
 	lappend required_execs no-multifile-prop
     }
+    if { $basename == "pr27463.sh" } {
+	lappend required_execs unavailable-dwarf-piece
+    }
 
     set unsupported 0
     foreach required_exec $required_execs {
diff --git a/testsuite/dwz.tests/main.c b/testsuite/dwz.tests/main.c
index 398ec67..486b018 100644
--- a/testsuite/dwz.tests/main.c
+++ b/testsuite/dwz.tests/main.c
@@ -3,3 +3,23 @@ main (void)
 {
   return 0;
 }
+
+int
+foo (int i)
+{
+  int j;
+  asm (".global foo_start_lbl\nfoo_start_lbl:");
+  j = i *2;
+  asm (".global foo_end_lbl\nfoo_end_lbl:");
+  return j;
+}
+
+int
+bar (int i)
+{
+  int j;
+  asm (".global bar_start_lbl\nbar_start_lbl:");
+  j = i *2;
+  asm (".global bar_end_lbl\nbar_end_lbl:");
+  return j;
+}
diff --git a/testsuite/dwz.tests/pr27463.sh b/testsuite/dwz.tests/pr27463.sh
new file mode 100644
index 0000000..cd0238c
--- /dev/null
+++ b/testsuite/dwz.tests/pr27463.sh
@@ -0,0 +1,6 @@
+cp $execs/unavailable-dwarf-piece 1
+cp 1 2
+
+dwz -m 3 1 2
+
+rm -f 1 2 3
diff --git a/testsuite/lib/unavailable-dwarf-piece.exp b/testsuite/lib/unavailable-dwarf-piece.exp
new file mode 100644
index 0000000..0fa1df9
--- /dev/null
+++ b/testsuite/lib/unavailable-dwarf-piece.exp
@@ -0,0 +1,272 @@
+# Copyright (C) 2013-2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib dwarf-lib.exp
+load_lib dwarf.exp
+
+set asm_file unavailable-dwarf-piece-dw.S
+
+Dwarf::assemble $asm_file {
+    declare_labels uchar_label struct_s_label foo_label struct_t_label bar_label
+
+    cu {} {
+	compile_unit {{language @DW_LANG_C}} {
+	    uchar_label: DW_TAG_base_type {
+		{name "unsigned char"}
+		{byte_size 1 DW_FORM_sdata}
+		{encoding @DW_ATE_unsigned_char}
+	    }
+
+	    struct_s_label: DW_TAG_structure_type {
+		{name s}
+		{byte_size 3 DW_FORM_sdata}
+		{decl_file 0 DW_FORM_udata}
+		{decl_line 1 DW_FORM_sdata}
+	    } {
+		DW_TAG_member {
+		    {name a}
+		    {type :$uchar_label}
+		    {data_member_location {
+			DW_OP_plus_uconst 0
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name b}
+		    {type :$uchar_label}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name c}
+		    {type :$uchar_label}
+		    {data_member_location {
+			DW_OP_plus_uconst 2
+		    } SPECIAL_expr}
+		}
+	    }
+
+	    struct_t_label: DW_TAG_structure_type {
+		{name t}
+		{byte_size 3 DW_FORM_sdata}
+		{decl_file 0 DW_FORM_udata}
+		{decl_line 1 DW_FORM_sdata}
+	    } {
+		DW_TAG_member {
+		    {name a}
+		    {type :$uchar_label}
+		    {data_member_location {
+			DW_OP_plus_uconst 0
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name b}
+		    {type :$uchar_label}
+		    {byte_size 1 DW_FORM_sdata}
+		    {bit_size 1 DW_FORM_sdata}
+		    {bit_offset 7 DW_FORM_sdata}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name c}
+		    {type :$uchar_label}
+		    {byte_size 1 DW_FORM_sdata}
+		    {bit_size 1 DW_FORM_sdata}
+		    {bit_offset 6 DW_FORM_sdata}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name d}
+		    {type :$uchar_label}
+		    {byte_size 1 DW_FORM_sdata}
+		    {bit_size 1 DW_FORM_sdata}
+		    {bit_offset 5 DW_FORM_sdata}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name e}
+		    {type :$uchar_label}
+		    {byte_size 1 DW_FORM_sdata}
+		    {bit_size 1 DW_FORM_sdata}
+		    {bit_offset 4 DW_FORM_sdata}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name f}
+		    {type :$uchar_label}
+		    {byte_size 1 DW_FORM_sdata}
+		    {bit_size 1 DW_FORM_sdata}
+		    {bit_offset 3 DW_FORM_sdata}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name g}
+		    {type :$uchar_label}
+		    {byte_size 1 DW_FORM_sdata}
+		    {bit_size 1 DW_FORM_sdata}
+		    {bit_offset 2 DW_FORM_sdata}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name h}
+		    {type :$uchar_label}
+		    {byte_size 1 DW_FORM_sdata}
+		    {bit_size 1 DW_FORM_sdata}
+		    {bit_offset 1 DW_FORM_sdata}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name i}
+		    {type :$uchar_label}
+		    {byte_size 1 DW_FORM_sdata}
+		    {bit_size 1 DW_FORM_sdata}
+		    {bit_offset 0 DW_FORM_sdata}
+		    {data_member_location {
+			DW_OP_plus_uconst 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_member {
+		    {name j}
+		    {type :$uchar_label}
+		    {data_member_location {
+			DW_OP_plus_uconst 2
+		    } SPECIAL_expr}
+		}
+	    }
+
+	    DW_TAG_subprogram {
+		{name foo}
+		{decl_file 0 udata}
+		{low_pc foo_start_lbl addr}
+		{high_pc foo_end_lbl addr}
+	    } {
+		DW_TAG_formal_parameter {
+		    {type :$struct_s_label}
+		    {name x}
+		    {location {
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 2
+			DW_OP_reg0
+			DW_OP_piece 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_formal_parameter {
+		    {type :$struct_s_label}
+		    {name y}
+		    {location {
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 1
+			DW_OP_reg0
+			DW_OP_piece 1
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_formal_parameter {
+		    {type :$struct_s_label}
+		    {name z}
+		    {location {
+			DW_OP_reg0
+			DW_OP_piece 1
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 2
+		    } SPECIAL_expr}
+		}
+	    }
+
+
+	    DW_TAG_subprogram {
+		{name bar}
+		{decl_file 0 udata}
+		{low_pc bar_start_lbl addr}
+		{high_pc bar_end_lbl addr}
+	    } {
+		DW_TAG_formal_parameter {
+		    {type :$struct_t_label}
+		    {name x}
+		    {location {
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 1
+			DW_OP_reg0
+			DW_OP_bit_piece 1 0
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_bit_piece 7 0
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_formal_parameter {
+		    {type :$struct_t_label}
+		    {name y}
+		    {location {
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 1
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_bit_piece 3 0
+			DW_OP_reg0
+			DW_OP_bit_piece 1 0
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_bit_piece 4 0
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 1
+		    } SPECIAL_expr}
+		}
+		DW_TAG_formal_parameter {
+		    {type :$struct_t_label}
+		    {name z}
+		    {location {
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 1
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_bit_piece 7 0
+			DW_OP_reg0
+			DW_OP_bit_piece 1 0
+			DW_OP_lit0
+			DW_OP_stack_value
+			DW_OP_piece 1
+		    } SPECIAL_expr}
+		}
+	    }
+
+	}
+    }
+}
-- 
1.8.3.1



More information about the Dwz mailing list