# Copyright 1997, 1998, 1999, 2000, 2001, 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

if $tracelevel then {
	strace $tracelevel
	}

set prms_id 0
set bug_id 0

# are we on a target board
if ![isnative] then {
    return
}

# This test is presently only valid on HP-UX, since it requires
# that we use HP-UX-specific compiler & linker options to build
# the testcase.
# Actually this test works on solaris, and linux too.
 
if {! ([istarget "hppa*-*-*hpux*"]
       || [istarget "sparc-sun-solaris*"]
       || [istarget "*-*-linux-gnu*"]) } {
	 return
}

set libfile "solib"
set testfile "so-impl-ld"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}

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

# Build the shared libraries this test case needs.
#
#cd ${subdir}
#remote_exec build "$CC -g +z -c ${libfile}1.c -o ${libfile}1.o"


if { [test_compiler_info gcc-*-*] } then {
    set additional_flags "additional_flags=-fpic"
} else {
    if [istarget "hppa*-hp-hpux*"] then {
	set additional_flags "additional_flags=+z"
    } else {
	# don't know that the compiler is, hope for the best...
	set additional_flags ""
    }
}

if {[gdb_compile "${srcdir}/${subdir}/${libfile}1.c" "${libfile}1.o" object [list debug $additional_flags]] != ""} {
    perror "Couldn't compile ${libfile}1.c"
    return -1
}

if [istarget "hppa*-hp-hpux*"] then {
    remote_exec build "ld -b ${libfile}1.o -o ${objdir}/${subdir}/${libfile}1.sl"
} else {
    set additional_flags "additional_flags=-shared"
    gdb_compile "${libfile}1.o" "${objdir}/${subdir}/${libfile}1.sl" executable [list debug $additional_flags]
}

# Build the test case
#remote_exec build "$CC -Aa -g ${srcfile} ${libfile}1.sl -o ${binfile}"


if {$hp_cc_compiler} {
    set additional_flags "additional_flags=-Ae"
} else {
    set additional_flags ""
}

if {[gdb_compile "${srcdir}/${subdir}/${srcfile} ${objdir}/${subdir}/${libfile}1.sl" "${binfile}" executable [list debug $additional_flags]] != ""} {
    perror "Couldn't build ${binfile}"
    return -1
}
#cd ..

# Start with a fresh gdb

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

# This program implicitly loads SOM shared libraries.
#
if ![runto_main] then { fail "implicit solibs tests suppressed" }

# Verify that we can step over the first shlib call.
#
send_gdb "next\n"
gdb_expect {
  -re "21\[ \t\]*result = solib_main .result.*$gdb_prompt $"\
          {pass "step over solib call"}
  -re "$gdb_prompt $"\
          {fail "step over solib call"}
  timeout {fail "(timeout) step over solib call"}
}

# Verify that we can step into the second shlib call.
#
send_gdb "step\n"
gdb_expect {
  -re "solib_main .arg=10000. at.*${libfile}1.c:17.*$gdb_prompt $"\
          {pass "step into solib call"}
  -re "$gdb_prompt $"\
          {fail "step into solib call"}
  timeout {fail "(timeout) step into solib call"}
}

# Verify that we can step within the shlib call.
#
send_gdb "next\n"
gdb_expect {
  -re "18\[ \t\]*\}.*$gdb_prompt $"\
          {pass "step in solib call"}
  -re "$gdb_prompt $"\
          {fail "step in solib call"}
  timeout {fail "(timeout) step in solib call"}
}

# Verify that we can step out of the shlib call, and back out into
# the caller.
#
send_gdb "next\n"
gdb_expect {
    -re "0x\[0-9a-f\]*\[ \t\]*9\[ \t\]*.*$gdb_prompt $" {
	# we haven't left the callee yet, so do another next
	send_gdb "next\n"
	gdb_expect {
	    -re "main .. at.*so-impl-ld.c:22.*$gdb_prompt $"\
		{pass "step out of solib call"}
	    -re "$gdb_prompt $"\
		{fail "step out of solib call"}
	    timeout {fail "(timeout) step out of solib call"}
	}
    }

    -re "main .. at.*so-impl-ld.c:22.*$gdb_prompt $"\
	{pass "step out of solib call"}
    -re "$gdb_prompt $"\
	{fail "step out of solib call"}
    timeout {fail "(timeout) step out of solib call"}
}

gdb_exit
return 0






