gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 3 Feb 2013 16:09:33 +0000 (16:09 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 3 Feb 2013 16:09:33 +0000 (16:09 +0000)
Add a new variable that controls a way in which filenames are
displayed.
* NEWS (set filename-display): New entry.
* source.c (filename_display_basename, filename_display_relative)
(filename_display_absolute, filename_display_kind_names)
(filename_display_string, show_filename_display_string)
(symtab_to_filename_for_display): New.
(_initialize_source): Added initialization of 'filename-display'
variable.
* source.h (symtab_to_filename_for_display): Added declaration.
* stack.c (print_frame): Added new variable and calling of a new
function and condition with this variable. Changed third argument of
calling of a function.

gdb/doc/
* gdb.texinfo (Backtrace): Added description of 'filename-display'
variable in 'set/show backtrace' section.

gdb/testsuite/
* gdb.dwarf2/dw2-dir-file-name.exp: New file.
* gdb.dwarf2/dw2-dir-file-name.c: New file.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/source.c
gdb/source.h
gdb/stack.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.c [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.exp [new file with mode: 0644]

index 793188aa53fb7559f029e2cf6c5f3349d423513a..82eebfaa5a89d097f7d075654380d740002485a2 100644 (file)
@@ -1,3 +1,20 @@
+2013-02-03  Eldar Gaynetdinov <hal9000ed2k@gmail.com>
+           Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Add a new variable that controls a way in which filenames are
+       displayed.
+       * NEWS (set filename-display): New entry.
+       * source.c (filename_display_basename, filename_display_relative)
+       (filename_display_absolute, filename_display_kind_names)
+       (filename_display_string, show_filename_display_string)
+       (symtab_to_filename_for_display): New.
+       (_initialize_source): Added initialization of 'filename-display'
+       variable.
+       * source.h (symtab_to_filename_for_display): Added declaration.
+       * stack.c (print_frame): Added new variable and calling of a new
+       function and condition with this variable. Changed third argument of
+       calling of a function.
+
 2013-02-03  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * tui/tui-data.c (init_win_info, tui_del_window, tui_free_window):
index 539ceb9b4f57fb3a78e0dce5dd19ceeac890cdb8..dd4c40a2f14cd8ee4630c70a6ffa87e2c5d52d1f 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -115,6 +115,11 @@ show print type typedefs
   Control whether typedef definitions are displayed by "ptype".
   The default is to show them.
 
+set filename-display basename|relative|absolute
+show filename-display
+  Control the way in which filenames is displayed.
+  The default is "relative", which preserves previous behavior.
+
 * MI changes
 
   ** Command parameter changes are now notified using new async record
index 1e1b2fb7e3d15c8b1055305a6998432f52453bd2..62e35908a15c3e94402929fd40ccfd1272a8d915 100644 (file)
@@ -1,3 +1,9 @@
+2013-02-03  Eldar Gaynetdinov <hal9000ed2k@gmail.com>
+           Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * gdb.texinfo (Backtrace): Added description of 'filename-display'
+       variable in 'set/show backtrace' section.
+
 2013-01-31  Tom Tromey  <tromey@redhat.com>
 
        * gdb.texinfo (Target Commands): Fix typo.
index a8a72842cad08dde725ccf082c6fbed7cdecfb23..a448c97caeb363645c99786f718dec6729890250 100644 (file)
@@ -6535,6 +6535,24 @@ unlimited.
 Display the current limit on backtrace levels.
 @end table
 
+You can control how file names are displayed.
+
+@table @code
+@item set filename-display
+@itemx set filename-display relative
+@cindex filename-display
+Display file names relative to the compilation directory.  This is the default.
+
+@item set filename-display basename
+Display only basename of a filename.
+
+@item set filename-display absolute
+Display an absolute filename.
+
+@item show filename-display
+Show the current way to display filenames.
+@end table
+
 @node Selection
 @section Selecting a Frame
 
index 13cc7c86aa1223da679d196f1d313536543564c4..68fbcdfa49d5d2c23ba78620e0d5be56126d80a2 100644 (file)
@@ -109,6 +109,27 @@ show_lines_to_list (struct ui_file *file, int from_tty,
                    value);
 }
 
+/* Possible values of 'set filename-display'.  */
+static const char filename_display_basename[] = "basename";
+static const char filename_display_relative[] = "relative";
+static const char filename_display_absolute[] = "absolute";
+
+static const char *const filename_display_kind_names[] = {
+  filename_display_basename,
+  filename_display_relative,
+  filename_display_absolute,
+  NULL
+};
+
+static const char *filename_display_string = filename_display_relative;
+
+static void
+show_filename_display_string (struct ui_file *file, int from_tty,
+                             struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Filenames are displayed as \"%s\".\n"), value);
+}
 /* Line number of last line printed.  Default for various commands.
    current_source_line is usually, but not always, the same as this.  */
 
@@ -1111,6 +1132,21 @@ symtab_to_fullname (struct symtab *s)
 
   return s->fullname;
 }
+
+/* See commentary in source.h.  */
+
+const char *
+symtab_to_filename_for_display (struct symtab *symtab)
+{
+  if (filename_display_string == filename_display_basename)
+    return lbasename (symtab->filename);
+  else if (filename_display_string == filename_display_absolute)
+    return symtab_to_fullname (symtab);
+  else if (filename_display_string == filename_display_relative)
+    return symtab->filename;
+  else
+    internal_error (__FILE__, __LINE__, _("invalid filename_display_string"));
+}
 \f
 /* Create and initialize the table S->line_charpos that records
    the positions of the lines in the source file, which is assumed
@@ -2014,4 +2050,19 @@ Usage: show substitute-path [FROM]\n\
 Print the rule for substituting FROM in source file names. If FROM\n\
 is not specified, print all substitution rules."),
            &showlist);
+
+  add_setshow_enum_cmd ("filename-display", class_files,
+                       filename_display_kind_names,
+                       &filename_display_string, _("\
+Set how to display filenames."), _("\
+Show how to display filenames."), _("\
+filename-display can be:\n\
+  basename - display only basename of a filename\n\
+  relative - display a filename relative to the compilation directory\n\
+  absolute - display an absolute filename\n\
+By default, relative filenames are displayed."),
+                       NULL,
+                       show_filename_display_string,
+                       &setlist, &showlist);
+
 }
index 0c6804cb065d551492afd789eba815a2b00cde3a..1e9d8a530ec0e9d27ac45628b3d582e264ff83b5 100644 (file)
@@ -50,6 +50,10 @@ extern int open_source_file (struct symtab *s);
 
 extern const char *symtab_to_fullname (struct symtab *s);
 
+/* Returns filename without the compile directory part, basename or absolute
+   filename.  It depends on 'set filename-display' value.  */
+extern const char *symtab_to_filename_for_display (struct symtab *symtab);
+
 /* Create and initialize the table S->line_charpos that records the
    positions of the lines in the source file, which is assumed to be
    open on descriptor DESC.  All set S->nlines to the number of such
index c8a6a7e5e64b5d59ad6ec2a3092486bd3d845838..662b351d209a395af05eacda33bb59a1eb64eca9 100644 (file)
@@ -1178,11 +1178,14 @@ print_frame (struct frame_info *frame, int print_level,
   ui_out_text (uiout, ")");
   if (sal.symtab)
     {
+      const char *filename_display;
+      
+      filename_display = symtab_to_filename_for_display (sal.symtab);
       annotate_frame_source_begin ();
       ui_out_wrap_hint (uiout, "   ");
       ui_out_text (uiout, " at ");
       annotate_frame_source_file ();
-      ui_out_field_string (uiout, "file", sal.symtab->filename);
+      ui_out_field_string (uiout, "file", filename_display);
       if (ui_out_is_mi_like_p (uiout))
        {
          const char *fullname = symtab_to_fullname (sal.symtab);
index 964997116c0214c645b57532a3baa013fa9206bf..c45ccac1324a124e43d69725e7db53d73926f1fa 100644 (file)
@@ -1,3 +1,8 @@
+2013-02-03  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * gdb.dwarf2/dw2-dir-file-name.exp: New file.
+       * gdb.dwarf2/dw2-dir-file-name.c: New file.
+
 2013-02-03  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * gdb.mi/mi-fullname-deleted.exp: Use double last slash for $srcfileabs.
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.c b/gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.c
new file mode 100644 (file)
index 0000000..724f22a
--- /dev/null
@@ -0,0 +1,87 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 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, see <http://www.gnu.org/licenses/>.  */
+
+volatile int v;
+
+static void
+marker (void)
+{
+  v++;
+}
+
+/* *R* marks possibly invalid compiler output as the first path component is
+   not absolute.  Still DWARF-4 does not forbid such DWARF; GCC does not
+   produce it.  */
+
+#define FUNCBLOCK                                              \
+FUNC (compdir_missing__ldir_missing__file_basename)       /*R*/\
+FUNC (compdir_missing__ldir_missing__file_relative)       /*R*/\
+FUNC (compdir_missing__ldir_missing__file_absolute)            \
+FUNC (compdir_missing__ldir_relative_file_basename)       /*R*/\
+FUNC (compdir_missing__ldir_relative_file_relative)       /*R*/\
+FUNC (compdir_missing__ldir_relative_file_absolute)       /*R*/\
+FUNC (compdir_missing__ldir_absolute_file_basename)            \
+FUNC (compdir_missing__ldir_absolute_file_relative)            \
+FUNC (compdir_missing__ldir_absolute_file_absolute_same)       \
+FUNC (compdir_missing__ldir_absolute_file_absolute_different)  \
+FUNC (compdir_relative_ldir_missing__file_basename)       /*R*/\
+FUNC (compdir_relative_ldir_missing__file_relative)       /*R*/\
+FUNC (compdir_relative_ldir_missing__file_absolute)       /*R*/\
+FUNC (compdir_relative_ldir_relative_file_basename)       /*R*/\
+FUNC (compdir_relative_ldir_relative_file_relative)       /*R*/\
+FUNC (compdir_relative_ldir_relative_file_absolute)       /*R*/\
+FUNC (compdir_relative_ldir_absolute_file_basename)       /*R*/\
+FUNC (compdir_relative_ldir_absolute_file_relative)       /*R*/\
+FUNC (compdir_relative_ldir_absolute_file_absolute_same)   /*R*/\
+FUNC (compdir_relative_ldir_absolute_file_absolute_different) /*R*/\
+FUNC (compdir_absolute_ldir_missing__file_basename)            \
+FUNC (compdir_absolute_ldir_missing__file_relative)            \
+FUNC (compdir_absolute_ldir_missing__file_absolute_same)       \
+FUNC (compdir_absolute_ldir_missing__file_absolute_different)  \
+FUNC (compdir_absolute_ldir_relative_file_basename)            \
+FUNC (compdir_absolute_ldir_relative_file_relative)            \
+FUNC (compdir_absolute_ldir_relative_file_absolute_same)       \
+FUNC (compdir_absolute_ldir_relative_file_absolute_different)  \
+FUNC (compdir_absolute_ldir_absolute_file_basename_same)       \
+FUNC (compdir_absolute_ldir_absolute_file_basename_different)  \
+FUNC (compdir_absolute_ldir_absolute_file_relative_same)       \
+FUNC (compdir_absolute_ldir_absolute_file_relative_different)  \
+FUNC (compdir_absolute_ldir_absolute_file_absolute_same)       \
+FUNC (compdir_absolute_ldir_absolute_file_absolute_different)
+
+#define FUNC(name)                                     \
+  asm (#name "_start: .globl " #name "_start\n");      \
+  static void                                          \
+  name (void)                                          \
+  {                                                    \
+    v++;                                               \
+  }                                                    \
+  asm (#name "_end: .globl " #name "_end\n");
+FUNCBLOCK
+#undef FUNC
+
+int
+main (void)
+{
+
+#define FUNC(name)                                     \
+  name ();
+FUNCBLOCK
+#undef FUNC
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.exp b/gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.exp
new file mode 100644 (file)
index 0000000..882bdb0
--- /dev/null
@@ -0,0 +1,400 @@
+# Copyright 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, 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  
+}
+
+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
+
+    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   4                               /* 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 */
+       .4byte  ${name}_start                   /* DW_AT_low_pc */
+       .4byte  ${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 */
+       .4byte          ${name}_start           /* DW_AT_low_pc */
+       .4byte          ${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
+
+    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        5
+       .byte           2
+       .4byte          ${name}_start
+       .byte           1       /* DW_LNS_copy */
+       .byte           3       /* DW_LNS_advance_line */
+       .sleb128        1       /* ... to 1000 */
+       .byte           0       /* DW_LNE_set_address */
+       .uleb128        5
+       .byte           2
+       .4byte          ${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
+}
+
+remote_exec host "sh -c \"rm -f ${srcabsdir}{/rdir,}{/xdir,}{/compdir,}{/ldir,}{/fdir,}/${srctmpfile}\""
+remote_exec host "sh -c \"rmdir ${srcabsdir}{/rdir,}{/xdir,}{/compdir,}{/ldir,}{/fdir,}\""
+remote_exec host "sh -c \"mkdir ${srcabsdir}{,/rdir}{,/xdir}{,/compdir}{,/ldir}{,/fdir}\""
+remote_exec host "sh -c \"for d in ${srcabsdir}{,/rdir}{,/xdir}{,/compdir}{,/ldir}{,/fdir};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\\."
+
+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"