#   Copyright 2010, 2012
#   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 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.

# Test compressed .debug section.

if { [is_remote host] || ![is_elf_format] || ![is_zlib_supported] } then {
    return
}

set testfile tmpdir/dw2-1.o
set compressedfile tmpdir/dw2-1-compressed.o
set copyfile tmpdir/dw2-copy
set compressedfile2 tmpdir/dw2-2-compressed.o
set libfile tmpdir/libdw2.a
set compressedcopyfile tmpdir/dw2-copy-compressed

if { ![binutils_assemble_flags $srcdir/$subdir/dw2-1.S $testfile --nocompress-debug-sections] } then {
    unsupported "compressed debug sections"
    return
}

if { ![binutils_assemble_flags $srcdir/$subdir/dw2-1.S $compressedfile --compress-debug-sections] } then {
    unsupported "compressed debug sections"
    return
}

if { ![binutils_assemble_flags $srcdir/$subdir/dw2-2.S $compressedfile2 --compress-debug-sections] } then {
    unsupported "compressed debug sections"
    return
}

remote_file host delete $libfile
set got [binutils_run $AR "rc $libfile $compressedfile $compressedfile2"]
if ![string match "" $got] then {
    fail "compressed debug sections"
    return
}

set testname "objcopy compress debug sections"
set got [binutils_run $OBJCOPY "--compress-debug-sections $testfile ${copyfile}.o"]
if ![string match "" $got] then {
    fail "objcopy ($testname)"
} else {
    send_log "cmp $compressedfile ${copyfile}.o\n"
    verbose "cmp $compressedfile ${copyfile}.o"
    set src1 ${compressedfile}
    set src2 ${copyfile}.o
    set status [remote_exec build cmp "${src1} ${src2}"]
    set exec_output [lindex $status 1]
    set exec_output [prune_warnings $exec_output]

    if [string match "" $exec_output] then {
	pass "objcopy ($testname)"
    } else {
	send_log "$exec_output\n"
	verbose "$exec_output" 1
	fail "objcopy ($testname)"
    }
}

set testname "objcopy decompress compressed debug sections"
set got [binutils_run $OBJCOPY "--decompress-debug-sections $compressedfile ${copyfile}.o"]
if ![string match "" $got] then {
    fail "objcopy ($testname)"
} else {
    send_log "cmp $testfile ${copyfile}.o\n"
    verbose "cmp $testfile ${copyfile}.o"
    set src1 ${testfile}
    set src2 ${copyfile}.o
    set status [remote_exec build cmp "${src1} ${src2}"]
    set exec_output [lindex $status 1]
    set exec_output [prune_warnings $exec_output]

    if [string match "" $exec_output] then {
	pass "objcopy ($testname)"
    } else {
	send_log "$exec_output\n"
	verbose "$exec_output" 1
	fail "objcopy ($testname)"
    }
}

set testname "objcopy decompress debug sections in archive"
set got [binutils_run $OBJCOPY "--decompress-debug-sections $libfile ${copyfile}.a"]
if ![string match "" $got] then {
    fail "objcopy ($testname)"
} else {
    set got [remote_exec host "$READELF -S --wide ${copyfile}.a" "" "/dev/null" "tmpdir/libdw2.out"]

    if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
	fail "$testname (reason: unexpected output)"
	send_log $got
	send_log "\n"
    }

    if { [regexp_diff tmpdir/libdw2.out $srcdir/$subdir/libdw2.out] } then {
	fail "$testname"
    } else {
	pass "$testname"
    }
}

set testname "objcopy compress debug sections in archive"
set got [binutils_run $OBJCOPY "--compress-debug-sections ${copyfile}.a ${compressedcopyfile}.a"]
if ![string match "" $got] then {
    fail "objcopy ($testname)"
} else {
    set got [remote_exec host "$OBJDUMP -s -j .zdebug_line ${compressedcopyfile}.a" "" "/dev/null" "tmpdir/libdw2-compressed.out"]

    if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
	fail "$testname (reason: unexpected output)"
	send_log $got
	send_log "\n"
    }

    if { [regexp_diff tmpdir/libdw2-compressed.out $srcdir/$subdir/libdw2-compressed.out] } then {
	fail "$testname"
    } else {
	pass "$testname"
    }
}

set testname "objdump compress debug sections"
set got [remote_exec host "$OBJDUMP -W $compressedfile" "" "/dev/null" "objdump.out"]
if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
    fail "$testname"
    send_log "$got\n"
}
if { [regexp_diff objdump.out $srcdir/$subdir/dw2-1.W] } then {
    fail "$testname"
} else {
    pass "$testname"
}

set testfile tmpdir/dw2-emty.o

if { ![binutils_assemble_flags $srcdir/$subdir/dw2-empty.S $testfile --nocompress-debug-sections] } then {
    unsupported "compressed debug sections"
    return
}

set testname "objcopy compress empty debug sections"
set got [binutils_run $OBJCOPY "--compress-debug-sections $testfile ${copyfile}.o"]
if ![string match "" $got] then {
    fail "objcopy ($testname)"
} else {
    send_log "cmp $testfile ${copyfile}.o\n"
    verbose "cmp $testfile ${copyfile}.o"
    set src1 ${testfile}
    set src2 ${copyfile}.o
    set status [remote_exec build cmp "${src1} ${src2}"]
    set exec_output [lindex $status 1]
    set exec_output [prune_warnings $exec_output]

    if [string match "" $exec_output] then {
	pass "objcopy ($testname)"
    } else {
	send_log "$exec_output\n"
	verbose "$exec_output" 1
	fail "objcopy ($testname)"
    }
}
