# Copyright (C) 2003, 2005 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 2 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

# 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 {[istarget *-elf*] || [istarget *-coff] || [istarget *-aout]} then {
    verbose "test skipped - shared object files not supported by this target."
    return 0
}

if $tracelevel then {
    strace $tracelevel
}

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

set prms_id 0
set bug_id 0

set workdir ${objdir}/${subdir}
set testfile "shreloc"
set libfile1 "shreloc1"
set libfile2 "shreloc2"
set srcfile $srcdir/$subdir/$testfile.c
set lib1src $srcdir/$subdir/$libfile1.c
set lib2src $srcdir/$subdir/$libfile2.c
set binfile $objdir/$subdir/$testfile
set lib1_sl $objdir/$subdir/$libfile1.sl
set lib2_sl $objdir/$subdir/$libfile2.sl

if [get_compiler_info ${binfile}] {
    return -1
}

if { [istarget "*-*-*darwin*"] } {
    set additional_flags "additional_flags=-dynamiclib"
} else {
    set additional_flags "additional_flags=-shared"
}

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 "additional_flags=-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.

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${workdir}/shreloc

# 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

  send_gdb "print &${var}\n"
  # Match output like:
  # $1 = (int *) 0x0
  # $5 = (int (*)()) 0
  # $6 = (int (*)()) 0x24 <function_bar>
  gdb_expect {
    -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)
	  }
	}
    -re "${gdb_prompt} $"
	{ fail "get address of ${var} (unknown output)" }
    timeout
	{ fail "get address of ${var} (timeout)" }
  }
  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

    send_gdb "${command}\n"

    # Discard output
    gdb_expect {
	-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} (${result})"
		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
}

set msymfile "${workdir}/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"
    }
}
