* Makefile.in: Add stuff to build nlmstub.

* Add rule for annotate.o to keep Sun make happy.
	* configure.in:  Add config for powerpc/Netware.

	* partial-stab.h (near N_SO):  Don't call START_PSYMTAB with null
	filename.  This speeds up handling of trailing N_SO stabs (they
	mark the end of a .o file).

	* target.c, target.h:  Change the way pushing and popping of
	targets work to support target overlays and inheritance.
	* corelow.c, hppa-tdep.c, inflow.c, remote-nindy.c, utils.c:
	Fixup references to current_target, due to previous changes.

	* config/i386/tm-i386nw.h:  Enable longjmp support.  More work is
	needed to get the address of longjmp out of the target.
This commit is contained in:
Stu Grossman 1994-07-23 00:53:28 +00:00
parent f2c2e75ce0
commit cad1498f8a
11 changed files with 350 additions and 138 deletions

View File

@ -1,3 +1,21 @@
Fri Jul 22 17:30:39 1994 Stu Grossman (grossman@cygnus.com)
* Makefile.in: Add stuff to build nlmstub.
* Add rule for annotate.o to keep Sun make happy.
* configure.in: Add config for powerpc/Netware.
* partial-stab.h (near N_SO): Don't call START_PSYMTAB with null
filename. This speeds up handling of trailing N_SO stabs (they
mark the end of a .o file).
* target.c, target.h: Change the way pushing and popping of
targets work to support target overlays and inheritance.
* corelow.c, hppa-tdep.c, inflow.c, remote-nindy.c, utils.c:
Fixup references to current_target, due to previous changes.
* config/i386/tm-i386nw.h: Enable longjmp support. More work is
needed to get the address of longjmp out of the target.
Tue Jul 19 13:25:06 1994 Stan Shebs (shebs@andros.cygnus.com)
* main.c: Include <ctype.h>.

View File

@ -268,6 +268,31 @@ CHILL_FOR_TARGET = ` \
fi`
CHILL_LIB = -lchill
NLMCONV_FOR_TARGET = ` \
if [ -f $${rootme}/../binutils/nlmconv ] ; then \
echo $${rootme}/../binutils/nlmconv; \
else \
if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
echo $(NLMCONV); \
else \
t='$(program_transform_name)'; echo nlmconv | sed -e '' $$t; \
fi; \
fi`
NWSOURCE = /gaunt/grossman/unsupported/Novell
NWINCLUDES = $(NWSOURCE)/novh40
LD_FOR_TARGET = ` \
if [ -f $${rootme}/../binutils/ld ] ; then \
echo $${rootme}/../binutils/ld; \
else \
if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
echo $(LD); \
else \
t='$(program_transform_name)'; echo ld | sed -e '' $$t; \
fi; \
fi`
# The use of $$(x_FOR_TARGET) reduces the command line length by not
# duplicating the lengthy definition.
TARGET_FLAGS_TO_PASS = \
@ -559,6 +584,20 @@ gdb: $(OBS) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o
$(CC-LD) $(INTERNAL_LDFLAGS) -o gdb \
init.o $(OBS) $(TSOBS) $(ADD_FILES) $(CLIBS) $(LOADLIBES)
prelude.o: $(NWSOURCE)/prelude.c
rootme=`pwd`; export rootme; $(CC_FOR_TARGET) -g -I $(NWINCLUDES) -c $(NWSOURCE)/prelude.c
i386-nlmstub.o: $(srcdir)/i386-nlmstub.c
rootme=`pwd`; export rootme; $(CC_FOR_TARGET) -g -I $(NWINCLUDES) -c $(srcdir)/i386-nlmstub.c
nlmstub.o: prelude.o i386-nlmstub.o
rootme=`pwd`; export rootme; $(LD_FOR_TARGET) -r -o nlmstub.o prelude.o i386-nlmstub.o
nlmstub.nlm: nlmstub.o $(srcdir)/nlmstub.def
rootme=`pwd`; export rootme; $(NLMCONV_FOR_TARGET) -T $(srcdir)/nlmstub.def nlmstub.o nlmstub.nlm
nlmstub: nlmstub.nlm
# libproc is not listed here because all-libproc is a dependency of all-gui,
# not all-gdb, and thus might be built after us.
LIBGDBDEPS=$(COMMON_OBS) $(LIBGDB_OBS) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o
@ -1301,6 +1340,8 @@ top.o: top.c top.h $(bfd_h) $(getopt_h) $(readline_headers) call-cmds.h \
main.o: main.c top.h $(defs_h)
annotate.o: annotate.c annotate.h $(defs_h) value.h target.h $(gdbtypes_h)
maint.o: maint.c $(defs_h) $(gdbcmd_h) $(gdbtypes_h) $(symtab_h) language.h \
$(expression_h)

View File

@ -29,3 +29,22 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Stop backtracing when we wander into main. */
#define FRAME_CHAIN_VALID_ALTERNATE
/* Offsets (in target ints) into jmp_buf. Not defined in any system header
file, so we have to step through setjmp/longjmp with a debugger and figure
them out. */
#define JB_ELEMENT_SIZE 4 /* jmp_buf[] is array of ints */
#define JB_PC 6 /* Setjmp()'s return PC saved here */
/* Figure out where the longjmp will land. Slurp the args out of the stack.
We expect the first arg to be a pointer to the jmp_buf structure from which
we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
This routine returns true on success */
extern int
get_longjmp_target PARAMS ((CORE_ADDR *));
#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)

View File

@ -300,6 +300,7 @@ ns32k-utek-sysv*) gdb_target=merlin ;;
ns32k-utek-*) gdb_target=umax ;;
pn-*-*) gdb_target=pn ;;
powerpc-*-netware*) gdb_target=ppc-nw ;;
pyramid-*-*) gdb_target=pyramid ;;

View File

@ -209,7 +209,7 @@ core_open (filename, from_tty)
} else {
warning (
"you won't be able to access this core file until you terminate\n\
your %s; do ``info files''", current_target->to_longname);
your %s; do ``info files''", target_longname);
}
}

View File

@ -1209,7 +1209,7 @@ restore_pc_queue (fsr)
}
}
target_terminal_ours ();
(current_target->to_fetch_registers) (-1);
target_fetch_registers (-1);
return 1;
}

View File

@ -545,7 +545,7 @@ kill_command (arg, from_tty)
/* Killing off the inferior can leave us with a core file. If so,
print the state we are left in. */
if (target_has_stack) {
printf_filtered ("In %s,\n", current_target->to_longname);
printf_filtered ("In %s,\n", target_longname);
if (selected_frame == NULL)
fputs_filtered ("No selected stack frame.\n", gdb_stdout);
else
@ -578,6 +578,67 @@ clear_sigint_trap()
signal (SIGINT, osig);
}
#if defined (SIGIO) && defined (FASYNC) && defined (FD_SET)
static void (*old_sigio) ();
static void
handle_sigio (signo)
int signo;
{
int numfds;
fd_set readfds;
signal (SIGIO, handle_sigio);
FD_ZERO (&readfds);
FD_SET (target_activity_fd, &readfds);
numfds = select (target_activity_fd + 1, &readfds, NULL, NULL, NULL);
if (numfds >= 0 && FD_ISSET (target_activity_fd, &readfds))
{
if ((*target_activity_function) ())
kill (inferior_pid, SIGINT);
}
}
static int old_fcntl_flags;
void
set_sigio_trap ()
{
if (target_activity_function)
{
old_sigio = (void (*) ()) signal (SIGIO, handle_sigio);
fcntl (target_activity_fd, F_SETOWN, getpid());
old_fcntl_flags = fcntl (target_activity_fd, F_GETFL, 0);
fcntl (target_activity_fd, F_SETFL, old_fcntl_flags | FASYNC);
}
}
void
clear_sigio_trap ()
{
if (target_activity_function)
{
signal (SIGIO, old_sigio);
fcntl (target_activity_fd, F_SETFL, old_fcntl_flags);
}
}
#else /* No SIGIO. */
void
set_sigio_trap ()
{
if (target_activity_function)
abort ();
}
void
clear_sigio_trap ()
{
if (target_activity_function)
abort ();
}
#endif /* No SIGIO. */
/* This is here because this is where we figure out whether we (probably)
have job control. Just using job_control only does part of it because

View File

@ -217,6 +217,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
SET_NAMESTRING();
/* Null name means end of .o file. Don't start a new one. */
if (*namestring == '\000')
continue;
/* Some compilers (including gcc) emit a pair of initial N_SOs.
The first one is a directory name; the second the file name.
If pst exists, is empty, and has a filename ending in '/',

View File

@ -685,7 +685,8 @@ nindy_before_main_loop ()
char ttyname[100];
char *p, *p2;
while (current_target != &nindy_ops) { /* remote tty not specified yet */
while (target_stack->target_ops != &nindy_ops) /* What is this crap??? */
{ /* remote tty not specified yet */
if ( instream == stdin ){
printf_unfiltered("\nAttach /dev/ttyNN -- specify NN, or \"quit\" to quit: ");
gdb_flush( gdb_stdout );

View File

@ -104,14 +104,14 @@ struct target_ops dummy_target = {"None", "None", "",
OPS_MAGIC,
};
/* Top of target stack. */
struct target_stack_item *target_stack;
/* The target structure we are currently using to talk to a process
or file or whatever "inferior" we have. */
struct target_ops *current_target;
/* The stack of target structures that have been pushed. */
struct target_ops **current_target_stack;
struct target_ops current_target;
/* Command list for target. */
@ -140,13 +140,6 @@ void
add_target (t)
struct target_ops *t;
{
if (t->to_magic != OPS_MAGIC)
{
fprintf_unfiltered(gdb_stderr, "Magic number of %s target struct wrong\n",
t->to_shortname);
abort();
}
if (!target_structs)
{
target_struct_allocsize = DEFAULT_ALLOCSIZE;
@ -197,7 +190,7 @@ static void
tcomplain ()
{
error ("You can't do that when your target is `%s'",
current_target->to_shortname);
current_target.to_shortname);
}
void
@ -224,35 +217,6 @@ default_terminal_info (args, from_tty)
printf_unfiltered("No saved terminal information.\n");
}
#if 0
/* With strata, this function is no longer needed. FIXME. */
/* This is the default target_create_inferior function. It looks up
the stack for some target that cares to create inferiors, then
calls it -- or complains if not found. */
static void
upstack_create_inferior (exec, args, env)
char *exec;
char *args;
char **env;
{
struct target_ops *t;
for (t = current_target;
t;
t = t->to_next)
{
if (t->to_create_inferior != upstack_create_inferior)
{
t->to_create_inferior (exec, args, env);
return;
}
}
tcomplain();
}
#endif
/* This is the default target_create_inferior and target_attach function.
If the current target is executing, it asks whether to kill it off.
If this function returns without calling error(), it has killed off
@ -305,15 +269,6 @@ cleanup_target (t)
struct target_ops *t;
{
/* Check magic number. If wrong, it probably means someone changed
the struct definition, but not all the places that initialize one. */
if (t->to_magic != OPS_MAGIC)
{
fprintf_unfiltered(gdb_stderr, "Magic number of %s target struct wrong\n",
t->to_shortname);
abort();
}
#define de_fault(field, value) \
if (!t->field) t->field = value
@ -344,16 +299,74 @@ cleanup_target (t)
de_fault (to_mourn_inferior, (void (*)())noprocess);
de_fault (to_can_run, return_zero);
de_fault (to_notice_signals, (void (*)())ignore);
de_fault (to_next, 0);
de_fault (to_has_all_memory, 0);
de_fault (to_has_memory, 0);
de_fault (to_has_stack, 0);
de_fault (to_has_registers, 0);
de_fault (to_has_execution, 0);
#undef de_fault
}
/* Go through the target stack from top to bottom, copying over zero entries in
current_target. In effect, we are doing class inheritance through the
pushed target vectors. */
static void
update_current_target ()
{
struct target_stack_item *item;
struct target_ops *t;
/* First, reset current_target */
memset (&current_target, 0, sizeof current_target);
for (item = target_stack; item; item = item->next)
{
t = item->target_ops;
#define INHERIT(FIELD, TARGET) \
if (!current_target.FIELD) \
current_target.FIELD = TARGET->FIELD
INHERIT (to_shortname, t);
INHERIT (to_longname, t);
INHERIT (to_doc, t);
INHERIT (to_open, t);
INHERIT (to_close, t);
INHERIT (to_attach, t);
INHERIT (to_detach, t);
INHERIT (to_resume, t);
INHERIT (to_wait, t);
INHERIT (to_fetch_registers, t);
INHERIT (to_store_registers, t);
INHERIT (to_prepare_to_store, t);
INHERIT (to_xfer_memory, t);
INHERIT (to_files_info, t);
INHERIT (to_insert_breakpoint, t);
INHERIT (to_remove_breakpoint, t);
INHERIT (to_terminal_init, t);
INHERIT (to_terminal_inferior, t);
INHERIT (to_terminal_ours_for_output, t);
INHERIT (to_terminal_ours, t);
INHERIT (to_terminal_info, t);
INHERIT (to_kill, t);
INHERIT (to_load, t);
INHERIT (to_lookup_symbol, t);
INHERIT (to_create_inferior, t);
INHERIT (to_mourn_inferior, t);
INHERIT (to_can_run, t);
INHERIT (to_notice_signals, t);
INHERIT (to_stratum, t);
INHERIT (DONT_USE, t);
INHERIT (to_has_all_memory, t);
INHERIT (to_has_memory, t);
INHERIT (to_has_stack, t);
INHERIT (to_has_registers, t);
INHERIT (to_has_execution, t);
INHERIT (to_sections, t);
INHERIT (to_sections_end, t);
INHERIT (to_magic, t);
#undef INHERIT
}
}
/* Push a new target type into the stack of the existing target accessors,
possibly superseding some of the existing accessors.
@ -368,74 +381,103 @@ int
push_target (t)
struct target_ops *t;
{
struct target_ops *st, *prev;
struct target_stack_item *cur, *prev, *tmp;
for (prev = 0, st = current_target;
st;
prev = st, st = st->to_next) {
if ((int)(t->to_stratum) >= (int)(st->to_stratum))
break;
}
/* Check magic number. If wrong, it probably means someone changed
the struct definition, but not all the places that initialize one. */
if (t->to_magic != OPS_MAGIC)
{
fprintf_unfiltered(gdb_stderr,
"Magic number of %s target struct wrong\n",
t->to_shortname);
abort();
}
while (t->to_stratum == st->to_stratum) {
/* There's already something on this stratum. Close it off. */
(st->to_close) (0);
if (prev)
prev->to_next = st->to_next; /* Unchain old target_ops */
else
current_target = st->to_next; /* Unchain first on list */
st = st->to_next;
}
/* Find the proper stratum to install this target in. */
for (prev = NULL, cur = target_stack; cur; prev = cur, cur = cur->next)
{
if ((int)(t->to_stratum) >= (int)(cur->target_ops->to_stratum))
break;
}
/* If there's already targets at this stratum, remove them. */
if (cur)
while (t->to_stratum == cur->target_ops->to_stratum)
{
/* There's already something on this stratum. Close it off. */
(cur->target_ops->to_close) (0);
if (prev)
prev->next = cur->next; /* Unchain old target_ops */
else
target_stack = cur->next; /* Unchain first on list */
tmp = cur->next;
free (cur);
cur = tmp;
}
/* We have removed all targets in our stratum, now add the new one. */
tmp = xmalloc (sizeof (struct target_stack_item));
tmp->next = cur;
tmp->target_ops = t;
/* We have removed all targets in our stratum, now add ourself. */
t->to_next = st;
if (prev)
prev->to_next = t;
prev->next = tmp;
else
current_target = t;
target_stack = tmp;
cleanup_target (current_target);
update_current_target ();
cleanup_target (&current_target); /* Fill in the gaps */
return prev != 0;
}
/* Remove a target_ops vector from the stack, wherever it may be.
Return how many times it was removed (0 or 1 unless bug). */
Return how many times it was removed (0 or 1). */
int
unpush_target (t)
struct target_ops *t;
{
struct target_ops *u, *v;
int result = 0;
struct target_stack_item *cur, *prev;
for (u = current_target, v = 0;
u;
v = u, u = u->to_next)
if (u == t)
{
if (v == 0)
pop_target(); /* unchain top copy */
else {
(t->to_close)(0); /* Let it clean up */
v->to_next = t->to_next; /* unchain middle copy */
}
result++;
}
return result;
/* Look for the specified target. Note that we assume that a target
can only occur once in the target stack. */
for (cur = target_stack, prev = NULL; cur; prev = cur, cur = cur->next)
if (cur->target_ops == t)
break;
if (!cur)
return 0; /* Didn't find target_ops, quit now */
/* Unchain the target */
if (!prev)
target_stack = NULL;
else
prev->next = cur->next;
free (cur); /* Release the target_stack_item */
(t->to_close) (0); /* Let it clean up */
return 1;
}
void
pop_target ()
{
(current_target->to_close)(0); /* Let it clean up */
current_target = current_target->to_next;
#if 0
/* This will dump core if ever called--push_target expects current_target
to be non-NULL. But I don't think it's needed; I don't see how the
dummy_target could ever be removed from the stack. */
if (!current_target) /* At bottom, push dummy. */
push_target (&dummy_target);
#endif
(current_target.to_close)(0); /* Let it clean up */
if (unpush_target (target_stack->target_ops) == 1)
return;
fprintf_unfiltered(gdb_stderr,
"pop_target couldn't find target %s\n",
current_target.to_shortname);
abort();
}
#undef MIN
@ -599,14 +641,15 @@ target_xfer_memory (memaddr, myaddr, len, write)
int curlen;
int res;
struct target_ops *t;
struct target_stack_item *item;
/* to_xfer_memory is not guaranteed to set errno, even when it returns
0. */
errno = 0;
/* The quick case is that the top target does it all. */
res = current_target->to_xfer_memory
(memaddr, myaddr, len, write, current_target);
res = current_target.to_xfer_memory
(memaddr, myaddr, len, write, &current_target);
if (res == len)
return 0;
@ -617,15 +660,17 @@ target_xfer_memory (memaddr, myaddr, len, write)
for (; len > 0;)
{
curlen = len; /* Want to do it all */
for (t = current_target;
t;
t = t->to_has_all_memory? 0: t->to_next)
for (item = target_stack; item; item = item->next)
{
res = t->to_xfer_memory(memaddr, myaddr, curlen, write, t);
if (res > 0) break; /* Handled all or part of xfer */
if (res == 0) continue; /* Handled none */
curlen = -res; /* Could handle once we get past res bytes */
t = item->target_ops;
res = t->to_xfer_memory (memaddr, myaddr, curlen, write, t);
if (res > 0)
break; /* Handled all or part of xfer */
if (t->to_has_all_memory)
break;
}
if (res <= 0)
{
/* If this address is for nonexistent memory,
@ -653,6 +698,7 @@ target_info (args, from_tty)
int from_tty;
{
struct target_ops *t;
struct target_stack_item *item;
int has_all_mem = 0;
if (symfile_objfile != NULL)
@ -663,14 +709,14 @@ target_info (args, from_tty)
return;
#endif
for (t = current_target;
t;
t = t->to_next)
for (item = target_stack; item; item = item->next)
{
t = item->target_ops;
if ((int)(t->to_stratum) <= (int)dummy_stratum)
continue;
if (has_all_mem)
printf_unfiltered("\tWhile running this, gdb does not access memory from...\n");
printf_unfiltered("\tWhile running this, GDB does not access memory from...\n");
printf_unfiltered("%s:\n", t->to_longname);
(t->to_files_info)(t);
has_all_mem = t->to_has_all_memory;
@ -712,7 +758,7 @@ target_detach (args, from_tty)
#ifdef DO_DEFERRED_STORES
DO_DEFERRED_STORES;
#endif
(current_target->to_detach) (args, from_tty);
(current_target.to_detach) (args, from_tty);
}
void
@ -720,9 +766,9 @@ target_link (modname, t_reloc)
char *modname;
CORE_ADDR *t_reloc;
{
if (STREQ(current_target->to_shortname, "rombug"))
if (STREQ(current_target.to_shortname, "rombug"))
{
(current_target->to_lookup_symbol) (modname, t_reloc);
(current_target.to_lookup_symbol) (modname, t_reloc);
if (*t_reloc == 0)
error("Unable to link to %s and get relocation in rombug", modname);
}
@ -820,6 +866,8 @@ find_core_target ()
void
generic_mourn_inferior ()
{
extern int show_breakpoint_hit_counts;
inferior_pid = 0;
attach_flag = 0;
breakpoint_init_inferior ();
@ -835,7 +883,10 @@ generic_mourn_inferior ()
/* It is confusing to the user for ignore counts to stick around
from previous runs of the inferior. So clear them. */
breakpoint_clear_ignore_counts ();
/* However, it is more confusing for the ignore counts to disappear when
using hit counts. So don't clear them if we're counting hits. */
if (!show_breakpoint_hit_counts)
breakpoint_clear_ignore_counts ();
}
/* This table must match in order and size the signals in enum target_signal
@ -1269,6 +1320,10 @@ store_waitstatus (ourstatus, hoststatus)
}
}
/* Returns zero to leave the inferior alone, one to interrupt it. */
int (*target_activity_function) PARAMS ((void));
int target_activity_fd;
/* Convert a normal process ID to a string. Returns the string in a static
buffer. */
@ -1292,8 +1347,7 @@ core-file, and process, if any), as well as the symbol file name.";
void
_initialize_targets ()
{
current_target = &dummy_target;
cleanup_target (current_target);
push_target (&dummy_target);
add_info ("target", target_info, targ_desc);
add_info ("files", target_info, targ_desc);

View File

@ -465,7 +465,7 @@ quit ()
if (job_control
/* If there is no terminal switching for this target, then we can't
possibly get screwed by the lack of job control. */
|| current_target->to_terminal_ours == NULL)
|| current_target.to_terminal_ours == NULL)
fprintf_unfiltered (gdb_stderr, "Quit\n");
else
fprintf_unfiltered (gdb_stderr,
@ -541,8 +541,12 @@ request_quit (signo)
about USG defines and stuff like that. */
signal (signo, request_quit);
#ifdef REQUEST_QUIT
REQUEST_QUIT;
#else
if (immediate_quit)
quit ();
#endif
}
@ -823,6 +827,13 @@ query (va_alist)
/* Automatically answer "yes" if input is not from a terminal. */
if (!input_from_terminal_p ())
return 1;
/* start-sanitize-mpw */
#ifdef MPW
/* Automatically answer "yes" if called from MacGDB. */
if (mac_app)
return 1;
#endif /* MPW */
/* end-sanitize-mpw */
while (1)
{
@ -841,6 +852,14 @@ query (va_alist)
if (annotation_level > 1)
printf_filtered ("\n\032\032query\n");
/* start-sanitize-mpw */
#ifdef MPW
/* If not in MacGDB, move to a new line so the entered line doesn't
have a prompt on the front of it. */
if (!mac_app)
fputs_unfiltered ("\n", gdb_stdout);
#endif /* MPW */
/* end-sanitize-mpw */
gdb_flush (gdb_stdout);
answer = fgetc (stdin);
clearerr (stdin); /* in case of C-d */
@ -1148,6 +1167,10 @@ void
wrap_here(indent)
char *indent;
{
/* This should have been allocated, but be paranoid anyway. */
if (!wrap_buffer)
abort ();
if (wrap_buffer[0])
{
*wrap_pointer = '\0';
@ -1331,16 +1354,6 @@ fputs_filtered (linebuffer, stream)
fputs_maybe_filtered (linebuffer, stream, 1);
}
#ifndef FPUTS_UNFILTERED_OVERRIDE
void
fputs_unfiltered (linebuffer, stream)
const char *linebuffer;
FILE *stream;
{
fputs (linebuffer, stream);
}
#endif /* FPUTS_UNFILTERED_OVERRIDE */
void
putc_unfiltered (c)
int c;