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

# Test debuginfod functionality

standard_testfile main.c

load_lib dwarf.exp

if { [which debuginfod] == 0 } {
    untested "cannot find debuginfod"
    return -1
}

if { [which curl] == 0 } {
    untested "cannot find curl"
    return -1
}

# Skip testing if gdb was not configured with debuginfod
if { [string first "with-debuginfod" \
	 [eval exec $GDB $INTERNAL_GDBFLAGS --configuration]] == -1 } {
    untested "gdb not configured with debuginfod"
    return -1
}

set cache [standard_output_file ".client_cache"]
set db [standard_output_file ".debuginfod.db"]

# Delete any preexisting test files
file delete -force $cache
file delete -force $db

set sourcetmp [standard_output_file tmp-${srcfile}]
set outputdir [standard_output_file {}]

# Make a copy source file that we can move around
if { [catch {file copy -force ${srcdir}/${subdir}/${srcfile} \
	     [standard_output_file ${sourcetmp}]}] != 0 } {
    error "create temporary file"
    return -1
}

if { [gdb_compile "$sourcetmp" "$binfile" executable {debug}] != "" } {
    untested "failed to compile"
    return -1
}

# Write some assembly that just has a .gnu_debugaltlink section.
# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp.
proc write_just_debugaltlink {filename dwzname buildid} {
    set asm_file [standard_output_file $filename]

    Dwarf::assemble $asm_file {
	upvar dwzname dwzname
	upvar buildid buildid

	gnu_debugaltlink $dwzname $buildid

	# Only the DWARF reader checks .gnu_debugaltlink, so make sure
	# there is a bit of DWARF in here.
	cu {} {
	    compile_unit {{language @DW_LANG_C}} {
	    }
	}
    }
}

# Write some DWARF that also sets the buildid.
# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp.
proc write_dwarf_file {filename buildid {value 99}} {
    set asm_file [standard_output_file $filename]

    Dwarf::assemble $asm_file {
	declare_labels int_label int_label2

	upvar buildid buildid
	upvar value value

	build_id $buildid

	cu {} {
	    compile_unit {{language @DW_LANG_C}} {
		int_label2: base_type {
		    {name int}
		    {byte_size 4 sdata}
		    {encoding @DW_ATE_signed}
		}

		constant {
		    {name the_int}
		    {type :$int_label2}
		    {const_value $value data1}
		}
	    }
	}
    }
}

proc no_url { } {
    global binfile outputdir debugdir

    setenv DEBUGINFOD_URLS ""

    # Test that gdb cannot find source without debuginfod
    clean_restart $binfile
    gdb_test_no_output "set substitute-path $outputdir /dev/null" \
	"set substitute-path"
    gdb_test "list" ".*No such file or directory.*"

    # Strip symbols into separate file and move it so gdb cannot find it \
	without debuginfod
    if { [gdb_gnu_strip_debug $binfile ""] != 0 } {
	fail "strip debuginfo"
	return -1
    }

    set debugdir [standard_output_file "debug"]
    set debuginfo [standard_output_file "fetch_src_and_symbols.debug"]

    file mkdir $debugdir
    file rename -force $debuginfo $debugdir

    # Test that gdb cannot find symbols without debuginfod
    clean_restart $binfile
    gdb_test "file" ".*No symbol file.*"

    set buildid "01234567890abcdef0123456"

    write_just_debugaltlink ${binfile}_has_altlink.S ${binfile}_dwz.o \
	$buildid
    write_dwarf_file ${binfile}_dwz.S $buildid

    if {[gdb_compile ${binfile}_has_altlink.S ${binfile}_alt.o object \
	     nodebug] != ""} {
	fail "compile main with altlink"
	return -1
    }

    if {[gdb_compile ${binfile}_dwz.S ${binfile}_dwz.o object \
	     nodebug] != ""} {
	fail "compile altlink"
	return -1
    }

    file rename -force ${binfile}_dwz.o $debugdir

    # Test that gdb cannot find dwz without debuginfod.
    clean_restart
    gdb_test "file ${binfile}_alt.o" \
	".*could not find '.gnu_debugaltlink'.*" \
	"file [file tail ${binfile}_alt.o]"
}

proc local_url { } {
    global binfile outputdir db debugdir

    # Find an unused port
    set port 7999
    set found 0
    while { ! $found } {
	incr port
	if { $port == 65536 } {
	    fail "no available ports"
	    return -1
	}

	spawn debuginfod -vvvv -d $db -p $port -F $debugdir
	expect {
	    "started http server on IPv4 IPv6 port=$port" { set found 1 }
	    "failed to bind to port" { kill_wait_spawned_process $spawn_id }
	    timeout {
		fail "find port timeout"
		return -1
	    }
	}
    }

    set metrics [list "ready 1" \
		     "thread_work_total{role=\"traverse\"} 1" \
		     "thread_work_pending{role=\"scan\"} 0" \
		     "thread_busy{role=\"scan\"} 0"]

    # Check server metrics to confirm init has completed.
    foreach m $metrics {
	set timelim 20
	while { $timelim != 0 } {
	    sleep 0.5
	    catch {exec curl -s http://127.0.0.1:$port/metrics} got

	    if { [regexp $m $got] } {
		break
	    }

	    incr timelim -1
	}

	if { $timelim == 0 } {
	    fail "server init timeout"
	    return -1
	}
    }

    # Point the client to the server
    setenv DEBUGINFOD_URLS http://127.0.0.1:$port

    # gdb should now find the symbol and source files
    clean_restart $binfile
    gdb_test_no_output "set substitute-path $outputdir /dev/null" \
	"set substitute-path"
    gdb_test "br main" "Breakpoint 1 at.*file.*"
    gdb_test "l" ".*This program is distributed in the hope.*"

    # gdb should now find the debugaltlink file
    clean_restart
    gdb_test "file ${binfile}_alt.o" \
	".*Reading symbols from ${binfile}_alt.o\.\.\.*" \
	"file [file tail ${binfile}_alt.o]"
}

set envlist \
    [list \
	 env(DEBUGINFOD_URLS) \
	 env(DEBUGINFOD_TIMEOUT) \
	 env(DEBUGINFOD_CACHE_PATH)]

save_vars $envlist {
    setenv DEBUGINFOD_TIMEOUT 30
    setenv DEBUGINFOD_CACHE_PATH $cache

    with_test_prefix no_url no_url

    with_test_prefix local_url local_url
}
