Re: [vxworks 03/14] New module remote-wtx-utils

Joel Brobecker
2010-04-27T16:27:20Z

[-- Attachment #1: Type: text/plain, Size: 1554 bytes --]

Hi Tom,

Thanks much for the feedback!

> Just "skip_whitespace" sounds more natural to me.
> I think "whitespace" is commonly used for both singular and plural.

Fixed.

> Joel> +skip_until_character (char *str, char delimiter)
> Joel> +skip_until_whitespace (char *str)
> Joel> +skip_space_delimited_token (char *str)
> Joel> +get_space_delimited_token (char *str, char **token)
>
> I think all of these (including the others above) could be in util.c.

Agreed - moved thusly.

> Joel> +void *load_shared_lib (char *lib_name)
>
> Formatting.
>
> Also, this should mention how errors are to be detected.

All fixed. These two routines are the two left in remote-wtx-utils
after the exercise. I was thinking of moving them to a non-wtx context,
but it turns out I forgot that one of them (load_shared_lib) is more
than just a dlopen wrapper. What I had forgotten is that function takes
a library name (eg: "wtx40", and build the DSO filename depending on
the host filesystem -> either libwtx40.so or wtx40.dll). It would have
been too easy if it was just a matter of using a .so vs .dll extension...
So it really belongs in a vxworks-specific unit.

I thought it might have been useful to have a gdb_dlfcn.h module that
abstracts out shared library support. It's relatively easy to write,
the code itself, but it's the packaging that raises questions. See the
revision history that I wrote for patch 0003.2 (attached). In any case,
I made it easier for this to happen, when/if we want to.

Here are 2 new patches, replacing patch 0003...

--
Joel

[-- Attachment #2: 0003.1-new-general-purpose-routines-in-utils.diff --]
[-- Type: text/x-diff, Size: 5160 bytes --]

commit 6a619bbabb16472cfc4e9ba41758a43cc8bbfd5e
Author: Joel Brobecker <brobecker@adacore.com>
Date: Tue Apr 27 11:12:43 2010 -0400

New general purpose routines in utils.c

These are some general-purpose routines that were added for the VxWorks
port... Hopefully other parts of the GDB code will make use of them.

2010-04-27 Joel Brobecker <brobecker@adacore.com>

* utils.c (have_dos_based_filesystem, is_regular_file)
(skip_whitespace, skip_until_character, skip_until_whitespace)
(skip_space_delimited_token, get_space_delimited_token): New functions.
* source.c (is_regular_file): Delete. Moved to utils.c.
* defs.h (have_dos_based_filesystem, is_regular_file)
(skip_whitespace, skip_until_character, skip_space_delimited_token)
(get_space_delimited_token): Add declaration.

diff --git a/gdb/defs.h b/gdb/defs.h
index e8a1dd4..0d84170 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -432,6 +432,18 @@ extern const char *gdb_bfd_errmsg (bfd_error_type error_tag, char **matching);

extern int parse_pid_to_attach (char *args);

+extern int have_dos_based_filesystem (void);
+
+extern int is_regular_file (const char *name);
+
+extern char *skip_whitespace (char *str);
+
+extern char *skip_until_character (char *str, char delimiter);
+
+extern char *skip_space_delimited_token (char *str);
+
+extern char *get_space_delimited_token (char *str, char **token);
+
/* From demangle.c */

extern void set_demangling_style (char *);
diff --git a/gdb/source.c b/gdb/source.c
index 47caa14..1e4107b 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -622,24 +622,6 @@ source_info (char *ignore, int from_tty)
}
\f

-/* Return True if the file NAME exists and is a regular file */
-static int
-is_regular_file (const char *name)
-{
- struct stat st;
- const int status = stat (name, &st);
-
- /* Stat should never fail except when the file does not exist.
- If stat fails, analyze the source of error and return True
- unless the file does not exist, to avoid returning false results
- on obscure systems where stat does not work as expected.
- */
- if (status != 0)
- return (errno != ENOENT);
-
- return S_ISREG (st.st_mode);
-}
-
/* Open a file named STRING, searching path PATH (dir names sep by some char)
using mode MODE in the calls to open. You cannot use this function to
create files (O_CREAT).
diff --git a/gdb/utils.c b/gdb/utils.c
index e225a3f..cac312f 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -3673,6 +3673,116 @@ parse_pid_to_attach (char *args)
return pid;
}

+/* Return non-zero if the host has a dos-based file system. */
+
+int
+have_dos_based_filesystem (void)
+{
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/* Return True if the file NAME exists and is a regular file. */
+
+int
+is_regular_file (const char *name)
+{
+ struct stat st;
+ const int status = stat (name, &st);
+
+ /* Stat should never fail except when the file does not exist.
+ If stat fails, analyze the source of error and return True
+ unless the file does not exist, to avoid returning false results
+ on obscure systems where stat does not work as expected. */
+ if (status != 0)
+ return (errno != ENOENT);
+
+ return S_ISREG (st.st_mode);
+}
+
+/* Return a pointer to the first non-whitepace character found
+ in the string. A whitespace is either a space or a tab. */
+
+char *
+skip_whitespace (char *str)
+{
+ char *index = str;
+
+ while (*index == ' ' || *index == '\t')
+ index++;
+
+ return index;
+}
+
+/* Return a pointer to the first DELIMITER character in the given
+ string. Return a pointer to the end-of-line character if
+ DELIMITER was not found. */
+
+char *
+skip_until_character (char *str, char delimiter)
+{
+ char *index = str;
+
+ while (*index != delimiter && *index != '\0')
+ index++;
+
+ return index;
+}
+
+/* return a pointer to the first whitespace character. If no whitespace
+ is found before the end of string, a pointer to the end of string
+ is returned. A whitespace is either a space or a tab. */
+
+static char *
+skip_until_whitespace (char *str)
+{
+ char *index = str;
+
+ while (*index != ' ' && *index != '\t' && *index != '\0')
+ index++;
+
+ return index;
+}
+
+/* Return a pointer to the first white space after the next
+ whitespace-delimited token. */
+
+char *
+skip_space_delimited_token (char *str)
+{
+ char *index = str;
+
+ index = skip_whitespace (index);
+ index = skip_until_whitespace (index);
+
+ return index;
+}
+
+/* Copy the next whitespace token into TOKEN. This string will be
+ allocated using malloc, and must be dealocated later. */
+
+char *
+get_space_delimited_token (char *str, char **token)
+{
+ char *start;
+ char *end;
+ char tmp;
+
+ start = skip_whitespace (str);
+ end = skip_until_whitespace (start);
+
+ tmp = *end;
+ *end = '\0';
+ *token = xstrdup (start);
+ *end = tmp;
+
+ return end;
+}
+
+
/* Provide a prototype to silence -Wmissing-prototypes. */
extern initialize_file_ftype _initialize_utils;

[-- Attachment #3: 0003.2-new-module-remote-wtx-utils.diff --]
[-- Type: text/x-diff, Size: 5723 bytes --]

commit ea576c2d84a757e64871bf61b659a1481da100ee
Author: Joel Brobecker <brobecker@adacore.com>
Date: Sat Apr 24 11:26:24 2010 -0400

[vxworks] New module remote-wtx-utils

This module provides a couple of routines to deal with loading the
VxWorks host-side shared libraries, such as the WTX library for instance.

I rewrote a bit the routines to depend on two functions gdb_dlopen and
gdb_dlsym which we could isolate in its own gdb_dlfcn.h/c if we wanted to.
But since this is used only when adding the vxworks target, I kept these
routines local for now - otherwise, it opens the door for questions such
as: What do we do when these are not defined? Should we fail the configure
even though chances are these routines might not be actually needed for
the build? Or do we fail the configure only when they are in fact needed
(ideal, but harder to maintain I believe), or do we just fail at link
time (a bit ugly but much easier to implement)? For now, I don't think
we really need to answer these questions, but I wrote the code in a way
that it makes it easy to extract the code and create the module if we
ever need to.

2010-04-27 Joel Brobecker <brobecker@adacore.com>

* remote-wtx-utils.h, remote-wtx-utils.c: New files.

diff --git a/gdb/remote-wtx-utils.c b/gdb/remote-wtx-utils.c
new file mode 100644
index 0000000..0a282bc
--- /dev/null
+++ b/gdb/remote-wtx-utils.c
@@ -0,0 +1,101 @@
+/* Support for the WTX protocol.
+
+ Copyright (C) 2007, 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 "remote-wtx-utils.h"
+#include "gdb_string.h"
+#ifdef HAVE_LIBDL
+#include <dlfcn.h>
+#elif __MINGW32__
+#include <windows.h>
+#else
+/* Unsupported configuration. See Eg. gdb_dlopen for details. */
+#error API to load shared library missing (Eg. libdl)
+#endif
+
+/* Load the dynamic library file named FILENAME, and return a handle
+ for that dynamic library. Return NULL if the loading fails for
+ any reason. */
+
+static void *
+gdb_dlopen (const char *filename)
+{
+#ifdef HAVE_LIBDL
+ return dlopen (filename, RTLD_NOW);
+#elif __MINGW32__
+ return (void *) LoadLibrary (filename);
+#endif
+}
+
+/* Return the address of the symbol named SYMBOL inside the shared library
+ whose handle is HANDLE. Return NULL when the symbol could not be found. */
+
+static void *
+gdb_dlsym(void *handle, const char *symbol)
+{
+#ifdef HAVE_LIBDL
+ return dlsym (handle, symbol);
+#elif __MINGW32__
+ return (void *) GetProcAddress (handle, symbol);
+#endif
+}
+
+/* Load the shared library whose name is LIB_NAME and return a handle
+ on it. Return NULL if the library could not be loaded.
+
+ Note that this name correspond to a different file name depending on
+ the host; for example, the name "wtxapi40" would identify libwtxapi40.so
+ on linux and solaris, whereas it would identify wtxapi40.dll. */
+
+void *
+load_shared_lib (char *lib_name)
+{
+ const char dos_suffix [] = ".dll";
+ const char unix_prefix[] = "lib";
+ const char unix_suffix [] = ".so";
+ char *filename;
+
+ if (have_dos_based_filesystem ())
+ {
+ filename = (char *) alloca (strlen (lib_name) + strlen (dos_suffix) + 1);
+ strcpy (filename, lib_name);
+ strcat (filename, dos_suffix);
+ }
+ else
+ {
+ filename = (char *) alloca (strlen (unix_prefix)
+ + strlen (lib_name)
+ + strlen (unix_suffix) + 1);
+ strcpy (filename, unix_prefix);
+ strcat (filename, lib_name);
+ strcat (filename, unix_suffix);
+ }
+
+ return gdb_dlopen (filename);
+}
+
+/* Get the address of SYMBOL in a shared library identified
+ by HANDLE (HANDLE is the value returned by load_shared_lib
+ for this library). */
+
+void *
+get_symbol_from_shared_lib (void *handle, char *symbol)
+{
+ return gdb_dlsym (handle, symbol);
+}
diff --git a/gdb/remote-wtx-utils.h b/gdb/remote-wtx-utils.h
new file mode 100644
index 0000000..24a03b1
--- /dev/null
+++ b/gdb/remote-wtx-utils.h
@@ -0,0 +1,27 @@
+/* Support for the WTX protocol.
+
+ Copyright (C) 2007, 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 REMOTE_WTX_UTILS_H
+#define REMOTE_WTX_UTILS_H
+
+extern void *load_shared_lib (char *lib_name);
+
+extern void *get_symbol_from_shared_lib (void *handle, char *symbol);
+
+#endif