#   Copyright 2010
#   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] } 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 $srcdir/$subdir/dw2-1.S $testfile] } then {
    fail "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"
    }
}
