diff options
-rw-r--r-- | gdb/ChangeLog | 21 | ||||
-rw-r--r-- | gdb/Makefile.in | 89 | ||||
-rw-r--r-- | gdb/coffread.c | 150 | ||||
-rw-r--r-- | gdb/exec.c | 19 | ||||
-rw-r--r-- | gdb/remote-vx.c | 390 |
5 files changed, 410 insertions, 259 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 91e5a4d..6b860b7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,24 @@ +Mon Oct 17 10:29:08 1994 Jim Kingdon (kingdon@lioth.cygnus.com) + + * Makefile.in (ALLDEPFILES): Remove xcoffexec.c. + * Makefile.in: Remove xcoffexec.o rule. + + * exec.c (exec_file_command): Add comment. + + Fix data and bss relocation for VxWorks 5.1: + * remote-vx.c (vx_add_symbols): New function. + (vx_load_command, add_symbol_stub): Call it instead of + symbol_file_add. + (vx_wait): Remove comment which was wrong to useless. + * remote-vx.c: Reindent much of file. + * coffread.c (cs_to_section, find_targ_sec): New functions. + (process_coff_symbol): Set SYMBOL_SECTION to result + from cs_to_section. + (coff_symtab_read): Call cs_to_section and deal appropriate + rather than assuming sections are in a certain order. Deal with + BSS. + * coffread.c: Remove text_bfd_scnum variable. + Sat Oct 15 16:55:48 1994 Stan Shebs (shebs@andros.cygnus.com) * corelow.c: Format to standard. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 213f294..4b38d0b 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -203,6 +203,8 @@ SER_HARDWIRE=ser-unix.o # but not all (e.g. 960) REMOTE_O = remote.o dcache.o remote-utils.o +ANNOTATE_OBS = annotate.o + # Host and target-dependent makefile fragments come in here. #### # End of host and target-dependent makefile fragments @@ -287,9 +289,6 @@ NLMCONV_FOR_TARGET = ` \ fi; \ fi` -NWSOURCE = /gaunt/grossman/unsupported/Novell -NWINCLUDES = $(NWSOURCE)/novh40 - LD_FOR_TARGET = ` \ if [ -f $${rootme}/../ld/ld.new ] ; then \ echo $${rootme}/../ld/ld.new; \ @@ -334,8 +333,10 @@ TARGET_FLAGS_TO_PASS = \ SFILES = blockframe.c breakpoint.c buildsym.c c-exp.y c-lang.c \ c-typeprint.c c-valprint.c ch-exp.y ch-lang.c ch-typeprint.c \ ch-valprint.c coffread.c command.c complaints.c core.c cp-valprint.c \ - dbxread.c demangle.c dwarfread.c elfread.c environ.c eval.c expprint.c \ - findvar.c gdbtypes.c infcmd.c inflow.c infrun.c language.c \ + dbxread.c demangle.c dwarfread.c \ + elfread.c environ.c eval.c expprint.c \ + f-exp.y f-lang.c f-typeprint.c f-valprint.c findvar.c \ + gdbtypes.c infcmd.c inflow.c infrun.c language.c \ m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \ mem-break.c minsyms.c mipsread.c nlmread.c objfiles.c parse.c \ printcmd.c remote.c source.c stabsread.c stack.c symfile.c symmisc.c \ @@ -402,7 +403,8 @@ HFILES_NO_SRCDIR = buildsym.h call-cmds.h coff-solib.h defs.h dst.h environ.h \ gdb-stabs.h $(inferior_h) language.h minimon.h monitor.h \ objfiles.h parser-defs.h partial-stab.h serial.h signals.h solib.h \ symfile.h stabsread.h target.h terminal.h typeprint.h xcoffsolib.h \ - c-lang.h ch-lang.h m2-lang.h complaints.h ns32k-opcode.h valprint.h \ + c-lang.h ch-lang.h f-lang.h m2-lang.h \ + complaints.h valprint.h \ 29k-share/udi/udiids.h 29k-share/udi_soc nindy-share/b.out.h \ nindy-share/block_io.h nindy-share/coff.h \ nindy-share/env.h nindy-share/stop.h \ @@ -448,13 +450,16 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o stack.o thread.o \ symtab.o symfile.o symmisc.o infcmd.o infrun.o command.o \ expprint.o environ.o gdbtypes.o copying.o $(DEPFILES) \ mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \ - objfiles.o minsyms.o maint.o demangle.o dbxread.o coffread.o elfread.o \ - dwarfread.o mipsread.o stabsread.o core.o c-lang.o ch-lang.o m2-lang.o \ - complaints.o typeprint.o c-typeprint.o ch-typeprint.o m2-typeprint.o \ - c-valprint.o cp-valprint.o ch-valprint.o m2-valprint.o nlmread.o \ - serial.o mdebugread.o os9kread.o top.o utils.o + exec.o objfiles.o minsyms.o maint.o demangle.o \ + dbxread.o coffread.o elfread.o \ + dwarfread.o mipsread.o stabsread.o core.o \ + c-lang.o ch-lang.o f-lang.o m2-lang.o \ + complaints.o typeprint.o \ + c-typeprint.o ch-typeprint.o f-typeprint.o m2-typeprint.o \ + c-valprint.o cp-valprint.o ch-valprint.o f-valprint.o m2-valprint.o \ + nlmread.o serial.o mdebugread.o os9kread.o top.o utils.o -OBS = $(COMMON_OBS) main.o annotate.o +OBS = $(COMMON_OBS) $(ANNOTATE_OBS) main.o LIBGDB_OBS = @@ -467,8 +472,8 @@ NTSSTART = kdb-start.o SUBDIRS = doc testsuite nlm # For now, shortcut the "configure GDB for fewer languages" stuff. -YYFILES = c-exp.tab.c m2-exp.tab.c ch-exp.tab.c -YYOBJ = c-exp.tab.o m2-exp.tab.o ch-exp.tab.o +YYFILES = c-exp.tab.c f-exp.tab.c m2-exp.tab.c ch-exp.tab.c +YYOBJ = c-exp.tab.o f-exp.tab.o m2-exp.tab.o ch-exp.tab.o # Things which need to be built when making a distribution. @@ -572,20 +577,6 @@ 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; rootsrc=`cd $(srcdir); pwd`; export rootsrc; $(CC_FOR_TARGET) -g -I $(NWINCLUDES) -c $(NWSOURCE)/prelude.c - -i386-nlmstub.o: $(srcdir)/i386-nlmstub.c - rootme=`pwd`; export rootme; rootsrc=`cd $(srcdir); pwd`; export rootsrc; $(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 - nlm: force rootme=`pwd`; export rootme; $(MAKE) $(TARGET_FLAGS_TO_PASS) DO=all DODIRS=nlm subdir_do @@ -713,7 +704,8 @@ distclean: clean realclean: clean @$(MAKE) $(FLAGS_TO_PASS) DO=realclean "DODIRS=$(SUBDIRS)" subdir_do - rm -f c-exp.tab.c m2-exp.tab.c ch-exp.tab.c TAGS $(INFOFILES) + rm -f c-exp.tab.c f-exp.tab.c m2-exp.tab.c ch-exp.tab.c + rm -f TAGS $(INFOFILES) rm -f nm.h tm.h xm.h config.status rm -f y.output yacc.acts yacc.tmp rm -f Makefile @@ -789,15 +781,28 @@ c-exp.tab.c: c-exp.y -rm y.tab.c mv c-exp.new ./c-exp.tab.c +f-exp.tab.o: f-exp.tab.c +f-exp.tab.c: f-exp.y c-exp.tab.c + $(YACC) $(YFLAGS) $(srcdir)/f-exp.y + -sed -e '/extern.*malloc/d' \ + -e '/extern.*realloc/d' \ + -e '/extern.*free/d' \ + -e '/include.*malloc.h/d' \ + -e 's/malloc/xmalloc/g' \ + -e 's/realloc/xrealloc/g' \ + < y.tab.c > f-exp.new + -rm y.tab.c + mv f-exp.new ./f-exp.tab.c + # ch-exp.tab.c is generated in objdir from ch-exp.y if it doesn't exist # in srcdir, then compiled in objdir to ch-exp.tab.o. # Remove bogus decls for malloc/realloc/free which conflict with everything # else. ch-exp.tab.o: ch-exp.tab.c -# the dependency here on c-exp.tab.c is artificial. Without this +# the dependency here on f-exp.tab.c is artificial. Without this # dependency, a parallel make will attempt to build both at the same # time and the second yacc will pollute the first y.tab.c file. -ch-exp.tab.c: ch-exp.y c-exp.tab.c +ch-exp.tab.c: ch-exp.y f-exp.tab.c $(YACC) $(YFLAGS) $(srcdir)/ch-exp.y -sed -e '/extern.*malloc/d' \ -e '/extern.*realloc/d' \ @@ -830,7 +835,7 @@ m2-exp.tab.c: m2-exp.y ch-exp.tab.c mv m2-exp.new ./m2-exp.tab.c # These files are updated atomically, so make never has to remove them -.PRECIOUS: m2-exp.tab.c ch-exp.tab.c c-exp.tab.c +.PRECIOUS: m2-exp.tab.c ch-exp.tab.c f-exp.tab.c c-exp.tab.c lint: $(LINTFILES) $(LINT) $(INCLUDE_CFLAGS) $(LINTFLAGS) $(LINTFILES) \ @@ -899,7 +904,7 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \ tahoe-pinsn.c ultra3-nat.c ultra3-xdep.c umax-xdep.c \ vax-pinsn.c \ vx-share/xdr_ld.c vx-share/xdr_ptrace.c vx-share/xdr_rdb.c \ - xcoffexec.c xcoffread.c xcoffsolib.c z8k-tdep.c + xcoffread.c xcoffsolib.c z8k-tdep.c ALLCONFIG = config/a29k/a29k-kern.mt config/a29k/a29k-udi.mt \ config/a29k/a29k.mt config/a29k/ultra3.mh config/a29k/ultra3.mt \ @@ -1009,6 +1014,16 @@ c-typeprint.o: c-typeprint.c c-lang.h $(defs_h) $(expression_h) \ c-valprint.o: c-valprint.c $(defs_h) $(expression_h) $(gdbtypes_h) \ language.h $(symtab_h) valprint.h $(value_h) +f-lang.o: f-lang.c f-lang.h $(defs_h) $(expression_h) $(gdbtypes_h) \ + language.h parser-defs.h $(symtab_h) + +f-typeprint.o: f-typeprint.c f-lang.h $(defs_h) $(expression_h) \ + $(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \ + typeprint.h $(value_h) + +f-valprint.o: f-valprint.c $(defs_h) $(expression_h) $(gdbtypes_h) \ + language.h $(symtab_h) valprint.h $(value_h) + ch-lang.o: ch-lang.c ch-lang.h $(defs_h) $(expression_h) $(gdbtypes_h) \ language.h parser-defs.h $(symtab_h) @@ -1185,8 +1200,6 @@ 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) @@ -1233,8 +1246,7 @@ ttyflush.o: nindy-share/ttyflush.c nindy-tdep.o: nindy-tdep.c $(defs_h) $(frame_h) $(symtab_h) -ns32k-pinsn.o: ns32k-pinsn.c $(defs_h) $(gdbcore_h) ns32k-opcode.h \ - $(symtab_h) +ns32k-pinsn.o: ns32k-pinsn.c $(bfd_h) $(dis-asm_h) $(defs_h) objfiles.o: objfiles.c $(bfd_h) $(defs_h) objfiles.h symfile.h \ $(symtab_h) @@ -1420,9 +1432,6 @@ xdr_rdb.o: vx-share/xdr_rdb.c $(defs_h) vx-share/vxTypes.h \ vx-share/vxWorks.h vx-share/xdr_rdb.h $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/vx-share/xdr_rdb.c -xcoffexec.o: xcoffexec.c $(BFD_SRC)/libbfd.h $(defs_h) $(gdbcmd_h) \ - $(gdbcore_h) $(inferior_h) objfiles.h symfile.h target.h xcoffsolib.h - xcoffread.o: xcoffread.c $(bfd_h) $(INCLUDE_DIR)/aout/stab.def \ $(INCLUDE_DIR)/aout/stab_gnu.h $(INCLUDE_DIR)/coff/internal.h \ $(INCLUDE_DIR)/coff/rs6000.h $(BFD_SRC)/libcoff.h buildsym.h \ diff --git a/gdb/coffread.c b/gdb/coffread.c index d04cbb7..82b7299 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -284,6 +284,48 @@ coff_locate_sections (ignore_abfd, sectp, csip) } } +/* Return the section_offsets* that CS points to. */ +static int cs_to_section PARAMS ((struct coff_symbol *, struct objfile *)); + +struct find_targ_sec_arg { + int targ_index; + int *resultp; +}; + +static void find_targ_sec PARAMS ((bfd *, asection *, void *)); + +static void find_targ_sec (abfd, sect, obj) + bfd *abfd; + asection *sect; + PTR obj; +{ + struct find_targ_sec_arg *args = (struct find_targ_sec_arg *)obj; + if (sect->target_index == args->targ_index) + { + /* This is the section. Figure out what SECT_OFF_* code it is. */ + if (bfd_get_section_flags (abfd, sect) & SEC_CODE) + *args->resultp = SECT_OFF_TEXT; + else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD) + *args->resultp = SECT_OFF_DATA; + else + *args->resultp = SECT_OFF_BSS; + } +} + +/* Return the section number (SECT_OFF_*) that CS points to. */ +static int +cs_to_section (cs, objfile) + struct coff_symbol *cs; + struct objfile *objfile; +{ + int off = SECT_OFF_TEXT; + struct find_targ_sec_arg args; + args.targ_index = cs->c_secnum; + args.resultp = &off; + bfd_map_over_sections (objfile->obfd, find_targ_sec, &args); + return off; +} + /* Look up a coff type-number index. Return the address of the slot where the type for that index is stored. The type-number is in INDEX. @@ -482,13 +524,10 @@ record_minimal_symbol (name, address, type, objfile) The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */ -static int text_bfd_scnum; - static void coff_symfile_init (objfile) struct objfile *objfile; { - asection *section; bfd *abfd = objfile->obfd; /* Allocate struct to keep track of stab reading. */ @@ -504,13 +543,6 @@ coff_symfile_init (objfile) memset (objfile->sym_private, 0, sizeof (struct coff_symfile_info)); init_entry_point_info (objfile); - - /* Save the section number for the text section */ - section = bfd_get_section_by_name (abfd, ".text"); - if (section) - text_bfd_scnum = section->index; - else - text_bfd_scnum = -1; } /* This function is called for every section; it finds the outer limits @@ -867,36 +899,39 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile) break; /* fall in for static symbols that don't start with '.' */ case C_EXT: - /* Record it in the minimal symbols regardless of SDB_TYPE. - This parallels what we do for other debug formats, and - probably is needed to make print_address_symbolic work right - without the (now gone) "set fast-symbolic-addr off" kludge. */ - - /* FIXME: This bogusly assumes the sections are in a certain - order, text (SEC_CODE) sections are before data sections, - etc. */ - if (cs->c_secnum <= text_bfd_scnum+1) - { - /* text or absolute. (FIXME, should use mst_abs if - absolute). */ - tmpaddr = cs->c_value; - if (cs->c_sclass != C_STAT) - tmpaddr += ANOFFSET (section_offsets, SECT_OFF_TEXT); - record_minimal_symbol - (cs->c_name, tmpaddr, - cs->c_sclass == C_STAT ? mst_file_text : mst_text, - objfile); - } - else - { - tmpaddr = cs->c_value; - if (cs->c_sclass != C_STAT) - tmpaddr += ANOFFSET (section_offsets, SECT_OFF_DATA); - record_minimal_symbol - (cs->c_name, tmpaddr, - cs->c_sclass == C_STAT ? mst_file_data : mst_data, - objfile); - } + { + /* Record it in the minimal symbols regardless of + SDB_TYPE. This parallels what we do for other debug + formats, and probably is needed to make + print_address_symbolic work right without the (now + gone) "set fast-symbolic-addr off" kludge. */ + + /* FIXME: should use mst_abs, and not relocate, if absolute. */ + enum minimal_symbol_type ms_type; + int sec = cs_to_section (cs, objfile); + tmpaddr = cs->c_value; + if (cs->c_sclass != C_STAT) + tmpaddr += ANOFFSET (section_offsets, sec); + switch (sec) + { + case SECT_OFF_TEXT: + case SECT_OFF_RODATA: + ms_type = cs->c_sclass == C_STAT ? mst_file_text : mst_text; + break; + case SECT_OFF_DATA: + ms_type = cs->c_sclass == C_STAT ? mst_file_data : mst_data; + break; + case SECT_OFF_BSS: + ms_type = cs->c_sclass == C_STAT ? mst_file_bss : mst_bss; + break; + default: + ms_type = mst_unknown; + break; + } + + record_minimal_symbol (cs->c_name, tmpaddr, ms_type, objfile); + } + if (SDB_TYPE (cs->c_type)) process_coff_symbol (cs, &main_aux, section_offsets, objfile); break; @@ -1362,6 +1397,7 @@ process_coff_symbol (cs, aux, section_offsets, objfile) /* default assumptions */ SYMBOL_VALUE (sym) = cs->c_value; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_SECTION (sym) = cs_to_section (cs, objfile); if (ISFCN (cs->c_type)) { @@ -1443,22 +1479,24 @@ process_coff_symbol (cs, aux, section_offsets, objfile) add_param_to_type(&in_function_type,sym); #endif add_symbol_to_list (sym, &local_symbols); -#if !defined (BELIEVE_PCC_PROMOTION) && (TARGET_BYTE_ORDER == BIG_ENDIAN) - { - /* If PCC says a parameter is a short or a char, - aligned on an int boundary, realign it to the "little end" - of the int. */ - struct type *temptype; - temptype = lookup_fundamental_type (current_objfile, FT_INTEGER); - if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype) - && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT - && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype)) - { - SYMBOL_VALUE (sym) += - TYPE_LENGTH (temptype) - - TYPE_LENGTH (SYMBOL_TYPE (sym)); - } - } +#if !defined (BELIEVE_PCC_PROMOTION) + if (TARGET_BYTE_ORDER == BIG_ENDIAN) + { + /* If PCC says a parameter is a short or a char, + aligned on an int boundary, realign it to the + "little end" of the int. */ + struct type *temptype; + temptype = lookup_fundamental_type (current_objfile, + FT_INTEGER); + if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype) + && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT + && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype)) + { + SYMBOL_VALUE (sym) += + TYPE_LENGTH (temptype) + - TYPE_LENGTH (SYMBOL_TYPE (sym)); + } + } #endif break; @@ -103,22 +103,29 @@ exec_close (quitting) need_symtab_cleanup = 1; } else if (vp->bfd != exec_bfd) - bfd_close (vp->bfd); + /* FIXME-leak: We should be freeing vp->name too, I think. */ + if (!bfd_close (vp->bfd)) + warning ("cannot close \"%s\": %s", + vp->name, bfd_errmsg (bfd_get_error ())); /* FIXME: This routine is #if 0'd in symfile.c. What should we be doing here? Should we just free everything in - vp->objfile->symtabs? Should free_objfile do that? */ + vp->objfile->symtabs? Should free_objfile do that? + FIXME-as-well: free_objfile already free'd vp->name, so it isn't + valid here. */ free_named_symtabs (vp->name); free (vp); } - + vmap = NULL; if (exec_bfd) { char *name = bfd_get_filename (exec_bfd); - bfd_close (exec_bfd); + if (!bfd_close (exec_bfd)) + warning ("cannot close \"%s\": %s", + name, bfd_errmsg (bfd_get_error ())); free (name); exec_bfd = NULL; } @@ -229,6 +236,8 @@ exec_file_command (args, from_tty) /* Set text_start to the lowest address of the start of any readonly code section and set text_end to the highest address of the end of any readonly code section. */ + /* FIXME: The comment above does not match the code. The code + checks for sections with are either code *or* readonly. */ text_start = ~(CORE_ADDR)0; text_end = (CORE_ADDR)0; @@ -366,7 +375,7 @@ map_vmap (abfd, arch) struct vmap_and_bfd vmap_bfd; struct vmap *vp, **vpp; - vp = (PTR) xmalloc (sizeof (*vp)); + vp = (struct vmap *) xmalloc (sizeof (*vp)); memset ((char *) vp, '\0', sizeof (*vp)); vp->nxt = 0; vp->bfd = abfd; diff --git a/gdb/remote-vx.c b/gdb/remote-vx.c index c8625f5..8f0c2d4 100644 --- a/gdb/remote-vx.c +++ b/gdb/remote-vx.c @@ -28,6 +28,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "symtab.h" #include "complaints.h" #include "gdbcmd.h" +#include "bfd.h" /* Required by objfiles.h. */ +#include "symfile.h" /* Required by objfiles.h. */ +#include "objfiles.h" +#include "gdb-stabs.h" #include <string.h> #include <errno.h> @@ -92,91 +96,91 @@ static char *find_white_space (); static int net_load (filename, pTextAddr, pDataAddr, pBssAddr) - char *filename; - CORE_ADDR *pTextAddr; - CORE_ADDR *pDataAddr; - CORE_ADDR *pBssAddr; - { - enum clnt_stat status; - struct ldfile ldstruct; - struct timeval load_timeout; - - memset ((char *) &ldstruct, '\0', sizeof (ldstruct)); + char *filename; + CORE_ADDR *pTextAddr; + CORE_ADDR *pDataAddr; + CORE_ADDR *pBssAddr; +{ + enum clnt_stat status; + struct ldfile ldstruct; + struct timeval load_timeout; - /* We invoke clnt_call () here directly, instead of through - net_clnt_call (), because we need to set a large timeout value. - The load on the target side can take quite a while, easily - more than 10 seconds. The user can kill this call by typing - CTRL-C if there really is a problem with the load. + memset ((char *) &ldstruct, '\0', sizeof (ldstruct)); - Do not change the tv_sec value without checking -- select() imposes - a limit of 10**8 on it for no good reason that I can see... */ + /* We invoke clnt_call () here directly, instead of through + net_clnt_call (), because we need to set a large timeout value. + The load on the target side can take quite a while, easily + more than 10 seconds. The user can kill this call by typing + CTRL-C if there really is a problem with the load. - load_timeout.tv_sec = 99999999; /* A large number, effectively inf. */ - load_timeout.tv_usec = 0; + Do not change the tv_sec value without checking -- select() imposes + a limit of 10**8 on it for no good reason that I can see... */ + + load_timeout.tv_sec = 99999999; /* A large number, effectively inf. */ + load_timeout.tv_usec = 0; - status = clnt_call (pClient, VX_LOAD, xdr_wrapstring, &filename, xdr_ldfile, - &ldstruct, load_timeout); - - if (status == RPC_SUCCESS) - { - if (*ldstruct.name == 0) /* load failed on VxWorks side */ - return -1; - *pTextAddr = ldstruct.txt_addr; - *pDataAddr = ldstruct.data_addr; - *pBssAddr = ldstruct.bss_addr; - return 0; - } - else - return -1; + status = clnt_call (pClient, VX_LOAD, xdr_wrapstring, &filename, xdr_ldfile, + &ldstruct, load_timeout); + + if (status == RPC_SUCCESS) + { + if (*ldstruct.name == 0) /* load failed on VxWorks side */ + return -1; + *pTextAddr = ldstruct.txt_addr; + *pDataAddr = ldstruct.data_addr; + *pBssAddr = ldstruct.bss_addr; + return 0; } - + else + return -1; +} + /* returns 0 if successful, errno if RPC failed or VxWorks complains. */ static int net_break (addr, procnum) - int addr; - u_long procnum; - { - enum clnt_stat status; - int break_status; - Rptrace ptrace_in; /* XXX This is stupid. It doesn't need to be a ptrace - structure. How about something smaller? */ + int addr; + u_long procnum; +{ + enum clnt_stat status; + int break_status; + Rptrace ptrace_in; /* XXX This is stupid. It doesn't need to be a ptrace + structure. How about something smaller? */ + + memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); + break_status = 0; - memset ((char *) &ptrace_in, '\0', sizeof (ptrace_in)); - break_status = 0; + ptrace_in.addr = addr; + ptrace_in.pid = inferior_pid; - ptrace_in.addr = addr; - ptrace_in.pid = inferior_pid; + status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int, + &break_status); - status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int, - &break_status); + if (status != RPC_SUCCESS) + return errno; - if (status != RPC_SUCCESS) - return errno; + if (break_status == -1) + return ENOMEM; + return break_status; /* probably (FIXME) zero */ +} - if (break_status == -1) - return ENOMEM; - return break_status; /* probably (FIXME) zero */ - } - /* returns 0 if successful, errno otherwise */ static int vx_insert_breakpoint (addr) - int addr; - { - return net_break (addr, VX_BREAK_ADD); - } + int addr; +{ + return net_break (addr, VX_BREAK_ADD); +} /* returns 0 if successful, errno otherwise */ static int vx_remove_breakpoint (addr) - int addr; - { - return net_break (addr, VX_BREAK_DELETE); - } + int addr; +{ + return net_break (addr, VX_BREAK_DELETE); +} /* Start an inferior process and sets inferior_pid to its pid. EXEC_FILE is the file to run. @@ -333,7 +337,8 @@ net_wait (pEvent) memset ((char *) pEvent, '\0', sizeof (RDB_EVENT)); pid = inferior_pid; - status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT, pEvent); + status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT, + pEvent); return (status == RPC_SUCCESS)? pEvent->status: -1; } @@ -344,21 +349,21 @@ net_wait (pEvent) static int net_quit () { - int pid; - int quit_status; - enum clnt_stat status; + int pid; + int quit_status; + enum clnt_stat status; - quit_status = 0; + quit_status = 0; - /* don't let rdbTask suspend itself by passing a pid of 0 */ + /* don't let rdbTask suspend itself by passing a pid of 0 */ - if ((pid = inferior_pid) == 0) - return -1; + if ((pid = inferior_pid) == 0) + return -1; - status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int, - &quit_status); + status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int, + &quit_status); - return (status == RPC_SUCCESS)? quit_status: -1; + return (status == RPC_SUCCESS)? quit_status: -1; } /* Read a register or registers from the remote system. */ @@ -395,10 +400,10 @@ vx_read_register (regno) } #ifdef VX_SIZE_FPREGS - /* If the target has floating point registers, fetch them. - Otherwise, zero the floating point register values in - registers[] for good measure, even though we might not - need to. */ + /* If the target has floating point registers, fetch them. + Otherwise, zero the floating point register values in + registers[] for good measure, even though we might not + need to. */ if (target_has_fp) { @@ -437,7 +442,7 @@ vx_prepare_to_store () /* Store our register values back into the inferior. If REGNO is -1, do this for all registers. Otherwise, REGNO specifies which register (so we can save time). */ - /* FIXME, look at REGNO to save time here */ +/* FIXME, look at REGNO to save time here */ static void vx_write_register (regno) @@ -464,7 +469,7 @@ vx_write_register (regno) /* XXX change second param to be a proc number */ status = net_ptrace_clnt_call (PTRACE_SETREGS, &ptrace_in, &ptrace_out); if (status) - error (rpcerr); + error (rpcerr); if (ptrace_out.status == -1) { errno = ptrace_out.errno; @@ -484,7 +489,8 @@ vx_write_register (regno) in_data.bytes = ®isters[REGISTER_BYTE (FP0_REGNUM)]; in_data.len = VX_SIZE_FPREGS; - status = net_ptrace_clnt_call (PTRACE_SETFPREGS, &ptrace_in, &ptrace_out); + status = net_ptrace_clnt_call (PTRACE_SETFPREGS, &ptrace_in, + &ptrace_out); if (status) error (rpcerr); if (ptrace_out.status == -1) @@ -533,7 +539,8 @@ vx_xfer_memory (memaddr, myaddr, len, write, target) data.len = len; /* How many bytes (again, for XDR) */ /* XXX change second param to be a proc number */ - status = net_ptrace_clnt_call (PTRACE_WRITEDATA, &ptrace_in, &ptrace_out); + status = net_ptrace_clnt_call (PTRACE_WRITEDATA, &ptrace_in, + &ptrace_out); } else { @@ -599,7 +606,7 @@ vx_resume (pid, step, siggnal) status = net_ptrace_clnt_call (step? PTRACE_SINGLESTEP: PTRACE_CONT, &ptrace_in, &ptrace_out); if (status) - error (rpcerr); + error (rpcerr); if (ptrace_out.status == -1) { errno = ptrace_out.errno; @@ -615,17 +622,84 @@ vx_mourn_inferior () } +static void vx_add_symbols PARAMS ((char *, int, CORE_ADDR, CORE_ADDR, + CORE_ADDR)); + +struct find_sect_args { + CORE_ADDR text_start; + CORE_ADDR data_start; + CORE_ADDR bss_start; +}; + +static void find_sect PARAMS ((bfd *, asection *, void *)); + +static void +find_sect (abfd, sect, obj) + bfd *abfd; + asection *sect; + PTR obj; +{ + struct find_sect_args *args = (struct find_sect_args *)obj; + + if (bfd_get_section_flags (abfd, sect) & (SEC_CODE & SEC_READONLY)) + args->text_start = bfd_get_section_vma (abfd, sect); + else if (bfd_get_section_flags (abfd, sect) & SEC_ALLOC) + { + if (bfd_get_section_flags (abfd, sect) & SEC_LOAD) + { + /* Exclude .ctor and .dtor sections which have SEC_CODE set but not + SEC_DATA. */ + if (bfd_get_section_flags (abfd, sect) & SEC_DATA) + args->data_start = bfd_get_section_vma (abfd, sect); + } + else + args->bss_start = bfd_get_section_vma (abfd, sect); + } +} + +static void +vx_add_symbols (name, from_tty, text_addr, data_addr, bss_addr) + char *name; + int from_tty; + CORE_ADDR text_addr; + CORE_ADDR data_addr; + CORE_ADDR bss_addr; +{ + struct section_offsets *offs; + struct objfile *objfile; + struct find_sect_args ss; + + objfile = symbol_file_add (name, from_tty, 0, 0, 0, 0); + offs = (struct section_offsets *) + alloca (sizeof (struct section_offsets) + + objfile->num_sections * sizeof (offs->offsets)); + memcpy (offs, objfile->section_offsets, + sizeof (struct section_offsets) + + objfile->num_sections * sizeof (offs->offsets)); + + ss.text_start = 0; + ss.data_start = 0; + ss.bss_start = 0; + bfd_map_over_sections (objfile->obfd, find_sect, &ss); + + /* Both COFF and b.out frontends use these SECT_OFF_* values. */ + ANOFFSET (offs, SECT_OFF_TEXT) = text_addr - ss.text_start; + ANOFFSET (offs, SECT_OFF_DATA) = data_addr - ss.data_start; + ANOFFSET (offs, SECT_OFF_BSS) = bss_addr - ss.bss_start; + objfile_relocate (objfile, offs); +} + /* This function allows the addition of incrementally linked object files. */ static void vx_load_command (arg_string, from_tty) - char* arg_string; + char *arg_string; int from_tty; { CORE_ADDR text_addr; CORE_ADDR data_addr; CORE_ADDR bss_addr; - + if (arg_string == 0) error ("The load command takes a file name"); @@ -640,8 +714,7 @@ vx_load_command (arg_string, from_tty) error ("Load failed on target machine"); immediate_quit--; - /* FIXME, for now we ignore data_addr and bss_addr. */ - symbol_file_add (arg_string, from_tty, text_addr, 0, 0, 0); + vx_add_symbols (arg_string, from_tty, text_addr, data_addr, bss_addr); /* Getting new symbols may change our opinion about what is frameless. */ @@ -757,10 +830,11 @@ vx_lookup_symbol (name, pAddr) status = net_clnt_call (VX_SYMBOL_INQ, xdr_wrapstring, &name, xdr_SYMBOL_ADDR, &symbolAddr); - if (status != RPC_SUCCESS) { + if (status != RPC_SUCCESS) + { complain (&cant_contact_target); return -1; - } + } *pAddr = symbolAddr.addr; return symbolAddr.status; @@ -778,7 +852,7 @@ net_check_for_fp () status = net_clnt_call (VX_FP_INQUIRE, xdr_void, 0, xdr_bool, &fp); if (status != RPC_SUCCESS) - error (rpcerr); + error (rpcerr); return (int) fp; } @@ -793,7 +867,7 @@ net_connect (host) struct sockaddr_in destAddr; struct hostent *destHost; unsigned long addr; - + /* Get the internet address for the given host. Allow a numeric IP address or a hostname. */ @@ -802,6 +876,9 @@ net_connect (host) { destHost = (struct hostent *) gethostbyname (host); if (destHost == NULL) + /* FIXME: Probably should include hostname here in quotes. + For example if the user types "target vxworks vx960 " it should + say "Invalid host `vx960 '." not just "Invalid hostname". */ error ("Invalid hostname. Couldn't find remote host address."); addr = * (unsigned long *) destHost->h_addr; } @@ -818,8 +895,9 @@ net_connect (host) ptraceSock = RPC_ANYSOCK; pClient = clnttcp_create (&destAddr, RDBPROG, RDBVERS, &ptraceSock, 0, 0); - /* FIXME, here is where we deal with different version numbers of the proto */ - + /* FIXME, here is where we deal with different version numbers of the + proto */ + if (pClient == NULL) { clnt_pcreateerror ("\tnet_connect"); @@ -843,24 +921,13 @@ sleep_ms (ms) select_timeout.tv_sec = 0; select_timeout.tv_usec = ms * 1000; - status = select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &select_timeout); + status = select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, + &select_timeout); if (status < 0 && errno != EINTR) perror_with_name ("select"); } -/* Wait for control to return from inferior to debugger. - If inferior gets a signal, we may decide to start it up again - instead of returning. That is why there is a loop in this function. - When this function actually returns it means the inferior - should be left stopped and GDB should read more commands. */ - -/* For network debugging with VxWorks. - * VxWorks knows when tasks hit breakpoints, receive signals, exit, etc, - * so vx_wait() receives this information directly from - * VxWorks instead of trying to figure out what happenned via a wait() call. - */ - static int vx_wait (pid_to_wait_for, status) int pid_to_wait_for; @@ -984,7 +1051,8 @@ add_symbol_stub (arg) struct ldfile *pLoadFile = (struct ldfile *)arg; printf_unfiltered("\t%s: ", pLoadFile->name); - symbol_file_add (pLoadFile->name, 0, pLoadFile->txt_addr, 0, 0, 0); + vx_add_symbols (pLoadFile->name, 0, pLoadFile->txt_addr, + pLoadFile->data_addr, pLoadFile->bss_addr); printf_unfiltered ("ok\n"); return 1; } @@ -1042,13 +1110,19 @@ vx_open (args, from_tty) bootFile = NULL; if (!net_get_boot_file (&bootFile)) { - if (*bootFile) { - printf_filtered ("\t%s: ", bootFile); - if (catch_errors - (symbol_stub, bootFile, - "Error while reading symbols from boot file:\n", RETURN_MASK_ALL)) - puts_filtered ("ok\n"); - } else if (from_tty) + if (*bootFile) + { + printf_filtered ("\t%s: ", bootFile); + /* This assumes that the kernel is never relocated. Hope that is an + accurate assumption. */ + if (catch_errors + (symbol_stub, + bootFile, + "Error while reading symbols from boot file:\n", + RETURN_MASK_ALL)) + puts_filtered ("ok\n"); + } + else if (from_tty) printf_unfiltered ("VxWorks kernel symbols not loaded.\n"); } else @@ -1079,9 +1153,10 @@ vx_open (args, from_tty) do_cleanups (old_chain); } #else - /* Botches, FIXME: - (1) Searches the PATH, not the source path. - (2) data and bss are assumed to be at the usual offsets from text. */ + /* FIXME: Is there something better to search than the PATH? (probably + not the source path, since source might be in different directories + than objects. */ + if (catch_errors (add_symbol_stub, (char *)pLoadFile, (char *)0, RETURN_MASK_ALL)) symbols_added = 1; @@ -1282,65 +1357,64 @@ vx_proc_open (name, from_tty) /* Target ops structure for accessing memory and such over the net */ struct target_ops vx_ops = { - "vxworks", "VxWorks target memory via RPC over TCP/IP", - "Use VxWorks target memory. \n\ + "vxworks", "VxWorks target memory via RPC over TCP/IP", + "Use VxWorks target memory. \n\ Specify the name of the machine to connect to.", - vx_open, vx_close, vx_attach, 0, /* vx_detach, */ - 0, 0, /* resume, wait */ - 0, 0, /* read_reg, write_reg */ - 0, /* prep_to_store, */ - vx_xfer_memory, vx_files_info, - 0, 0, /* insert_breakpoint, remove_breakpoint */ - 0, 0, 0, 0, 0, /* terminal stuff */ - 0, /* vx_kill, */ - vx_load_command, - vx_lookup_symbol, - vx_create_inferior, 0, /* mourn_inferior */ - 0, /* can_run */ - 0, /* notice_signals */ - core_stratum, 0, /* next */ - 1, 1, 0, 0, 0, /* all mem, mem, stack, regs, exec */ - 0, 0, /* Section pointers */ - OPS_MAGIC, /* Always the last thing */ + vx_open, vx_close, vx_attach, 0, /* vx_detach, */ + 0, 0, /* resume, wait */ + 0, 0, /* read_reg, write_reg */ + 0, /* prep_to_store, */ + vx_xfer_memory, vx_files_info, + 0, 0, /* insert_breakpoint, remove_breakpoint */ + 0, 0, 0, 0, 0, /* terminal stuff */ + 0, /* vx_kill, */ + vx_load_command, + vx_lookup_symbol, + vx_create_inferior, 0, /* mourn_inferior */ + 0, /* can_run */ + 0, /* notice_signals */ + core_stratum, 0, /* next */ + 1, 1, 0, 0, 0, /* all mem, mem, stack, regs, exec */ + 0, 0, /* Section pointers */ + OPS_MAGIC, /* Always the last thing */ }; /* Target ops structure for accessing VxWorks child processes over the net */ struct target_ops vx_run_ops = { - "vxprocess", "VxWorks process", - "VxWorks process, started by the \"run\" command.", - vx_proc_open, vx_proc_close, 0, vx_detach, /* vx_attach */ - vx_resume, vx_wait, - vx_read_register, vx_write_register, - vx_prepare_to_store, - vx_xfer_memory, vx_run_files_info, - vx_insert_breakpoint, vx_remove_breakpoint, - 0, 0, 0, 0, 0, /* terminal stuff */ - vx_kill, - vx_load_command, - vx_lookup_symbol, - 0, vx_mourn_inferior, - 0, /* can_run */ - 0, /* notice_signals */ - process_stratum, 0, /* next */ - 0, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */ - /* all_mem is off to avoid spurious msg in "i files" */ - 0, 0, /* Section pointers */ - OPS_MAGIC, /* Always the last thing */ + "vxprocess", "VxWorks process", + "VxWorks process, started by the \"run\" command.", + vx_proc_open, vx_proc_close, 0, vx_detach, /* vx_attach */ + vx_resume, vx_wait, + vx_read_register, vx_write_register, + vx_prepare_to_store, + vx_xfer_memory, vx_run_files_info, + vx_insert_breakpoint, vx_remove_breakpoint, + 0, 0, 0, 0, 0, /* terminal stuff */ + vx_kill, + vx_load_command, + vx_lookup_symbol, + 0, vx_mourn_inferior, + 0, /* can_run */ + 0, /* notice_signals */ + process_stratum, 0, /* next */ + 0, /* all_mem--off to avoid spurious msg in "i files" */ + 1, 1, 1, 1, /* mem, stack, regs, exec */ + 0, 0, /* Section pointers */ + OPS_MAGIC, /* Always the last thing */ }; /* ==> Remember when reading at end of file, there are two "ops" structs here. */ void _initialize_vx () { - - add_show_from_set + add_show_from_set (add_set_cmd ("vxworks-timeout", class_support, var_uinteger, (char *) &rpcTimeout.tv_sec, "Set seconds to wait for rpc calls to return.\n\ Set the number of seconds to wait for rpc calls to return.", &setlist), &showlist); - add_target (&vx_ops); + add_target (&vx_ops); add_target (&vx_run_ops); } |