| # Copyright 2012-2016 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, see <http://www.gnu.org/licenses/>. |
| load_lib dwarf.exp |
| |
| # This test can only be run on targets which support DWARF-2 and use gas. |
| if {![dwarf2_support]} { |
| return 0 |
| } |
| |
| # Find length of addresses in bytes. |
| if {[is_64_target]} { |
| set addr_len 8 |
| } else { |
| set addr_len 4 |
| } |
| |
| standard_testfile |
| set asmsrcfile [standard_output_file ${testfile}asm.S] |
| set asmobjfile [standard_output_file ${testfile}asm.o] |
| set srcabsdir [standard_output_file ${testfile}.d] |
| set srctmpfile tmp-${testfile}.c |
| |
| # $srcdir may be relative. |
| if {[file pathtype $srcabsdir] != "absolute"} { |
| untested "objdir pathtype is not absolute" |
| return -1 |
| } |
| |
| set f [open $asmsrcfile "w"] |
| puts $f "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */" |
| |
| proc out_cu { name cu_dir cu_name line_dir line_name } { |
| global f |
| global addr_len |
| |
| puts -nonewline $f "\ |
| .L${name}_begin: |
| .4byte .L${name}_end - .L${name}_start /* Length of Compilation Unit */ |
| .L${name}_start: |
| .2byte 2 /* DWARF Version */ |
| .4byte .Labbrev1_begin /* Offset into abbrev section */ |
| .byte ${addr_len} /* Pointer size */ |
| " |
| if { $cu_dir != "" } { |
| puts $f " .uleb128 ABBREV_COMP_DIR_NAME /* Abbrev: DW_TAG_compile_unit */" |
| } else { |
| puts $f " .uleb128 ABBREV_NAME /* Abbrev: DW_TAG_compile_unit */" |
| } |
| puts -nonewline $f "\ |
| .ascii \"GNU C\\0\" /* DW_AT_producer */ |
| .byte 2 /* DW_AT_language (DW_LANG_C) */ |
| .4byte .Lline_${name}_begin /* DW_AT_stmt_list */ |
| .${addr_len}byte ${name}_start /* DW_AT_low_pc */ |
| .${addr_len}byte ${name}_end /* DW_AT_high_pc */ |
| " |
| if { $cu_dir != "" } { |
| puts $f " .ascii $cu_dir /* DW_AT_comp_dir */" |
| } |
| puts -nonewline $f "\ |
| .ascii $cu_name /* DW_AT_name */ |
| |
| .uleb128 3 /* Abbrev: DW_TAG_subprogram */ |
| .asciz \"${name}\" /* DW_AT_name */ |
| .${addr_len}byte ${name}_start /* DW_AT_low_pc */ |
| .${addr_len}byte ${name}_end /* DW_AT_high_pc */ |
| |
| .byte 0 /* End of children of CU */ |
| .L${name}_end: |
| " |
| } |
| |
| proc out_line { name cu_dir cu_name line_dir line_name } { |
| global f |
| global addr_len |
| |
| puts -nonewline $f "\ |
| .Lline_${name}_begin: |
| .4byte .Lline_${name}_end - .Lline_${name}_start /* Initial length */ |
| .Lline_${name}_start: |
| .2byte 2 /* Version */ |
| .4byte .Lline_${name}_lines - .Lline_${name}_hdr /* header_length */ |
| .Lline_${name}_hdr: |
| .byte 1 /* Minimum insn length */ |
| .byte 1 /* default_is_stmt */ |
| .byte 1 /* line_base */ |
| .byte 1 /* line_range */ |
| .byte 4 /* opcode_base */ |
| |
| /* Standard lengths */ |
| .byte 0 |
| .byte 1 |
| .byte 1 |
| |
| /* Include directories */ |
| " |
| if { $line_dir != "" } { |
| puts $f " .ascii $line_dir" |
| } |
| puts -nonewline $f "\ |
| .byte 0 |
| |
| /* File names */ |
| .ascii $line_name |
| " |
| if { $line_dir != "" } { |
| puts $f " .uleb128 1" |
| } else { |
| puts $f " .uleb128 0" |
| } |
| puts -nonewline $f "\ |
| .uleb128 0 |
| .uleb128 0 |
| |
| .byte 0 |
| |
| .Lline_${name}_lines: |
| .byte 3 /* DW_LNS_advance_line */ |
| .sleb128 998 /* ... to 999 */ |
| .byte 0 /* DW_LNE_set_address */ |
| .uleb128 ${addr_len}+1 |
| .byte 2 |
| .${addr_len}byte ${name}_start |
| .byte 1 /* DW_LNS_copy */ |
| .byte 3 /* DW_LNS_advance_line */ |
| .sleb128 1 /* ... to 1000 */ |
| .byte 0 /* DW_LNE_set_address */ |
| .uleb128 ${addr_len}+1 |
| .byte 2 |
| .${addr_len}byte ${name}_end |
| .byte 1 /* DW_LNS_copy */ |
| .byte 0 /* DW_LNE_end_of_sequence */ |
| .uleb128 1 |
| .byte 1 |
| .Lline_${name}_end: |
| " |
| } |
| |
| # IFSOME can be optionally _same or _different if >= 2 absolute directories are |
| # provided. Then in the _different case the overriden directories have invalid |
| # XDIR value. |
| |
| proc out_unit { func compdir ldir file ifsame } { |
| set name "compdir_${compdir}_ldir_${ldir}_file_${file}${ifsame}" |
| |
| if { $compdir == "missing_" } { |
| set cu_dir {} |
| } elseif { $compdir == "relative" } { |
| set cu_dir {COMPDIR "\0"} |
| } elseif { $compdir == "absolute" } { |
| set cu_dir {BDIR "/" COMPDIR "\0"} |
| } else { |
| error "compdir $compdir" |
| } |
| |
| if { $ldir == "missing_" } { |
| set line_dir {} |
| } elseif { $ldir == "relative" } { |
| set line_dir {LDIR "\0"} |
| } elseif { $ldir == "absolute" } { |
| set line_dir {BDIR "/" LDIR "\0"} |
| } else { |
| error "ldir $ldir" |
| } |
| |
| if { $file == "basename" } { |
| set cu_name {FILE "\0"} |
| } elseif { $file == "relative" } { |
| set cu_name {FDIR "/" FILE "\0"} |
| } elseif { $file == "absolute" } { |
| set cu_name {BDIR "/" FILE "\0"} |
| } else { |
| error "file $file" |
| } |
| set line_name $cu_name |
| |
| if { "$ifsame" == "_different" } { |
| if { $file == "absolute" } { |
| if { $ldir == "absolute" } { |
| set line_dir {XDIR "\0"} |
| } |
| if { $compdir == "absolute" } { |
| set cu_dir {XDIR "\0"} |
| } |
| } elseif { $ldir == "absolute" } { |
| if { $compdir == "absolute" } { |
| set cu_dir {XDIR "\0"} |
| } |
| } else { |
| error "not enough absolutes" |
| } |
| } |
| |
| $func $name $cu_dir $cu_name $line_dir $line_name |
| } |
| |
| proc out_diff { func compdir ldir file } { |
| set abscount 0 |
| if { $compdir == "absolute" } { |
| incr abscount |
| } |
| if { $ldir == "absolute" } { |
| incr abscount |
| } |
| if { $file == "absolute" } { |
| incr abscount |
| } |
| if { $abscount <= 1 } { |
| out_unit $func $compdir $ldir $file "" |
| } else { |
| out_unit $func $compdir $ldir $file "_same" |
| out_unit $func $compdir $ldir $file "_different" |
| } |
| } |
| |
| proc out_file { func compdir ldir } { |
| out_diff $func $compdir $ldir "basename" |
| out_diff $func $compdir $ldir "relative" |
| out_diff $func $compdir $ldir "absolute" |
| } |
| |
| proc out_ldir { func compdir } { |
| out_file $func $compdir "missing_" |
| out_file $func $compdir "relative" |
| out_file $func $compdir "absolute" |
| } |
| |
| proc out_compdir { func } { |
| out_ldir $func "missing_" |
| out_ldir $func "relative" |
| out_ldir $func "absolute" |
| } |
| |
| puts -nonewline $f "\ |
| #define ABBREV_NAME 1 |
| #define ABBREV_COMP_DIR_NAME 2 |
| .section .debug_info |
| " |
| out_compdir out_cu |
| |
| puts $f " .section .debug_line" |
| out_compdir out_line |
| |
| puts -nonewline $f "\ |
| .section .debug_abbrev |
| .Labbrev1_begin: |
| |
| .uleb128 ABBREV_NAME /* Abbrev code */ |
| .uleb128 0x11 /* DW_TAG_compile_unit */ |
| .byte 1 /* has_children */ |
| .uleb128 0x25 /* DW_AT_producer */ |
| .uleb128 0x8 /* DW_FORM_string */ |
| .uleb128 0x13 /* DW_AT_language */ |
| .uleb128 0xb /* DW_FORM_data1 */ |
| .uleb128 0x10 /* DW_AT_stmt_list */ |
| .uleb128 0x6 /* DW_FORM_data4 */ |
| .uleb128 0x11 /* DW_AT_low_pc */ |
| .uleb128 0x1 /* DW_FORM_addr */ |
| .uleb128 0x12 /* DW_AT_high_pc */ |
| .uleb128 0x1 /* DW_FORM_addr */ |
| .uleb128 0x3 /* DW_AT_name */ |
| .uleb128 0x8 /* DW_FORM_string */ |
| .byte 0x0 /* Terminator */ |
| .byte 0x0 /* Terminator */ |
| |
| .uleb128 ABBREV_COMP_DIR_NAME /* Abbrev code */ |
| .uleb128 0x11 /* DW_TAG_compile_unit */ |
| .byte 1 /* has_children */ |
| .uleb128 0x25 /* DW_AT_producer */ |
| .uleb128 0x8 /* DW_FORM_string */ |
| .uleb128 0x13 /* DW_AT_language */ |
| .uleb128 0xb /* DW_FORM_data1 */ |
| .uleb128 0x10 /* DW_AT_stmt_list */ |
| .uleb128 0x6 /* DW_FORM_data4 */ |
| .uleb128 0x11 /* DW_AT_low_pc */ |
| .uleb128 0x1 /* DW_FORM_addr */ |
| .uleb128 0x12 /* DW_AT_high_pc */ |
| .uleb128 0x1 /* DW_FORM_addr */ |
| .uleb128 0x1b /* DW_AT_comp_dir */ |
| .uleb128 0x8 /* DW_FORM_string */ |
| .uleb128 0x3 /* DW_AT_name */ |
| .uleb128 0x8 /* DW_FORM_string */ |
| .byte 0x0 /* Terminator */ |
| .byte 0x0 /* Terminator */ |
| |
| .uleb128 3 /* Abbrev code */ |
| .uleb128 0x2e /* DW_TAG_subprogram */ |
| .byte 0 /* has_children */ |
| .uleb128 0x3 /* DW_AT_name */ |
| .uleb128 0x8 /* DW_FORM_string */ |
| .uleb128 0x11 /* DW_AT_low_pc */ |
| .uleb128 0x1 /* DW_FORM_addr */ |
| .uleb128 0x12 /* DW_AT_high_pc */ |
| .uleb128 0x1 /* DW_FORM_addr */ |
| .byte 0x0 /* Terminator */ |
| .byte 0x0 /* Terminator */ |
| |
| .byte 0x0 /* Terminator */ |
| .byte 0x0 /* Terminator */ |
| " |
| |
| close $f |
| |
| set opts {} |
| # Base directory. |
| lappend opts "additional_flags=-DBDIR=\"${srcabsdir}\"" |
| # Incorrect directory which should never be visible from GDB. |
| lappend opts "additional_flags=-DXDIR=\"${srcabsdir}/xdir\"" |
| # CU's DW_AT_comp_dir. |
| lappend opts "additional_flags=-DCOMPDIR=\"compdir\"" |
| # .debug_line's directory. |
| lappend opts "additional_flags=-DLDIR=\"ldir\"" |
| # CU's DW_AT_name and .debug_line's filename relative directory, if needed. |
| lappend opts "additional_flags=-DFDIR=\"fdir\"" |
| # CU's DW_AT_name and .debug_line's filename. |
| lappend opts "additional_flags=-DFILE=\"${srctmpfile}\"" |
| |
| if { [gdb_compile "${asmsrcfile} ${srcdir}/${subdir}/$srcfile" "${binfile}" executable $opts] != "" } { |
| untested "Cannot compile ${asmsrcfile} or $srcfile" |
| return -1 |
| } |
| |
| set dirs {} |
| foreach r {"" /rdir} { |
| foreach x {"" /xdir} { |
| foreach comp {"" /compdir} { |
| foreach l {"" /ldir} { |
| foreach f {"" /fdir} { |
| lappend dirs $r$x$comp$l$f |
| } |
| } |
| } |
| } |
| } |
| |
| proc pathexpand {prefix dirlst suffix} { |
| set retlst {} |
| foreach dir $dirlst { |
| lappend retlst "$prefix$dir$suffix" |
| } |
| return $retlst |
| } |
| |
| set filelist [pathexpand $srcabsdir $dirs "/$srctmpfile"] |
| set dircreatelist [pathexpand $srcabsdir $dirs ""] |
| set dirremovelist [pathexpand $srcabsdir [lreverse $dirs] ""] |
| |
| remote_exec host "sh -c \"rm -f $filelist\"" |
| remote_exec host "sh -c \"rmdir $dirremovelist\"" |
| remote_exec host "sh -c \"mkdir $dircreatelist\"" |
| remote_exec host "sh -c \"for d in $dircreatelist; do cp ${srcdir}/${subdir}/${srcfile} \\\$d/${srctmpfile}; done\"" |
| |
| clean_restart ${testfile} |
| |
| if ![runto_main] { |
| return -1 |
| } |
| |
| gdb_test "cd ${srcabsdir}/rdir" "Working directory [string_to_regexp ${srcabsdir}]/rdir\\." "cd .../rdir" |
| |
| proc test { func compdir filename } { |
| with_test_prefix "$func" { |
| # Clear the GDB cache. |
| gdb_test_no_output "set directories" "" |
| |
| if {$compdir == ""} { |
| set absolute "$filename" |
| } else { |
| set absolute "$compdir/$filename" |
| } |
| if {[string index $absolute 0] != "/"} { |
| error "not absolute" |
| } |
| |
| gdb_breakpoint $func |
| gdb_continue_to_breakpoint $func "$func \\(\\) at .*" |
| |
| gdb_test_no_output "set filename-display absolute" |
| verbose -log "expect: ${absolute}" |
| gdb_test "frame" " in $func \\(\\) at [string_to_regexp ${absolute}]:999" "absolute" |
| |
| gdb_test_no_output "set filename-display basename" |
| verbose -log "expect: [file tail $filename]" |
| gdb_test "frame" " in $func \\(\\) at [string_to_regexp [file tail $filename]]:999" "basename" |
| |
| gdb_test_no_output "set filename-display relative" |
| verbose -log "expect: $filename" |
| gdb_test "frame" " in $func \\(\\) at [string_to_regexp $filename]:999" "relative" |
| } |
| } |
| |
| set bdir "${srcabsdir}" |
| set file "${srctmpfile}" |
| test "compdir_missing__ldir_missing__file_basename" "$bdir/rdir" "$file" |
| test "compdir_missing__ldir_missing__file_relative" "$bdir/rdir" "fdir/$file" |
| test "compdir_missing__ldir_missing__file_absolute" "" "$bdir/$file" |
| test "compdir_missing__ldir_relative_file_basename" "$bdir/rdir" "ldir/$file" |
| test "compdir_missing__ldir_relative_file_relative" "$bdir/rdir" "ldir/fdir/$file" |
| test "compdir_missing__ldir_relative_file_absolute" "" "$bdir/$file" |
| test "compdir_missing__ldir_absolute_file_basename" "" "$bdir/ldir/$file" |
| test "compdir_missing__ldir_absolute_file_relative" "" "$bdir/ldir/fdir/$file" |
| test "compdir_missing__ldir_absolute_file_absolute_same" "" "$bdir/$file" |
| test "compdir_missing__ldir_absolute_file_absolute_different" "" "$bdir/$file" |
| test "compdir_relative_ldir_missing__file_basename" "$bdir/rdir/compdir" "$file" |
| test "compdir_relative_ldir_missing__file_relative" "$bdir/rdir/compdir" "fdir/$file" |
| test "compdir_relative_ldir_missing__file_absolute" "" "$bdir/$file" |
| test "compdir_relative_ldir_relative_file_basename" "$bdir/rdir/compdir" "ldir/$file" |
| test "compdir_relative_ldir_relative_file_relative" "$bdir/rdir/compdir" "ldir/fdir/$file" |
| test "compdir_relative_ldir_relative_file_absolute" "" "$bdir/$file" |
| test "compdir_relative_ldir_absolute_file_basename" "" "$bdir/ldir/$file" |
| test "compdir_relative_ldir_absolute_file_relative" "" "$bdir/ldir/fdir/$file" |
| test "compdir_relative_ldir_absolute_file_absolute_same" "" "$bdir/$file" |
| test "compdir_relative_ldir_absolute_file_absolute_different" "" "$bdir/$file" |
| test "compdir_absolute_ldir_missing__file_basename" "$bdir/compdir" "$file" |
| test "compdir_absolute_ldir_missing__file_relative" "$bdir/compdir" "fdir/$file" |
| test "compdir_absolute_ldir_missing__file_absolute_same" "" "$bdir/$file" |
| test "compdir_absolute_ldir_missing__file_absolute_different" "" "$bdir/$file" |
| test "compdir_absolute_ldir_relative_file_basename" "$bdir/compdir" "ldir/$file" |
| test "compdir_absolute_ldir_relative_file_relative" "$bdir/compdir" "ldir/fdir/$file" |
| test "compdir_absolute_ldir_relative_file_absolute_same" "" "$bdir/$file" |
| test "compdir_absolute_ldir_relative_file_absolute_different" "" "$bdir/$file" |
| test "compdir_absolute_ldir_absolute_file_basename_same" "" "$bdir/ldir/$file" |
| test "compdir_absolute_ldir_absolute_file_relative_different" "" "$bdir/ldir/fdir/$file" |
| test "compdir_absolute_ldir_absolute_file_absolute_same" "" "$bdir/$file" |
| test "compdir_absolute_ldir_absolute_file_absolute_different" "" "$bdir/$file" |