From 1eeba68641b9b75e2d780759c39a079d8ddda0fc Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Sun, 29 Mar 1992 22:33:35 +0000 Subject: [PATCH] Merged in latest RS6000 diffs from Metin G. Ozisik. --- gdb/.Sanitize | 2 + gdb/ChangeLog | 7 ++ gdb/breakpoint.c | 39 +++++++++- gdb/buildsym.c | 12 +-- gdb/config/rs6000.mt | 2 +- gdb/infrun.c | 23 +++++- gdb/main.c | 4 + gdb/minsyms.c | 7 +- gdb/printcmd.c | 5 +- gdb/rs6000-tdep.c | 17 ++++ gdb/rs6000-xdep.c | 5 ++ gdb/symfile.c | 2 +- gdb/tm-rs6000.h | 72 ++++++++++++++--- gdb/utils.c | 12 +++ gdb/xcoffexec.c | 122 ++++++++++++++++------------- gdb/xcoffread.c | 182 ++++++++++++++++++++++++++++++++++--------- gdb/xcoffsolib.c | 177 +++++++++++++++++++++++++++++++++++++++++ gdb/xcoffsolib.h | 33 ++++++++ gdb/xm-rs6000.h | 4 +- 19 files changed, 607 insertions(+), 120 deletions(-) create mode 100644 gdb/xcoffsolib.c create mode 100644 gdb/xcoffsolib.h diff --git a/gdb/.Sanitize b/gdb/.Sanitize index 2b0492945cb..0377eff23aa 100644 --- a/gdb/.Sanitize +++ b/gdb/.Sanitize @@ -241,6 +241,8 @@ vax-pinsn.c vx-share xcoffexec.c xcoffread.c +xcoffsolib.c +xcoffsolib.h xm-3b1.h xm-m88k.h xm-altos.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 094aa4de63c..803ef3944a9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +Sun Mar 29 14:16:22 1992 Per Bothner (bothner@cygnus.com) + + * Merged in latest RS6000 diffs from Metin G. Ozisik. + * xcoffsolib.c, xcoffsolib.h: New files, from Metin. + * Various files: Changed #ifdef IBM6000 to IBM6000_HOST + or IBM6000_TARGET as (approximately) appropriate. + Sat Mar 28 13:00:10 1992 Fred Fish (fnf@cygnus.com) * objfiles.h (OBJF_SYMS): Define flag bit for objfile flags. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index b9aef04c657..ab30a6718e8 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -17,9 +17,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include #include "defs.h" +#include #include "symtab.h" #include "frame.h" #include "breakpoint.h" @@ -2270,8 +2269,12 @@ breakpoint_re_set () create_longjmp_breakpoint("siglongjmp"); create_longjmp_breakpoint(NULL); +#if 0 + /* Took this out (temporaliy at least), since it produces an extra + blank line at startup. This messes up the gdbtests. -PB */ /* Blank line to finish off all those mention() messages we just printed. */ printf_filtered ("\n"); +#endif } /* Set ignore-count of breakpoint number BPTNUM to COUNT. @@ -2693,3 +2696,35 @@ an expression changes."); "Status of all watchpoints, or watchpoint number NUMBER.\n\ Second column is \"y\" for enabled watchpoints, \"n\" for disabled."); } + +#ifdef IBM6000_HOST +/* Where should this function go? It is used by AIX only. FIXME. */ + +/* Breakpoint address relocation used to be done in breakpoint_re_set(). That + approach the following problem: + + before running the program, if a file is list, then a breakpoint is + set (just the line number), then if we switch into another file and run + the program, just a line number as a breakpoint address was not + descriptive enough and breakpoint was ending up in a different file's + similar line. + + I don't think any other platform has this breakpoint relocation problem, so this + is not an issue for other platforms. */ + +void +fixup_breakpoints (low, high, delta) + CORE_ADDR low; + CORE_ADDR high; + CORE_ADDR delta; +{ + struct breakpoint *b; + extern struct breakpoint *breakpoint_chain; + + ALL_BREAKPOINTS (b) + { + if (b->address >= low && b->address <= high) + b->address += delta; + } +} +#endif diff --git a/gdb/buildsym.c b/gdb/buildsym.c index eab5cb6f216..a104eb58dca 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -726,7 +726,7 @@ patch_block_stabs (symbols, stabs, objfile) struct symbol *sym = find_symbol_in_list (symbols, name, pp-name); if (!sym) { -#ifndef IBM6000 +#ifndef IBM6000_TARGET printf ("ERROR! stab symbol not found!\n"); /* FIXME */ #endif } @@ -882,7 +882,7 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) symtab->free_code = free_linetable; symtab->free_ptr = 0; -#if 0 /* defined(IBM6000) */ +#ifdef IBM6000_TARGET /* In case we need to duplicate symbol tables (to represent include files), and in case our system needs relocation, we want to relocate the main symbol table node only (for the main file, @@ -898,11 +898,11 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) free (subfile); } -#if 0 /* defined(IBM6000) */ +#ifdef IBM6000_TARGET /* all include symbol tables are non-relocatable, except the main source file's. */ - if (symtab_list) - symtab_list->nonreloc = FALSE; + if (symtab) + symtab->nonreloc = FALSE; #endif if (type_vector) @@ -1863,7 +1863,7 @@ read_type (pp, objfile) case '*': type1 = read_type (pp, objfile); /* FIXME -- we should be doing smash_to_XXX types here. */ -#if 0 +#ifdef IBM6000_TARGET /* postponed type decoration should be allowed. */ if (typenums[1] > 0 && typenums[1] < type_vector_length && (type = type_vector[typenums[1]])) { diff --git a/gdb/config/rs6000.mt b/gdb/config/rs6000.mt index 85441c78d90..a818fea14ac 100644 --- a/gdb/config/rs6000.mt +++ b/gdb/config/rs6000.mt @@ -18,5 +18,5 @@ # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. #TDEPFILES= exec.o rs6k-pinsn.o rs6k-tdep.o -TDEPFILES= rs6000-pinsn.o rs6000-tdep.o +TDEPFILES= rs6000-pinsn.o rs6000-tdep.o xcoffsolib.o TM_FILE= tm-rs6000.h diff --git a/gdb/infrun.c b/gdb/infrun.c index 051682f7a77..9bd4d3e327f 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -191,6 +191,12 @@ extern struct target_ops child_ops; /* In inftarg.c */ #define SKIP_TRAMPOLINE_CODE(pc) 0 #endif +/* For SVR4 shared libraries, each call goes through a small piece of + trampoline code in the ".init" section. IN_SOLIB_TRAMPOLINE evaluates + to nonzero if we are current stopped in one of these. */ +#ifndef IN_SOLIB_TRAMPOLINE +#define IN_SOLIB_TRAMPOLINE(pc,name) 0 +#endif #ifdef TDESC #include "tdesc.h" @@ -791,6 +797,14 @@ wait_for_inferior () target_wait (&w); +#ifdef SIGTRAP_STOP_AFTER_LOAD + + /* Somebody called load(2), and it gave us a "trap signal after load". + Ignore it gracefully. */ + + SIGTRAP_STOP_AFTER_LOAD (w); +#endif + /* See if the process still exists; clean up if it doesn't. */ if (WIFEXITED (w)) { @@ -1201,10 +1215,11 @@ wait_for_inferior () /* ==> See comments at top of file on this algorithm. <==*/ - if (stop_pc == stop_func_start - && (stop_func_start != prev_func_start - || prologue_pc != stop_func_start - || stop_sp != prev_sp)) + if ((stop_pc == stop_func_start + || IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name)) + && (stop_func_start != prev_func_start + || prologue_pc != stop_func_start + || stop_sp != prev_sp)) { /* It's a subroutine call. (0) If we are not stepping over any calls ("stepi"), we diff --git a/gdb/main.c b/gdb/main.c index 8543c3b463b..35465258576 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -1216,6 +1216,10 @@ init_signals () if (signal (SIGHUP, do_nothing) != SIG_IGN) signal (SIGHUP, disconnect); signal (SIGFPE, float_handler); + +#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER) + signal (SIGWINCH, SIGWINCH_HANDLER); +#endif } /* Read one line from the command input stream `instream' diff --git a/gdb/minsyms.c b/gdb/minsyms.c index d3f6c7ba467..760ea75d461 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -130,7 +130,7 @@ lookup_minimal_symbol (name, objf) struct objfile *objfile; struct minimal_symbol *msymbol; struct minimal_symbol *found_symbol = NULL; -#ifdef IBM6000 +#ifdef IBM6000_TARGET struct minimal_symbol *trampoline_symbol = NULL; #endif @@ -147,13 +147,13 @@ lookup_minimal_symbol (name, objf) { if (strcmp (msymbol -> name, name) == 0) { +#ifdef IBM6000_TARGET /* I *think* all platforms using shared libraries (and trampoline code) * will suffer this problem. Consider a case where there are 5 shared * libraries, each referencing `foo' with a trampoline entry. When someone * wants to put a breakpoint on `foo' and the only info we have is minimal * symbol vector, we want to use the real `foo', rather than one of those * trampoline entries. MGO */ -#ifdef IBM6000 /* If a trampoline symbol is found, we prefer to keep looking for the *real* symbol. If the actual symbol not found, then we'll use the trampoline entry. Sorry for the machine @@ -173,7 +173,7 @@ lookup_minimal_symbol (name, objf) } } } -#ifdef IBM6000 +#ifdef IBM6000_TARGET return found_symbol ? found_symbol : trampoline_symbol; #endif @@ -232,6 +232,7 @@ lookup_minimal_symbol_by_pc (pc) Warning: this code is trickier than it would appear at first. */ + /* Should also requires that pc is <= end of objfile. FIXME! */ if (pc >= msymbol[lo].address) { while (msymbol[hi].address > pc) diff --git a/gdb/printcmd.c b/gdb/printcmd.c index d2d867ae2cf..db0394eb93c 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -17,9 +17,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include #include "defs.h" +#include #include "frame.h" #include "symtab.h" #include "gdbtypes.h" @@ -1555,7 +1554,7 @@ print_frame_args (func, fi, num, stream) two entries (one a parameter, one a register or local), and the one we want is the non-parm, which lookup_symbol will find for us. After this, sym could be any SYMBOL_CLASS... */ -#ifdef IBM6000 +#ifdef IBM6000_TARGET /* AIX/RS6000 implements a concept of traceback tables, in which case it creates nameless parameters. Looking for those parameter symbols will result in an error. */ diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index fea31f10ae3..1a26ab2e3ac 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -187,6 +187,15 @@ int pc; if ((op & 0xfc000000) == 0x48000000) { /* bl foo, to save fprs??? */ pc += 4; op = read_memory_integer (pc, 4); + + /* At this point, make sure this is not a trampoline function + (a function that simply calls another functions, and nothing else). + If the next is not a nop, this branch was part of the function + prologue. */ + + if (op == 0x4def7b82 || /* crorc 15, 15, 15 */ + op == 0x0) + return pc - 4; /* don't skip over this branch */ } if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */ @@ -546,6 +555,14 @@ function_frame_info (pc, fdata) if ((op & 0xfc000000) == 0x48000000) { /* bl foo, to save fprs??? */ pc += 4; op = read_memory_integer (pc, 4); + /* At this point, make sure this is not a trampoline function + (a function that simply calls another functions, and nothing else). + If the next is not a nop, this branch was part of the function + prologue. */ + + if (op == 0x4def7b82 || /* crorc 15, 15, 15 */ + op == 0x0) + return; /* prologue is over */ } if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */ diff --git a/gdb/rs6000-xdep.c b/gdb/rs6000-xdep.c index c8c0c1d12a8..6fb8469d6f6 100644 --- a/gdb/rs6000-xdep.c +++ b/gdb/rs6000-xdep.c @@ -510,6 +510,10 @@ exec_one_dummy_insn () } +#if 0 + + *** not needed anymore *** + /* Return the number of initial trap signals we need to ignore once the inferior process starts running. This will be `2' for aix-3.1, `3' for aix-3.2 */ @@ -530,3 +534,4 @@ aix_starting_inferior_traps () else return 3; } +#endif diff --git a/gdb/symfile.c b/gdb/symfile.c index 9b50d6f2d1a..3cfe4ea18bb 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -803,7 +803,7 @@ reread_symbols () the_big_top: for (objfile = object_files; objfile; objfile = objfile->next) { if (objfile->obfd) { -#ifdef IBM6000 +#ifdef IBM6000_TARGET /* If this object is from a shared library, then you should stat on the library name, not member name. */ diff --git a/gdb/tm-rs6000.h b/gdb/tm-rs6000.h index 64720585ca4..b99deb3cf03 100644 --- a/gdb/tm-rs6000.h +++ b/gdb/tm-rs6000.h @@ -45,6 +45,11 @@ extern int symtab_relocated; if (!symtab_relocated && !inferior_pid && (PC) > TEXT_SEGMENT_BASE) \ (PC) -= ( TEXT_SEGMENT_BASE + text_adjustment (exec_bfd)); +/* Load segment of a given pc value. */ + +#define PC_LOAD_SEGMENT(PC) pc_load_segment_name(PC) + + /* Conversion between a register number in stab string to actual register num. */ #define STAB_REG_TO_REGNUM(value) (value) @@ -131,11 +136,37 @@ extern int aix_loadInfoTextIndex; } while (0) +#if 0 + The following comment is not correct anymore. AIX has a trap signal + that might be sent with a "stopped after a load" status. This might + show up when the inferior is just started, or anytime inferior + loads something else. It is incorrect to try to skip over it *only* in + startup-time. It always has to be ignored and should not be mixed up + with breakpoint traps. See the macro SIGTRAP_STOP_AFTER_LOAD and its + usage in infrun.c. + /* In aix, number of the trap signals we need to skip over once the inferior process starts running is different in version 3.1 and 3.2. This will be 2 for version 3.1x, 3 for version 3.2x. */ #define START_INFERIOR_TRAPS_EXPECTED aix_starting_inferior_traps () +#endif /* 0 */ + +#define START_INFERIOR_TRAPS_EXPECTED 2 + +/* AIX might return a sigtrap, with a "stop after load" status. It should + be ignored by gdb, shouldn't be mixed up with breakpoint traps. */ + +#define SIGTRAP_STOP_AFTER_LOAD(W) \ + if ( (W) == 0x57c ) { \ + if (breakpoints_inserted) { \ + mark_breakpoints_out (); \ + insert_breakpoints (); \ + insert_step_breakpoint (); \ + } \ + resume (0, 0); \ + continue; \ + } /* In aixcoff, we cannot process line numbers when we see them. This is mainly because we don't know the boundaries of the include files. So, @@ -442,12 +473,7 @@ extern unsigned int rs6000_struct_return_address; #define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \ fi->initial_sp = 0; \ - fi->cache_fsr = 0; \ - if (fromleaf) { \ - int tmp = 0; \ - read_memory ((fi)->frame, &tmp, sizeof (int)); \ - (fi)->frame = tmp; \ - } + fi->cache_fsr = 0; #define FRAME_SAVED_PC(FRAME) \ read_memory_integer (read_memory_integer ((FRAME)->frame, 4)+8, 4) @@ -587,7 +613,35 @@ extern unsigned int rs6000_struct_return_address; #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, using_gcc) \ fix_call_dummy(dummyname, pc, fun, nargs, type) + +/* Signal handler for SIGWINCH `window size changed'. */ + +#define SIGWINCH_HANDLER aix_resizewindow +extern void aix_resizewindow (); + +/* `lines_per_page' and `chars_per_line' are local to utils.c. Rectify this. */ + +#define SIGWINCH_HANDLER_BODY \ + \ +/* Respond to SIGWINCH `window size changed' signal, and reset GDB's \ + window settings approproatelt. */ \ + \ +void \ +aix_resizewindow () \ +{ \ + int fd = fileno (stdout); \ + if (isatty (fd)) { \ + int val; \ + \ + val = atoi (termdef (fd, 'l')); \ + if (val > 0) \ + lines_per_page = val; \ + val = atoi (termdef (fd, 'c')); \ + if (val > 0) \ + chars_per_line = val; \ + } \ +} + + /* Flag for machine-specific stuff in shared files. FIXME */ -#ifndef IBM6000 -#define IBM6000 -#endif +#define IBM6000_TARGET diff --git a/gdb/utils.c b/gdb/utils.c index 24fd9ea98b6..974f2ce374f 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -1323,6 +1323,12 @@ _initialize_utils () } } +#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER) + + /* If tere is a better way to determine window size, use it. */ + SIGWINCH_HANDLER (); +#endif + /* If the output is not a terminal, don't paginate it. */ if (!ISATTY (stdout)) lines_per_page = UINT_MAX; @@ -1350,3 +1356,9 @@ _initialize_utils () &setprintlist), &showprintlist); } + +/* Machine specific function to handle SIGWINCH signal. */ + +#ifdef SIGWINCH_HANDLER_BODY + SIGWINCH_HANDLER_BODY +#endif diff --git a/gdb/xcoffexec.c b/gdb/xcoffexec.c index 8588ffb1733..d64dec4df64 100644 --- a/gdb/xcoffexec.c +++ b/gdb/xcoffexec.c @@ -40,6 +40,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "objfiles.h" #include "libbfd.h" /* BFD internals (sigh!) FIXME */ +#include "xcoffsolib.h" /* Prototypes for local functions */ @@ -68,6 +69,7 @@ extern void symbol_file_command (); static void exec_files_info(); extern struct objfile *lookup_objfile_bfd (); +#if 0 /* * the vmap struct is used to describe the virtual address space of * the target we are manipulating. The first entry is always the "exec" @@ -96,6 +98,9 @@ struct vmap_and_bfd { }; static struct vmap *vmap; /* current vmap */ +#endif /* 0 */ + +struct vmap *vmap; /* current vmap */ extern struct target_ops exec_ops; @@ -320,6 +325,7 @@ map_vmap (bfd *bf, bfd *arch) struct objfile *obj; vp = (void*) xmalloc (sizeof (*vp)); + bzero (vp, sizeof (*vp)); vp->nxt = 0; vp->bfd = bf; vp->name = bfd_get_filename(arch ? arch : bf); @@ -332,7 +338,14 @@ map_vmap (bfd *bf, bfd *arch) obj = lookup_objfile_bfd (bf); if (exec_bfd && !obj) { obj = allocate_objfile (bf, 0); + +#if 0 + This is only needed if we want to load shared libraries no matter what. + Since we provide the choice of incremental loading of shared objects now, + we don't have to load them as default anymore. + syms_from_objfile (obj, 0, 0, 0); +#endif } /* find the end of the list, and append. */ @@ -436,8 +449,8 @@ struct stat *vip; if (fstat(fileno(io), &si) < 0) fatal("cannot fstat BFD for sym"); - if (si.st_dev != vip->st_dev - || si.st_ino != vip->st_ino) + if (vip && (si.st_dev != vip->st_dev + || si.st_ino != vip->st_ino)) continue; } @@ -717,59 +730,61 @@ register struct ld_info *ldi; , name); retry: for (got_one = 0, vp = vmap; vp; vp = vp->nxt) { - FILE *io; + FILE *io; + + /* First try to find a `vp', which is the same as in ldinfo. + If not the same, just continue and grep the next `vp'. If same, + relocate its tstart, tend, dstart, dend values. If no such `vp' + found, get out of this for loop, add this ldi entry as a new vmap + (add_vmap) and come back, fins its `vp' and so on... */ + + /* The filenames are not always sufficient to match on. */ - /* The filenames are not always sufficient to match on. */ - if ((name[0] == "/" - && !eq(name, vp->name)) - || (memb[0] && !eq(memb, vp->member))) - continue; + if ((name[0] == "/" && !eq(name, vp->name)) + || (memb[0] && !eq(memb, vp->member))) + continue; - /* totally opaque! */ - io = bfd_cache_lookup(vp->bfd); - if (!io) - fatal("cannot find BFD's iostream for %s" - , vp->name); + io = bfd_cache_lookup(vp->bfd); /* totally opaque! */ + if (!io) + fatal("cannot find BFD's iostream for %s", vp->name); - /* see if we are referring to the same file */ - if (fstat(fileno(io), &vi) < 0) - fatal("cannot fstat BFD for %s", vp->name); + /* see if we are referring to the same file */ - if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino) - continue; + if (fstat(fileno(io), &vi) < 0) + fatal("cannot fstat BFD for %s", vp->name); - if (!retried) - close(ldi->ldinfo_fd); + if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino) + continue; - ++got_one; + if (!retried) + close(ldi->ldinfo_fd); - /* found a corresponding VMAP. remap! */ - ostart = vp->tstart; + ++got_one; - vp->tstart = ldi->ldinfo_textorg; - vp->tend = vp->tstart + ldi->ldinfo_textsize; - vp->dstart = ldi->ldinfo_dataorg; - vp->dend = vp->dstart + ldi->ldinfo_datasize; + /* found a corresponding VMAP. remap! */ + ostart = vp->tstart; - if (vp->tadj) { - vp->tstart += vp->tadj; - vp->tend += vp->tadj; - } + vp->tstart = ldi->ldinfo_textorg; + vp->tend = vp->tstart + ldi->ldinfo_textsize; + vp->dstart = ldi->ldinfo_dataorg; + vp->dend = vp->dstart + ldi->ldinfo_datasize; - /* relocate symbol table(s). */ - vmap_symtab(vp, ostart, &vi); + if (vp->tadj) { + vp->tstart += vp->tadj; + vp->tend += vp->tadj; + } + + /* relocate symbol table(s). */ + vmap_symtab(vp, ostart, &vi); - /* there may be more, so we don't break out of the loop. */ + /* there may be more, so we don't break out of the loop. */ } - /* - * if there was no matching *vp, we must perforce create - * the sucker(s) - */ - if (!got_one && !retried) { - add_vmap(ldi); - ++retried; - goto retry; + /* if there was no matching *vp, we must perforce create the sucker(s) */ + if (!got_one && !retried) { + add_vmap(ldi); + ++retried; + goto retry; } } while (ldi->ldinfo_next && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi))); @@ -894,18 +909,21 @@ exec_files_info (t) if (!vp) return; - printf("\n\tMapping info for file `%s'.\n", vp->name); - printf("\t %8.8s %8.8s %8.8s %s\n", - "start", "end", "section", "file(member)"); + printf("\tMapping info for file `%s'.\n", vp->name); + + printf("\t %8.8s %8.8s %8.8s %8.8s %8.8s %s\n", + "tstart", "tend", "dstart", "dend", "section", "file(member)"); for (; vp; vp = vp->nxt) - printf("\t0x%8.8x 0x%8.8x %s%s%s%s\n", - vp->tstart, - vp->tend, - vp->name, - vp->member ? "(" : "", - vp->member, - vp->member ? ")" : ""); + printf("\t0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x %s%s%s%s\n", + vp->tstart, + vp->tend, + vp->dstart, + vp->dend, + vp->name, + *vp->member ? "(" : "", + vp->member, + *vp->member ? ")" : ""); } #ifdef DAMON diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c index 93fe780004c..a677f7bcb41 100644 --- a/gdb/xcoffread.c +++ b/gdb/xcoffread.c @@ -22,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "bfd.h" -#ifdef IBM6000 +#ifdef IBM6000_HOST /* Native only: Need struct tbtable in . */ /* AIX COFF names have a preceeding dot `.' */ @@ -38,7 +38,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #endif #include -/*#include */ #include #include "symtab.h" @@ -51,6 +50,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "libcoff.h" /* FIXME, internal data from BFD */ #include "coff/rs6000.h" /* FIXME, raw file-format guts of xcoff */ + +/* Define this if you want gdb use the old xcoff symbol processing. This + way it won't use common `define_symbol()' function and Sun dbx stab + string grammar. And likely it won't be able to do G++ debugging. */ + +/* #define NO_DEFINE_SYMBOL 1 */ + +/* Define this if you want gdb to ignore typdef stabs. This was needed for + one of Transarc, to reduce the size of the symbol table. Types won't be + recognized, but tag names will be. */ + +/* #define NO_TYPES 1 */ + /* Simplified internal version of coff symbol table information */ struct coff_symbol { @@ -942,7 +954,8 @@ retrieve_traceback (abfd, textsec, cs, size) if (ALLOCED) \ namestr = (NAME) + 1; \ else { \ - namestr = obstack_copy0 (&objfile->symbol_obstack, (NAME) + 1, strlen ((NAME)+1)); \ + (NAME) = namestr = \ + obstack_copy0 (&objfile->symbol_obstack, (NAME) + 1, strlen ((NAME)+1)); \ (ALLOCED) = 1; \ } \ prim_record_minimal_symbol (namestr, (ADDR), (TYPE)); \ @@ -1012,6 +1025,8 @@ read_xcoff_symtab (objfile, nsyms) long fcn_line_offset; size_t size; + struct coff_symbol fcn_stab_saved; + /* fcn_cs_saved is global because process_xcoff_symbol needs it. */ union internal_auxent fcn_aux_saved; struct type *fcn_type_saved = NULL; @@ -1293,8 +1308,30 @@ function_entry_point: /* record trampoline code entries as mst_unknown symbol. When we lookup mst symbols, we will choose mst_text over mst_unknown. */ +#if 1 + /* After the implementation of incremental loading of shared + libraries, we don't want to access trampoline entries. This + approach has a consequence of the necessity to bring the whole + shared library at first, in order do anything with it (putting + breakpoints, using malloc, etc). On the other side, this is + consistient with gdb's behaviour on a SUN platform. */ + + /* Trying to prefer *real* function entry over its trampoline, + by assigning `mst_unknown' type to trampoline entries fails. + Gdb treats those entries as chars. FIXME. */ + + /* Recording this entry is necessary. Single stepping relies on + this vector to get an idea about function address boundaries. */ + + prim_record_minimal_symbol (0, cs->c_value, mst_unknown); +#else + + /* record trampoline code entries as mst_unknown symbol. When we + lookup mst symbols, we will choose mst_text over mst_unknown. */ + RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_unknown, symname_alloced); +#endif continue; } break; @@ -1348,6 +1385,7 @@ function_entry_point: case C_FUN: +#ifdef NO_DEFINE_SYMBOL /* For a function stab, just save its type in `fcn_type_saved', and leave it for the `.bf' processing. */ { @@ -1362,6 +1400,9 @@ function_entry_point: fcn_type_saved = lookup_function_type (read_type (&pp, objfile)); } +#else + fcn_stab_saved = *cs; +#endif break; @@ -1430,6 +1471,8 @@ function_entry_point: mark_first_line (fcn_line_offset, cs->c_symnum); new = push_context (0, fcn_start_addr); + +#ifdef NO_DEFINE_SYMBOL new->name = process_xcoff_symbol (&fcn_cs_saved, objfile); /* Between a function symbol and `.bf', there always will be a function @@ -1443,6 +1486,10 @@ function_entry_point: SYMBOL_TYPE (new->name) = fcn_type_saved; fcn_type_saved = NULL; } +#else + new->name = define_symbol + (fcn_cs_saved.c_value, fcn_stab_saved.c_name, 0, 0, objfile); +#endif } else if (strcmp (cs->c_name, ".ef") == 0) { @@ -1610,6 +1657,8 @@ process_xcoff_symbol (cs, objfile) #endif case C_DECL: /* a type decleration?? */ + +#if defined(NO_TYPEDEFS) || defined(NO_DEFINE_SYMBOL) qq = (char*) strchr (name, ':'); if (!qq) /* skip if there is no ':' */ return NULL; @@ -1637,7 +1686,32 @@ process_xcoff_symbol (cs, objfile) obsavestring (name, qq-name, &objfile->symbol_obstack); } - ttype = SYMBOL_TYPE (sym) = read_type (&pp, objfile); + ttype = SYMBOL_TYPE (sym) = read_type (&pp); + + /* if there is no name for this typedef, you don't have to keep its + symbol, since nobody could ask for it. Otherwise, build a symbol + and add it into symbol_list. */ + + if (nameless) + return; + +#ifdef NO_TYPEDEFS + /* Transarc wants to eliminate type definitions from the symbol table. + Limited debugging capabilities, but faster symbol table processing + and less memory usage. Note that tag definitions (starting with + 'T') will remain intact. */ + + if (qq[1] != 'T' && (!TYPE_NAME (ttype) || *(TYPE_NAME (ttype)) == '\0')) { + + if (SYMBOL_NAME (sym)) + TYPE_NAME (ttype) = SYMBOL_NAME (sym); + else + TYPE_NAME (ttype) = obsavestring (name, qq-name); + + return; + } + +#endif /* !NO_TYPEDEFS */ /* read_type() will return null if type (or tag) definition was unnnecessarily duplicated. Also, if the symbol doesn't have a name, @@ -1651,58 +1725,58 @@ process_xcoff_symbol (cs, objfile) symbol, since nobody could ask for it. Otherwise, build a symbol and add it into symbol_list. */ - if (!nameless) { - if (qq[1] == 'T') + if (qq[1] == 'T') SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; - else if (qq[1] == 't') + else if (qq[1] == 't') SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - else { - printf ("ERROR: Unrecognized stab string.\n"); + else { + warning ("Unrecognized stab string.\n"); return NULL; - } + } - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - if (!SYMBOL_NAME (sym)) - SYMBOL_NAME (sym) = obsavestring (name, qq-name, - &objfile->symbol_obstack); + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + if (!SYMBOL_NAME (sym)) + SYMBOL_NAME (sym) = obsavestring (name, qq-name); - SYMBOL_DUP (sym, sym2); - add_symbol_to_list + SYMBOL_DUP (sym, sym2); + add_symbol_to_list (sym2, within_function ? &local_symbols : &file_symbols); - /* For a combination of struct and type, add one more symbol - for the type. */ + /* For a combination of struct and type, add one more symbol + for the type. */ - if (struct_and_type_combined) { + if (struct_and_type_combined) { SYMBOL_DUP (sym, sym2); SYMBOL_NAMESPACE (sym2) = VAR_NAMESPACE; add_symbol_to_list (sym2, within_function ? &local_symbols : &file_symbols); - } - } + } - /* assign a name to the type node. */ + /* assign a name to the type node. */ - if (!nameless && (!TYPE_NAME (ttype) || *(TYPE_NAME (ttype)) == '\0')) { + if (!TYPE_NAME (ttype) || *(TYPE_NAME (ttype)) == '\0') { if (struct_and_type_combined) TYPE_NAME (ttype) = SYMBOL_NAME (sym); - -/* else if (SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE) */ else if (qq[1] == 'T') /* struct namespace */ TYPE_NAME (ttype) = concat ( TYPE_CODE (ttype) == TYPE_CODE_UNION ? "union " : TYPE_CODE (ttype) == TYPE_CODE_STRUCT? "struct " : "enum ", SYMBOL_NAME (sym), NULL); } - break; +#else /* !NO_DEFINE_SYMBOL */ + return define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); +#endif + case C_GSYM: add_stab_to_list (name, &global_stabs); break; case C_PSYM: case C_RPSYM: + +#ifdef NO_DEFINE_SYMBOL if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL) return NULL; SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack); @@ -1712,8 +1786,15 @@ process_xcoff_symbol (cs, objfile) SYMBOL_DUP (sym, sym2); add_symbol_to_list (sym2, &local_symbols); break; +#else + sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); + SYMBOL_CLASS (sym) = (cs->c_sclass == C_PSYM) ? LOC_ARG : LOC_REGPARM; + return sym; +#endif case C_STSYM: + +#ifdef NO_DEFINE_SYMBOL if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL) return NULL; SYMBOL_NAME (sym) = obsavestring (name, pp-name, &objfile -> symbol_obstack); @@ -1725,6 +1806,20 @@ process_xcoff_symbol (cs, objfile) add_symbol_to_list (sym2, within_function ? &local_symbols : &file_symbols); break; +#else + /* If we are going to use Sun dbx's define_symbol(), we need to + massage our stab string a little. Change 'V' type to 'S' to be + comparible with Sun. */ + + if (*name == ':' || (pp = (char *) index (name, ':')) == NULL) + return NULL; + + ++pp; + if (*pp == 'V') *pp = 'S'; + sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); + SYMBOL_VALUE (sym) += static_block_base; + return sym; +#endif case C_LSYM: if (*name == ':' || (pp = (char *) strchr (name, ':')) == NULL) @@ -1768,6 +1863,8 @@ process_xcoff_symbol (cs, objfile) break; case C_RSYM: + +#ifdef NO_DEFINE_SYMBOL pp = (char*) strchr (name, ':'); SYMBOL_CLASS (sym) = LOC_REGISTER; SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (cs->c_value); @@ -1788,9 +1885,19 @@ process_xcoff_symbol (cs, objfile) SYMBOL_DUP (sym, sym2); add_symbol_to_list (sym2, &local_symbols); break; +#else + if (pp) { + sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); + return sym; + } + else { + warning ("A non-stab C_RSYM needs special handling."); + return NULL; + } +#endif default : - printf ("ERROR: Unexpected storage class: %d.\n", cs->c_sclass); + warning ("Unexpected storage class: %d.", cs->c_sclass); return NULL; } } @@ -2198,7 +2305,8 @@ aixcoff_symfile_read (objfile, addr, mainline) read_xcoff_symtab(objfile, num_symbols); - make_cleanup (free_debugsection, 0); + /* Free debug section. */ + free_debugsection (); /* Sort symbols alphabetically within each block. */ sort_syms (); @@ -2241,7 +2349,8 @@ _initialize_xcoffread () struct s *p; }; */ -#if 0 + + /* Smash TYPE to be a type of pointers to TO_TYPE. If TO_TYPE is not permanent and has no pointer-type yet, record TYPE as its pointer-type. */ @@ -2250,7 +2359,7 @@ void smash_to_pointer_type (type, to_type) struct type *type, *to_type; { - int type_permanent = (TYPE_FLAGS (type) & TYPE_FLAG_PERM); +/* int type_permanent = (TYPE_FLAGS (type) & TYPE_FLAG_PERM); */ bzero (type, sizeof (struct type)); TYPE_TARGET_TYPE (type) = to_type; @@ -2261,33 +2370,34 @@ smash_to_pointer_type (type, to_type) /* ??? TYPE_TARGET_TYPE and TYPE_MAIN_VARIANT are the same. You can't do this. It will break the target type!!! TYPE_MAIN_VARIANT (type) = type; -*/ if (type_permanent) TYPE_FLAGS (type) |= TYPE_FLAG_PERM; +*/ - if (TYPE_POINTER_TYPE (to_type) == 0 + if (TYPE_POINTER_TYPE (to_type) == 0) +#if 0 && (!(TYPE_FLAGS (to_type) & TYPE_FLAG_PERM) || type_permanent)) +#endif /* 0 */ { TYPE_POINTER_TYPE (to_type) = type; } } -#endif -#else /* IBM6000 */ +#else /* IBM6000_HOST */ struct type * builtin_type (pp) char **pp; { fatal ("internals eror: builtin_type called!"); } -#endif /* IBM6000 */ +#endif /* IBM6000_HOST */ #define DEBUG 1 -#if defined (DEBUG) && defined (IBM6000) /* Needs both defined */ +#if defined (DEBUG) && defined (IBM6000_HOST) /* Needs both defined */ void dump_strtbl () { diff --git a/gdb/xcoffsolib.c b/gdb/xcoffsolib.c new file mode 100644 index 00000000000..0ad843225e7 --- /dev/null +++ b/gdb/xcoffsolib.c @@ -0,0 +1,177 @@ +#include +#include +#include + +#include "defs.h" +#include "bfd.h" +/*#include "libbfd.h" /* BFD internals (sigh!) FIXME */ +#include "xcoffsolib.h" + + +extern struct symtab *current_source_symtab; +extern int current_source_line; + + +/* The real work of adding a shared library file to the symtab and + the section list. */ + +void +solib_add (arg_string, from_tty, target) + char *arg_string; + int from_tty; + struct target_ops *target; +{ + char *val; + struct vmap *vp = vmap; + struct objfile *obj; + struct symtab *saved_symtab; + int saved_line; + + int loaded = 0; /* true if any shared obj loaded */ + int matched = 0; /* true if any shared obj matched */ + + if (arg_string == 0) + re_comp ("."); + else if (val = (char *) re_comp (arg_string)) { + error ("Invalid regexp: %s", val); + } + if (!vp || !vp->nxt) + return; + + /* save current symbol table and line number, in case they get changed + in symbol loading process. */ + + saved_symtab = current_source_symtab; + saved_line = current_source_line; + + /* skip over the first vmap, it is the main program, always loaded. */ + vp = vp->nxt; + + for (; vp; vp = vp->nxt) { + + if (re_exec (vp->name) || (*vp->member && re_exec (vp->member))) { + + matched = 1; + + /* if already loaded, continue with the next one. */ + if (vp->loaded) { + + printf ("%s%s%s%s: already loaded.\n", + *vp->member ? "(" : "", + vp->member, + *vp->member ? ") " : "", + vp->name); + continue; + } + + printf ("Loading %s%s%s%s...", + *vp->member ? "(" : "", + vp->member, + *vp->member ? ") " : "", + vp->name); + fflush (stdout); + + obj = lookup_objfile_bfd (vp->bfd); + if (!obj) { + warning ("\nObj structure for the shared object not found. Loading failed."); + continue; + } + + syms_from_objfile (obj, 0, 0); + vmap_symtab (vp, 0, 0); + printf ("Done.\n"); + loaded = vp->loaded = 1; + } + } + /* if any shared object is loaded, then misc_func_vector needs sorting. */ + if (loaded) { +#if 0 + sort_misc_function_vector (); +#endif + current_source_symtab = saved_symtab; + current_source_line = saved_line; + + /* Getting new symbols might change our opinion about what is frameless. + Is this correct?? FIXME. */ +/* reinit_frame_cache(); */ + } + else if (!matched) + printf ("No matching shared object found.\n"); + +} + + +/* Return the module name of a given text address. Note that returned buffer + is not persistent. */ + +char * +pc_load_segment_name (addr) +CORE_ADDR addr; +{ + static char buffer [BUFSIZ]; + struct vmap *vp = vmap; + + buffer [0] = buffer [1] = '\0'; + for (; vp; vp = vp->nxt) + if (vp->tstart <= addr && addr < vp->tend) { + if (*vp->member) { + buffer [0] = '('; + strcat (&buffer[1], vp->member); + strcat (buffer, ")"); + } + strcat (buffer, vp->name); + return buffer; + } + return "(unknown load module)"; +} + + +solib_info (ldi) +register struct ld_info *ldi; +{ + + struct vmap *vp = vmap; + + if (!vp || !vp->nxt) { + printf("No shared libraries loaded at this time.\n"); + return; + } + + /* skip over the first vmap, it is the main program, always loaded. */ + vp = vp->nxt; + + printf ("\ +Text Range Data Range Syms Shared Object Library\n"); + + for (; vp; vp = vp->nxt) { + + printf ("0x%08x-0x%08x 0x%08x-0x%08x %s %s%s%s%s\n", + vp->tstart, vp->tend, + vp->dstart, vp->dend, + vp->loaded ? "Yes" : "No ", + *vp->member ? "(" : "", + vp->member, + *vp->member ? ") " : "", + vp->name); + } +} + + +void +sharedlibrary_command (args, from_tty) + char *args; + int from_tty; +{ + dont_repeat(); + solib_add (args, from_tty, (struct target_ops *)0); +} + +void +_initialize_solib() +{ + + add_com("sharedlibrary", class_files, sharedlibrary_command, + "Load shared object library symbols for files matching REGEXP."); + add_info("sharedlibrary", solib_info, + "Status of loaded shared object libraries"); +} diff --git a/gdb/xcoffsolib.h b/gdb/xcoffsolib.h new file mode 100644 index 00000000000..9e5e4ef910d --- /dev/null +++ b/gdb/xcoffsolib.h @@ -0,0 +1,33 @@ +/* + the vmap struct is used to describe the virtual address space of + the target we are manipulating. The first entry is always the "exec" + file. Subsequent entries correspond to other objects that are + mapped into the address space of a process created from the "exec" file. + These are either in response to exec()ing the file, in which case all + shared libraries are loaded, or a "load" system call, followed by the + user's issuance of a "load" command. */ + +struct vmap { + struct vmap *nxt; /* ^ to next in chain */ + bfd *bfd; /* BFD for mappable object library */ + char *name; /* ^ to object file name */ + char *member; /* ^ to member name */ + CORE_ADDR tstart; /* virtual addr where member is mapped */ + CORE_ADDR tend; /* virtual upper bound of member */ + CORE_ADDR tadj; /* heuristically derived adjustment */ + CORE_ADDR dstart; /* virtual address of data start */ + CORE_ADDR dend; /* vitrual address of data end */ + + CORE_ADDR ostart; /* objext start ??? */ + unsigned loaded:1; /* True if symbols are loaded */ + unsigned reloced:1; /* True, if symbols relocated */ + unsigned padding:14; +}; + + +struct vmap_and_bfd { + bfd *pbfd; + struct vmap *pvmap; +}; + +extern struct vmap *vmap; diff --git a/gdb/xm-rs6000.h b/gdb/xm-rs6000.h index ab594317de0..f75cead2b9a 100644 --- a/gdb/xm-rs6000.h +++ b/gdb/xm-rs6000.h @@ -72,9 +72,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define CPLUS_MARKER '.' /* Flag for machine-specific stuff in shared files. FIXME */ -#ifndef IBM6000 -#define IBM6000 -#endif +#define IBM6000_HOST /* /usr/include/stdlib.h always uses void* and void, even when __STDC__ isn't defined. */ -- 2.30.2