# Expect script for various DWARF tests.
#   Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
#

#
# Written by H.J. Lu (hongjiu.lu@intel.com)
#

# Exclude non-ELF targets.

if ![is_elf_format] {
    return
}

# Skip targets where -shared is not supported

if ![check_shared_lib_support] {
    return
}

# Check if compiler works
if { ![check_compiler_available] } {
    return
}

# Skip if -feliminate-dwarf2-dups isn't supported.
if ![ld_compile "$CC_FOR_TARGET -g -feliminate-dwarf2-dups" $srcdir/$subdir/dummy.c tmpdir/dummy.o] {
    return
}

set build_tests {
  {"Build libdwarf1.so"
   "-s -shared" "-fPIC -g -feliminate-dwarf2-dups"
   {dwarf1.c} {} "libdwarf1.so"}
  {"DWARF parse during linker error"
   "" "-fno-toplevel-reorder"
   {dwarf2a.c dwarf2b.c} {{error_output "dwarf2.err"}} "dwarf2.x"}
  {"Handle no DWARF information"
   "" "-g0"
   {dwarf3.c} {{error_output "dwarf3.err"}} "dwarf3.x"}
}

set run_tests {
    {"Run with libdwarf1.so first"
     "-Wl,--no-as-needed tmpdir/libdwarf1.so" ""
     {dwarf1main.c} "dwarf1a" "dwarf1.out"
     "-g -feliminate-dwarf2-dups"}
    {"Run with libdwarf1.so last"
     "tmpdir/dwarf1main.o tmpdir/libdwarf1.so" ""
     {dummy.c} "dwarf1b" "dwarf1.out"
     "-g -feliminate-dwarf2-dups"}
}

# Disable all sanitizers.
set old_CFLAGS "$CFLAGS_FOR_TARGET"
append CFLAGS_FOR_TARGET " $NOSANITIZE_CFLAGS"
run_cc_link_tests $build_tests
run_ld_link_exec_tests $run_tests
set CFLAGS_FOR_TARGET "$old_CFLAGS"

proc strip_test {} {
    global ld
    global strip
    global NM

    set test "libdwarf1c.so"
    set test_name "Strip -s $test"
    set prog $strip

    if ![ld_link $ld tmpdir/$test "-shared tmpdir/dwarf1.o"] {
	fail "$test_name"
	return
    }

    send_log "$NM -D tmpdir/$test > tmpdir/$test.exp\n"
    catch "exec $NM -D tmpdir/$test > tmpdir/$test.exp" got
    if ![string match "" $got] then {
	send_log "$got\n"
	fail "$test_name"
	return
    }

    send_log "$prog -s tmpdir/$test\n"
    catch "exec $prog -s tmpdir/$test" got
    if ![string match "" $got] then {
	send_log "$got\n"
	fail "$test_name"
	return
    }

    send_log "$NM -D tmpdir/$test > tmpdir/$test.out\n"
    catch "exec $NM -D tmpdir/$test > tmpdir/$test.out" got
    if ![string match "" $got] then {
	send_log "$got\n"
	fail "$test_name"
 	return
    }

    if { [catch {exec cmp tmpdir/$test.exp tmpdir/$test.out}] } then {
	send_log "tmpdir/$test.exp tmpdir/$test.out differ.\n"
 	fail "$test_name"
 	return
    }

    pass "$test_name"
}

strip_test
