# Copyright 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/>.

# This test is as much about testing the lib/dwarf.exp DWARF generator
# as it is about testing GDB.  At the time this test was written, this
# was the only test that generated any DWARF using DW_FORM_strp.

load_lib dwarf.exp

# This test can only be run on targets which support DWARF-2 and use gas.
if {![dwarf2_support]} {
    return 0
}

standard_testfile .c -dw.S

if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
    return -1
}

set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
    global srcfile

    cu {} {
	compile_unit {
            {language @DW_LANG_C}
            {name ${srcfile}}
        } {
	    declare_labels int4_type struct_type

	    int4_type: DW_TAG_base_type {
		{DW_AT_byte_size 4 DW_FORM_sdata}
		{DW_AT_encoding  @DW_ATE_signed}
		{DW_AT_name      integer}
	    }

	    struct_type: DW_TAG_structure_type {
		{DW_AT_name "foo_t" DW_FORM_strp}
		{DW_AT_byte_size 12 DW_FORM_sdata}
	    } {
		member {
		    {name "aa" DW_FORM_strp}
		    {type :$int4_type}
		    {data_member_location 0 data1}
		}
		member {
		    {name "bb" DW_FORM_strp}
		    {type :$int4_type}
		    {data_member_location 4 data1}
		}
		member {
		    {name "cc" DW_FORM_strp}
		    {type :$int4_type}
		    {data_member_location 8 data1}
		}
	    }

	    DW_TAG_variable {
		{DW_AT_name global_var DW_FORM_strp}
		{DW_AT_type :$struct_type}
		{DW_AT_location {
		    DW_OP_addr [gdb_target_symbol global_var]
		} SPECIAL_expr}
		{external 1 flag}
	    }

	    subprogram {
		{external 1 flag}
		{name main DW_FORM_strp}
		{MACRO_AT_range {main}}
	    }
	}
    }
}

if { [prepare_for_testing "failed to prepare" ${testfile} \
	  [list $srcfile $asm_file] {nodebug}] } {
    return -1
}

if ![runto_main] {
    return -1
}

# Print the type of global_var.  This type information is entirely
# fictional, it only exists in the DWARF, but it contains lots of nice
# field names, all of which are stored in the .debug_str section.
gdb_test "p global_var" " = \\{aa = 0, bb = 0, cc = 0\\}"

# Verify that the executable actually contains a .debug_str section, before
# trying to remove it.  This can be missing with target boards
# cc-with-dwz-m.exp and cc-with-gnu-debuglink.exp.  Handle this by
# skipping the remainder of the test-case.
set debug_str_section "${binfile}-debug-str"
set args "--dump-section .debug_str=debug_str_section $binfile"
set result [remote_exec host "[gdb_find_objcopy] $args"]
set status [lindex $result 0]
set output [lindex $result 1]
if { $status == 0 && ![string equal $output ""] } {
    return -1
}

# Now copy the executable, and remove the .debug_str section.  This
# creates an executable with an invalid DWARF configuration.  GDB
# should give an error when trying to read the debug information from
# this executable.
set binfile_no_debug_str "${binfile}-no-debug-str"
set args "--remove-section .debug_str $binfile ${binfile_no_debug_str}"
if {[run_on_host "objcopy" [gdb_find_objcopy] "$args"]} {
    perror "failed to run objcopy"
    return -1
}

# Restart GDB, but don't load an executable.  When we do load the
# executable we're going to get an error, which we check for below.
clean_restart

set line1 "Reading symbols from \[^\r\n\]+"
set dwarf_error "Dwarf Error: DW_FORM_strp used without required section"

# This pattern is hit when GDB does not use -readnow (i.e. the default
# behaviour).
set pattern1 \
    [multi_line \
         $line1 \
         $dwarf_error \
        "\\(No debugging symbols \[^\r\n\]+\\)"]

# This pattern is hit when GDB does use -readnow (e.g. running with
# --target_board=readnow).
set pattern2 \
    [multi_line \
        $line1 \
        "Expanding full symbols from \[^\r\n\]+" \
        $dwarf_error]

# This pattern is hit when gcc adds an index (e.g. running with
# --target_board=cc-with-gdb-index).
set pattern3 \
    [multi_line \
        $line1 \
        $dwarf_error]

# Load the executable, we expect an error from the DWARF parser.
gdb_test "file $binfile_no_debug_str" "($pattern1|$pattern2|$pattern3)" \
    "file $testfile"
