# Copyright 2002 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.  

# This file was written by Jason Molenda (jmolenda@apple.com)

# In this test, we have a program that loads a dylib at run-time.  Before
# startup, we set a future-break breakpoint which should get finally set
# when the shlib is settled in.

# The shared library is compiled several different ways to force slides.

if $tracelevel then {
	strace $tracelevel
}

set prms_id 0
set bug_id 0

set libfile "libmylib"
set libbinfile ${objdir}/${subdir}/${libfile}.dylib

set testfile "dylib-loader"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}

proc get_libsystem_load_addr { } {
   global decimal
   global hex
   global gdb_prompt
   global libsystem_load_addr

   set libsystem_load_addr -1

   gdb_exit
   gdb_start
   gdb_load "/bin/echo"
   send_gdb "info sharedlibrary\n"
   gdb_expect {
     -re ".*$decimal libSystem...dylib - - *init Y Y \"\[^\"\]+libSystem...dylib\" at ($hex).*$gdb_prompt $" {
       set libsystem_load_addr $expect_out(1,string)
     }
     -re "$gdb_prompt $" { }
     timeout { }
   }
   return 0
}
   

proc build_library { args } {
   global srcdir
   global subdir
   global libfile
   global libbinfile

   set more_opts [lindex $args 0]
   set additional_flags "additional_flags=-dynamiclib $more_opts"
if     { [gdb_compile "${srcdir}/${subdir}/${libfile}.c" "${libbinfile}" executable [list debug $additional_flags]] != "" } {
        gdb_suppress_entire_file "Testcase library compile failed, so all tests in this file will automatically fail."
   }

   return 0
}

proc test_run { args } {
   # Start with a fresh gdb
   global srcdir
   global subdir
   global binfile
   global hex
   global decimal
   global libbinfile
 
   set run_name [lindex $args 0]

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

   gdb_test "future-break foo" "Function \"foo\" not defined..*Breakpoint 1 at 0x0.*" "Set object breakpoint ($run_name)"
   gdb_test "run" "Starting program: $binfile *.*\\\[Switching to process $decimal thread $hex\].*Reading symbols for shared libraries \\.+ done.*Re-enabling shared library breakpoints: 1.*foo is resolved to address \[a-f0-9A-F\].*Breakpoint 1, foo.*libmylib.c.*" "continue to object bp ($run_name)"
   gdb_test "bt" "#0 *foo.*libmylib.c.*#1 *$hex in main.*dylib-loader.c.*" "backtrace in dynamically loaded lib"
   gdb_test "info sharedlibrary" ".*libmylib.dylib *- $hex *dyld Y Y *\"${libbinfile}\" at $hex \\(offset $hex\\).*"
   gdb_test "fin" "Run till exit from #0 *foo.*in main.*dylib-loader.c.*" "finish back to main"

   gdb_exit
   return 0
}

set additional_flags "additional_flags=-DLIBNAME=\"${libbinfile}\""
if  { [gdb_compile "${srcdir}/${subdir}/$srcfile" "${binfile}" executable [list debug $additional_flags]] != "" } {
     gdb_suppress_entire_file "Testcase executable compile failed, so all tests in this file will automatically fail."
}


build_library ""
test_run "dylib no addr specified"

build_library "-seg1addr 0x0"
test_run "dylib slide from 0x0"

get_libsystem_load_addr
build_library "-seg1addr $libsystem_load_addr"
test_run "dylib slide from $libsystem_load_addr"

build_library "-seg1addr  0x500000"
test_run "dylib maybe without a slide"

return 0
