* target.c, target.h (target_read_string): Provide error detection to
caller. Put string in malloc'd space, so caller need not impose arbitrary limits. * solib.c (find_solib): Update to use new interface. * irix5-nat.c (find_solib): Read o_path from inferior (clear_solib): Free storage for o_path. * valprint.c (val_print_string): Add comments.
This commit is contained in:
parent
8b1d1557f3
commit
4ad0021ebc
|
@ -1,3 +1,13 @@
|
||||||
|
Tue Mar 1 11:54:11 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
|
||||||
|
|
||||||
|
* target.c, target.h (target_read_string): Provide error detection to
|
||||||
|
caller. Put string in malloc'd space, so caller need not impose
|
||||||
|
arbitrary limits.
|
||||||
|
* solib.c (find_solib): Update to use new interface.
|
||||||
|
* irix5-nat.c (find_solib): Read o_path from inferior
|
||||||
|
(clear_solib): Free storage for o_path.
|
||||||
|
* valprint.c (val_print_string): Add comments.
|
||||||
|
|
||||||
Mon Feb 28 23:54:39 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
Mon Feb 28 23:54:39 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||||
|
|
||||||
* symtab.c (decode_line_1): Handle the case when skip_quoted does not
|
* symtab.c (decode_line_1): Handle the case when skip_quoted does not
|
||||||
|
|
|
@ -524,6 +524,9 @@ find_solib (so_list_ptr)
|
||||||
}
|
}
|
||||||
if ((so_list_next == NULL) && (lm != NULL))
|
if ((so_list_next == NULL) && (lm != NULL))
|
||||||
{
|
{
|
||||||
|
int errcode;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
/* Get next link map structure from inferior image and build a local
|
/* Get next link map structure from inferior image and build a local
|
||||||
abbreviated load_map structure */
|
abbreviated load_map structure */
|
||||||
new = (struct so_list *) xmalloc (sizeof (struct so_list));
|
new = (struct so_list *) xmalloc (sizeof (struct so_list));
|
||||||
|
@ -544,6 +547,10 @@ find_solib (so_list_ptr)
|
||||||
sizeof (struct obj_list));
|
sizeof (struct obj_list));
|
||||||
read_memory ((CORE_ADDR) new->ll.data, (char *) &(new -> lm),
|
read_memory ((CORE_ADDR) new->ll.data, (char *) &(new -> lm),
|
||||||
sizeof (struct obj));
|
sizeof (struct obj));
|
||||||
|
target_read_string (new->lm.o_path, &buffer, INT_MAX, &errcode);
|
||||||
|
if (errcode != 0)
|
||||||
|
memory_error (errcode, new->lm.o_path);
|
||||||
|
new->lm.o_path = buffer;
|
||||||
solib_map_sections (new);
|
solib_map_sections (new);
|
||||||
}
|
}
|
||||||
return (so_list_next);
|
return (so_list_next);
|
||||||
|
@ -797,10 +804,11 @@ clear_solib()
|
||||||
else
|
else
|
||||||
/* This happens for the executable on SVR4. */
|
/* This happens for the executable on SVR4. */
|
||||||
bfd_filename = NULL;
|
bfd_filename = NULL;
|
||||||
|
|
||||||
next = so_list_head -> next;
|
next = so_list_head -> next;
|
||||||
if (bfd_filename)
|
if (bfd_filename)
|
||||||
free ((PTR)bfd_filename);
|
free ((PTR)bfd_filename);
|
||||||
|
free (so_list_head->lm.o_path);
|
||||||
free ((PTR)so_list_head);
|
free ((PTR)so_list_head);
|
||||||
so_list_head = next;
|
so_list_head = next;
|
||||||
}
|
}
|
||||||
|
|
102
gdb/solib.c
102
gdb/solib.c
|
@ -69,14 +69,27 @@ static char *bkpt_names[] = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Symbols which are used to locate the base of the link map structures. */
|
||||||
|
|
||||||
|
static char *debug_base_symbols[] = {
|
||||||
|
#ifdef SVR4_SHARED_LIBS
|
||||||
|
"_r_debug", /* Most SVR4 systems, Solaris 2.1, 2.2 */
|
||||||
|
"r_debug", /* Solaris 2.3 */
|
||||||
|
#else
|
||||||
|
"_DYNAMIC", /* SunOS */
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
/* local data declarations */
|
/* local data declarations */
|
||||||
|
|
||||||
#ifndef SVR4_SHARED_LIBS
|
#ifndef SVR4_SHARED_LIBS
|
||||||
|
|
||||||
#define DEBUG_BASE "_DYNAMIC"
|
|
||||||
#define LM_ADDR(so) ((so) -> lm.lm_addr)
|
#define LM_ADDR(so) ((so) -> lm.lm_addr)
|
||||||
#define LM_NEXT(so) ((so) -> lm.lm_next)
|
#define LM_NEXT(so) ((so) -> lm.lm_next)
|
||||||
#define LM_NAME(so) ((so) -> lm.lm_name)
|
#define LM_NAME(so) ((so) -> lm.lm_name)
|
||||||
|
/* Test for first link map entry; first entry is a shared library. */
|
||||||
|
#define IGNORE_FIRST_LINK_MAP_ENTRY(x) (0)
|
||||||
static struct link_dynamic dynamic_copy;
|
static struct link_dynamic dynamic_copy;
|
||||||
static struct link_dynamic_2 ld_2_copy;
|
static struct link_dynamic_2 ld_2_copy;
|
||||||
static struct ld_debug debug_copy;
|
static struct ld_debug debug_copy;
|
||||||
|
@ -85,10 +98,11 @@ static CORE_ADDR flag_addr;
|
||||||
|
|
||||||
#else /* SVR4_SHARED_LIBS */
|
#else /* SVR4_SHARED_LIBS */
|
||||||
|
|
||||||
#define DEBUG_BASE "_r_debug"
|
|
||||||
#define LM_ADDR(so) ((so) -> lm.l_addr)
|
#define LM_ADDR(so) ((so) -> lm.l_addr)
|
||||||
#define LM_NEXT(so) ((so) -> lm.l_next)
|
#define LM_NEXT(so) ((so) -> lm.l_next)
|
||||||
#define LM_NAME(so) ((so) -> lm.l_name)
|
#define LM_NAME(so) ((so) -> lm.l_name)
|
||||||
|
/* Test for first link map entry; first entry is the exec-file. */
|
||||||
|
#define IGNORE_FIRST_LINK_MAP_ENTRY(x) ((x).l_prev == NULL)
|
||||||
static struct r_debug debug_copy;
|
static struct r_debug debug_copy;
|
||||||
char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
|
char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
|
||||||
|
|
||||||
|
@ -222,7 +236,7 @@ solib_map_sections (so)
|
||||||
{
|
{
|
||||||
close (scratch_chan);
|
close (scratch_chan);
|
||||||
error ("Could not open `%s' as an executable file: %s",
|
error ("Could not open `%s' as an executable file: %s",
|
||||||
scratch_pathname, bfd_errmsg (bfd_error));
|
scratch_pathname, bfd_errmsg (bfd_get_error ()));
|
||||||
}
|
}
|
||||||
/* Leave bfd open, core_xfer_memory and "info files" need it. */
|
/* Leave bfd open, core_xfer_memory and "info files" need it. */
|
||||||
so -> abfd = abfd;
|
so -> abfd = abfd;
|
||||||
|
@ -231,12 +245,12 @@ solib_map_sections (so)
|
||||||
if (!bfd_check_format (abfd, bfd_object))
|
if (!bfd_check_format (abfd, bfd_object))
|
||||||
{
|
{
|
||||||
error ("\"%s\": not in executable format: %s.",
|
error ("\"%s\": not in executable format: %s.",
|
||||||
scratch_pathname, bfd_errmsg (bfd_error));
|
scratch_pathname, bfd_errmsg (bfd_get_error ()));
|
||||||
}
|
}
|
||||||
if (build_section_table (abfd, &so -> sections, &so -> sections_end))
|
if (build_section_table (abfd, &so -> sections, &so -> sections_end))
|
||||||
{
|
{
|
||||||
error ("Can't find the file sections in `%s': %s",
|
error ("Can't find the file sections in `%s': %s",
|
||||||
bfd_get_filename (exec_bfd), bfd_errmsg (bfd_error));
|
bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p = so -> sections; p < so -> sections_end; p++)
|
for (p = so -> sections; p < so -> sections_end; p++)
|
||||||
|
@ -421,7 +435,7 @@ DESCRIPTION
|
||||||
an open file descriptor for the file mapped to that space, and the
|
an open file descriptor for the file mapped to that space, and the
|
||||||
base address of that mapped space.
|
base address of that mapped space.
|
||||||
|
|
||||||
Our job is to find the symbol DEBUG_BASE in the file that this
|
Our job is to find the debug base symbol in the file that this
|
||||||
fd is open on, if it exists, and if so, initialize the dynamic
|
fd is open on, if it exists, and if so, initialize the dynamic
|
||||||
linker structure base address debug_base.
|
linker structure base address debug_base.
|
||||||
|
|
||||||
|
@ -437,6 +451,7 @@ look_for_base (fd, baseaddr)
|
||||||
{
|
{
|
||||||
bfd *interp_bfd;
|
bfd *interp_bfd;
|
||||||
CORE_ADDR address;
|
CORE_ADDR address;
|
||||||
|
char **symbolp;
|
||||||
|
|
||||||
/* If the fd is -1, then there is no file that corresponds to this
|
/* If the fd is -1, then there is no file that corresponds to this
|
||||||
mapped memory segment, so skip it. Also, if the fd corresponds
|
mapped memory segment, so skip it. Also, if the fd corresponds
|
||||||
|
@ -461,10 +476,18 @@ look_for_base (fd, baseaddr)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now try to find our DEBUG_BASE symbol in this file, which we at
|
/* Now try to find our debug base symbol in this file, which we at
|
||||||
least know to be a valid ELF executable or shared library. */
|
least know to be a valid ELF executable or shared library. */
|
||||||
|
|
||||||
if ((address = bfd_lookup_symbol (interp_bfd, DEBUG_BASE)) == 0)
|
for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++)
|
||||||
|
{
|
||||||
|
address = bfd_lookup_symbol (interp_bfd, *symbolp);
|
||||||
|
if (address != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (address == 0)
|
||||||
{
|
{
|
||||||
bfd_close (interp_bfd);
|
bfd_close (interp_bfd);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -505,10 +528,9 @@ DESCRIPTION
|
||||||
inferior executable has been linked dynamically, there is a single
|
inferior executable has been linked dynamically, there is a single
|
||||||
address somewhere in the inferior's data space which is the key to
|
address somewhere in the inferior's data space which is the key to
|
||||||
locating all of the dynamic linker's runtime structures. This
|
locating all of the dynamic linker's runtime structures. This
|
||||||
address is the value of the symbol defined by the macro DEBUG_BASE.
|
address is the value of the debug base symbol. The job of this
|
||||||
The job of this function is to find and return that address, or to
|
function is to find and return that address, or to return 0 if there
|
||||||
return 0 if there is no such address (the executable is statically
|
is no such address (the executable is statically linked for example).
|
||||||
linked for example).
|
|
||||||
|
|
||||||
For SunOS, the job is almost trivial, since the dynamic linker and
|
For SunOS, the job is almost trivial, since the dynamic linker and
|
||||||
all of it's structures are statically linked to the executable at
|
all of it's structures are statically linked to the executable at
|
||||||
|
@ -521,10 +543,10 @@ DESCRIPTION
|
||||||
The SVR4 version is much more complicated because the dynamic linker
|
The SVR4 version is much more complicated because the dynamic linker
|
||||||
and it's structures are located in the shared C library, which gets
|
and it's structures are located in the shared C library, which gets
|
||||||
run as the executable's "interpreter" by the kernel. We have to go
|
run as the executable's "interpreter" by the kernel. We have to go
|
||||||
to a lot more work to discover the address of DEBUG_BASE. Because
|
to a lot more work to discover the address of the debug base symbol.
|
||||||
of this complexity, we cache the value we find and return that value
|
Because of this complexity, we cache the value we find and return that
|
||||||
on subsequent invocations. Note there is no copy in the executable
|
value on subsequent invocations. Note there is no copy in the
|
||||||
symbol tables.
|
executable symbol tables.
|
||||||
|
|
||||||
Note that we can assume nothing about the process state at the time
|
Note that we can assume nothing about the process state at the time
|
||||||
we need to find this address. We may be stopped on the first instruc-
|
we need to find this address. We may be stopped on the first instruc-
|
||||||
|
@ -542,17 +564,22 @@ locate_base ()
|
||||||
|
|
||||||
struct minimal_symbol *msymbol;
|
struct minimal_symbol *msymbol;
|
||||||
CORE_ADDR address = 0;
|
CORE_ADDR address = 0;
|
||||||
|
char **symbolp;
|
||||||
|
|
||||||
/* For SunOS, we want to limit the search for DEBUG_BASE to the executable
|
/* For SunOS, we want to limit the search for the debug base symbol to the
|
||||||
being debugged, since there is a duplicate named symbol in the shared
|
executable being debugged, since there is a duplicate named symbol in the
|
||||||
library. We don't want the shared library versions. */
|
shared library. We don't want the shared library versions. */
|
||||||
|
|
||||||
msymbol = lookup_minimal_symbol (DEBUG_BASE, symfile_objfile);
|
for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++)
|
||||||
if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
|
|
||||||
{
|
{
|
||||||
address = SYMBOL_VALUE_ADDRESS (msymbol);
|
msymbol = lookup_minimal_symbol (*symbolp, symfile_objfile);
|
||||||
|
if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
|
||||||
|
{
|
||||||
|
address = SYMBOL_VALUE_ADDRESS (msymbol);
|
||||||
|
return (address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (address);
|
return (0);
|
||||||
|
|
||||||
#else /* SVR4_SHARED_LIBS */
|
#else /* SVR4_SHARED_LIBS */
|
||||||
|
|
||||||
|
@ -709,14 +736,23 @@ find_solib (so_list_ptr)
|
||||||
so_list_next = new;
|
so_list_next = new;
|
||||||
read_memory ((CORE_ADDR) lm, (char *) &(new -> lm),
|
read_memory ((CORE_ADDR) lm, (char *) &(new -> lm),
|
||||||
sizeof (struct link_map));
|
sizeof (struct link_map));
|
||||||
/* For the SVR4 version, there is one entry that has no name
|
/* For SVR4 versions, the first entry in the link map is for the
|
||||||
(for the inferior executable) since it is not a shared object. */
|
inferior executable, so we must ignore it. For some versions of
|
||||||
if (LM_NAME (new) != 0)
|
SVR4, it has no name. For others (Solaris 2.3 for example), it
|
||||||
|
does have a name, so we can no longer use a missing name to
|
||||||
|
decide when to ignore it. */
|
||||||
|
if (!IGNORE_FIRST_LINK_MAP_ENTRY (new -> lm))
|
||||||
{
|
{
|
||||||
if (!target_read_string((CORE_ADDR) LM_NAME (new), new -> so_name,
|
int errcode;
|
||||||
MAX_PATH_SIZE - 1))
|
char *buffer;
|
||||||
error ("find_solib: Can't read pathname for load map\n");
|
target_read_string ((CORE_ADDR) LM_NAME (new), &buffer,
|
||||||
new -> so_name[MAX_PATH_SIZE - 1] = 0;
|
MAX_PATH_SIZE - 1, &errcode);
|
||||||
|
if (errcode != 0)
|
||||||
|
error ("find_solib: Can't read pathname for load map: %s\n",
|
||||||
|
safe_strerror (errcode));
|
||||||
|
strncpy (new -> so_name, buffer, MAX_PATH_SIZE - 1);
|
||||||
|
new -> so_name[MAX_PATH_SIZE - 1] = '\0';
|
||||||
|
free (buffer);
|
||||||
solib_map_sections (new);
|
solib_map_sections (new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -900,6 +936,8 @@ info_sharedlibrary_command (ignore, from_tty)
|
||||||
"Shared Object Library");
|
"Shared Object Library");
|
||||||
header_done++;
|
header_done++;
|
||||||
}
|
}
|
||||||
|
/* FIXME-32x64: need print_address_numeric with field width or
|
||||||
|
some such. */
|
||||||
printf_unfiltered ("%-12s",
|
printf_unfiltered ("%-12s",
|
||||||
local_hex_string_custom ((unsigned long) LM_ADDR (so),
|
local_hex_string_custom ((unsigned long) LM_ADDR (so),
|
||||||
"08l"));
|
"08l"));
|
||||||
|
@ -1265,13 +1303,13 @@ solib_create_inferior_hook()
|
||||||
|
|
||||||
clear_proceed_status ();
|
clear_proceed_status ();
|
||||||
stop_soon_quietly = 1;
|
stop_soon_quietly = 1;
|
||||||
stop_signal = 0;
|
stop_signal = TARGET_SIGNAL_0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
target_resume (-1, 0, stop_signal);
|
target_resume (-1, 0, stop_signal);
|
||||||
wait_for_inferior ();
|
wait_for_inferior ();
|
||||||
}
|
}
|
||||||
while (stop_signal != SIGTRAP);
|
while (stop_signal != TARGET_SIGNAL_TRAP);
|
||||||
stop_soon_quietly = 0;
|
stop_soon_quietly = 0;
|
||||||
|
|
||||||
/* We are now either at the "mapping complete" breakpoint (or somewhere
|
/* We are now either at the "mapping complete" breakpoint (or somewhere
|
||||||
|
|
406
gdb/target.c
406
gdb/target.c
|
@ -1,5 +1,5 @@
|
||||||
/* Select target systems and architectures at runtime for GDB.
|
/* Select target systems and architectures at runtime for GDB.
|
||||||
Copyright 1990, 1992, 1993 Free Software Foundation, Inc.
|
Copyright 1990, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||||
Contributed by Cygnus Support.
|
Contributed by Cygnus Support.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
@ -28,6 +28,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
|
#include "wait.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
extern int errno;
|
extern int errno;
|
||||||
|
|
||||||
|
@ -434,22 +436,31 @@ pop_target ()
|
||||||
#undef MIN
|
#undef MIN
|
||||||
#define MIN(A, B) (((A) <= (B)) ? (A) : (B))
|
#define MIN(A, B) (((A) <= (B)) ? (A) : (B))
|
||||||
|
|
||||||
/* target_read_string -- read a null terminated string from MEMADDR in target.
|
/* target_read_string -- read a null terminated string, up to LEN bytes,
|
||||||
The read may also be terminated early by getting an error from target_xfer_
|
from MEMADDR in target. Set *ERRNOP to the errno code, or 0 if successful.
|
||||||
memory.
|
Set *STRING to a pointer to malloc'd memory containing the data; the caller
|
||||||
LEN is the size of the buffer pointed to by MYADDR. Note that a terminating
|
is responsible for freeing it. Return the number of bytes successfully
|
||||||
null will only be written if there is sufficient room. The return value is
|
read. */
|
||||||
is the number of bytes (including the null) actually transferred.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
target_read_string (memaddr, myaddr, len)
|
target_read_string (memaddr, string, len, errnop)
|
||||||
CORE_ADDR memaddr;
|
CORE_ADDR memaddr;
|
||||||
char *myaddr;
|
char **string;
|
||||||
int len;
|
int len;
|
||||||
|
int *errnop;
|
||||||
{
|
{
|
||||||
int tlen, origlen, offset, i;
|
int tlen, origlen, offset, i;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
int errcode = 0;
|
||||||
|
char *buffer;
|
||||||
|
int buffer_allocated;
|
||||||
|
char *bufptr;
|
||||||
|
unsigned int nbytes_read = 0;
|
||||||
|
|
||||||
|
/* Small for testing. */
|
||||||
|
buffer_allocated = 4;
|
||||||
|
buffer = xmalloc (buffer_allocated);
|
||||||
|
bufptr = buffer;
|
||||||
|
|
||||||
origlen = len;
|
origlen = len;
|
||||||
|
|
||||||
|
@ -458,20 +469,39 @@ target_read_string (memaddr, myaddr, len)
|
||||||
tlen = MIN (len, 4 - (memaddr & 3));
|
tlen = MIN (len, 4 - (memaddr & 3));
|
||||||
offset = memaddr & 3;
|
offset = memaddr & 3;
|
||||||
|
|
||||||
if (target_xfer_memory (memaddr & ~3, buf, 4, 0))
|
errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0);
|
||||||
return origlen - len;
|
if (errcode != 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (bufptr - buffer + tlen > buffer_allocated)
|
||||||
|
{
|
||||||
|
unsigned int bytes;
|
||||||
|
bytes = bufptr - buffer;
|
||||||
|
buffer_allocated *= 2;
|
||||||
|
buffer = xrealloc (buffer, buffer_allocated);
|
||||||
|
bufptr = buffer + bytes;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < tlen; i++)
|
for (i = 0; i < tlen; i++)
|
||||||
{
|
{
|
||||||
*myaddr++ = buf[i + offset];
|
*bufptr++ = buf[i + offset];
|
||||||
if (buf[i + offset] == '\000')
|
if (buf[i + offset] == '\000')
|
||||||
return (origlen - len) + i + 1;
|
{
|
||||||
|
nbytes_read += i + 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memaddr += tlen;
|
memaddr += tlen;
|
||||||
len -= tlen;
|
len -= tlen;
|
||||||
|
nbytes_read += tlen;
|
||||||
}
|
}
|
||||||
return origlen;
|
done:
|
||||||
|
if (errnop != NULL)
|
||||||
|
*errnop = errcode;
|
||||||
|
if (string != NULL)
|
||||||
|
*string = buffer;
|
||||||
|
return nbytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read LEN bytes of target memory at address MEMADDR, placing the results in
|
/* Read LEN bytes of target memory at address MEMADDR, placing the results in
|
||||||
|
@ -658,6 +688,12 @@ target_preopen (from_tty)
|
||||||
else
|
else
|
||||||
error ("Program not killed.");
|
error ("Program not killed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calling target_kill may remove the target from the stack. But if
|
||||||
|
it doesn't (which seems like a win for UDI), remove it now. */
|
||||||
|
|
||||||
|
if (target_has_execution)
|
||||||
|
pop_target ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detach a target after doing deferred register stores. */
|
/* Detach a target after doing deferred register stores. */
|
||||||
|
@ -811,6 +847,8 @@ static struct {
|
||||||
{"SIGSOUND", "Sound completed"},
|
{"SIGSOUND", "Sound completed"},
|
||||||
{"SIGSAK", "Secure attention"},
|
{"SIGSAK", "Secure attention"},
|
||||||
{NULL, "Unknown signal"},
|
{NULL, "Unknown signal"},
|
||||||
|
{NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"},
|
||||||
|
|
||||||
/* Last entry, used to check whether the table is the right size. */
|
/* Last entry, used to check whether the table is the right size. */
|
||||||
{NULL, "TARGET_SIGNAL_MAGIC"}
|
{NULL, "TARGET_SIGNAL_MAGIC"}
|
||||||
};
|
};
|
||||||
|
@ -847,11 +885,347 @@ target_signal_from_name (name)
|
||||||
questionable; seems like by now people should call it SIGABRT
|
questionable; seems like by now people should call it SIGABRT
|
||||||
instead. */
|
instead. */
|
||||||
|
|
||||||
for (sig = TARGET_SIGNAL_HUP; signals[sig].name != NULL; ++sig)
|
/* This ugly cast brought to you by the native VAX compiler. */
|
||||||
|
for (sig = TARGET_SIGNAL_HUP;
|
||||||
|
signals[sig].name != NULL;
|
||||||
|
sig = (enum target_signal)((int)sig + 1))
|
||||||
if (STREQ (name, signals[sig].name))
|
if (STREQ (name, signals[sig].name))
|
||||||
return sig;
|
return sig;
|
||||||
return TARGET_SIGNAL_UNKNOWN;
|
return TARGET_SIGNAL_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The following functions are to help certain targets deal
|
||||||
|
with the signal/waitstatus stuff. They could just as well be in
|
||||||
|
a file called native-utils.c or unixwaitstatus-utils.c or whatever. */
|
||||||
|
|
||||||
|
/* Convert host signal to our signals. */
|
||||||
|
enum target_signal
|
||||||
|
target_signal_from_host (hostsig)
|
||||||
|
int hostsig;
|
||||||
|
{
|
||||||
|
/* A switch statement would make sense but would require special kludges
|
||||||
|
to deal with the cases where more than one signal has the same number. */
|
||||||
|
|
||||||
|
if (hostsig == 0) return TARGET_SIGNAL_0;
|
||||||
|
|
||||||
|
#if defined (SIGHUP)
|
||||||
|
if (hostsig == SIGHUP) return TARGET_SIGNAL_HUP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGINT)
|
||||||
|
if (hostsig == SIGINT) return TARGET_SIGNAL_INT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGQUIT)
|
||||||
|
if (hostsig == SIGQUIT) return TARGET_SIGNAL_QUIT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGILL)
|
||||||
|
if (hostsig == SIGILL) return TARGET_SIGNAL_ILL;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTRAP)
|
||||||
|
if (hostsig == SIGTRAP) return TARGET_SIGNAL_TRAP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGABRT)
|
||||||
|
if (hostsig == SIGABRT) return TARGET_SIGNAL_ABRT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGEMT)
|
||||||
|
if (hostsig == SIGEMT) return TARGET_SIGNAL_EMT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGFPE)
|
||||||
|
if (hostsig == SIGFPE) return TARGET_SIGNAL_FPE;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGKILL)
|
||||||
|
if (hostsig == SIGKILL) return TARGET_SIGNAL_KILL;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGBUS)
|
||||||
|
if (hostsig == SIGBUS) return TARGET_SIGNAL_BUS;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSEGV)
|
||||||
|
if (hostsig == SIGSEGV) return TARGET_SIGNAL_SEGV;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSYS)
|
||||||
|
if (hostsig == SIGSYS) return TARGET_SIGNAL_SYS;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPIPE)
|
||||||
|
if (hostsig == SIGPIPE) return TARGET_SIGNAL_PIPE;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGALRM)
|
||||||
|
if (hostsig == SIGALRM) return TARGET_SIGNAL_ALRM;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTERM)
|
||||||
|
if (hostsig == SIGTERM) return TARGET_SIGNAL_TERM;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGUSR1)
|
||||||
|
if (hostsig == SIGUSR1) return TARGET_SIGNAL_USR1;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGUSR2)
|
||||||
|
if (hostsig == SIGUSR2) return TARGET_SIGNAL_USR2;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGCLD)
|
||||||
|
if (hostsig == SIGCLD) return TARGET_SIGNAL_CHLD;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGCHLD)
|
||||||
|
if (hostsig == SIGCHLD) return TARGET_SIGNAL_CHLD;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPWR)
|
||||||
|
if (hostsig == SIGPWR) return TARGET_SIGNAL_PWR;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGWINCH)
|
||||||
|
if (hostsig == SIGWINCH) return TARGET_SIGNAL_WINCH;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGURG)
|
||||||
|
if (hostsig == SIGURG) return TARGET_SIGNAL_URG;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGIO)
|
||||||
|
if (hostsig == SIGIO) return TARGET_SIGNAL_IO;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPOLL)
|
||||||
|
if (hostsig == SIGPOLL) return TARGET_SIGNAL_POLL;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSTOP)
|
||||||
|
if (hostsig == SIGSTOP) return TARGET_SIGNAL_STOP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTSTP)
|
||||||
|
if (hostsig == SIGTSTP) return TARGET_SIGNAL_TSTP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGCONT)
|
||||||
|
if (hostsig == SIGCONT) return TARGET_SIGNAL_CONT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTTIN)
|
||||||
|
if (hostsig == SIGTTIN) return TARGET_SIGNAL_TTIN;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTTOU)
|
||||||
|
if (hostsig == SIGTTOU) return TARGET_SIGNAL_TTOU;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGVTALRM)
|
||||||
|
if (hostsig == SIGVTALRM) return TARGET_SIGNAL_VTALRM;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPROF)
|
||||||
|
if (hostsig == SIGPROF) return TARGET_SIGNAL_PROF;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGXCPU)
|
||||||
|
if (hostsig == SIGXCPU) return TARGET_SIGNAL_XCPU;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGXFSZ)
|
||||||
|
if (hostsig == SIGXFSZ) return TARGET_SIGNAL_XFSZ;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGWIND)
|
||||||
|
if (hostsig == SIGWIND) return TARGET_SIGNAL_WIND;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPHONE)
|
||||||
|
if (hostsig == SIGPHONE) return TARGET_SIGNAL_PHONE;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGLOST)
|
||||||
|
if (hostsig == SIGLOST) return TARGET_SIGNAL_LOST;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGWAITING)
|
||||||
|
if (hostsig == SIGWAITING) return TARGET_SIGNAL_WAITING;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGLWP)
|
||||||
|
if (hostsig == SIGLWP) return TARGET_SIGNAL_LWP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGDANGER)
|
||||||
|
if (hostsig == SIGDANGER) return TARGET_SIGNAL_DANGER;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGGRANT)
|
||||||
|
if (hostsig == SIGGRANT) return TARGET_SIGNAL_GRANT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGRETRACT)
|
||||||
|
if (hostsig == SIGRETRACT) return TARGET_SIGNAL_RETRACT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGMSG)
|
||||||
|
if (hostsig == SIGMSG) return TARGET_SIGNAL_MSG;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSOUND)
|
||||||
|
if (hostsig == SIGSOUND) return TARGET_SIGNAL_SOUND;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSAK)
|
||||||
|
if (hostsig == SIGSAK) return TARGET_SIGNAL_SAK;
|
||||||
|
#endif
|
||||||
|
return TARGET_SIGNAL_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
target_signal_to_host (oursig)
|
||||||
|
enum target_signal oursig;
|
||||||
|
{
|
||||||
|
switch (oursig)
|
||||||
|
{
|
||||||
|
case TARGET_SIGNAL_0: return 0;
|
||||||
|
|
||||||
|
#if defined (SIGHUP)
|
||||||
|
case TARGET_SIGNAL_HUP: return SIGHUP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGINT)
|
||||||
|
case TARGET_SIGNAL_INT: return SIGINT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGQUIT)
|
||||||
|
case TARGET_SIGNAL_QUIT: return SIGQUIT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGILL)
|
||||||
|
case TARGET_SIGNAL_ILL: return SIGILL;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTRAP)
|
||||||
|
case TARGET_SIGNAL_TRAP: return SIGTRAP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGABRT)
|
||||||
|
case TARGET_SIGNAL_ABRT: return SIGABRT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGEMT)
|
||||||
|
case TARGET_SIGNAL_EMT: return SIGEMT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGFPE)
|
||||||
|
case TARGET_SIGNAL_FPE: return SIGFPE;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGKILL)
|
||||||
|
case TARGET_SIGNAL_KILL: return SIGKILL;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGBUS)
|
||||||
|
case TARGET_SIGNAL_BUS: return SIGBUS;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSEGV)
|
||||||
|
case TARGET_SIGNAL_SEGV: return SIGSEGV;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSYS)
|
||||||
|
case TARGET_SIGNAL_SYS: return SIGSYS;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPIPE)
|
||||||
|
case TARGET_SIGNAL_PIPE: return SIGPIPE;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGALRM)
|
||||||
|
case TARGET_SIGNAL_ALRM: return SIGALRM;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTERM)
|
||||||
|
case TARGET_SIGNAL_TERM: return SIGTERM;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGUSR1)
|
||||||
|
case TARGET_SIGNAL_USR1: return SIGUSR1;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGUSR2)
|
||||||
|
case TARGET_SIGNAL_USR2: return SIGUSR2;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGCHLD) || defined (SIGCLD)
|
||||||
|
case TARGET_SIGNAL_CHLD:
|
||||||
|
#if defined (SIGCHLD)
|
||||||
|
return SIGCHLD;
|
||||||
|
#else
|
||||||
|
return SIGCLD;
|
||||||
|
#endif
|
||||||
|
#endif /* SIGCLD or SIGCHLD */
|
||||||
|
#if defined (SIGPWR)
|
||||||
|
case TARGET_SIGNAL_PWR: return SIGPWR;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGWINCH)
|
||||||
|
case TARGET_SIGNAL_WINCH: return SIGWINCH;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGURG)
|
||||||
|
case TARGET_SIGNAL_URG: return SIGURG;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGIO)
|
||||||
|
case TARGET_SIGNAL_IO: return SIGIO;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPOLL)
|
||||||
|
case TARGET_SIGNAL_POLL: return SIGPOLL;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSTOP)
|
||||||
|
case TARGET_SIGNAL_STOP: return SIGSTOP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTSTP)
|
||||||
|
case TARGET_SIGNAL_TSTP: return SIGTSTP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGCONT)
|
||||||
|
case TARGET_SIGNAL_CONT: return SIGCONT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTTIN)
|
||||||
|
case TARGET_SIGNAL_TTIN: return SIGTTIN;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGTTOU)
|
||||||
|
case TARGET_SIGNAL_TTOU: return SIGTTOU;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGVTALRM)
|
||||||
|
case TARGET_SIGNAL_VTALRM: return SIGVTALRM;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPROF)
|
||||||
|
case TARGET_SIGNAL_PROF: return SIGPROF;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGXCPU)
|
||||||
|
case TARGET_SIGNAL_XCPU: return SIGXCPU;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGXFSZ)
|
||||||
|
case TARGET_SIGNAL_XFSZ: return SIGXFSZ;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGWIND)
|
||||||
|
case TARGET_SIGNAL_WIND: return SIGWIND;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGPHONE)
|
||||||
|
case TARGET_SIGNAL_PHONE: return SIGPHONE;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGLOST)
|
||||||
|
case TARGET_SIGNAL_LOST: return SIGLOST;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGWAITING)
|
||||||
|
case TARGET_SIGNAL_WAITING: return SIGWAITING;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGLWP)
|
||||||
|
case TARGET_SIGNAL_LWP: return SIGLWP;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGDANGER)
|
||||||
|
case TARGET_SIGNAL_DANGER: return SIGDANGER;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGGRANT)
|
||||||
|
case TARGET_SIGNAL_GRANT: return SIGGRANT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGRETRACT)
|
||||||
|
case TARGET_SIGNAL_RETRACT: return SIGRETRACT;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGMSG)
|
||||||
|
case TARGET_SIGNAL_MSG: return SIGMSG;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSOUND)
|
||||||
|
case TARGET_SIGNAL_SOUND: return SIGSOUND;
|
||||||
|
#endif
|
||||||
|
#if defined (SIGSAK)
|
||||||
|
case TARGET_SIGNAL_SAK: return SIGSAK;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
/* The user might be trying to do "signal SIGSAK" where this system
|
||||||
|
doesn't have SIGSAK. */
|
||||||
|
warning ("Signal %s does not exist on this system.\n",
|
||||||
|
target_signal_to_name (oursig));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper function for child_wait and the Lynx derivatives of child_wait.
|
||||||
|
HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
|
||||||
|
translation of that in OURSTATUS. */
|
||||||
|
void
|
||||||
|
store_waitstatus (ourstatus, hoststatus)
|
||||||
|
struct target_waitstatus *ourstatus;
|
||||||
|
int hoststatus;
|
||||||
|
{
|
||||||
|
#ifdef CHILD_SPECIAL_WAITSTATUS
|
||||||
|
/* CHILD_SPECIAL_WAITSTATUS should return nonzero and set *OURSTATUS
|
||||||
|
if it wants to deal with hoststatus. */
|
||||||
|
if (CHILD_SPECIAL_WAITSTATUS (ourstatus, hoststatus))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (WIFEXITED (hoststatus))
|
||||||
|
{
|
||||||
|
ourstatus->kind = TARGET_WAITKIND_EXITED;
|
||||||
|
ourstatus->value.integer = WEXITSTATUS (hoststatus);
|
||||||
|
}
|
||||||
|
else if (!WIFSTOPPED (hoststatus))
|
||||||
|
{
|
||||||
|
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
|
||||||
|
ourstatus->value.sig = target_signal_from_host (WTERMSIG (hoststatus));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ourstatus->kind = TARGET_WAITKIND_STOPPED;
|
||||||
|
ourstatus->value.sig = target_signal_from_host (WSTOPSIG (hoststatus));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Convert a normal process ID to a string. Returns the string in a static
|
/* Convert a normal process ID to a string. Returns the string in a static
|
||||||
buffer. */
|
buffer. */
|
||||||
|
|
|
@ -359,8 +359,7 @@ target_detach PARAMS ((char *, int));
|
||||||
#define target_prepare_to_store() \
|
#define target_prepare_to_store() \
|
||||||
(*current_target->to_prepare_to_store) ()
|
(*current_target->to_prepare_to_store) ()
|
||||||
|
|
||||||
extern int
|
extern int target_read_string PARAMS ((CORE_ADDR, char **, int, int *));
|
||||||
target_read_string PARAMS ((CORE_ADDR, char *, int));
|
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
target_read_memory PARAMS ((CORE_ADDR, char *, int));
|
target_read_memory PARAMS ((CORE_ADDR, char *, int));
|
||||||
|
|
|
@ -710,6 +710,13 @@ value_print_array_elements (val, stream, format, pretty)
|
||||||
byte, otherwise printing proceeds (including null bytes) until either
|
byte, otherwise printing proceeds (including null bytes) until either
|
||||||
print_max or LEN characters have been printed, whichever is smaller. */
|
print_max or LEN characters have been printed, whichever is smaller. */
|
||||||
|
|
||||||
|
/* FIXME: All callers supply LEN of zero. Supplying a non-zero LEN is
|
||||||
|
pointless, this routine just then becomes a convoluted version of
|
||||||
|
target_read_memory_partial. Removing all the LEN stuff would simplify
|
||||||
|
this routine enormously.
|
||||||
|
|
||||||
|
FIXME: Use target_read_string. */
|
||||||
|
|
||||||
int
|
int
|
||||||
val_print_string (addr, len, stream)
|
val_print_string (addr, len, stream)
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
|
|
Loading…
Reference in New Issue