[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