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

# Please email any bugs, comments, and/or additions to this file to:
# bug-gdb@prep.ai.mit.edu

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

foreach module [list "shreloc" "shreloc1" "shreloc2"] {
    if {[gdb_compile "${srcdir}/${subdir}/${module}.c" "${workdir}/${module}.o" object {debug}] != ""} {
	untested "Couldn't compile ${module}.c"
	return -1
    }
}

set additional_flags "additional_flags=-shared"

if {([istarget "*pc-cygwin"] || [istarget "*pc-mingw32"]) } {
    set additional_flags "${additional_flags} -Wl,--image-base,0x04000000"
}

foreach module [list "shreloc1" "shreloc2"] {
    if {[gdb_compile "${workdir}/${module}.o" "${workdir}/${module}.dll" executable [list debug $additional_flags]] != ""} {
	untested "Couldn't link ${module}.dll"
	return -1
    }
}

if {[gdb_compile [list "${workdir}/shreloc.o" "${workdir}/shreloc1.dll" "${workdir}/shreloc2.dll"] "${workdir}/shreloc" executable debug] != ""} {
    untested "Couldn't link shreloc executable"
    return -1
}

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