# Copyright (C) 2003-2016 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
}

proc get_var_address { var } {
    global gdb_prompt hex

    # Match output like:
    # $1 = (int *) 0x0
    # $5 = (int (*)()) 0
    # $6 = (int (*)()) 0x24 <function_bar>

    gdb_test_multiple "print &${var}" "get address of ${var}" {
	-re "\\\$\[0-9\]+ = \\(.*\\) (0|$hex)( <${var}>)?\[\r\n\]+${gdb_prompt} $"
	{
	    pass "get address of ${var}"
	    if { $expect_out(1,string) == "0" } {
		return "0x0"
	    } else {
		return $expect_out(1,string)
	    }
	}
    }
    return ""
}

#
# 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"
    }
}
