* defs.h: Adjust comment.
authorPedro Alves <palves@redhat.com>
Sat, 24 Apr 2010 13:12:56 +0000 (13:12 +0000)
committerPedro Alves <palves@redhat.com>
Sat, 24 Apr 2010 13:12:56 +0000 (13:12 +0000)
* filesystem.h, filesystem.c: New files.
* Makefile.in (SFILES): Add filesystem.c.
(COMMON_OBS): Add filesystem.o.
* solib.c (solib_find): Handle DOS-based filesystems.  Handle
different target and host path flavours.
* arm-symbian-tdep.c (arm_symbian_init_abi): Set
has_dos_based_file_system on the gdbarch.
* arm-wince-tdep.c (arm_wince_init_abi): Ditto.
* i386-cygwin-tdep.c (i386_cygwin_init_abi): Ditto.
* i386-tdep.c (i386_go32_init_abi): Ditto.
* gdbarch.sh (has_dos_based_file_system): New.
* gdbarch.h, gdbarch.c: Regenerate.
* NEWS: Mention improved support for remote targets with DOS-based
filesystems.  Mention new `set/show target-file-system-kind'
commands.

gdb/doc/
* gdb.texinfo (Commands to specify files): Describe what how GDB
looks up DOS-based filesystem paths on the system root.  Document
the new `set/show target-file-system-kind' commands.

16 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/NEWS
gdb/arm-symbian-tdep.c
gdb/arm-wince-tdep.c
gdb/defs.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/filesystem.c [new file with mode: 0644]
gdb/filesystem.h [new file with mode: 0644]
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/i386-cygwin-tdep.c
gdb/i386-tdep.c
gdb/solib.c

index 82c4f74325e058476582d548a2098f851a629dad..148219ea9b3075f567e9f63f6afaa4cb87a1581c 100644 (file)
@@ -1,3 +1,22 @@
+2010-04-24  Pedro Alves  <pedro@codesourcery.com>
+
+       * defs.h: Adjust comment.
+       * filesystem.h, filesystem.c: New files.
+       * Makefile.in (SFILES): Add filesystem.c.
+       (COMMON_OBS): Add filesystem.o.
+       * solib.c (solib_find): Handle DOS-based filesystems.  Handle
+       different target and host path flavours.
+       * arm-symbian-tdep.c (arm_symbian_init_abi): Set
+       has_dos_based_file_system on the gdbarch.
+       * arm-wince-tdep.c (arm_wince_init_abi): Ditto.
+       * i386-cygwin-tdep.c (i386_cygwin_init_abi): Ditto.
+       * i386-tdep.c (i386_go32_init_abi): Ditto.
+       * gdbarch.sh (has_dos_based_file_system): New.
+       * gdbarch.h, gdbarch.c: Regenerate.
+       * NEWS: Mention improved support for remote targets with DOS-based
+       filesystems.  Mention new `set/show target-file-system-kind'
+       commands.
+
 2010-04-23  Stan Shebs  <stan@codesourcery.com>
 
        * ax.h (struct agent_expr): Merge in agent_reqs fields, add some
index d62dc63915ddd9a0cc53a1bf22c1760476775578..fc148feef5b66acd313acc69fc93f80e0c4b3e85 100644 (file)
@@ -663,8 +663,8 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
        dwarf2expr.c dwarf2loc.c dwarf2read.c dwarf2-frame.c \
        elfread.c environ.c eval.c event-loop.c event-top.c \
        exceptions.c expprint.c \
-       f-exp.y f-lang.c f-typeprint.c f-valprint.c findcmd.c findvar.c \
-       frame.c frame-base.c frame-unwind.c \
+       f-exp.y f-lang.c f-typeprint.c f-valprint.c filesystem.c \
+       findcmd.c findvar.c frame.c frame-base.c frame-unwind.c \
        gdbarch.c arch-utils.c gdbtypes.c gnu-v2-abi.c gnu-v3-abi.c \
        inf-loop.c \
        infcall.c \
@@ -814,6 +814,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
        infcmd.o infrun.o \
        expprint.o environ.o stack.o thread.o \
        exceptions.o \
+       filesystem.o \
        inf-child.o \
        interps.o \
        main.o \
index 0fcf2b5857ecef46943cd3dfac58b1c38888f577..696da2e6ff3a208838e94088ca848b37c9cf1301 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -51,8 +51,24 @@ qGetTIBAddr
   its argument, limiting the functions selected by the regex to those
   in the specified file.
 
+* Support for remote debugging Windows and SymbianOS shared libraries
+  from Unix hosts has been improved.  Non Windows GDB builds now can
+  understand target reported file names that follow MS-DOS based file
+  system semantics, such as file names that include drive letters and
+  use the backslash character as directory separator.  This makes it
+  possible to transparently use the "set sysroot" and "set
+  solib-search-path" on Unix hosts to point as host copies of the
+  target's shared libraries.  See the new command "set
+  target-file-system-kind" described below, and the "Commands to
+  specify files" section in the user manual for more information.
+
 * New commands
 
+set target-file-system-kind unix|dos-based|auto
+show target-file-system-kind
+  Set or show the assumed file system kind for target reported file
+  names.
+
 save breakpoints <filename>
   Save all current breakpoint definitions to a file suitable for use
   in a later debugging session.  To read the saved breakpoint
index 32f65f40a50aeccc8dc3ed894188dbd376f8050d..8e06852e58a49e72d064b2dadc551174bd4c7c44 100644 (file)
@@ -78,6 +78,10 @@ arm_symbian_init_abi (struct gdbarch_info info,
      corresponding ELF files on the host's filesystem.  */
   set_gdbarch_solib_symbols_extension (gdbarch, "sym");
 
+  /* Canonical paths on this target look like `c:\sys\bin\bar.dll',
+     for example.  */
+  set_gdbarch_has_dos_based_file_system (gdbarch, 1);
+
   set_solib_ops (gdbarch, &solib_target_so_ops);
 }
 
index 7a76463a7e7a0d1874341e6f8dc19edf3b453856..1bf28f84adb98c75871287346bd50e76d216dfab 100644 (file)
@@ -139,6 +139,10 @@ arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Skip call to __gccmain that gcc places in main.  */
   set_gdbarch_skip_main_prologue (gdbarch, arm_wince_skip_main_prologue);
+
+  /* Canonical paths on this target look like `\Windows\coredll.dll',
+     for example.  */
+  set_gdbarch_has_dos_based_file_system (gdbarch, 1);
 }
 
 static enum gdb_osabi
index e8a1dd4c8ca334550b3e5c8802e60cccee0b828e..2c4e5c449db30d4b37e61e55217673441c417d82 100644 (file)
@@ -1155,9 +1155,9 @@ extern int (*deprecated_ui_load_progress_hook) (const char *section,
 
 extern int use_windows;
 
-/* Symbolic definitions of filename-related things.  */
-/* FIXME, this doesn't work very well if host and executable
-   filesystems conventions are different.  */
+/* Definitions of filename-related things.  */
+
+/* Host specific things.  */
 
 #ifdef __MSDOS__
 # define CANT_FORK
index a97c639ac8b52dcc8a38b4ea9ca4f4eba8d10e35..ff59559eaeee888a3e9006fc269463dbc38196d9 100644 (file)
@@ -1,3 +1,9 @@
+2010-04-24  Pedro Alves  <pedro@codesourcery.com>
+
+       * gdb.texinfo (Commands to specify files): Describe what how GDB
+       looks up DOS-based filesystem paths on the system root.  Document
+       the new `set/show target-file-system-kind' commands.
+
 2010-04-23  Doug Evans  <dje@google.com>
 
        * gdb.texinfo (Python): Move Auto-loading section here ...
index 93a98f3db459e9eba874550496faa8f98f06bc73..3bb8ef96c2d239905a8787ef9fdef778bd7c1faa 100644 (file)
@@ -14404,6 +14404,59 @@ The part of @var{path} following the initial @file{remote:}
 that happens to be named @file{remote:}, you need to use some equivalent
 variant of the name like @file{./remote:}.}
 
+For targets with an MS-DOS based filesystem, such as MS-Windows and
+SymbianOS, @value{GDBN} tries prefixing a few variants of the target
+absolute file name with @var{path}.  But first, on Unix hosts,
+@value{GDBN} converts all backslash directory separators into forward
+slashes, because the backslash is not a directory separator on Unix:
+
+@smallexample
+  c:\foo\bar.dll @result{} c:/foo/bar.dll
+@end smallexample
+
+Then, @value{GDBN} attempts prefixing the target file name with
+@var{path}, and looks for the resulting file name in the host file
+system:
+
+@smallexample
+  c:/foo/bar.dll @result{} /path/to/sysroot/c:/foo/bar.dll
+@end smallexample
+
+If that does not find the shared library, @value{GDBN} tries removing
+the @samp{:} character from the drive spec, both for convenience, and,
+for the case of the host file system not supporting file names with
+colons:
+
+@smallexample
+  c:/foo/bar.dll @result{} /path/to/sysroot/c/foo/bar.dll
+@end smallexample
+
+This makes it possible to have a system root that mirrors a target
+with more than one drive.  E.g., you may want to setup your local
+copies of the target system shared libraries like so (note @samp{c} vs
+@samp{z}):
+
+@smallexample
+ @file{/path/to/sysroot/c/sys/bin/foo.dll}
+ @file{/path/to/sysroot/c/sys/bin/bar.dll}
+ @file{/path/to/sysroot/z/sys/bin/bar.dll}
+@end smallexample
+
+@noindent
+and point the system root at @file{/path/to/sysroot}, so that
+@value{GDBN} can find the correct copies of both
+@file{c:\sys\bin\foo.dll}, and @file{z:\sys\bin\bar.dll}.
+
+If that still does not find the shared library, @value{GDBN} tries
+removing the whole drive spec from the target file name:
+
+@smallexample
+  c:/foo/bar.dll @result{} /path/to/sysroot/foo/bar.dll
+@end smallexample
+
+This last lookup makes it possible to not care about the drive name,
+if you don't want or need to.
+
 The @code{set solib-absolute-prefix} command is an alias for @code{set
 sysroot}.
 
@@ -14435,6 +14488,55 @@ of shared library symbols.
 @kindex show solib-search-path
 @item show solib-search-path
 Display the current shared library search path.
+
+@cindex DOS file-name semantics of file names.
+@kindex set target-file-system-kind (unix|dos-based|auto)
+@kindex show target-file-system-kind
+@item set target-file-system-kind @var{kind}
+Set assumed file system kind for target reported file names.
+
+Shared library file names as reported by the target system may not
+make sense as is on the system @value{GDBN} is running on.  For
+example, when remote debugging a target that has MS-DOS based file
+system semantics, from a Unix host, the target may be reporting to
+@value{GDBN} a list of loaded shared libraries with file names such as
+@file{c:\Windows\kernel32.dll}.  On Unix hosts, there's no concept of
+drive letters, so the @samp{c:\} prefix is not normally understood as
+indicating an absolute file name, and neither is the backslash
+normally considered a directory separator character.  In that case,
+the native file system would interpret this whole absolute file name
+as a relative file name with no directory components.  This would make
+it impossible to point @value{GDBN} at a copy of the remote target's
+shared libraries on the host using @code{set sysroot}, and impractical
+with @code{set solib-search-path}.  Setting
+@code{target-file-system-kind} to @code{dos-based} tells @value{GDBN}
+to interpret such file names similarly to how the target would, and to
+map them to file names valid on @value{GDBN}'s native file system
+semantics.  The value of @var{kind} can be @code{"auto"}, in addition
+to one of the supported file system kinds.  In that case, @value{GDBN}
+tries to determine the appropriate file system variant based on the
+current target's operating system (@pxref{ABI, ,Configuring the
+Current ABI}).  The supported file system settings are:
+
+@table @code
+@item unix
+Instruct @value{GDBN} to assume the target file system is of Unix
+kind.  Only file names starting the forward slash (@samp{/}) character
+are considered absolute, and the directory separator character is also
+the forward slash.
+
+@item dos-based
+Instruct @value{GDBN} to assume the target file system is DOS based.
+File names starting with either a forward slash, or a drive letter
+followed by a colon (e.g., @samp{c:}), are considered absolute, and
+both the slash (@samp{/}) and the backslash (@samp{\\}) characters are
+considered directory separators.
+
+@item auto
+Instruct @value{GDBN} to use the file system kind associated with the
+target operating system (@pxref{ABI, ,Configuring the Current ABI}).
+This is the default.
+@end table
 @end table
 
 
diff --git a/gdb/filesystem.c b/gdb/filesystem.c
new file mode 100644 (file)
index 0000000..38a597d
--- /dev/null
@@ -0,0 +1,103 @@
+/* Handle different target file systems for GDB, the GNU Debugger.
+
+   Copyright (C) 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "defs.h"
+#include "filesystem.h"
+#include "gdbarch.h"
+#include "gdbcmd.h"
+
+const char file_system_kind_auto[] = "auto";
+const char file_system_kind_unix[] = "unix";
+const char file_system_kind_dos_based[] = "dos-based";
+const char *target_file_system_kinds[] =
+{
+  file_system_kind_auto,
+  file_system_kind_unix,
+  file_system_kind_dos_based,
+  NULL
+};
+const char *target_file_system_kind = file_system_kind_auto;
+
+const char *
+effective_target_file_system_kind (void)
+{
+  if (target_file_system_kind == file_system_kind_auto)
+    {
+      if (gdbarch_has_dos_based_file_system (target_gdbarch))
+       return file_system_kind_dos_based;
+      else
+       return file_system_kind_unix;
+    }
+  else
+    return target_file_system_kind;
+}
+
+const char *
+target_lbasename (const char *kind, const char *name)
+{
+  if (kind == file_system_kind_dos_based)
+    return dos_lbasename (name);
+  else
+    return unix_lbasename (name);
+}
+
+static void
+show_target_file_system_kind_command (struct ui_file *file,
+                                     int from_tty,
+                                     struct cmd_list_element *c,
+                                     const char *value)
+{
+  if (target_file_system_kind == file_system_kind_auto)
+    fprintf_filtered (file, _("\
+The assumed file system kind for target reported file names \
+is \"%s\" (currently \"%s\").\n"),
+                     value,
+                     effective_target_file_system_kind ());
+  else
+    fprintf_filtered (file, _("\
+The assumed file system kind for target reported file names \
+is \"%s\".\n"),
+                     value);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_filesystem;
+
+void
+_initialize_filesystem (void)
+{
+  add_setshow_enum_cmd ("target-file-system-kind",
+                       class_files,
+                       target_file_system_kinds,
+                       &target_file_system_kind, _("\
+Set assumed file system kind for target reported file names"), _("\
+Show assumed file system kind for target reported file names"),
+                       _("\
+If `unix', target file names (e.g., loaded shared library file names) \n\
+starting the forward slash (`/') character are considered absolute, \n\
+and the directory separator character is the forward slash (`/').  If \n\
+`dos-based', target file names starting with a drive letter followed \n\
+by a colon (e.g., `c:'), are also considered absolute, and the \n\
+backslash (`\\') is also considered a directory separator.  Set to \n\
+`auto' (which is the default), to let GDB decide, based on its \n\
+knowledge of the target operating system."),
+                       NULL, /* setfunc */
+                       show_target_file_system_kind_command,
+                       &setlist, &showlist);
+}
diff --git a/gdb/filesystem.h b/gdb/filesystem.h
new file mode 100644 (file)
index 0000000..992e2e2
--- /dev/null
@@ -0,0 +1,58 @@
+/* Handle different target file systems for GDB, the GNU Debugger.
+   Copyright (C) 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#ifndef FILESYSTEM_H
+#define FILESYSTEM_H
+
+extern const char file_system_kind_auto[];
+extern const char file_system_kind_unix[];
+extern const char file_system_kind_dos_based[];
+
+extern const char *target_file_system_kind;
+
+/* Same as IS_DIR_SEPARATOR but with file system kind KIND's
+   semantics, instead of host semantics.  */
+
+#define IS_TARGET_DIR_SEPARATOR(kind, c)                               \
+  (((kind) == file_system_kind_dos_based) ? IS_DOS_DIR_SEPARATOR (c) \
+   : IS_UNIX_DIR_SEPARATOR (c))
+
+/* Same as IS_ABSOLUTE_PATH but with file system kind KIND's
+   semantics, instead of host semantics.  */
+
+#define IS_TARGET_ABSOLUTE_PATH(kind, p)                               \
+  (((kind) == file_system_kind_dos_based) ? IS_DOS_ABSOLUTE_PATH (p) \
+   : IS_UNIX_ABSOLUTE_PATH (p))
+
+/* Same as HAS_DRIVE_SPEC but with file system kind KIND's semantics,
+   instead of host semantics.  */
+
+#define HAS_TARGET_DRIVE_SPEC(kind, p)                                 \
+  (((kind) == file_system_kind_dos_based) ? HAS_DOS_DRIVE_SPEC (p) \
+   : 0)
+
+/* Same as lbasename, but with file system kind KIND's semantics,
+   instead of host semantics.  */
+extern const char *target_lbasename (const char *kind, const char *name);
+
+/* The effective setting of "set target-file-system-kind", with "auto"
+   resolved to the real kind.  That is, you never see "auto" as a
+   result from this function.  */
+extern const char *effective_target_file_system_kind (void);
+
+#endif
index 9aa6111c6f3bda6d33680dcf89e52552445f7987..fa08fe02c40c28243a8982488e2b9a71ecfbf8be 100644 (file)
@@ -264,6 +264,7 @@ struct gdbarch
   gdbarch_auto_charset_ftype *auto_charset;
   gdbarch_auto_wide_charset_ftype *auto_wide_charset;
   const char * solib_symbols_extension;
+  int has_dos_based_file_system;
 };
 
 
@@ -411,6 +412,7 @@ struct gdbarch startup_gdbarch =
   default_auto_charset,  /* auto_charset */
   default_auto_wide_charset,  /* auto_wide_charset */
   0,  /* solib_symbols_extension */
+  0,  /* has_dos_based_file_system */
   /* startup_gdbarch() */
 };
 
@@ -682,6 +684,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of qsupported, invalid_p == 0 */
   /* Skip verify of auto_charset, invalid_p == 0 */
   /* Skip verify of auto_wide_charset, invalid_p == 0 */
+  /* Skip verify of has_dos_based_file_system, invalid_p == 0 */
   buf = ui_file_xstrdup (log, &length);
   make_cleanup (xfree, buf);
   if (length > 0)
@@ -926,6 +929,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: get_syscall_number = <%s>\n",
                       host_address_to_string (gdbarch->get_syscall_number));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: has_dos_based_file_system = %s\n",
+                      plongest (gdbarch->has_dos_based_file_system));
   fprintf_unfiltered (file,
                       "gdbarch_dump: has_global_breakpoints = %s\n",
                       plongest (gdbarch->has_global_breakpoints));
@@ -3676,6 +3682,23 @@ set_gdbarch_solib_symbols_extension (struct gdbarch *gdbarch,
   gdbarch->solib_symbols_extension = solib_symbols_extension;
 }
 
+int
+gdbarch_has_dos_based_file_system (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  /* Skip verify of has_dos_based_file_system, invalid_p == 0 */
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_has_dos_based_file_system called\n");
+  return gdbarch->has_dos_based_file_system;
+}
+
+void
+set_gdbarch_has_dos_based_file_system (struct gdbarch *gdbarch,
+                                       int has_dos_based_file_system)
+{
+  gdbarch->has_dos_based_file_system = has_dos_based_file_system;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules. */
index ec5f9d8d282980b325975f102962b50d49084bd7..6ccabfc1807745761ce8060e1c15b789607d59dc 100644 (file)
@@ -950,6 +950,13 @@ extern void set_gdbarch_auto_wide_charset (struct gdbarch *gdbarch, gdbarch_auto
 extern const char * gdbarch_solib_symbols_extension (struct gdbarch *gdbarch);
 extern void set_gdbarch_solib_symbols_extension (struct gdbarch *gdbarch, const char * solib_symbols_extension);
 
+/* If true the target OS has DOS-based file system semantics.  That is,
+   absolute paths include a drive name, and the backslash is considered
+   a path separator. */
+
+extern int gdbarch_has_dos_based_file_system (struct gdbarch *gdbarch);
+extern void set_gdbarch_has_dos_based_file_system (struct gdbarch *gdbarch, int has_dos_based_file_system);
+
 /* Definition for an unknown syscall, used basically in error-cases.  */
 #define UNKNOWN_SYSCALL (-1)
 
index 28851675c517149d9dedefece728f7bc50dc4e4c..121ca7c40c7242df5927cd16c1a051575da9abd9 100755 (executable)
@@ -782,6 +782,11 @@ f:const char *:auto_wide_charset:void::default_auto_wide_charset:default_auto_wi
 # where the names of the files run on the target differ in extension
 # compared to the names of the files GDB should load for debug info.
 v:const char *:solib_symbols_extension:::::::pstring (gdbarch->solib_symbols_extension)
+
+# If true, the target OS has DOS-based file system semantics.  That
+# is, absolute paths include a drive name, and the backslash is
+# considered a directory separator.
+v:int:has_dos_based_file_system:::0:0::0
 EOF
 }
 
index ef24670fbf333ca152eabf5d7322d05b8db12d45..50ce2e3f0795948b68943ff2d5c2eccf0a02bee9 100644 (file)
@@ -235,6 +235,10 @@ i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     (gdbarch, windows_core_xfer_shared_libraries);
 
   set_gdbarch_auto_wide_charset (gdbarch, i386_cygwin_auto_wide_charset);
+
+  /* Canonical paths on this target look like
+     `c:\Program Files\Foo App\mydll.dll', for example.  */
+  set_gdbarch_has_dos_based_file_system (gdbarch, 1);
 }
 
 static enum gdb_osabi
index 22854bdbf77d43b2150ec03d2004e6d5d41cf6e9..1b31acce51011d47ff1ecbfc1ed8df9893983fab 100644 (file)
@@ -2947,6 +2947,8 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
      set_gdbarch_sdb_reg_to_regnum.  */
   set_gdbarch_stab_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
   set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
+
+  set_gdbarch_has_dos_based_file_system (gdbarch, 1);
 }
 \f
 
index 3fed9dbe96e770670d46f7ffbc6535d7064bde9a..df8f3d33d6fdfa434ff4c51e272ba6df1ab83af0 100644 (file)
@@ -47,6 +47,7 @@
 #include "remote.h"
 #include "solib.h"
 #include "interps.h"
+#include "filesystem.h"
 
 /* Architecture-specific operations.  */
 
@@ -104,6 +105,13 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
                    value);
 }
 
+/* Same as HAVE_DOS_BASED_FILE_SYSTEM, but useable as an rvalue.  */
+#if (HAVE_DOS_BASED_FILE_SYSTEM)
+#  define DOS_BASED_FILE_SYSTEM 1
+#else
+#  define DOS_BASED_FILE_SYSTEM 0
+#endif
+
 /*
 
    GLOBAL FUNCTION
@@ -133,7 +141,7 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
    * If gdb_sysroot is NOT set, perform the following two searches:
    *   Look in inferior's $PATH.
    *   Look in inferior's $LD_LIBRARY_PATH.
-   *   
+   *
    * The last check avoids doing this search when targetting remote
    * machines since gdb_sysroot will almost always be set.
 
@@ -152,6 +160,9 @@ solib_find (char *in_pathname, int *fd)
   int gdb_sysroot_is_empty;
   const char *solib_symbols_extension
     = gdbarch_solib_symbols_extension (target_gdbarch);
+  const char *fskind = effective_target_file_system_kind ();
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+  char *sysroot = NULL;
 
   /* If solib_symbols_extension is set, replace the file's
      extension.  */
@@ -177,9 +188,7 @@ solib_find (char *in_pathname, int *fd)
 
   gdb_sysroot_is_empty = (gdb_sysroot == NULL || *gdb_sysroot == 0);
 
-  if (! IS_ABSOLUTE_PATH (in_pathname) || gdb_sysroot_is_empty)
-    temp_pathname = in_pathname;
-  else
+  if (!gdb_sysroot_is_empty)
     {
       int prefix_len = strlen (gdb_sysroot);
 
@@ -188,61 +197,152 @@ solib_find (char *in_pathname, int *fd)
             && IS_DIR_SEPARATOR (gdb_sysroot[prefix_len - 1]))
        prefix_len--;
 
+      sysroot = savestring (gdb_sysroot, prefix_len);
+      make_cleanup (xfree, sysroot);
+    }
+
+  /* If we're on a non-DOS-based system, backslashes won't be
+     understood as directory separator, so, convert them to forward
+     slashes, iff we're supposed to handle DOS-based file system
+     semantics for target paths.  */
+  if (!DOS_BASED_FILE_SYSTEM && fskind == file_system_kind_dos_based)
+    {
+      char *p;
+
+      /* Avoid clobbering our input.  */
+      p = alloca (strlen (in_pathname) + 1);
+      strcpy (p, in_pathname);
+      in_pathname = p;
+
+      for (; *p; p++)
+       {
+         if (*p == '\\')
+           *p = '/';
+       }
+    }
+
+  /* Note, we're interested in IS_TARGET_ABSOLUTE_PATH, not
+     IS_ABSOLUTE_PATH.  The latter is for host paths only, while
+     IN_PATHNAME is a target path.  For example, if we're supposed to
+     be handling DOS-like semantics we want to consider a
+     'c:/foo/bar.dll' path as an absolute path, even on a Unix box.
+     With such a path, before giving up on the sysroot, we'll try:
+
+       1st attempt, c:/foo/bar.dll ==> /sysroot/c:/foo/bar.dll
+       2nd attempt, c:/foo/bar.dll ==> /sysroot/c/foo/bar.dll
+       3rd attempt, c:/foo/bar.dll ==> /sysroot/foo/bar.dll
+  */
+
+  if (!IS_TARGET_ABSOLUTE_PATH (fskind, in_pathname) || gdb_sysroot_is_empty)
+    temp_pathname = xstrdup (in_pathname);
+  else
+    {
+      int need_dir_separator;
+
+      need_dir_separator = !IS_DIR_SEPARATOR (in_pathname[0]);
+
       /* Cat the prefixed pathname together.  */
-      temp_pathname = alloca (prefix_len + strlen (in_pathname) + 1);
-      strncpy (temp_pathname, gdb_sysroot, prefix_len);
-      temp_pathname[prefix_len] = '\0';
-      strcat (temp_pathname, in_pathname);
+      temp_pathname = concat (sysroot,
+                             need_dir_separator ? SLASH_STRING : "",
+                             in_pathname, (char *) NULL);
     }
 
   /* Handle remote files.  */
   if (remote_filename_p (temp_pathname))
     {
       *fd = -1;
-      return xstrdup (temp_pathname);
+      return temp_pathname;
     }
 
   /* Now see if we can open it.  */
   found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
+  if (found_file < 0)
+    xfree (temp_pathname);
 
-  /* We try to find the library in various ways.  After each attempt
-     (except for the one above), either found_file >= 0 and
-     temp_pathname is a malloc'd string, or found_file < 0 and
-     temp_pathname does not point to storage that needs to be
-     freed.  */
+  /* If the search in gdb_sysroot failed, and the path name has a
+     drive spec (e.g, c:/foo), try stripping ':' from the drive spec,
+     and retrying in the sysroot:
+       c:/foo/bar.dll ==> /sysroot/c/foo/bar.dll.  */
 
-    if (found_file < 0)
-      temp_pathname = NULL;
-    else
-      temp_pathname = xstrdup (temp_pathname);
+  if (found_file < 0
+      && !gdb_sysroot_is_empty
+      && HAS_TARGET_DRIVE_SPEC (fskind, in_pathname))
+    {
+      int need_dir_separator = !IS_DIR_SEPARATOR (in_pathname[2]);
+      char *drive = savestring (in_pathname, 1);
+
+      temp_pathname = concat (sysroot,
+                             SLASH_STRING,
+                             drive,
+                             need_dir_separator ? SLASH_STRING : "",
+                             in_pathname + 2, (char *) NULL);
+      xfree (drive);
+
+      found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
+      if (found_file < 0)
+       {
+         char *p;
+
+         xfree (temp_pathname);
+
+         /* If the search in gdb_sysroot still failed, try fully
+            stripping the drive spec, and trying once more in the
+            sysroot before giving up.
+
+            c:/foo/bar.dll ==> /sysroot/foo/bar.dll.  */
+
+         temp_pathname = concat (sysroot,
+                                 need_dir_separator ? SLASH_STRING : "",
+                                 in_pathname + 2, (char *) NULL);
+
+         found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
+         if (found_file < 0)
+           xfree (temp_pathname);
+       }
+    }
+
+  do_cleanups (old_chain);
+
+  /* We try to find the library in various ways.  After each attempt,
+     either found_file >= 0 and temp_pathname is a malloc'd string, or
+     found_file < 0 and temp_pathname does not point to storage that
+     needs to be freed.  */
+
+  if (found_file < 0)
+    temp_pathname = NULL;
+
+  /* If not found, search the solib_search_path (if any).  */
+  if (found_file < 0 && solib_search_path != NULL)
+    found_file = openp (solib_search_path, OPF_TRY_CWD_FIRST,
+                       in_pathname, O_RDONLY | O_BINARY, &temp_pathname);
 
   /* If the search in gdb_sysroot failed, and the path name is
      absolute at this point, make it relative.  (openp will try and open the
      file according to its absolute path otherwise, which is not what we want.)
      Affects subsequent searches for this solib.  */
-  if (found_file < 0 && IS_ABSOLUTE_PATH (in_pathname))
+  if (found_file < 0 && IS_TARGET_ABSOLUTE_PATH (fskind, in_pathname))
     {
       /* First, get rid of any drive letters etc.  */
-      while (!IS_DIR_SEPARATOR (*in_pathname))
-        in_pathname++;
+      while (!IS_TARGET_DIR_SEPARATOR (fskind, *in_pathname))
+       in_pathname++;
 
       /* Next, get rid of all leading dir separators.  */
-      while (IS_DIR_SEPARATOR (*in_pathname))
-        in_pathname++;
+      while (IS_TARGET_DIR_SEPARATOR (fskind, *in_pathname))
+       in_pathname++;
     }
-  
+
   /* If not found, search the solib_search_path (if any).  */
   if (found_file < 0 && solib_search_path != NULL)
     found_file = openp (solib_search_path, OPF_TRY_CWD_FIRST,
                        in_pathname, O_RDONLY | O_BINARY, &temp_pathname);
-  
+
   /* If not found, next search the solib_search_path (if any) for the basename
      only (ignoring the path).  This is to allow reading solibs from a path
      that differs from the opened path.  */
   if (found_file < 0 && solib_search_path != NULL)
     found_file = openp (solib_search_path, OPF_TRY_CWD_FIRST,
-                        lbasename (in_pathname), O_RDONLY | O_BINARY,
-                        &temp_pathname);
+                       target_lbasename (fskind, in_pathname),
+                       O_RDONLY | O_BINARY, &temp_pathname);
 
   /* If not found, try to use target supplied solib search method */
   if (found_file < 0 && ops->find_and_open_solib)
@@ -256,7 +356,7 @@ solib_find (char *in_pathname, int *fd)
                        OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY,
                        &temp_pathname);
 
-  /* If not found, next search the inferior's $LD_LIBRARY_PATH 
+  /* If not found, next search the inferior's $LD_LIBRARY_PATH
      environment variable. */
   if (found_file < 0 && gdb_sysroot_is_empty)
     found_file = openp (get_in_environ (current_inferior ()->environment,