blob: af62fc20fbb762057a78f2b139aff48562cc9f08 [file]
# Copyright 2026 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/>.
# Test DW_OP_call2 and DW_OP_call4 in a .dwo file (split DWARF), to verify
# that GDB correctly computes offsets when evaluating these operators.
# See PR gdb/31772.
#
# The CU in the .dwo file is placed after a type unit, so that it is not at
# offset 0. This is important to test that GDB correctly adds the CU offset
# within the section when computing the target of DW_OP_call2/call4.
load_lib dwarf.exp
require dwarf2_support
standard_testfile .c -dw.S
set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
# Skeleton CU in the main file.
cu {
version 5
dwo_id 0x1234
} {
compile_unit {
DW_AT_dwo_name ${::gdb_test_file_name}-dw.dwo DW_FORM_strp
} {}
}
# Type unit in the .dwo file. This is placed before the CU to ensure
# it is not at offset 0 in .debug_info.dwo.
tu {
fission 1
version 5
} 0xCAFE "the_type" {
type_unit {} {
the_type: base_type {
DW_AT_byte_size 4 DW_FORM_sdata
DW_AT_encoding @DW_ATE_signed
DW_AT_name dummy_type
}
}
}
# Compilation unit in the .dwo file.
cu {
fission 1
version 5
dwo_id 0x1234
label cu_start
} {
compile_unit {} {
declare_labels int_type dwarf_proc
int_type: DW_TAG_base_type {
DW_AT_byte_size 4 DW_FORM_sdata
DW_AT_encoding @DW_ATE_signed
DW_AT_name int
}
# DWARF procedure that multiplies the top of stack by 2.
dwarf_proc: DW_TAG_dwarf_procedure {
DW_AT_location {
DW_OP_lit2
DW_OP_mul
} SPECIAL_expr
}
# Variable using DW_OP_call2 (2-byte CU-relative offset).
# Pushes 5, calls the procedure (5 * 2 = 10).
DW_TAG_variable {
DW_AT_name var_call2
DW_AT_type :$int_type
DW_AT_location {
DW_OP_lit5
DW_OP_call2 "$dwarf_proc - $cu_start"
DW_OP_stack_value
} SPECIAL_expr
}
# Variable using DW_OP_call4 (4-byte CU-relative offset).
# Pushes 6, calls the procedure (6 * 2 = 12).
DW_TAG_variable {
DW_AT_name var_call4
DW_AT_type :$int_type
DW_AT_location {
DW_OP_lit6
DW_OP_call4 "$dwarf_proc - $cu_start"
DW_OP_stack_value
} SPECIAL_expr
}
}
}
}
set obj [standard_output_file "${testfile}-dw.o"]
if {[build_executable_and_dwo_files "$testfile.exp" "${binfile}" {} \
[list $asm_file {nodebug split-dwo} $obj] \
[list $srcfile {nodebug}]]} {
return
}
clean_restart ${testfile}
gdb_test "print var_call2" " = 10" "DW_OP_call2"
gdb_test "print var_call4" " = 12" "DW_OP_call4"