diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c index 037b6433bc8..e9698a758e6 100644 --- a/gdb/compile/compile-loc2c.c +++ b/gdb/compile/compile-loc2c.c @@ -361,6 +361,10 @@ compute_stack_depth_worker (int start, int *need_tempvar, --stack_depth; break; + case DW_OP_LLVM_undefined: + ++stack_depth; + break; + case DW_OP_LLVM_offset_constu: case DW_OP_nop: break; diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index dfe34f877a7..a65d18d492a 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -3738,6 +3738,10 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, } break; + case DW_OP_LLVM_undefined: + result_entry = entry_factory->create_undefined (); + break; + default: error (_("Unhandled dwarf expression opcode 0x%x"), op); } diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index fe2174ab14a..1a903ce1233 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -1831,6 +1831,7 @@ dwarf2_get_symbol_read_needs (gdb::array_view expr, case DW_OP_push_object_address: case DW_OP_LLVM_offset: case DW_OP_LLVM_bit_offset: + case DW_OP_LLVM_undefined: break; case DW_OP_form_tls_address: diff --git a/gdb/testsuite/gdb.dwarf2/dw2-llvm-undefined.exp b/gdb/testsuite/gdb.dwarf2/dw2-llvm-undefined.exp new file mode 100644 index 00000000000..be677a1ddce --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-llvm-undefined.exp @@ -0,0 +1,144 @@ +# Copyright 2017-2020 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 . + +# Test the new DW_OP_LLVM_undefined operation. +# +# The test uses a composite location description, where some pieces +# of that location description are undefined location description. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +# Choose suitable integer registers for the test. + +set dwarf_regnum 0 + +if { [is_aarch64_target] } { + set regname x0 +} elseif { [is_aarch32_target] + || [istarget "s390*-*-*" ] + || [istarget "powerpc*-*-*"] + || [istarget "rs6000*-*-aix*"] } { + set regname r0 +} elseif { [is_x86_like_target] } { + set regname eax +} elseif { [is_amd64_regs_target] } { + set regname rax +} else { + verbose "Skipping ${gdb_test_file_name}." + return +} + +standard_testfile var-access.c ${gdb_test_file_name}-dw.S + +# Make some DWARF for the test. + +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global dwarf_regnum regname srcdir subdir srcfile + set buf_src [gdb_target_symbol buf] + + set main_result [function_range main ${srcdir}/${subdir}/${srcfile}] + set main_start [lindex $main_result 0] + set main_length [lindex $main_result 1] + + cu {} { + DW_TAG_compile_unit { + {DW_AT_name var-access.c} + {DW_AT_comp_dir /tmp} + } { + declare_labels int_type_label char_type_label array_type_label + + # define char type + char_type_label: DW_TAG_base_type { + {DW_AT_name "char"} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_byte_size 1 DW_FORM_sdata} + } + + int_type_label: DW_TAG_base_type { + {DW_AT_name "int"} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_byte_size 4 DW_FORM_sdata} + } + + array_type_label: DW_TAG_array_type { + {DW_AT_type :$char_type_label} + } { + DW_TAG_subrange_type { + {DW_AT_type :$int_type_label} + {DW_AT_upper_bound 5 DW_FORM_udata} + } + } + + DW_TAG_subprogram { + {DW_AT_name main} + {DW_AT_low_pc $main_start addr} + {DW_AT_high_pc $main_length data8} + } { + + # Array spread in different pieces of which some are + # undefined (1st and sixth bytes) and some are in a + # REGNAME register. + DW_TAG_variable { + {DW_AT_name var_array} + {DW_AT_type :$array_type_label} + {DW_AT_location { + DW_OP_LLVM_undefined + DW_OP_piece 0x1 + DW_OP_regx $dwarf_regnum + DW_OP_piece 0x4 + DW_OP_LLVM_undefined + DW_OP_piece 0x1 + } SPECIAL_expr} + } + + DW_TAG_variable { + {DW_AT_name var_int} + {DW_AT_type :$int_type_label} + {DW_AT_location { + DW_OP_LLVM_undefined + } SPECIAL_expr} + } + } + } + } +} + +if { [prepare_for_testing ${testfile}.exp ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_test_no_output "set var \$$regname = 0x04030201" "init reg" + +# Determine byte order. +set endian [get_endianness] + +switch $endian { + little {set val ", 0x1, 0x2, 0x3, 0x4, "} + big {set val ", 0x4, 0x3, 0x2, 0x1, "} +} + +gdb_test "print/x var_array" " = \\{${val}\\}" "var_array print" +gdb_test "print/x var_int" " = " "var_int print" diff --git a/include/dwarf2.def b/include/dwarf2.def index 4880a2268f6..b58560296d6 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -708,6 +708,7 @@ DW_OP (DW_OP_AARCH64_operation, 0xea) DW_OP_DUP (DW_OP_LLVM_offset, 0xe3) DW_OP_DUP (DW_OP_LLVM_offset_constu, 0xe4) DW_OP_DUP (DW_OP_LLVM_bit_offset, 0xe5) +DW_OP (DW_OP_LLVM_undefined, 0xe7) DW_END_OP DW_FIRST_ATE (DW_ATE_void, 0x0)