# Copyright (C) 2003-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 <http://www.gnu.org/licenses/>.
#

# Tests for shared object file relocation. If two shared objects have
# the same load address (actually, overlapping load spaces), one of
# them gets relocated at load-time. Check that gdb gets the right
# values for the debugging and minimal symbols.

if {[skip_shlib_tests]} {
    return 0
}

#
# This file uses shreloc.c, shreloc1.c and shreloc2.c
#


standard_testfile .c shreloc1.c shreloc2.c

set srcfile $srcdir/$subdir/$srcfile
set lib1src $srcdir/$subdir/$srcfile2
set lib2src $srcdir/$subdir/$srcfile3
set binfile [standard_output_file $testfile]
set lib1_sl [standard_output_file shreloc1.sl]
set lib2_sl [standard_output_file shreloc2.sl]

if [get_compiler_info] {
    return -1
}

set lib_opts "debug"
set exec_opts [list debug shlib=$lib1_sl shlib=$lib2_sl]

if {([istarget "*pc-cygwin"] || [istarget "*pc-mingw32"]) } {
    lappend lib_opts "ldflags=-Wl,--image-base,0x04000000"
}

if [test_compiler_info "xlc-*"] {

    # IBM's xlc compiler does not add static variables to the ELF symbol 
    # table by default.  We need this option to make the variables show 
    # up in "maint print msymbols". 

    lappend lib_opts "additional_flags=-qstatsym"

}

if { [gdb_compile_shlib $lib1src $lib1_sl $lib_opts] != ""} {
    untested "could not build $lib1_sl."
    return -1
} elseif { [gdb_compile_shlib $lib2src $lib2_sl $lib_opts] != ""} {
    untested "could not build $lib1_s2."
    return -1
} elseif { [gdb_compile $srcfile $binfile executable $exec_opts] != ""} {
    untested "could not build $binfile."
    return -1
}

# Start with a fresh gdb.

clean_restart $binfile
gdb_load_shlib $lib1_sl
gdb_load_shlib $lib2_sl

# Load up the shared objects
if ![runto_main] then {
    fail "can't run to main"
    return 0
}

#
# Check debugging symbol relocations
#

# Check extern function for relocation
set fn_1_addr [get_var_address fn_1]
set fn_2_addr [get_var_address fn_2]

if { "${fn_1_addr}" == "${fn_2_addr}" } {
  fail "relocated extern functions have different addresses"
} else {
  pass "relocated extern functions have different addresses"
}

# Check extern var for relocation
set extern_var_1_addr [get_var_address extern_var_1]
set extern_var_2_addr [get_var_address extern_var_2]

if { "${extern_var_1_addr}" == "${extern_var_2_addr}" } {
  fail "relocated extern variables have different addresses"
} else {
  pass "relocated extern variables have different addresses"
}

# Check static var for relocation
set static_var_1_addr [get_var_address static_var_1]
set static_var_2_addr [get_var_address static_var_2]

if { "${static_var_1_addr}" == "${static_var_2_addr}" } {
  fail "relocated static variables have different addresses"
} else {
  pass "relocated static variables have different addresses"
}

#
# Check minimal symbol relocations
#

proc send_gdb_discard { command } {
    # Send a command to gdb and discard output up to the next prompt

    global gdb_prompt

    # Discard output
    gdb_test_multiple "${command}" "${command}" {
	-re ".*\[\r\n]+${gdb_prompt} $" {
	    return 1
	}
	timeout {
	    fail "{$command} (timeout)"
	    return 0
	}
    }
}

proc get_msym_addrs { var msymfile } {
    # Extract the list of values for symbols matching var in the
    # minimal symbol output file

    global gdb_prompt hex
    set result ""

    send_gdb "shell grep -E \" ${var}(\[ \t\]+.*)?\$\" ${msymfile}\n"

    while 1 {
	gdb_expect {
	    -re "\[\[\]\[ 0-9\]+\] . (${hex}) ${var}(\[ \t\]+\[^\r\n\]*)?\[\r\n\]+" {
		set result [concat $result $expect_out(1,string)]
	    }

	    -re "$gdb_prompt $" {
		pass "get_msym_addrs ${var}"
		return "${result}"
	    }

	    -re "\[^\r\n\]*\[\r\n\]+" {
		# Skip
	    }

	    timeout {
		fail "get_msym_addrs ${var} (timeout)"
		return -1
	    }
	}
    }
}

proc check_same {var msymfile} {
    # Check that the minimal symbol values matching var are the same

    set len [llength [lsort -unique [get_msym_addrs "${var}" "${msymfile}"]]]

    if { $len == 1 } {
	return 1
    } else {
	return 0
    }
}

proc check_different {var msymfile} {
    # Check that the minimal symbol values matching var are different

    set addr_list [lsort [get_msym_addrs "${var}" "${msymfile}"]]
    set prev ""

    if { [llength ${addr_list}] < 2 } {
	return 0
    }

    foreach addr ${addr_list} {
	if { ${prev} == ${addr} } {
	  return 0
	}
	set prev ${addr}
    }

    return 1
}

if [is_remote host] {
    set msymfile shreloc.txt
} else {
    set msymfile [standard_output_file shreloc.txt]
}

if [send_gdb_discard "maint print msymbols ${msymfile}"] {
    if {[check_different "static_var_\[12\]" "${msymfile}"]} {
	pass "(msymbol) relocated static vars have different addresses"
    } else {
	fail "(msymbol) relocated static vars have different addresses"
    }

    if {[check_different "extern_var_\[12\]" "${msymfile}"]} {
	pass "(msymbol) relocated extern vars have different addresses"
    } else {
	fail "(msymbol) relocated extern vars have different addresses"
    }

    if {[check_different "fn_\[12\]" "${msymfile}"]} {
	pass "(msymbol) relocated functions have different addresses"
    } else {
	fail "(msymbol) relocated functions have different addresses"
    }
}

if {([istarget "*pc-cygwin"] || [istarget "*pc-mingw32"]) } {
    #
    # We know the names of some absolute symbols included in the
    # portable-executable (DLL) format. Check that they didn't get
    # relocated.
    #
    # A better approach would be include absolute symbols via the assembler.
    #
    if {[check_same "_minor_os_version__" "${msymfile}"]} {
	pass "absolute symbols not relocated"
    } else {
	fail "absolute symbols not relocated"
    }
}
